Fix branch label handling.

Conditional branches and goto now go to the correct location.
This commit is contained in:
Bill Currie 2011-01-27 21:11:32 +09:00
parent 95b17d9fd4
commit 4738c767a2
2 changed files with 16 additions and 9 deletions

View file

@ -120,6 +120,18 @@ add_statement_def_ref (def_t *def, dstatement_t *st, int field)
} }
} }
static void
add_statement_op_ref (operand_t *op, dstatement_t *st, int field)
{
if (op && op->op_type == op_label) {
int st_ofs = st - pr.code->code;
reloc_t *reloc = new_reloc (st_ofs, rel_op_a_op + field);
reloc->next = op->o.label->dest->relocs;
op->o.label->dest->relocs = reloc;
}
}
static void static void
emit_statement (statement_t *statement) emit_statement (statement_t *statement)
{ {
@ -141,6 +153,10 @@ emit_statement (statement_t *statement)
add_statement_def_ref (def_a, s, 0); add_statement_def_ref (def_a, s, 0);
add_statement_def_ref (def_b, s, 1); add_statement_def_ref (def_b, s, 1);
add_statement_def_ref (def_c, s, 2); add_statement_def_ref (def_c, s, 2);
add_statement_op_ref (statement->opa, s, 0);
add_statement_op_ref (statement->opb, s, 1);
add_statement_op_ref (statement->opc, s, 2);
} }
void void

View file

@ -660,20 +660,11 @@ statement_bool (sblock_t *sblock, expr_t *e)
static sblock_t * static sblock_t *
statement_label (sblock_t *sblock, expr_t *e) statement_label (sblock_t *sblock, expr_t *e)
{ {
reloc_t *r;
if (sblock->statements) { if (sblock->statements) {
sblock->next = new_sblock (); sblock->next = new_sblock ();
sblock = sblock->next; sblock = sblock->next;
} }
e->e.label.dest = sblock; e->e.label.dest = sblock;
for (r = e->e.label.refs; r && r->next; r = r->next)
;
if (r) {
r->next = sblock->relocs;
sblock->relocs = e->e.label.refs;
e->e.label.refs = 0;
}
return sblock; return sblock;
} }