summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTing-Wei Lan <lantw44@gmail.com>2016-01-20 15:47:11 +0800
committerTing-Wei Lan <lantw44@gmail.com>2016-01-20 15:47:11 +0800
commit80c985e625baabd65176bf2e6cca1dca9911a584 (patch)
treec26f10f5f2a19ab7dd13d4b6a01f9f0bc0ec993d
parentd78cec38b6850a5a59bd50da318f201528fdcb02 (diff)
downloadcompiler2015-80c985e625baabd65176bf2e6cca1dca9911a584.tar
compiler2015-80c985e625baabd65176bf2e6cca1dca9911a584.tar.gz
compiler2015-80c985e625baabd65176bf2e6cca1dca9911a584.tar.bz2
compiler2015-80c985e625baabd65176bf2e6cca1dca9911a584.tar.lz
compiler2015-80c985e625baabd65176bf2e6cca1dca9911a584.tar.xz
compiler2015-80c985e625baabd65176bf2e6cca1dca9911a584.tar.zst
compiler2015-80c985e625baabd65176bf2e6cca1dca9911a584.zip
Save arguments before calling any function
We should not skip the argument-saving step for functions without arguments of the special write function.
-rw-r--r--src/code-generation.c36
1 files changed, 20 insertions, 16 deletions
diff --git a/src/code-generation.c b/src/code-generation.c
index 8636322..361d596 100644
--- a/src/code-generation.c
+++ b/src/code-generation.c
@@ -405,29 +405,34 @@ static const char *call_write(CcmmcAst *id, CcmmcState *state,
static void call_function(CcmmcAst *id, CcmmcState *state,
uint64_t *current_offset)
{
+ // XXX: We should have a better way to find the function in which we are
+ CcmmcAst *in_func = id->parent;
+ for (; in_func->type_node != CCMMC_AST_NODE_DECL ||
+ in_func->value_decl.kind != CCMMC_KIND_DECL_FUNCTION;
+ in_func = in_func->parent);
+ // XXX: We should not search scopes other than the global scope
+ CcmmcSymbol *in_func_sym = ccmmc_symbol_table_retrieve(
+ state->table, in_func->child->right_sibling->value_id.name);
+ size_t stored_param_count = in_func_sym->type.param_count;
+
const char *func_name = id->value_id.name;
- size_t stored_param_count = 0;
- if (strcmp(func_name, "write") == 0)
+ if (strcmp(func_name, "write") == 0) {
+ ccmmc_register_save_arguments(state->reg_pool, stored_param_count);
+ ccmmc_register_caller_save(state->reg_pool);
func_name = call_write(id, state, current_offset);
- else if (strcmp(func_name, "read") == 0)
+ } else if (strcmp(func_name, "read") == 0) {
+ ccmmc_register_save_arguments(state->reg_pool, stored_param_count);
+ ccmmc_register_caller_save(state->reg_pool);
func_name = "_read_int";
- else if (strcmp(func_name, "fread") == 0)
+ } else if (strcmp(func_name, "fread") == 0) {
+ ccmmc_register_save_arguments(state->reg_pool, stored_param_count);
+ ccmmc_register_caller_save(state->reg_pool);
func_name = "_read_float";
- else if (id->right_sibling->child != NULL) {
+ } else if (id->right_sibling->child != NULL) {
CcmmcSymbol *func_sym = ccmmc_symbol_table_retrieve(
state->table, func_name);
size_t call_param_count = func_sym->type.param_count;
- // XXX: We should have a better way to find the function in which we are
- CcmmcAst *in_func = id->parent;
- for (; in_func->type_node != CCMMC_AST_NODE_DECL ||
- in_func->value_decl.kind != CCMMC_KIND_DECL_FUNCTION;
- in_func = in_func->parent);
- // XXX: We should not search scopes other than the global scope
- CcmmcSymbol *in_func_sym = ccmmc_symbol_table_retrieve(
- state->table, in_func->child->right_sibling->value_id.name);
- stored_param_count = in_func_sym->type.param_count;
-
CcmmcAst *arg;
CcmmcTmp *dists[call_param_count];
size_t i;
@@ -536,7 +541,6 @@ static void call_function(CcmmcAst *id, CcmmcState *state,
ccmmc_register_free(state->reg_pool, dists[i], current_offset);
return;
}
- ccmmc_register_caller_save(state->reg_pool);
fprintf(state->asm_output, "\tbl\t%s\n", func_name);
ccmmc_register_caller_load(state->reg_pool);
ccmmc_register_load_arguments(state->reg_pool, stored_param_count);