From: Carlos Maniero <carlos@maniero.me>
To: ~johnnyrichard/olang-devel@lists.sr.ht
Cc: Carlos Maniero <carlos@maniero.me>
Subject: [PATCH olang 5/5] codegen: perform mov instructions based on variable type
Date: Sat, 21 Sep 2024 08:25:03 +0000 (UTC) [thread overview]
Message-ID: <20240921082437.396691-6-carlos@maniero.me> (raw)
In-Reply-To: <20240921082437.396691-1-carlos@maniero.me>
There are two function that was introduced to performe the translations
bellow:
type | type_to_bytes | bytes_to_rax
-----------------------------------
u8 | 1 | ah
u16 | 2 | ax
u32 | 4 | eax
u64 | 8 | rax
I opted to create *bytes_to_rax* instead of *type_to_rax* mainly because
we may use the same function to mov literals once we extend the literals
as well (We say that all literals are u32 but we actually handle them as
u64 on codegen).
Signed-off-by: Carlos Maniero <carlos@maniero.me>
---
src/checker.c | 15 +++++
src/codegen_linux_x86_64.c | 64 +++++++++++++++++--
src/type.h | 5 +-
.../tests/0026_primitive_unsigneds.ol | 27 ++++++++
4 files changed, 105 insertions(+), 6 deletions(-)
create mode 100644 tests/integration/tests/0026_primitive_unsigneds.ol
diff --git a/src/checker.c b/src/checker.c
index f5068e0..3a78a59 100644
--- a/src/checker.c
+++ b/src/checker.c
@@ -133,11 +133,26 @@ populate_scope(checker_t *checker, scope_t *scope, ast_node_t *ast)
static void
evaluate_type(type_t *type)
{
+ if (string_view_eq_to_cstr(type->id, "u8")) {
+ type->kind = TYPE_PRIMITIVE;
+ type->as_primitive = TYPE_U8;
+ return;
+ }
+ if (string_view_eq_to_cstr(type->id, "u16")) {
+ type->kind = TYPE_PRIMITIVE;
+ type->as_primitive = TYPE_U16;
+ return;
+ }
if (string_view_eq_to_cstr(type->id, "u32")) {
type->kind = TYPE_PRIMITIVE;
type->as_primitive = TYPE_U32;
return;
}
+ if (string_view_eq_to_cstr(type->id, "u64")) {
+ type->kind = TYPE_PRIMITIVE;
+ type->as_primitive = TYPE_U64;
+ return;
+ }
type->kind = TYPE_USER_DEFINED;
}
diff --git a/src/codegen_linux_x86_64.c b/src/codegen_linux_x86_64.c
index 415c81b..fa2a082 100644
--- a/src/codegen_linux_x86_64.c
+++ b/src/codegen_linux_x86_64.c
@@ -38,6 +38,12 @@ codegen_linux_x86_64_emit_function(codegen_x86_64_t *codegen, ast_fn_definition_
static size_t
type_to_bytes(type_t *type);
+static char *
+bytes_to_mov(size_t bytes);
+
+static char *
+bytes_to_rax(size_t bytes);
+
void
codegen_linux_x86_64_init(codegen_x86_64_t *codegen, arena_t *arena, FILE *out)
{
@@ -108,7 +114,10 @@ codegen_linux_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr
size_t *offset = (size_t *)map_get(codegen->symbols_stack_offset, symbol_ptr);
assert(offset);
- fprintf(codegen->out, " mov -%ld(%%rbp), %%rax\n", *offset);
+ size_t type_size = type_to_bytes(&symbol->type);
+
+ fprintf(
+ codegen->out, " %s -%ld(%%rbp), %s\n", bytes_to_mov(type_size), *offset, bytes_to_rax(type_size));
return;
}
case AST_NODE_BINARY_OP: {
@@ -369,12 +378,19 @@ codegen_linux_x86_64_emit_block(codegen_x86_64_t *codegen, ast_block_t *block)
codegen_linux_x86_64_emit_expression(codegen, var_def.value);
}
- codegen->base_offset += type_to_bytes(&symbol->type);
size_t *offset = arena_alloc(codegen->arena, sizeof(size_t));
*offset = codegen->base_offset;
map_put(codegen->symbols_stack_offset, symbol_ptr, offset);
- fprintf(codegen->out, " mov %%rax, -%ld(%%rbp)\n", codegen->base_offset);
+
+ size_t type_size = type_to_bytes(&symbol->type);
+
+ fprintf(codegen->out,
+ " %s %s, -%ld(%%rbp)\n",
+ bytes_to_mov(type_size),
+ bytes_to_rax(type_size),
+ codegen->base_offset);
+ codegen->base_offset += type_size;
break;
}
@@ -427,7 +443,19 @@ type_to_bytes(type_t *type)
{
switch (type->kind) {
case TYPE_PRIMITIVE: {
- return 8;
+ switch (type->as_primitive) {
+ case TYPE_U8:
+ return 1;
+ case TYPE_U16:
+ return 2;
+ case TYPE_U32:
+ return 4;
+ case TYPE_U64:
+ return 8;
+ }
+
+ assert(0 && "unreachable");
+ return 0;
}
case TYPE_USER_DEFINED: {
assert(0 && "user defined types are not defined yet");
@@ -474,7 +502,7 @@ calculate_fn_local_size(scope_t *scope)
static void
codegen_linux_x86_64_emit_function(codegen_x86_64_t *codegen, ast_fn_definition_t *fn)
{
- codegen->base_offset = 0;
+ codegen->base_offset = 8;
ast_node_t *block_node = fn->block;
fprintf(codegen->out, "" SV_FMT ":\n", SV_ARG(fn->identifier));
@@ -493,3 +521,29 @@ codegen_linux_x86_64_emit_function(codegen_x86_64_t *codegen, ast_fn_definition_
codegen_linux_x86_64_emit_block(codegen, &block);
}
+
+static char *
+bytes_to_mov(size_t bytes)
+{
+ if (bytes <= 1) {
+ return "movb";
+ } else if (bytes <= 2) {
+ return "movw";
+ } else if (bytes <= 4) {
+ return "movl";
+ }
+ return "movq";
+}
+
+static char *
+bytes_to_rax(size_t bytes)
+{
+ if (bytes <= 1) {
+ return "%ah";
+ } else if (bytes <= 2) {
+ return "%ax";
+ } else if (bytes <= 4) {
+ return "%eax";
+ }
+ return "%rax";
+}
diff --git a/src/type.h b/src/type.h
index 855cd83..32da9c0 100644
--- a/src/type.h
+++ b/src/type.h
@@ -24,7 +24,10 @@ typedef enum
typedef enum
{
- TYPE_U32
+ TYPE_U8,
+ TYPE_U16,
+ TYPE_U32,
+ TYPE_U64
} type_primitive_t;
typedef struct type
diff --git a/tests/integration/tests/0026_primitive_unsigneds.ol b/tests/integration/tests/0026_primitive_unsigneds.ol
new file mode 100644
index 0000000..25f0f7e
--- /dev/null
+++ b/tests/integration/tests/0026_primitive_unsigneds.ol
@@ -0,0 +1,27 @@
+# Copyright (C) 2024 olang mantainers
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+fn main(): u64 {
+ var a: u8 = 255
+ var b: u16 = 65535
+ var c: u32 = 4294967295
+ var d: u64 = 4294967296
+
+ return a + b + c + d - a - b - c - d
+}
+
+# TEST test_compile(exit_code=0)
+
+# TEST test_run_binary(exit_code=0)
--
2.34.1
next prev parent reply other threads:[~2024-09-21 8:25 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-21 8:24 [PATCH olang 0/5] extend unsined integers types (u8, u16, u64) Carlos Maniero
2024-09-21 8:24 ` [PATCH olang 1/5] parser: replace type enum to an struction string id representation Carlos Maniero
2024-09-21 17:59 ` Johnny Richard
2024-09-21 8:24 ` [PATCH olang 2/5] checker: scope: populate symbol's type Carlos Maniero
2024-09-21 18:47 ` Johnny Richard
2024-09-21 21:23 ` Carlos Maniero
2024-09-22 13:46 ` Johnny Richard
2024-09-21 8:24 ` [PATCH olang 3/5] codegen: fix map simbol list type Carlos Maniero
2024-09-21 18:50 ` Johnny Richard
2024-09-21 8:25 ` [PATCH olang 4/5] codegen: calculate the variable offset based on symbol type Carlos Maniero
2024-09-21 18:56 ` Johnny Richard
2024-09-21 8:25 ` Carlos Maniero [this message]
2024-09-21 8:26 ` [olang/patches/.build.yml] build success builds.sr.ht
2024-09-21 19:17 ` [PATCH olang 5/5] codegen: perform mov instructions based on variable type Johnny Richard
2024-09-21 21:30 ` Carlos Maniero
2024-09-22 14:16 ` [PATCH olang 0/5] extend unsined integers types (u8, u16, u64) Johnny Richard
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240921082437.396691-6-carlos@maniero.me \
--to=carlos@maniero.me \
--cc=~johnnyrichard/olang-devel@lists.sr.ht \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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