public inbox for ~johnnyrichard/olang-devel@lists.sr.ht
 help / color / mirror / code / Atom feed
* [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; 4+ 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] 4+ 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; 4+ 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] 4+ 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; 4+ 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] 4+ 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; 4+ 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] 4+ messages in thread

end of thread, other threads:[~2024-10-17  2:53 UTC | newest]

Thread overview: 4+ 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

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