diff --git a/util/romcc/Makefile b/util/romcc/Makefile index 6161ad3e1e..71a97d1f25 100644 --- a/util/romcc/Makefile +++ b/util/romcc/Makefile @@ -74,6 +74,7 @@ TESTS=\ simple_test54.c \ simple_test55.c \ simple_test56.c \ + simple_test59.c \ raminit_test.c \ raminit_test2.c \ raminit_test3.c \ @@ -95,10 +96,10 @@ FAIL_OUT:=$(patsubst %.c, tests/%.out, $(FAIL_TESTS)) $(TEST_ASM): %.S: %.c romcc - export ALLOC_CHECK_=2; ./romcc -O2 -mcpu=k8 -o $@ $< > $*.debug + export ALLOC_CHECK_=2; ./romcc -O -mcpu=k8 -o $@ $< > $*.debug $(FAIL_OUT): %.out: %.c romcc - export ALLOC_CHECK_=2; if ./romcc -O2 -o $*.S $< > $*.debug 2> $@ ; then exit 1 ; else exit 0 ; fi + export ALLOC_CHECK_=2; if ./romcc -O -o $*.S $< > $*.debug 2> $@ ; then exit 1 ; else exit 0 ; fi $(TEST_OBJ): %.o: %.S as $< -o $@ diff --git a/util/romcc/romcc.c b/util/romcc/romcc.c index 42e06d3498..386d86a238 100644 --- a/util/romcc/romcc.c +++ b/util/romcc/romcc.c @@ -4002,7 +4002,7 @@ static size_t size_of(struct compile_state *state, struct type *type) } align = align_of(state, type); pad = needed_padding(size, align); - size = size + pad + sizeof(type); + size = size + pad + size_of(state, type); break; } case TYPE_OVERLAP: @@ -4021,8 +4021,15 @@ static size_t size_of(struct compile_state *state, struct type *type) } break; case TYPE_STRUCT: + { + size_t align, pad; size = size_of(state, type->left); + /* Pad structures so their size is a multiples of their alignment */ + align = align_of(state, type); + pad = needed_padding(size, align); + size = size + pad; break; + } default: internal_error(state, 0, "sizeof not yet defined for type\n"); break; @@ -4617,7 +4624,7 @@ static struct triple *read_expr(struct compile_state *state, struct triple *def) return triple(state, op, def->type, def, 0); } -static void write_compatible(struct compile_state *state, +int is_write_compatible(struct compile_state *state, struct type *dest, struct type *rval) { int compatible = 0; @@ -4642,11 +4649,31 @@ static void write_compatible(struct compile_state *state, (dest->type_ident == rval->type_ident)) { compatible = 1; } - if (!compatible) { + return compatible; +} + + +static void write_compatible(struct compile_state *state, + struct type *dest, struct type *rval) +{ + if (!is_write_compatible(state, dest, rval)) { error(state, 0, "Incompatible types in assignment"); } } +static int is_init_compatible(struct compile_state *state, + struct type *dest, struct type *rval) +{ + int compatible = 0; + if (is_write_compatible(state, dest, rval)) { + compatible = 1; + } + else if (equiv_types(dest, rval)) { + compatible = 1; + } + return compatible; +} + static struct triple *write_expr( struct compile_state *state, struct triple *dest, struct triple *rval) { @@ -5430,6 +5457,15 @@ static struct triple *mk_subscript_expr( return mk_deref_expr(state, mk_add_expr(state, left, right)); } +static struct triple *mk_cast_expr( + struct compile_state *state, struct type *type, struct triple *expr) +{ + struct triple *def; + def = read_expr(state, expr); + def = triple(state, OP_COPY, type, def, 0); + return def; +} + /* * Compile time evaluation * =========================== @@ -7333,8 +7369,7 @@ static struct triple *cast_expr(struct compile_state *state) eat(state, TOK_LPAREN); type = type_name(state); eat(state, TOK_RPAREN); - def = read_expr(state, cast_expr(state)); - def = triple(state, OP_COPY, type, def, 0); + def = mk_cast_expr(state, type, cast_expr(state)); } else { def = unary_expr(state); @@ -8182,7 +8217,6 @@ static void asm_statement(struct compile_state *state, struct triple *first) error(state, 0, "Maximum clobber limit exceeded."); } clobber = string_constant(state); - eat(state, TOK_RPAREN); clob_param[clobbers].constraint = clobber; if (peek(state) == TOK_COMMA) { @@ -8250,21 +8284,22 @@ static void asm_statement(struct compile_state *state, struct triple *first) RHS(def, i) = read_expr(state,in_param[i].expr); } flatten(state, first, def); - for(i = 0; i < out; i++) { + for(i = 0; i < (out + clobbers); i++) { + struct type *type; struct triple *piece; - piece = triple(state, OP_PIECE, out_param[i].expr->type, def, 0); - piece->u.cval = i; - LHS(def, i) = piece; - flatten(state, first, - write_expr(state, out_param[i].expr, piece)); - } - for(; i - out < clobbers; i++) { - struct triple *piece; - piece = triple(state, OP_PIECE, &void_type, def, 0); + type = (i < out)? out_param[i].expr->type : &void_type; + piece = triple(state, OP_PIECE, type, def, 0); piece->u.cval = i; LHS(def, i) = piece; flatten(state, first, piece); } + /* And write the helpers to their destinations */ + for(i = 0; i < out; i++) { + struct triple *piece; + piece = LHS(def, i); + flatten(state, first, + write_expr(state, out_param[i].expr, piece)); + } } @@ -8627,7 +8662,9 @@ static struct type *struct_or_union_specifier( struct_type = new_type(TYPE_STRUCT | spec, struct_type, 0); struct_type->type_ident = ident; struct_type->elements = elements; - symbol(state, ident, &ident->sym_struct, 0, struct_type); + if (ident) { + symbol(state, ident, &ident->sym_struct, 0, struct_type); + } } if (ident && ident->sym_struct) { struct_type = clone_type(spec, ident->sym_struct->type); @@ -9015,8 +9052,23 @@ static struct triple *initializer( struct compile_state *state, struct type *type) { struct triple *result; +#warning "FIXME handle string pointer initializers " +#warning "FIXME more consistent initializer handling (where should eval_const_expr go?" if (peek(state) != TOK_LBRACE) { result = assignment_expr(state); + if (((type->type & TYPE_MASK) == TYPE_ARRAY) && + (type->elements == ELEMENT_COUNT_UNSPECIFIED) && + ((result->type->type & TYPE_MASK) == TYPE_ARRAY) && + (result->type->elements != ELEMENT_COUNT_UNSPECIFIED) && + (equiv_types(type->left, result->type->left))) { + type->elements = result->type->elements; + } + if (!is_init_compatible(state, type, result->type)) { + error(state, 0, "Incompatible types in initializer"); + } + if (!equiv_types(type, result->type)) { + result = mk_cast_expr(state, type, result); + } } else { int comma;