public inbox for ~johnnyrichard/olang-devel@lists.sr.ht
 help / color / mirror / code / Atom feed
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


  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