aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/compile-i386.c
diff options
authorJeff Garzik <jgarzik@redhat.com>2004-02-08 17:54:55 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:01:19 -0700
commit498702a84daebe5057284d0456217c2619f5cffe (patch)
tree499b14f6e40aeffde3aace9e05b270c49822b2e9 /compile-i386.c
parent19209d98da91c3407fb2325420fc3e4da79b1feb (diff)
downloadsparse-dev-498702a84daebe5057284d0456217c2619f5cffe.tar.gz
[be] Handle 'break' and 'continue' inside loops.
Diffstat (limited to 'compile-i386.c')
-rw-r--r--compile-i386.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/compile-i386.c b/compile-i386.c
index 004b454f..297bdb96 100644
--- a/compile-i386.c
+++ b/compile-i386.c
@@ -1561,7 +1561,7 @@ static int loopstk_continue(void)
return current_func->loop_stack->continue_lbl;
}
-static void x86_loop(struct statement *stmt)
+static void emit_loop(struct statement *stmt)
{
struct statement *pre_statement = stmt->iterator_pre_statement;
struct expression *pre_condition = stmt->iterator_pre_condition;
@@ -1674,7 +1674,7 @@ static struct storage *x86_statement(struct statement *stmt)
break;
case STMT_ITERATOR:
- x86_loop(stmt);
+ emit_loop(stmt);
break;
case STMT_NONE:
@@ -1689,6 +1689,16 @@ static struct storage *x86_statement(struct statement *stmt)
if (stmt->goto_expression) {
struct storage *val = x86_expression(stmt->goto_expression);
printf("\tgoto *v%d\n", val->pseudo);
+ } else if (!strcmp("break", show_ident(stmt->goto_label->ident))) {
+ struct storage *lbv = new_storage(STOR_LABEL);
+ lbv->label = loopstk_break();
+ lbv->flags = STOR_WANTS_FREE;
+ insn("jmp", lbv, NULL, "'break'; go to loop bottom");
+ } else if (!strcmp("continue", show_ident(stmt->goto_label->ident))) {
+ struct storage *lbv = new_storage(STOR_LABEL);
+ lbv->label = loopstk_continue();
+ lbv->flags = STOR_WANTS_FREE;
+ insn("jmp", lbv, NULL, "'continue'; go to loop top");
} else {
struct storage *labelsym = new_labelsym(stmt->goto_label);
insn("jmp", labelsym, NULL, NULL);