aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2004-08-01 02:40:44 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:02:29 -0700
commit1997b4c9ef9bb8df4c3cff44d73bd9a2ba7422b3 (patch)
treedaf9bae35f2980596e67485983c1a592e47007b5 /compile-i386.c
parentFix symbol copy on inlining. (diff)
downloadsparse-1997b4c9ef9bb8df4c3cff44d73bd9a2ba7422b3.tar.gz
sparse-1997b4c9ef9bb8df4c3cff44d73bd9a2ba7422b3.tar.bz2
sparse-1997b4c9ef9bb8df4c3cff44d73bd9a2ba7422b3.zip
[be] fix some of the brokenness related to non-32-bit variables
Assumptions that values are 32-bit still remain in places, but some simple test cases involving 8-bit and 16-bit variables seem much more sane now.
Diffstat (limited to 'compile-i386.c')
-rw-r--r--compile-i386.c60
1 files changed, 37 insertions, 23 deletions
diff --git a/compile-i386.c b/compile-i386.c
index b92575e..a5467e7 100644
--- a/compile-i386.c
+++ b/compile-i386.c
@@ -234,6 +234,22 @@ static struct storage *x86_statement(struct statement *stmt);
static struct storage *x86_expression(struct expression *expr);
+static struct storage *temp_from_bits(unsigned int bit_size)
+{
+ switch(bit_size) {
+ case 8: return REG_AL;
+ case 16: return REG_AX;
+ case 32: return REG_EAX;
+
+ case 64: /* FIXME */
+ default:
+ assert(0);
+ break;
+ }
+
+ return NULL;
+}
+
static inline unsigned int pseudo_offset(struct storage *s)
{
if (s->type != STOR_PSEUDO)
@@ -375,7 +391,7 @@ static struct storage *stack_alloc(int n_bytes)
stor = new_storage(STOR_PSEUDO);
stor->type = STOR_PSEUDO;
stor->pseudo = f->pseudo_nr;
- stor->offset = f->stack_size;
+ stor->offset = f->stack_size; /* FIXME: stack req. natural align */
stor->size = n_bytes;
f->stack_size += n_bytes;
f->pseudo_nr++;
@@ -931,28 +947,26 @@ static void emit_copy(struct storage *dest, struct storage *src,
struct symbol *ctype)
{
struct storage *reg = NULL;
+ unsigned int bit_size;
- /* FIXME: Bitfield move! */
+ /* FIXME: Bitfield copy! */
- switch (ctype->bit_size) {
- case 8:
- reg = REG_AL;
- break;
- case 16:
- reg = REG_AX;
- break;
- case 32:
- reg = REG_EAX;
- break;
- case 64:
- reg = REG_EAX; /* FIXME */
- break;
- default:
- assert(0);
- break;
- }
+ bit_size = src->size * 8;
+ if (!bit_size)
+ bit_size = 32;
+ if ((src->type == STOR_ARG) && (bit_size < 32))
+ bit_size = 32;
+ reg = temp_from_bits(bit_size);
emit_move(src, reg, ctype, "begin copy ..");
+
+ bit_size = dest->size * 8;
+ if (!bit_size)
+ bit_size = 32;
+ if ((dest->type == STOR_ARG) && (bit_size < 32))
+ bit_size = 32;
+
+ reg = temp_from_bits(bit_size);
emit_move(reg, dest, ctype, ".... end copy");
}
@@ -1210,7 +1224,7 @@ static struct storage *emit_binop(struct expression *expr)
insn(opstr, left, accum_reg, NULL);
/* store result (EAX or EDX) in new pseudo / stack slot */
- new = stack_alloc(4);
+ new = stack_alloc(expr->ctype->bit_size / 8);
insn(movstr, result_reg, new,
doing_divide ? "end EXPR_DIVIDE" : "end EXPR_BINOP");
@@ -1407,7 +1421,7 @@ static struct storage *emit_cast_expr(struct expression *expr)
emit_move(op, REG_EAX, old_type, "begin cast ..");
- new = stack_alloc(4);
+ new = stack_alloc(newbits / 8);
emit_move(REG_EAX, new, new_type, ".... end cast");
return new;
@@ -1493,7 +1507,7 @@ static void emit_switch_statement(struct statement *stmt)
label = new_storage(STOR_LABEL);
label->flags |= STOR_WANTS_FREE;
label->label = next_test = new_label();
-
+
/* FIXME: signed/unsigned */
insn("jl", label, NULL, NULL);
@@ -1504,7 +1518,7 @@ static void emit_switch_statement(struct statement *stmt)
label = new_storage(STOR_LABEL);
label->flags |= STOR_WANTS_FREE;
label->label = next_test;
-
+
/* FIXME: signed/unsigned */
insn("jg", label, NULL, NULL);