- Structure handling fixes.
authorEric Biederman <ebiederm@xmission.com>
Sat, 12 Jul 2003 01:21:31 +0000 (01:21 +0000)
committerEric Biederman <ebiederm@xmission.com>
Sat, 12 Jul 2003 01:21:31 +0000 (01:21 +0000)
- Fix for asm statements with multiple results.

git-svn-id: svn://svn.coreboot.org/coreboot/trunk@942 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1

util/romcc/Makefile
util/romcc/romcc.c

index 6161ad3e1e1d8c812050e6c5b897d116e7679e39..71a97d1f25e65184b7beeebc4584674a1cff093d 100644 (file)
@@ -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 $@
index 42e06d3498cc0230c7b73cf0f75d779bd93c4ca2..386d86a238016988228b50bd96a4112db4213b9b 100644 (file)
@@ -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,20 +8284,21 @@ 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);
+               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,
-                       write_expr(state, out_param[i].expr, piece));
+               flatten(state, first, piece);
        }
-       for(; i - out < clobbers; i++) {
+       /* And write the helpers to their destinations */
+       for(i = 0; i < out; i++) {
                struct triple *piece;
-               piece = triple(state, OP_PIECE, &void_type, def, 0);
-               piece->u.cval = i;
-               LHS(def, i) = piece;
-               flatten(state, first, 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;