diff options
author | Ting-Wei Lan <lantw44@gmail.com> | 2015-12-31 03:53:03 +0800 |
---|---|---|
committer | Ting-Wei Lan <lantw44@gmail.com> | 2015-12-31 03:53:03 +0800 |
commit | 8e85068ff1b04a091d3c0d82d836e98bbe65fbd5 (patch) | |
tree | b9e94375c3332345563dd7ca9fd50cde0524f1bd | |
parent | a95fb07e9e74d8c8a4d1295211cb3d996c68a89c (diff) | |
download | compiler2015-8e85068ff1b04a091d3c0d82d836e98bbe65fbd5.tar compiler2015-8e85068ff1b04a091d3c0d82d836e98bbe65fbd5.tar.gz compiler2015-8e85068ff1b04a091d3c0d82d836e98bbe65fbd5.tar.bz2 compiler2015-8e85068ff1b04a091d3c0d82d836e98bbe65fbd5.tar.lz compiler2015-8e85068ff1b04a091d3c0d82d836e98bbe65fbd5.tar.xz compiler2015-8e85068ff1b04a091d3c0d82d836e98bbe65fbd5.tar.zst compiler2015-8e85068ff1b04a091d3c0d82d836e98bbe65fbd5.zip |
Generate code for global variable declarations
-rw-r--r-- | src/code-generation.c | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/src/code-generation.c b/src/code-generation.c index aa75f79..bba70c9 100644 --- a/src/code-generation.c +++ b/src/code-generation.c @@ -10,19 +10,58 @@ static void generate_global_variable(CcmmcAst *global_decl, CcmmcState *state) { - fputs("\t.data\n", state->asm_output); + fputs("\t.data\n\t.align\t2\n", state->asm_output); for (CcmmcAst *var_decl = global_decl->child->right_sibling; var_decl != NULL; var_decl = var_decl->right_sibling) { CcmmcSymbol *var_sym = ccmmc_symbol_table_retrieve(state->table, var_decl->value_id.name); switch (var_decl->value_id.kind) { case CCMMC_KIND_ID_NORMAL: - fprintf(state->asm_output, "\t.comm %s, 4\n", var_sym->name); - break; - case CCMMC_KIND_ID_ARRAY: - break; - case CCMMC_KIND_ID_WITH_INIT: + fprintf(state->asm_output, "\t.comm\t%s, 4\n", var_sym->name); break; + case CCMMC_KIND_ID_ARRAY: { + size_t total_elements = 1; + assert(var_sym->type.array_dimension > 0); + for (size_t i = 0; i < var_sym->type.array_dimension; i++) + total_elements *= var_sym->type.array_size[i]; + fprintf(state->asm_output, "\t.comm\t%s, %zu\n", + var_sym->name, total_elements * 4); + } break; + case CCMMC_KIND_ID_WITH_INIT: { + CcmmcAst *init_value = var_decl->child; + fprintf(state->asm_output, "\t.size\t%s, 4\n", var_sym->name); + if (var_sym->type.type_base == CCMMC_AST_VALUE_INT) { + int int_value; + if (init_value->type_node == CCMMC_AST_NODE_CONST_VALUE) { + assert(init_value->value_const.kind == CCMMC_KIND_CONST_INT); + int_value = init_value->value_const.const_int; + } else if (init_value->type_node == CCMMC_AST_NODE_EXPR) { + assert(ccmmc_ast_expr_get_is_constant(init_value)); + assert(ccmmc_ast_expr_get_is_int(init_value)); + int_value = ccmmc_ast_expr_get_int(init_value); + } else { + assert(false); + } + fprintf(state->asm_output, "%s:\n\t.word\t%d\n", + var_sym->name, int_value); + } else if (var_sym->type.type_base == CCMMC_AST_VALUE_FLOAT) { + float float_value; + if (init_value->type_node == CCMMC_AST_NODE_CONST_VALUE) { + assert(init_value->value_const.kind == CCMMC_KIND_CONST_FLOAT); + float_value = init_value->value_const.const_float; + } else if (init_value->type_node == CCMMC_AST_NODE_EXPR) { + assert(ccmmc_ast_expr_get_is_constant(init_value)); + assert(ccmmc_ast_expr_get_is_float(init_value)); + float_value = ccmmc_ast_expr_get_float(init_value); + } else { + assert(false); + } + fprintf(state->asm_output, "%s:\n\t.float\t%.9g\n", + var_sym->name, float_value); + } else { + assert(false); + } + } break; default: assert(false); } |