summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkugwa <kugwa2000@gmail.com>2016-01-18 18:42:20 +0800
committerkugwa <kugwa2000@gmail.com>2016-01-18 18:44:07 +0800
commite9435761fc4aafe290fe128ac8198afcce796b7e (patch)
tree9ee691f3b7e05e7155e5a87da803637d9e66983b
parent3f7afe9f13b43a6153d0740d2a2f912a6f85560a (diff)
downloadcompiler2015-e9435761fc4aafe290fe128ac8198afcce796b7e.tar
compiler2015-e9435761fc4aafe290fe128ac8198afcce796b7e.tar.gz
compiler2015-e9435761fc4aafe290fe128ac8198afcce796b7e.tar.bz2
compiler2015-e9435761fc4aafe290fe128ac8198afcce796b7e.tar.lz
compiler2015-e9435761fc4aafe290fe128ac8198afcce796b7e.tar.xz
compiler2015-e9435761fc4aafe290fe128ac8198afcce796b7e.tar.zst
compiler2015-e9435761fc4aafe290fe128ac8198afcce796b7e.zip
Complete code-gen of for statement
-rw-r--r--src/code-generation.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/src/code-generation.c b/src/code-generation.c
index 2aee268..7bc3416 100644
--- a/src/code-generation.c
+++ b/src/code-generation.c
@@ -830,8 +830,57 @@ static void generate_statement(
label_exit);
#undef FPREG_TMP
} break;
- case CCMMC_KIND_STMT_FOR:
- break;
+ case CCMMC_KIND_STMT_FOR: {
+#define FPREG_TMP "s16"
+ size_t label_cmp = state->label_number++;
+ size_t label_exit = state->label_number++;
+ const char *result_reg;
+ CcmmcTmp *result = ccmmc_register_alloc(state->reg_pool, &current_offset);
+
+ for (CcmmcAst *assign = stmt->child->child; assign != NULL;
+ assign = assign->right_sibling) {
+ generate_statement(assign, state, current_offset);
+ }
+
+ // for condition
+ fprintf(state->asm_output, ".LC%zu:\n", label_cmp);
+ for (CcmmcAst *expr = stmt->child->right_sibling->child; expr != NULL;
+ expr = expr->right_sibling) {
+ generate_expression(expr, state, result, &current_offset);
+ }
+ result_reg = ccmmc_register_lock(state->reg_pool, result);
+ if (stmt->child->type_value == CCMMC_AST_VALUE_FLOAT)
+ fprintf(state->asm_output,
+ "\tfmov\t%s, %s\n"
+ "\tfcmp\t%s, #0.0\n"
+ "\tb.e\t.LC%zu\n",
+ FPREG_TMP,
+ result_reg,
+ FPREG_TMP,
+ label_exit);
+ else
+ fprintf(state->asm_output,
+ "\tcbz\t%s, .LC%zu\n",
+ result_reg,
+ label_exit);
+ ccmmc_register_unlock(state->reg_pool, result);
+ ccmmc_register_free(state->reg_pool, result, &current_offset);
+
+ // for body
+ generate_statement(
+ stmt->child->right_sibling->right_sibling->right_sibling,
+ state, current_offset);
+ for (CcmmcAst *assign = stmt->child->right_sibling->right_sibling->child;
+ assign != NULL; assign = assign->right_sibling) {
+ generate_statement(assign, state, current_offset);
+ }
+ fprintf(state->asm_output,
+ "\tb\t.LC%zu\n"
+ ".LC%zu:\n",
+ label_cmp,
+ label_exit);
+#undef FPREG_TMP
+ } break;
case CCMMC_KIND_STMT_ASSIGN:
calc_and_save_expression_result(stmt->child,
stmt->child->right_sibling, state, &current_offset);