summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkugwa <kugwa2000@gmail.com>2016-01-03 21:45:40 +0800
committerkugwa <kugwa2000@gmail.com>2016-01-03 21:45:40 +0800
commitaac182f56b27cbdfcb924977efb74ea58d022ff8 (patch)
tree8e8212952d5dfe9e90cdfbc2a06e0cf6c0e53322
parent370a09d0b6408079e0eb8240c4d9517e216028a3 (diff)
downloadcompiler2015-aac182f56b27cbdfcb924977efb74ea58d022ff8.tar
compiler2015-aac182f56b27cbdfcb924977efb74ea58d022ff8.tar.gz
compiler2015-aac182f56b27cbdfcb924977efb74ea58d022ff8.tar.bz2
compiler2015-aac182f56b27cbdfcb924977efb74ea58d022ff8.tar.lz
compiler2015-aac182f56b27cbdfcb924977efb74ea58d022ff8.tar.xz
compiler2015-aac182f56b27cbdfcb924977efb74ea58d022ff8.tar.zst
compiler2015-aac182f56b27cbdfcb924977efb74ea58d022ff8.zip
Complete array reference for storing local variables
-rw-r--r--src/code-generation.c59
1 files changed, 41 insertions, 18 deletions
diff --git a/src/code-generation.c b/src/code-generation.c
index e65c2ba..a72cb17 100644
--- a/src/code-generation.c
+++ b/src/code-generation.c
@@ -135,6 +135,7 @@ static void load_variable(CcmmcAst *id, CcmmcState *state, CcmmcTmp *dist,
fprintf(state->asm_output, "\t/* var load, line %zu */\n", id->line_number);
if (ccmmc_symbol_attr_is_global(&var_sym->attr)) {
+ // TODO: global array
dist_reg = ccmmc_register_lock(state->reg_pool, dist);
fprintf(state->asm_output,
"\tadrp\t" REG_TMP ", %s\n"
@@ -142,7 +143,7 @@ static void load_variable(CcmmcAst *id, CcmmcState *state, CcmmcTmp *dist,
"\tldr\t%s, [" REG_TMP "]\n", var_name, var_name, dist_reg);
ccmmc_register_unlock(state->reg_pool, dist);
} else {
- if(id->value_id.kind != CCMMC_KIND_ID_ARRAY) {
+ if (id->value_id.kind != CCMMC_KIND_ID_ARRAY) {
dist_reg = ccmmc_register_lock(state->reg_pool, dist);
if (safe_immediate(var_sym->attr.addr)) {
fprintf(state->asm_output,
@@ -181,26 +182,54 @@ static void load_variable(CcmmcAst *id, CcmmcState *state, CcmmcTmp *dist,
}
}
-static inline void store_variable(CcmmcAst *id, CcmmcState *state, const char *r) {
- fprintf(state->asm_output, "\t/* var store, line %zu */\n", id->line_number);
- const char *var_name = id->value_id.name;
+static void store_variable(CcmmcAst *id, CcmmcState *state, CcmmcTmp *src,
+ uint64_t *current_offset)
+{
+ const char *src_reg, *var_name = id->value_id.name;
CcmmcSymbol *var_sym = ccmmc_symbol_table_retrieve(state->table, var_name);
- // TODO: array
+
+ fprintf(state->asm_output, "\t/* var store, line %zu */\n", id->line_number);
if (ccmmc_symbol_attr_is_global(&var_sym->attr)) {
+ //TODO: global array
fprintf(state->asm_output,
"\tadrp\t" REG_TMP ", %s\n"
"\tadd\t" REG_TMP ", " REG_TMP ", #:lo12:%s\n"
- "\tstr\t%s, [" REG_TMP "]\n", var_name, var_name, r);
+ "\tstr\t%s, [" REG_TMP "]\n", var_name, var_name, src_reg);
} else {
- if (safe_immediate(var_sym->attr.addr)) {
- fprintf(state->asm_output,
- "\tstr\t%s, [fp, #-%" PRIu64 "]\n", r, var_sym->attr.addr);
- } else {
+ if (id->value_id.kind != CCMMC_KIND_ID_ARRAY) {
+ src_reg = ccmmc_register_lock(state->reg_pool, src);
+ if (safe_immediate(var_sym->attr.addr)) {
+ fprintf(state->asm_output,
+ "\tstr\t%s, [fp, #-%" PRIu64 "]\n", src_reg, var_sym->attr.addr);
+ } else {
+ fprintf(state->asm_output,
+ "\tldr\t" REG_TMP ", =%" PRIu64 "\n"
+ "\tsub\t" REG_TMP ", fp, " REG_TMP "\n"
+ "\tstr\t%s, [" REG_TMP "]\n",
+ var_sym->attr.addr, src_reg);
+ }
+ ccmmc_register_unlock(state->reg_pool, src);
+ }
+ else {
+ CcmmcTmp *offset;
+ const char *offset_reg;
+
+ offset = ccmmc_register_alloc(state->reg_pool, current_offset);
+ calc_array_offset(id, &var_sym->type, state, offset, current_offset);
+
+ src_reg = ccmmc_register_lock(state->reg_pool, src);
+ offset_reg = ccmmc_register_lock(state->reg_pool, offset);
+
fprintf(state->asm_output,
"\tldr\t" REG_TMP ", =%" PRIu64 "\n"
"\tsub\t" REG_TMP ", fp, " REG_TMP "\n"
+ "\tadd\t" REG_TMP ", " REG_TMP ", %s\n"
"\tstr\t%s, [" REG_TMP "]\n",
- var_sym->attr.addr, r);
+ var_sym->attr.addr, offset_reg, src_reg);
+
+ ccmmc_register_unlock(state->reg_pool, src);
+ ccmmc_register_unlock(state->reg_pool, offset);
+ ccmmc_register_free(state->reg_pool, offset, current_offset);
}
}
}
@@ -673,16 +702,10 @@ static void calc_expression_result(CcmmcAst *expr, CcmmcAstValueType type,
static void calc_and_save_expression_result(CcmmcAst *lvar, CcmmcAst *expr,
CcmmcState *state, uint64_t *current_offset)
{
- const char *result_reg;
CcmmcTmp *result;
-
result = ccmmc_register_alloc(state->reg_pool, current_offset);
calc_expression_result(expr, lvar->type_value, state, result, current_offset);
-
- result_reg = ccmmc_register_lock(state->reg_pool, result);
- store_variable(lvar, state, result_reg);
- ccmmc_register_unlock(state->reg_pool, result);
-
+ store_variable(lvar, state, result, current_offset);
ccmmc_register_free(state->reg_pool, result, current_offset);
}