aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/compile-i386.c
diff options
authorJeff Garzik <jgarzik@redhat.com>2004-02-08 16:14:43 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:01:18 -0700
commitc9630e8363def11c0202332381c394d14ebf32ea (patch)
tree382ea093344dcc0184c6361b1707a72cec5b76af /compile-i386.c
parentbfcee9b9d5c517f38fcdabcb1ff4854e8e65b186 (diff)
downloadsparse-dev-c9630e8363def11c0202332381c394d14ebf32ea.tar.gz
[be] Get most of loops working.
The thing that remains is getting 'break' and 'continue' assigned to the correct jump targets.
Diffstat (limited to 'compile-i386.c')
-rw-r--r--compile-i386.c58
1 files changed, 46 insertions, 12 deletions
diff --git a/compile-i386.c b/compile-i386.c
index 1920ddcc..c1178581 100644
--- a/compile-i386.c
+++ b/compile-i386.c
@@ -1537,36 +1537,70 @@ static void x86_loop(struct statement *stmt)
if (pre_condition) {
if (pre_condition->type == EXPR_VALUE) {
if (!pre_condition->value) {
+ struct storage *lbv;
loop_bottom = new_label();
- printf("\tjmp\t\t.L%d\n", loop_bottom);
+
+ lbv = new_storage(STOR_LABEL);
+ lbv->label = loop_bottom;
+ lbv->flags = STOR_WANTS_FREE;
+ insn("jmp", lbv, NULL, "go to loop bottom");
}
} else {
+ struct storage *lbv = new_storage(STOR_LABEL);
loop_bottom = new_label();
+ lbv->label = loop_bottom;
+ lbv->flags = STOR_WANTS_FREE;
+
val = x86_expression(pre_condition);
- printf("\tje\t\tv%d, .L%d\n", val->pseudo, loop_bottom);
+
+ emit_move(val, REG_EAX, NULL, "loop pre condition");
+ insn("test", REG_EAX, REG_EAX, NULL);
+ insn("jz", lbv, NULL, NULL);
}
}
if (!post_condition || post_condition->type != EXPR_VALUE || post_condition->value) {
loop_top = new_label();
- printf(".L%d:\n", loop_top);
+ emit_label(loop_top, "loop top");
}
x86_statement(statement);
- if (stmt->iterator_continue->used)
- printf(".L%p:\n", stmt->iterator_continue);
+ if (stmt->iterator_continue->used) {
+ /* FIXME: incorrect; must get stmt->iterator_continue
+ * label emitted */
+ int incorrect_label = new_label();
+ emit_label(incorrect_label, "'continue' iterator");
+ }
x86_statement(post_statement);
if (!post_condition) {
- printf("\tjmp\t\t.L%d\n", loop_top);
+ struct storage *lbv = new_storage(STOR_LABEL);
+ lbv->label = loop_top;
+ lbv->flags = STOR_WANTS_FREE;
+ insn("jmp", lbv, NULL, "go to loop top");
} else if (post_condition->type == EXPR_VALUE) {
- if (post_condition->value)
- printf("\tjmp\t\t.L%d\n", loop_top);
+ if (post_condition->value) {
+ struct storage *lbv = new_storage(STOR_LABEL);
+ lbv->label = loop_top;
+ lbv->flags = STOR_WANTS_FREE;
+ insn("jmp", lbv, NULL, "go to loop top");
+ }
} else {
+ struct storage *lbv = new_storage(STOR_LABEL);
+ lbv->label = loop_top;
+ lbv->flags = STOR_WANTS_FREE;
+
val = x86_expression(post_condition);
- printf("\tjne\t\tv%d, .L%d\n", val->pseudo, loop_top);
+
+ emit_move(val, REG_EAX, NULL, "loop post condition");
+ insn("test", REG_EAX, REG_EAX, NULL);
+ insn("jnz", lbv, NULL, NULL);
+ }
+ if (stmt->iterator_break->used) {
+ /* FIXME: incorrect; must get stmt->iterator_break
+ * label emitted */
+ int incorrect_label = new_label();
+ emit_label(incorrect_label, "'break' target");
}
- if (stmt->iterator_break->used)
- printf(".L%p:\n", stmt->iterator_break);
if (loop_bottom)
- printf(".L%d:\n", loop_bottom);
+ emit_label(loop_bottom, "loop bottom");
}
/*