* [PATCH olang v1 0/1] deref operation returning value @ 2024-10-17 2:48 Carlos Maniero 2024-10-17 2:48 ` [PATCH olang v1 1/1] codegen: x64: deref returns pointer value Carlos Maniero 0 siblings, 1 reply; 6+ messages in thread From: Carlos Maniero @ 2024-10-17 2:48 UTC (permalink / raw) To: ~johnnyrichard/olang-devel; +Cc: Carlos Maniero We had discussed over IRC about may adding some extra information on the deref operation to support this feature, but there are two reasons why I opted to keep this on code gen: 1) Modifying the AST would require changing the unary data structure from a struct to an union, but no other operator would be beneficed by this since only the deref needs some extra information. 2) The assign operation is required to identify if its LHS is a deref, once the mov instruction will differ from a simple ref: The simple ref will mov the expression result to a RBP offset and the deref will mov the expression result to the pointer location. Also, once we have the IR, this logic could easily fit the layer that will build the IR. Carlos Maniero (1): codegen: x64: deref returns pointer value src/codegen_x86_64.c | 61 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 9 deletions(-) -- 2.46.1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH olang v1 1/1] codegen: x64: deref returns pointer value 2024-10-17 2:48 [PATCH olang v1 0/1] deref operation returning value Carlos Maniero @ 2024-10-17 2:48 ` Carlos Maniero 2024-10-17 2:49 ` [olang/patches/.build.yml] build failed builds.sr.ht 0 siblings, 1 reply; 6+ messages in thread From: Carlos Maniero @ 2024-10-17 2:48 UTC (permalink / raw) To: ~johnnyrichard/olang-devel; +Cc: Carlos Maniero Deref is context dependent, when doing an assignment: *a = 1 It is expected for the deref codegen to return the pointer location, so than the assignment binop would be able to assign a new value at that location. On another hand, when performing: return *a It is expected for deref to actually returns the pointer location value. The codegen of both behaviors were defined in new functions to avoid indiscriminately increase the codegen_x86_64_emit_expression switch/case. Register choice: ================ Since the operation *mov (%rax), %rax* is not possible, I arbitrarily choose R10 as it is a caller-saved register. Signed-off-by: Carlos Maniero <carlos@maniero.me> --- src/codegen_x86_64.c | 61 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/src/codegen_x86_64.c b/src/codegen_x86_64.c index deb7e24..db1b77a 100644 --- a/src/codegen_x86_64.c +++ b/src/codegen_x86_64.c @@ -52,6 +52,8 @@ typedef enum x86_64_register_type REG_R15 } x86_64_register_type_t; +typedef size_t size_in_bytes_t; + /** * Arch/ABI arg1 arg2 arg3 arg4 arg5 arg6 arg7 Notes * ────────────────────────────────────────────────────────────── @@ -76,6 +78,14 @@ codegen_x86_64_put_stack_offset(codegen_x86_64_t *codegen, static size_t codegen_x86_64_get_stack_offset(codegen_x86_64_t *codegen, symbol_t *symbol); +static size_in_bytes_t +codegen_x86_64_emit_unary_deref_address(codegen_x86_64_t *codegen, + ast_unary_op_t *unary_op); + +static size_in_bytes_t +codegen_x86_64_emit_unary_deref_value(codegen_x86_64_t *codegen, + ast_unary_op_t *unary_op); + static size_t type_to_bytes(type_t *type); @@ -126,8 +136,6 @@ codegen_x86_64_get_next_label(codegen_x86_64_t *codegen) return ++codegen->label_index; } -typedef size_t size_in_bytes_t; - static size_in_bytes_t codegen_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr_node) { @@ -619,7 +627,8 @@ codegen_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr_node) AST_UNARY_DEREFERENCE && "unsupported assignment lhs"); - codegen_x86_64_emit_expression(codegen, bin_op.lhs); + codegen_x86_64_emit_unary_deref_address( + codegen, &bin_op.lhs->as_unary_op); fprintf(codegen->out, " push %%rax\n"); @@ -679,12 +688,8 @@ codegen_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr_node) return 8; } case AST_UNARY_DEREFERENCE: { - // FIXME: support dereference of dereference (**) - assert(unary_op.expr->kind == AST_NODE_REF && - "unsupported unary expression for dereference (*)"); - - return codegen_x86_64_emit_expression(codegen, - unary_op.expr); + return codegen_x86_64_emit_unary_deref_value( + codegen, &unary_op); } default: { assert(0 && "unsupported unary operation"); @@ -829,6 +834,44 @@ codegen_x86_64_emit_if(codegen_x86_64_t *codegen, ast_if_stmt_t if_stmt) fprintf(codegen->out, ".L%ld:\n", end_else_label); } +static size_in_bytes_t +codegen_x86_64_emit_unary_deref_address(codegen_x86_64_t *codegen, + ast_unary_op_t *unary_op) +{ + assert(unary_op->kind == AST_UNARY_DEREFERENCE); + // FIXME: support dereference of dereference (**) + assert(unary_op->expr->kind == AST_NODE_REF && + "unsupported unary expression for dereference (*)"); + + return codegen_x86_64_emit_expression(codegen, unary_op->expr); +} + +static size_in_bytes_t +codegen_x86_64_emit_unary_deref_value(codegen_x86_64_t *codegen, + ast_unary_op_t *unary_op) +{ + codegen_x86_64_emit_unary_deref_address(codegen, unary_op); + + ast_ref_t ref = unary_op->expr->as_ref; + + symbol_t *symbol = scope_lookup(ref.scope, ref.id); + + assert(symbol->type->kind == TYPE_PTR); + + size_in_bytes_t deref_size = type_to_bytes(symbol->type->as_ptr.type); + + fprintf(codegen->out, + " mov (%%rax), %s\n", + get_reg_for(REG_R10, deref_size)); + + fprintf(codegen->out, + " mov %s, %s\n", + get_reg_for(REG_R10, deref_size), + get_reg_for(REG_ACCUMULATOR, deref_size)); + + return deref_size; +} + static size_t type_to_bytes(type_t *type) { -- 2.46.1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [olang/patches/.build.yml] build failed 2024-10-17 2:48 ` [PATCH olang v1 1/1] codegen: x64: deref returns pointer value Carlos Maniero @ 2024-10-17 2:49 ` builds.sr.ht 2024-10-17 2:52 ` Carlos Maniero 0 siblings, 1 reply; 6+ messages in thread From: builds.sr.ht @ 2024-10-17 2:49 UTC (permalink / raw) To: Carlos Maniero; +Cc: ~johnnyrichard/olang-devel olang/patches/.build.yml: FAILED in 20s [deref operation returning value][0] from [Carlos Maniero][1] [0]: https://lists.sr.ht/~johnnyrichard/olang-devel/patches/55515 [1]: mailto:carlos@maniero.me ✗ #1352279 FAILED olang/patches/.build.yml https://builds.sr.ht/~johnnyrichard/job/1352279 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [olang/patches/.build.yml] build failed 2024-10-17 2:49 ` [olang/patches/.build.yml] build failed builds.sr.ht @ 2024-10-17 2:52 ` Carlos Maniero 0 siblings, 0 replies; 6+ messages in thread From: Carlos Maniero @ 2024-10-17 2:52 UTC (permalink / raw) To: builds.sr.ht; +Cc: ~johnnyrichard/olang-devel I broke the format :( I'll wait for the review before submitting a v2. ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH olang v1 0/1] deref operation returning value @ 2024-10-19 14:10 Carlos Maniero 2024-10-19 14:14 ` Carlos Maniero 0 siblings, 1 reply; 6+ messages in thread From: Carlos Maniero @ 2024-10-19 14:10 UTC (permalink / raw) To: ~johnnyrichard/olang-devel; +Cc: Carlos Maniero We had discussed over IRC about may adding some extra information on the deref operation to support this feature, but there are two reasons why I opted to keep this on code gen: 1) Modifying the AST would require changing the unary data structure from a struct to an union, but no other operator would be beneficed by this since only the deref needs some extra information. 2) The assign operation is required to identify if its LHS is a deref, once the mov instruction will differ from a simple ref: The simple ref will mov the expression result to a RBP offset and the deref will mov the expression result to the pointer location. Also, once we have the IR, this logic could easily fit the layer that will build the IR. V2: - Fix code style - Allows multiple pointer dereference Carlos Maniero (1): codegen: x64: deref returns pointer value src/codegen_x86_64.c | 88 +++++++++++++++++++++++++--- src/parser.c | 11 ++-- tests/olc/0038_pointers_deref.ol | 24 ++++++++ tests/olc/0039_pointer_of_pointer.ol | 55 +++++++++++++++++ 4 files changed, 164 insertions(+), 14 deletions(-) create mode 100644 tests/olc/0038_pointers_deref.ol create mode 100644 tests/olc/0039_pointer_of_pointer.ol base-commit: 2dbf9a9896e5778535bd3dc1d5069a762d3b94fa -- 2.46.1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH olang v1 0/1] deref operation returning value 2024-10-19 14:10 [PATCH olang v1 0/1] deref operation returning value Carlos Maniero @ 2024-10-19 14:14 ` Carlos Maniero 0 siblings, 0 replies; 6+ messages in thread From: Carlos Maniero @ 2024-10-19 14:14 UTC (permalink / raw) To: Carlos Maniero, ~johnnyrichard/olang-devel Ops! I messed with the pathset coverletter subject. This is ment to be v2. The patch per si is right. Sorry :( ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-10-19 14:14 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2024-10-17 2:48 [PATCH olang v1 0/1] deref operation returning value Carlos Maniero 2024-10-17 2:48 ` [PATCH olang v1 1/1] codegen: x64: deref returns pointer value Carlos Maniero 2024-10-17 2:49 ` [olang/patches/.build.yml] build failed builds.sr.ht 2024-10-17 2:52 ` Carlos Maniero 2024-10-19 14:10 [PATCH olang v1 0/1] deref operation returning value Carlos Maniero 2024-10-19 14:14 ` Carlos Maniero
Code repositories for project(s) associated with this public inbox https://git.johnnyrichard.com/olang.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox