* [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
* 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
* [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
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