From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp2.migadu.com ([2001:41d0:303:e224::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms1.migadu.com with LMTPS id 2GywMuq9E2eJtgAAe85BDQ:P1 (envelope-from ) for ; Sat, 19 Oct 2024 16:10:51 +0200 Received: from aspmx1.migadu.com ([2001:41d0:303:e224::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp2.migadu.com with LMTPS id 2GywMuq9E2eJtgAAe85BDQ (envelope-from ) for ; Sat, 19 Oct 2024 16:10:50 +0200 X-Envelope-To: patches@johnnyrichard.com Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=lists.sr.ht header.s=20240113 header.b=f1tdLeiR; dkim=pass header.d=maniero.me header.s=hostingermail1 header.b=sscH70Cg; dmarc=pass (policy=none) header.from=maniero.me; spf=pass (aspmx1.migadu.com: domain of lists@sr.ht designates 46.23.81.152 as permitted sender) smtp.mailfrom=lists@sr.ht; arc=pass ("mailchannels.net:s=arc-2022:i=1") ARC-Seal: i=2; s=key1; d=johnnyrichard.com; t=1729347050; a=rsa-sha256; cv=pass; b=ioP5DpppFrNorMNTLAtjJ96QDpF5emNTFN19LjJQ4yye/VlTgnv8YgpCZy+Ei7FGDNPKrc dLqesu4dMGSaVQ9FZd1LTBd9zLFvAO772xa5T59zm+yADo5NbGONDdKq1Stz5qScD4l5fz oYQmIw7oW6nUVB2cJT0pq0Rc7N9PEhl1hJUCXsmyBx73Siz4dY9haPWzBU4SlZh2Q3dWTd 9OmJF4yKn6Tsd+InUjWP/dfrVECvPPpjgKhbu2LY8QFQujeH/CJvmrPc/3lY9BV1FXm2W9 Go9ljjwjMv2wFSojLRuCJ3rxTcJuNFAhVdRD5YA5iXzD4QA2KkdsM3uGn1ao2Q== ARC-Authentication-Results: i=2; aspmx1.migadu.com; dkim=pass header.d=lists.sr.ht header.s=20240113 header.b=f1tdLeiR; dkim=pass header.d=maniero.me header.s=hostingermail1 header.b=sscH70Cg; dmarc=pass (policy=none) header.from=maniero.me; spf=pass (aspmx1.migadu.com: domain of lists@sr.ht designates 46.23.81.152 as permitted sender) smtp.mailfrom=lists@sr.ht; arc=pass ("mailchannels.net:s=arc-2022:i=1") ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=johnnyrichard.com; s=key1; t=1729347050; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id: list-unsubscribe:list-subscribe:list-post:dkim-signature; bh=KC3JP4eFwHl0dVPvjuEVdCQsvcXk/mOq3joJ7J+CWcQ=; b=0nPjPt452xvfiLbxfYSu+5oWO2nsXFubxc9Qf2Tfn7XLLiokXVh24MybkAVTjeiBPQxfqk XF5HwtBIEpV6QWKZy6KDzPIJIm9xuvxAdyXB8dWCb2kZeTJ2k24NP4oC0deBB9lQgWJjly 9iOSI1hCO6mVEH03oUIHkuPTVDE8a7ZoAtjWGWM3VpMpYoAlXZz+7iqsyxdeAwQ41Ky00o rnV3C7+nh7w4l6YWIofaGB7vSoS/VdTwXw0NczromD8t4oaY94l/eplAPHHpSYnhFYxlk4 btYLL4TjeOHnNVqJCecPS83ll1kMWB3rrYePIUtpyJsEgiAxWyFOTiKAr0vSiw== Received: from mail-a.sr.ht (mail-a.sr.ht [46.23.81.152]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id B1DAD1C48A for ; Sat, 19 Oct 2024 16:10:47 +0200 (CEST) DKIM-Signature: a=rsa-sha256; bh=Dl/2D3oJjsZCDZTBHXgUXy5QfguACKumvQuKsbfyxYc=; c=simple/simple; d=lists.sr.ht; h=From:To:Cc:Subject:In-Reply-To:References:Date:List-Unsubscribe:List-Subscribe:List-Archive:List-Post:List-ID; q=dns/txt; s=20240113; t=1729347046; v=1; b=f1tdLeiRTvyJ4XfGvOqKve2dnPYdzEzFOOldZNNrTFUjcvbe/KT9JDANGPu3laIqq7V73GYK 4jHqE1rp+a8yB5k6SOvAzAFUGLV7PkrIREj44/ntb7NWayqwre1PYAgNf/Y1ku8F1jTwU6vfgtm 5nf9R4paWokRoov9a7DLpy9yAG9Tx4p+VWq6OnH2V/hNMxVqaWEdOWdbyTD1/21Iqbx2uvJA3SM yD5zDsOJDr33A4FeIfe1BIGKK18HP/1Gl6xhnOhMdkjPooj6z8E5zyTAGwiKzuta5gdOeTXVc4b uEoccdhF5aC2GJaA1WOOS7dwUSrD6ZwItaoY13MUiexDA== Received: from lists.sr.ht (unknown [46.23.81.154]) by mail-a.sr.ht (Postfix) with ESMTPSA id A235E20260 for ; Sat, 19 Oct 2024 14:10:46 +0000 (UTC) Received: from cow.ash.relay.mailchannels.net (cow.ash.relay.mailchannels.net [23.83.222.41]) by mail-a.sr.ht (Postfix) with ESMTPS id 890DC20259 for <~johnnyrichard/olang-devel@lists.sr.ht>; Sat, 19 Oct 2024 14:10:45 +0000 (UTC) X-Sender-Id: hostingeremail|x-authuser|carlos@maniero.me Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 83E839016C1 for <~johnnyrichard/olang-devel@lists.sr.ht>; Sat, 19 Oct 2024 14:10:43 +0000 (UTC) Received: from nl-srv-smtpout1.hostinger.io (100-98-255-245.trex-nlb.outbound.svc.cluster.local [100.98.255.245]) (Authenticated sender: hostingeremail) by relay.mailchannels.net (Postfix) with ESMTPA id C2DDA902BD0 for <~johnnyrichard/olang-devel@lists.sr.ht>; Sat, 19 Oct 2024 14:10:42 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1729347043; a=rsa-sha256; cv=none; b=uljVMHGvikS0erS+obcfELhVkXmAq5KIS7LjwR5VWickBJj/zw1zp2SFxPqYW+zywAb07c 18U5sOCp8I4+gGsO0nAqnSF655ozuJWp83p0KrDDJ2FUd+QV98FU3XrvUerkH0BH81rsBO FFSc3kwHopHzMinVKQtrzYnyhI9zvJtK/Yy8uESKJkoKWTJkFlA7+cNoqujwGSJhSlBB4y HHoPqXgxaKfoDY0Rls/wefg0F+tO5fR1bvhPSUb5az7Y15XDtIzVQd/y6paUl7sWyZnhge 9wpr3BnsXhGAIaxxO0Rkfbxx1Yjw1ACKDXc5k5YlgvM5efD5OpHuGGCOTwj92w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1729347043; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=KC3JP4eFwHl0dVPvjuEVdCQsvcXk/mOq3joJ7J+CWcQ=; b=uv/s0KeL156ywxDTpAQSLZYIbY55TBE0vsnbV+3r0ym+zw+QXHdABYO8yA/b6+LraRzTwE 6zgouz7d9wCGFhLeNF8fL28TQlTqkvyNpFx38OjUtAPvxx6SptX2Qn91+dzb9+jRnA4VYR 0+IGjjXg5vPQ/sftVfJZTsYWJatVTdOGn7/6Hk0S4ZgAdhr8xuExiJeaAj0Kik6PPRLEIo s8i0282y/1PTPwGp2kB8eOTACFp/x9thlK9qwkI9gfHy4EdalRP2+75Rnq+0x8gbXrOxOZ 4oFHxLnGxbQX0N6bIivtAZJEsgwXZpO/G/CO2xKRmYNtvHTYnIxE5NA8q2jgtw== ARC-Authentication-Results: i=1; rspamd-75d86777c9-55c8x; auth=pass smtp.auth=hostingeremail smtp.mailfrom=carlos@maniero.me X-Sender-Id: hostingeremail|x-authuser|carlos@maniero.me X-MC-Relay: Neutral X-MailChannels-SenderId: hostingeremail|x-authuser|carlos@maniero.me X-MailChannels-Auth-Id: hostingeremail X-Thoughtful-Stupid: 71fac41d1e8190e4_1729347043397_4141476537 X-MC-Loop-Signature: 1729347043397:3088403077 X-MC-Ingress-Time: 1729347043396 Received: from nl-srv-smtpout1.hostinger.io (nl-srv-smtpout1.hostinger.io [145.14.150.87]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.98.255.245 (trex/7.0.2); Sat, 19 Oct 2024 14:10:43 +0000 From: Carlos Maniero DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=maniero.me; s=hostingermail1; t=1729347041; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=KC3JP4eFwHl0dVPvjuEVdCQsvcXk/mOq3joJ7J+CWcQ=; b=sscH70CgunWt1FYZXFd1SRALGXo7pHh5bHuGNlr9HT/4H4FXUTFfGNu9yewwS5ZwvtSgWG Fho1exWdF1OXJs1H/SaIBFdj/S2itX3EzAZcgVJ7lIzPAdfntxxK+3EQBb+5ONFRSbwdIa orEXi+vsB8FfFSdEBzjMKmX13WjUBAA7u1ly17LYsRkiiQK7dBDKvzsb8W6gESw1rEfYo9 cw3aDivA4M78jnYb0iwGaWBb/NYqKGj2borBifCAWgNqRBEX6f3Z1kVH+KWPDGgdHT71vB ZlxRvK0wWELFcgMK+HC5RdmQXW57gztPnzzetWF66JaD5bCKy0Z6EPgUxmytIw== To: ~johnnyrichard/olang-devel@lists.sr.ht Cc: Carlos Maniero Subject: [PATCH olang v2 1/1] codegen: x64: deref returns pointer value Message-ID: <20241019141000.185147-2-carlos@maniero.me> X-Mailer: git-send-email 2.46.1 In-Reply-To: <20241019141000.185147-1-carlos@maniero.me> References: <20241019141000.185147-1-carlos@maniero.me> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Date: Sat, 19 Oct 2024 14:10:40 +0000 (UTC) X-CM-Analysis: v=2.4 cv=VemlP0p9 c=1 sm=1 tr=0 ts=6713bde1 a=WwxFCuf3mf1fs3oSi6/dng==:117 a=WwxFCuf3mf1fs3oSi6/dng==:17 a=IkcTkHD0fZMA:10 a=MKtGQD3n3ToA:10 a=1oJP67jkp3AA:10 a=mDV3o1hIAAAA:8 a=0owbBZFOtC7H_bykwgIA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=BXDaF_L80NY05PYiAFlV:22 X-CM-Envelope: MS4xfF5R1KnPL5ROalRLje6wkDuqsBeHWNFjRgL6sp7ogtIgoKdQT9WG9XHHUtomPEgAwY3mdtn9bCHVSG/rb5hx2qTS3iULT/mvqkRrGU48QGnvvcdzN0OP 5VuhwfA5pu4AXbdRTFCD/aNnIIPfjhY299+32KiQJU4YkGo3R+r1VCfSJl8whRo07S7fWJB3TCOcOZ28pbQuUVsLOBTPnZpNIOYcVfgtEz744wNX6w2VH2NB X-AuthUser: carlos@maniero.me X-Sourcehut-Patchset-Status: PROPOSED List-Unsubscribe: List-Subscribe: List-Archive: Archived-At: List-Post: List-ID: ~johnnyrichard/olang-devel <~johnnyrichard/olang-devel.lists.sr.ht> Sender: ~johnnyrichard/olang-devel <~johnnyrichard/olang-devel@lists.sr.ht> X-Migadu-Flow: FLOW_IN X-Migadu-Country: NL X-Migadu-Spam-Score: -1.26 X-Spam-Score: -1.26 X-Migadu-Queue-Id: B1DAD1C48A X-Migadu-Scanner: mx12.migadu.com X-TUID: esjd1bSmctCo 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. At this point, we don't have an easy way to get the operation result type so there is a tricky logic to determine if the unnary expression is returning a pointer or a value, ie: when dereferencing "var b: u16**" once (*b) the result size is 8 bits as it returns another pointer, but by dereferencing it twice (**b) we are returning 2 bits since at this point we are returning a u16. Signed-off-by: Carlos Maniero --- 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 diff --git a/src/codegen_x86_64.c b/src/codegen_x86_64.c index deb7e24..4213571 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,71 @@ 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); + + if (unary_op->expr->kind == AST_NODE_UNARY_OP) { + // dive into the AST until it finds a ref + size_in_bytes_t size = codegen_x86_64_emit_unary_deref_address( + codegen, &unary_op->expr->as_unary_op); + + fprintf(codegen->out, " mov (%%rax), %%rax\n"); + + return size; + } + + assert(unary_op->expr->kind == AST_NODE_REF); + 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_node_t *expr = unary_op->expr; + + size_t deref_levels = 0; + + while (expr->kind != AST_NODE_REF) { + assert(expr->kind == AST_NODE_UNARY_OP && + expr->as_unary_op.kind == AST_UNARY_DEREFERENCE); + + expr = expr->as_unary_op.expr; + deref_levels++; + } + + ast_ref_t ref = expr->as_ref; + + symbol_t *symbol = scope_lookup(ref.scope, ref.id); + + type_t *t_result = symbol->type; + + assert(t_result->kind == TYPE_PTR); + + // FIXME: Identifies the operation result type based on how many times the + // deref operator was used. The semantics should provide the result + // type of an operation, so then the codegen does not need to care + // about it. + while (deref_levels-- > 0) { + t_result = symbol->type->as_ptr.type; + + assert(symbol->type->kind == TYPE_PTR); + } + + size_in_bytes_t deref_size = type_to_bytes(t_result->as_ptr.type); + + fprintf(codegen->out, + " mov (%%rax), %s\n", + get_reg_for(REG_ACCUMULATOR, deref_size)); + + return deref_size; +} + static size_t type_to_bytes(type_t *type) { diff --git a/src/parser.c b/src/parser.c index d26f266..386f60b 100644 --- a/src/parser.c +++ b/src/parser.c @@ -538,13 +538,12 @@ parser_parse_type(parser_t *parser) return NULL; } - token_t ptr_token; + type_t *type = type_new_unknown(parser->arena, token.value); + token_t ptr_token; lexer_peek_next(parser->lexer, &ptr_token); - type_t *type = type_new_unknown(parser->arena, token.value); - - if (ptr_token.kind == TOKEN_STAR) { + while (ptr_token.kind == TOKEN_STAR) { if (!skip_expected_token(parser, TOKEN_STAR)) { return NULL; } @@ -553,7 +552,9 @@ parser_parse_type(parser_t *parser) ptr_id.size = ptr_token.value.chars - token.value.chars + ptr_token.value.size; - return type_new_ptr(parser->arena, ptr_id, type); + type = type_new_ptr(parser->arena, ptr_id, type); + + lexer_peek_next(parser->lexer, &ptr_token); } return type; diff --git a/tests/olc/0038_pointers_deref.ol b/tests/olc/0038_pointers_deref.ol new file mode 100644 index 0000000..cef91b2 --- /dev/null +++ b/tests/olc/0038_pointers_deref.ol @@ -0,0 +1,24 @@ +# 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 . + +fn main(): u32 { + var a: u64 = 0 + var b: u64* = &a + return *b +} + +# TEST test_compile(exit_code=0) + +# TEST test_run_binary(exit_code=0) diff --git a/tests/olc/0039_pointer_of_pointer.ol b/tests/olc/0039_pointer_of_pointer.ol new file mode 100644 index 0000000..e98178a --- /dev/null +++ b/tests/olc/0039_pointer_of_pointer.ol @@ -0,0 +1,55 @@ +# 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 . + +fn main(): u32 { + var a: u32 = 1 + var b: u32* = &a + var c: u32** = &b + var d: u32 = 41 + + **c = 42 + + if a != 42 { + return 1 + } + + if a != *b { + return 2 + } + + if *b != **c { + return 3 + } + + if b != &a { + return 4 + } + + if *c != &a { + return 5 + } + + *c = &d + + if *b != 41 { + return 6 + } + + return 0 +} + +# TEST test_compile(exit_code=0) + +# TEST test_run_binary(exit_code=0) -- 2.46.1