- Structure handling fixes.

- Fix for asm statements with multiple results.


git-svn-id: svn://svn.coreboot.org/coreboot/trunk@942 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Eric Biederman 2003-07-12 01:21:31 +00:00
parent a3c708b5d2
commit e058a1e418
2 changed files with 72 additions and 19 deletions

View 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 $@

View 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,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;