diff options
| author | Mustafa Quraish <[email protected]> | 2022-02-02 02:34:42 -0500 |
|---|---|---|
| committer | Mustafa Quraish <[email protected]> | 2022-02-02 02:34:42 -0500 |
| commit | 8ab8a025622f23354d205fa781a09b7c8cb00528 (patch) | |
| tree | 24348af68d0a9e8ee48ec66cc86777201183feda /src/generator.c | |
| parent | Add `size_for_type()` helper instead of hard-coding variable sizes (diff) | |
| download | cup-8ab8a025622f23354d205fa781a09b7c8cb00528.tar.xz cup-8ab8a025622f23354d205fa781a09b7c8cb00528.zip | |
Refactor variable access+assignment in terms of `generate_lvalue()`
This will make it trivial to compute pointers!
Diffstat (limited to 'src/generator.c')
| -rw-r--r-- | src/generator.c | 41 |
1 files changed, 21 insertions, 20 deletions
diff --git a/src/generator.c b/src/generator.c index d3e63de..9e898e6 100644 --- a/src/generator.c +++ b/src/generator.c @@ -26,6 +26,21 @@ void make_syscall(i64 syscall_no, FILE *out) { void generate_expr_into_rax(Node *expr, FILE *out); +void generate_lvalue_into_rbx(Node *node, FILE *out) +{ + assert(is_lvalue(node->type)); + i64 offset = node->variable->offset; + if (node->type == AST_LOCAL_VAR) { + fprintf(out, " mov rbx, rbp\n"); + fprintf(out, " sub rbx, %lld\n", offset); + } else if (node->type == AST_GLOBAL_VAR) { + fprintf(out, " mov rbx, global_vars\n"); + fprintf(out, " add rbx, %lld\n", offset); + } else { + assert(false && "Unknown lvalue type in generate_lvalue_into_rbx"); + } +} + void generate_func_call(Node *node, FILE *out) { assert(node->type == AST_FUNCCALL); @@ -56,32 +71,18 @@ void generate_expr_into_rax(Node *expr, FILE *out) generate_func_call(expr, out); } else if (expr->type == AST_LOCAL_VAR) { - i64 offset = expr->variable->offset; - if (offset > 0) - fprintf(out, " mov rax, [rbp-%lld]\n", offset); - else - fprintf(out, " mov rax, [rbp+%lld]\n", -offset); + generate_lvalue_into_rbx(expr, out); + fprintf(out, " mov rax, [rbx]\n"); } else if (expr->type == AST_GLOBAL_VAR) { - i64 offset = expr->variable->offset; - fprintf(out, " mov rax, global_vars\n"); - fprintf(out, " add rax, %lld\n", offset); - fprintf(out, " mov rax, [rax]\n"); + generate_lvalue_into_rbx(expr, out); + fprintf(out, " mov rax, [rbx]\n"); } else if (expr->type == OP_ASSIGN) { Node *var = expr->assign.var; - i64 offset = var->variable->offset; generate_expr_into_rax(expr->assign.value, out); - - if (var->type == AST_LOCAL_VAR) { - fprintf(out, " mov [rbp-%lld], rax\n", offset); - } else if (var->type == AST_GLOBAL_VAR) { - fprintf(out, " mov rbx, global_vars\n"); - fprintf(out, " mov [rbx+%lld], rax\n", offset); - } else { - fprintf(stderr, "Unhandled assignment type: %s\n", node_type_to_str(var->type)); - exit(1); - } + generate_lvalue_into_rbx(var, out); + fprintf(out, " mov [rbx], rax\n"); } else if (expr->type == OP_NEG) { generate_expr_into_rax(expr->unary_expr, out); |