diff options
Diffstat (limited to 'src/gas_assembly_generator.c')
-rw-r--r-- | src/gas_assembly_generator.c | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/src/gas_assembly_generator.c b/src/gas_assembly_generator.c index b9b8537..dd5d240 100644 --- a/src/gas_assembly_generator.c +++ b/src/gas_assembly_generator.c @@ -54,6 +54,13 @@ gas_assembly_generator_set_latest_evaluation_to_rax(gas_assembly_generator_t *ge gen->latest_evaluation = (evaluation_result_t){ .kind = EVALUATION_RESULT_ON_RAX }; } +static void +gas_assembly_generator_set_latest_evaluation_on_stack(gas_assembly_generator_t *gen, int stack_offset) +{ + gen->latest_evaluation = + (evaluation_result_t){ .kind = EVALUATION_RESULT_ON_STACK, .data = { .stack_offset = stack_offset } }; +} + typedef struct ref_entry_t { ast_identifier_t *id; @@ -167,11 +174,15 @@ gas_assembly_generator_compile_variable_declaration(gas_assembly_generator_t *ge switch (gen->latest_evaluation.kind) { case EVALUATION_RESULT_AS_LITERAL_INTEGER: - fprintf(gen->stream, " mov $%ld, %d(%%rbp)\n", gen->latest_evaluation.data.literal_int, entry->stack_offset); + fprintf(gen->stream, " movq $%ld, %d(%%rbp)\n", gen->latest_evaluation.data.literal_int, entry->stack_offset); break; case EVALUATION_RESULT_ON_RAX: fprintf(gen->stream, " mov %%rax, %d(%%rbp)\n", entry->stack_offset); break; + case EVALUATION_RESULT_ON_STACK: + fprintf(gen->stream, " movq %d(%%rbp), %%rax\n", gen->latest_evaluation.data.stack_offset); + fprintf(gen->stream, " movq %%rax, %d(%%rbp)\n", entry->stack_offset); + break; case EVALUATION_RESULT_VOID: assert(false && "Unexpected void result for variable declaration"); // FIXME: store the latest node at latest evaluation and print_ast @@ -190,8 +201,7 @@ gas_assembly_generator_compile_variable(gas_assembly_generator_t *gen, ast_varia } } assert(entry && "reference not found"); - fprintf(gen->stream, " mov %d(%%rbp), %%rax\n", entry->stack_offset); - gas_assembly_generator_set_latest_evaluation_to_rax(gen); + gas_assembly_generator_set_latest_evaluation_on_stack(gen, entry->stack_offset); } static void @@ -228,15 +238,27 @@ gas_assembly_generator_binary_operation(gas_assembly_generator_t *gen, ast_binar fprintf(gen->stream, " mov %d(%%rbp), %%rcx\n", gen->stack_offset); gen->stack_offset += 8; break; + case EVALUATION_RESULT_ON_STACK: + fprintf(gen->stream, " movq %d(%%rbp), %%rcx\n", right_evaluation.data.stack_offset); + break; case EVALUATION_RESULT_VOID: - assert(false && "Unexpected void result for variable declaration"); + assert(false && "Unexpected void result for binary operation"); // FIXME: store the latest node at latest evaluation and print_ast } gas_assembly_generator_set_latest_evaluation_to_rax(gen); - if (left_evaluation.kind == EVALUATION_RESULT_AS_LITERAL_INTEGER) { - fprintf(gen->stream, " mov $%ld, %%rax\n", left_evaluation.data.literal_int); + switch (left_evaluation.kind) { + case EVALUATION_RESULT_AS_LITERAL_INTEGER: + fprintf(gen->stream, " mov $%ld, %%rax\n", left_evaluation.data.literal_int); + break; + case EVALUATION_RESULT_ON_STACK: + fprintf(gen->stream, " movq %d(%%rbp), %%rax\n", left_evaluation.data.stack_offset); + break; + case EVALUATION_RESULT_ON_RAX: + break; + case EVALUATION_RESULT_VOID: + assert(false && "Unexpected void result for binary operation"); } if (binary_operation->kind == AST_BINOP_ADITION) { |