From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp2.migadu.com ([2001:41d0:403:58f0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id GOyyLwnkAGdCrwAAe85BDQ:P1 (envelope-from ) for ; Sat, 05 Oct 2024 09:00:25 +0200 Received: from aspmx1.migadu.com ([2001:41d0:403:58f0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp2.migadu.com with LMTPS id GOyyLwnkAGdCrwAAe85BDQ (envelope-from ) for ; Sat, 05 Oct 2024 09:00:25 +0200 X-Envelope-To: patches@johnnyrichard.com Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=lists.sr.ht header.s=20240113 header.b=e2oiHPbL; dkim=pass header.d=maniero.me header.s=hostingermail1 header.b=LEj0jwl3; spf=pass (aspmx1.migadu.com: domain of lists@sr.ht designates 46.23.81.152 as permitted sender) smtp.mailfrom=lists@sr.ht; dmarc=pass (policy=none) header.from=maniero.me; 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=1728111625; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: 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=u01XJDNSi+0DKOu7BwhsuJOf7aDUf8EqXafbuSaBzsc=; b=Mw9+/ibuHgU0nRcJsjXiJ1nIL+kplQzH3I3NOp/SvJ39MuGMxPxtBugDj4lzR5LrkA1gs3 7VoMVzkRdAOpG9jJc/RJEkzWwgDECce592WI457CzJoESfmPEFhlFafY5eSHp7Qw2hiJdj lHXinxpcCNf3k+U19UEaF87XjbwdCv3E9a2EBR7Fv2EUv9UHZVQUL26rmoqZanXoiiqids hgTHwgPit2/2mvdjw1T25zUT4fkAQaBG5tumZzpbqzem+BPAtjFUTfQtLIE0harGLyfbYo KfifarvLCK1QyD2KOntFSHTzSe3iESfWVry2y3i63n86IjoOWUkdcQsig1v9bw== ARC-Authentication-Results: i=2; aspmx1.migadu.com; dkim=pass header.d=lists.sr.ht header.s=20240113 header.b=e2oiHPbL; dkim=pass header.d=maniero.me header.s=hostingermail1 header.b=LEj0jwl3; spf=pass (aspmx1.migadu.com: domain of lists@sr.ht designates 46.23.81.152 as permitted sender) smtp.mailfrom=lists@sr.ht; dmarc=pass (policy=none) header.from=maniero.me; arc=pass ("mailchannels.net:s=arc-2022:i=1") ARC-Seal: i=2; s=key1; d=johnnyrichard.com; t=1728111625; a=rsa-sha256; cv=pass; b=xMbpBYPw1E0mW+ZuqqDmJmlr5B8MDW0JKOtTeN9yzJ+hCwZz+t5Fj+J4/ejRvF0AKTSho0 hRFc9PDu65ACq1Q0yYLl1aeKcqhGd/RJ0J2LRDbi0iJEBQzlWd3Q4jph3uHwd5SlH3wTZT HbEW1V5sZG+pKG3bS8FhuedvhF9XX/D/UXUEq+E3AJh3G/woVWWUVmwFbN/S0jfTsojYqJ 3hd7Xc9BAEAqzQZQICHBde7WhJ2SyULFXntFznItxRfaQ3CijMFZEBD4QrxQuCDpRMlK10 mWSBNsz/Q4/48u0FHrGNOCRjZ2ih49N3l3lQ462TqPKLXKGGpxmmj+mb2ZOBVA== 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 6227746BAF for ; Sat, 05 Oct 2024 09:00:25 +0200 (CEST) DKIM-Signature: a=rsa-sha256; bh=/LVbDdkAMuyXagtLOP+KSx2tMjZcL7Uqq7m+gtjbr00=; 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=1728111625; v=1; b=e2oiHPbLrUNgQ1zPTt24RpmFpEDXa6podBgh56G0DLght5nkdMEMxLpWpyhdmtkcTezZo/xg HSE9BrTdc3PRghRR5vECEw3W9fdkio6a0byho7pqo87+oO5B7JgWmmS6wj5RpgzUZbaLhNXqyIw 8gRmNpZvxM4yUyg/6VDcnmdBQ1sPUDo8PG8kqEfxIIZbJSnf0Qe75aClXA6E8hiMkBjXX5n6Fdk Bx0GHc+1ZoZlpi9jFNg43duVPEoylDtTyfUz+yNE9t+g0EKT2A/v96ky/pG1JGso4wWz73YVCiG 9elat8IpEEc9V+6lY4kWJYcxKwkV5ShPgNRhARirCCcSQ== Received: from lists.sr.ht (unknown [46.23.81.154]) by mail-a.sr.ht (Postfix) with ESMTPSA id 2FE1A2023D for ; Sat, 05 Oct 2024 07:00:25 +0000 (UTC) Received: from iguana.tulip.relay.mailchannels.net (iguana.tulip.relay.mailchannels.net [23.83.218.253]) by mail-a.sr.ht (Postfix) with ESMTPS id 4C0D42021D for <~johnnyrichard/olang-devel@lists.sr.ht>; Sat, 05 Oct 2024 06:59:59 +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 7C757845C1F for <~johnnyrichard/olang-devel@lists.sr.ht>; Sat, 5 Oct 2024 06:59:57 +0000 (UTC) Received: from nl-srv-smtpout1.hostinger.io (trex-2.trex.outbound.svc.cluster.local [100.101.175.87]) (Authenticated sender: hostingeremail) by relay.mailchannels.net (Postfix) with ESMTPA id A5AD184585D for <~johnnyrichard/olang-devel@lists.sr.ht>; Sat, 5 Oct 2024 06:59:56 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1728111597; a=rsa-sha256; cv=none; b=kcF6EiPXLQgvqIKLtHfL/ln1pxQE77NrFwl5MRn1IMgbYZptW39eyhn72Bz7Vr0u+4Y9ym WMkZPw98TPrrX6EbUNqCRzBeSvBBCtkrAU0XwpUdSjQy3zSjXE3vdNIeI5KiQ1cdk4cO9e yVR5rQl858s2vOo6FalOkfD9GWL6YhqAZ23Dath6CUS1lPyZy/aVHJjsRy3aEWnyRftmeD JVEz18kBp2lNSqpcOuMdiBpe5NdtWXihqlwAsm5e2J9lUQR63ofNxTSaDtHbyw69P2TdaW TYFBFqnoY5+iHrbAPBCumjNlCGrVBy2PuVYGHViG1qwh7SxaP6lfiyIlmqpkzA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1728111597; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=u01XJDNSi+0DKOu7BwhsuJOf7aDUf8EqXafbuSaBzsc=; b=Qhsu9GPLTfaibVAo/RyeSUtSiRdxSVrG9hWyuNlPhpymXJgfRad+iINutxgDHgHSWeirzc 1bKDFeX+CJuGDDsiIJan/raE2Ps2nStpVbXh5dM0Ae3N0eGOZSNp0lEmkZPcOe39dX2uIt TIrqE8bosAtfEasB8QL1vCRHU9xxK+bG3/GQSwdijOl5Yp6glBlpfIZDwdvkBtSgRuFyYC 6QEvxQX5Jq4DR+Z1kxqx9U3eVV/RNAtboyxtp+oCL7pR1oN7gHaqsHzvTFSHgl3QXHWOKw 09i5JAUILtcIJ4pjAMTbVwwXwmtdIP5W1eQwbpcfwarpwK9wxqFJFHOK6Zs0sQ== ARC-Authentication-Results: i=1; rspamd-58b99b864b-h7frn; 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-Cold-White: 38bbd9fb0e7c0727_1728111597273_1219947008 X-MC-Loop-Signature: 1728111597273:2805674949 X-MC-Ingress-Time: 1728111597273 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.101.175.87 (trex/7.0.2); Sat, 05 Oct 2024 06:59:57 +0000 From: Carlos Maniero DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=maniero.me; s=hostingermail1; t=1728111595; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=u01XJDNSi+0DKOu7BwhsuJOf7aDUf8EqXafbuSaBzsc=; b=LEj0jwl3Z6/7ifRpSe25o8l4RLBgVW98V/iDqJ0l2AwMP9Xgk7uD1pfAwsbvvXSXXocP+q aSM/spdoaowkwUVHzezIkolJ225IVMvh+WiRzqPryEkHqJpfkjODAYuTW/1QVW+SzLAugO 6+iKLXf2lLGckmYI/+1e0L2xs22K6hw8jtrcxuzrypTgTef1jmUZ+ObIHVTxVDbt4Ls3Wu 9kapCiEiL/pibIMNpmcdCIOQrIYqKo5bYlT4oNKA9rwj1ZSV3TGBZ+Ydrg6hNeQio91VxG 4Q8K9cXi5sWAOSlIh2FxwHmnaTTSCjgTMtp/JFf/ha1CbACvYlzE64gARvlZnw== To: ~johnnyrichard/olang-devel@lists.sr.ht Cc: Carlos Maniero Subject: [PATCH olang v1 2/2] codegen: x64: evaluate expression considering the data return data size Message-Id: <20241005065924.300710-3-carlos@maniero.me> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241005065924.300710-1-carlos@maniero.me> References: <20241005065924.300710-1-carlos@maniero.me> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Date: Sat, 05 Oct 2024 06:59:54 +0000 (UTC) X-CM-Analysis: v=2.4 cv=b6rg4cGx c=1 sm=1 tr=0 ts=6700e3eb a=WwxFCuf3mf1fs3oSi6/dng==:117 a=WwxFCuf3mf1fs3oSi6/dng==:17 a=MKtGQD3n3ToA:10 a=1oJP67jkp3AA:10 a=OhGCRg32Kdl1Z8el22EA:9 a=BXDaF_L80NY05PYiAFlV:22 X-CM-Envelope: MS4xfHR6f57wvtbunGxIJp+/Ge+lYx7oE8QKcNAjCIYHzsQy9VwpbvvA5g0w4l46P7PmptbBQRCxfLP998+tK9ypMj2lnJpbpMUOsHyAj0Xfh3qnVsS/HFlI PYD7kGLAqXwt+ej1jVp6YRsDQMPsxn0YDP6Peai5D2jyP+oTJygs5BuhEo8iBE6lYvdXMEm18Eg/LKUFRMTPmdiDybEGPtCHp1aOa3+bxotJu7uT9DBj3/g5 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-Country: NL X-Migadu-Flow: FLOW_IN X-Migadu-Scanner: mx11.migadu.com X-Migadu-Spam-Score: -1.63 X-Spam-Score: -1.63 X-Migadu-Queue-Id: 6227746BAF X-TUID: k78E3Oge4ZwK The expressions were always considering that it results in a 64 bits operation. Now, it evaluates the result size and use the proper register. Signed-off-by: Carlos Maniero --- src/codegen_linux_x86_64.c | 314 ++++++++++++++++++++++---------- tests/olc/0028_function_call.ol | 4 +- 2 files changed, 220 insertions(+), 98 deletions(-) diff --git a/src/codegen_linux_x86_64.c b/src/codegen_linux_x86_64.c index e04de0e..e501634 100644 --- a/src/codegen_linux_x86_64.c +++ b/src/codegen_linux_x86_64.c @@ -31,6 +31,8 @@ #define X86_CALL_EIP_STACK_OFFSET (8) #define X86_CALL_ARG_SIZE 6 +#define bytes_max(a, b) ((a) > (b) ? (a) : (b)) + typedef enum x86_64_register_type { REG_ACCUMULATOR, @@ -132,7 +134,9 @@ codegen_linux_x86_64_get_next_label(codegen_x86_64_t *codegen) return ++codegen->label_index; } -static void +typedef size_t size_in_bytes_t; + +static size_in_bytes_t codegen_linux_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr_node) { switch (expr_node->kind) { @@ -141,8 +145,8 @@ codegen_linux_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr assert(literal_u32.kind == AST_LITERAL_U32); uint32_t n = literal_u32.as_u32; - fprintf(codegen->out, " mov $%d, %%rax\n", n); - return; + fprintf(codegen->out, " mov $%d, %%eax\n", n); + return 4; } case AST_NODE_REF: { ast_ref_t ref = expr_node->as_ref; @@ -156,15 +160,17 @@ 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), %s\n", - *offset, - get_reg_for(REG_ACCUMULATOR, type_to_bytes(&symbol->type))); - return; + size_t bytes = type_to_bytes(&symbol->type); + + fprintf(codegen->out, " mov -%ld(%%rbp), %s\n", *offset, get_reg_for(REG_ACCUMULATOR, bytes)); + return bytes; } case AST_NODE_FN_CALL: { ast_fn_call_t fn_call = expr_node->as_fn_call; + symbol_t *symbol = scope_lookup(fn_call.scope, fn_call.id); + assert(symbol); + size_t i = 0; for (list_item_t *item = list_head(fn_call.args); item != NULL; item = list_next(item)) { // FIXME: add support for more args than X86_CALL_ARG_SIZE @@ -174,7 +180,6 @@ codegen_linux_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr codegen_linux_x86_64_emit_expression(codegen, arg_node); - // FIXME: should get the correct size according to the ast node fprintf(codegen->out, " push %s\n", get_reg_for(REG_ACCUMULATOR, 8)); ++i; } @@ -184,223 +189,339 @@ codegen_linux_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr } fprintf(codegen->out, " call " SV_FMT "\n", SV_ARG(fn_call.id)); - return; + + return type_to_bytes(&symbol->type); } case AST_NODE_BINARY_OP: { ast_binary_op_t bin_op = expr_node->as_bin_op; switch (bin_op.kind) { case AST_BINOP_ADDITION: { - codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t rhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); fprintf(codegen->out, " push %%rax\n"); - codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t lhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + + size_in_bytes_t expr_bytes = bytes_max(rhs_bytes, lhs_bytes); + fprintf(codegen->out, " pop %%rcx\n"); - fprintf(codegen->out, " add %%rcx, %%rax\n"); + fprintf(codegen->out, + " add %s, %s\n", + get_reg_for(REG_COUNTER, expr_bytes), + get_reg_for(REG_ACCUMULATOR, expr_bytes)); - return; + return expr_bytes; } case AST_BINOP_MULTIPLICATION: { - codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t rhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); fprintf(codegen->out, " push %%rax\n"); - codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t lhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + + size_in_bytes_t expr_bytes = bytes_max(rhs_bytes, lhs_bytes); + fprintf(codegen->out, " pop %%rcx\n"); - fprintf(codegen->out, " mul %%rcx\n"); + fprintf(codegen->out, " mul %s\n", get_reg_for(REG_COUNTER, expr_bytes)); - return; + return expr_bytes; } case AST_BINOP_DIVISION: { - codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t rhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); fprintf(codegen->out, " push %%rax\n"); - codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t lhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + + size_in_bytes_t expr_bytes = bytes_max(rhs_bytes, lhs_bytes); + fprintf(codegen->out, " pop %%rcx\n"); fprintf(codegen->out, " xor %%rdx, %%rdx\n"); - fprintf(codegen->out, " div %%rcx\n"); + fprintf(codegen->out, " div %s\n", get_reg_for(REG_COUNTER, expr_bytes)); - return; + return expr_bytes; } case AST_BINOP_REMINDER: { - codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t rhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); fprintf(codegen->out, " push %%rax\n"); - fprintf(codegen->out, " xor %%edx, %%edx\n"); - codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t lhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + + size_in_bytes_t expr_bytes = bytes_max(rhs_bytes, lhs_bytes); + fprintf(codegen->out, " pop %%rcx\n"); fprintf(codegen->out, " xor %%rdx, %%rdx\n"); - fprintf(codegen->out, " div %%rcx\n"); - fprintf(codegen->out, " mov %%edx, %%eax\n"); + fprintf(codegen->out, " div %s\n", get_reg_for(REG_COUNTER, expr_bytes)); + fprintf(codegen->out, + " mov %s, %s\n", + get_reg_for(REG_DATA, expr_bytes), + get_reg_for(REG_ACCUMULATOR, expr_bytes)); - return; + return expr_bytes; } case AST_BINOP_SUBTRACTION: { - codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t rhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); fprintf(codegen->out, " push %%rax\n"); - codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t lhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + + size_in_bytes_t expr_bytes = bytes_max(rhs_bytes, lhs_bytes); + fprintf(codegen->out, " pop %%rcx\n"); - fprintf(codegen->out, " sub %%rcx, %%rax\n"); + fprintf(codegen->out, + " sub %s, %s\n", + get_reg_for(REG_COUNTER, expr_bytes), + get_reg_for(REG_ACCUMULATOR, expr_bytes)); - return; + return expr_bytes; } case AST_BINOP_CMP_EQ: { - codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t rhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); fprintf(codegen->out, " push %%rax\n"); - codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t lhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + + size_in_bytes_t expr_bytes = bytes_max(rhs_bytes, lhs_bytes); + fprintf(codegen->out, " pop %%rcx\n"); - fprintf(codegen->out, " cmp %%rcx, %%rax\n"); + fprintf(codegen->out, + " cmp %s, %s\n", + get_reg_for(REG_COUNTER, expr_bytes), + get_reg_for(REG_ACCUMULATOR, expr_bytes)); fprintf(codegen->out, " sete %%al\n"); - fprintf(codegen->out, " movzb %%al, %%rax\n"); + fprintf(codegen->out, " movzb %%al, %s\n", get_reg_for(REG_ACCUMULATOR, expr_bytes)); - return; + return expr_bytes; } case AST_BINOP_CMP_LT: { - codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t rhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); fprintf(codegen->out, " push %%rax\n"); - codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t lhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + + size_in_bytes_t expr_bytes = bytes_max(rhs_bytes, lhs_bytes); + fprintf(codegen->out, " pop %%rcx\n"); - fprintf(codegen->out, " cmp %%rcx, %%rax\n"); + fprintf(codegen->out, + " cmp %s, %s\n", + get_reg_for(REG_COUNTER, expr_bytes), + get_reg_for(REG_ACCUMULATOR, expr_bytes)); fprintf(codegen->out, " setl %%al\n"); - fprintf(codegen->out, " movzb %%al, %%rax\n"); + fprintf(codegen->out, " movzb %%al, %s\n", get_reg_for(REG_ACCUMULATOR, expr_bytes)); - return; + return expr_bytes; } case AST_BINOP_CMP_GT: { - codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t rhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); fprintf(codegen->out, " push %%rax\n"); - codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t lhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + + size_in_bytes_t expr_bytes = bytes_max(rhs_bytes, lhs_bytes); + fprintf(codegen->out, " pop %%rcx\n"); - fprintf(codegen->out, " cmp %%rcx, %%rax\n"); + fprintf(codegen->out, + " cmp %s, %s\n", + get_reg_for(REG_COUNTER, expr_bytes), + get_reg_for(REG_ACCUMULATOR, expr_bytes)); fprintf(codegen->out, " setg %%al\n"); - fprintf(codegen->out, " movzb %%al, %%rax\n"); + fprintf(codegen->out, " movzb %%al, %s\n", get_reg_for(REG_ACCUMULATOR, expr_bytes)); - return; + return expr_bytes; } case AST_BINOP_CMP_NEQ: { - codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t rhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); fprintf(codegen->out, " push %%rax\n"); - codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t lhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + + size_in_bytes_t expr_bytes = bytes_max(rhs_bytes, lhs_bytes); + fprintf(codegen->out, " pop %%rcx\n"); - fprintf(codegen->out, " cmp %%rcx, %%rax\n"); + fprintf(codegen->out, + " cmp %s, %s\n", + get_reg_for(REG_COUNTER, expr_bytes), + get_reg_for(REG_ACCUMULATOR, expr_bytes)); fprintf(codegen->out, " setne %%al\n"); - fprintf(codegen->out, " movzb %%al, %%rax\n"); + fprintf(codegen->out, " movzb %%al, %s\n", get_reg_for(REG_ACCUMULATOR, expr_bytes)); - return; + return expr_bytes; } case AST_BINOP_CMP_LEQ: { - codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t rhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); fprintf(codegen->out, " push %%rax\n"); - codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t lhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + + size_in_bytes_t expr_bytes = bytes_max(rhs_bytes, lhs_bytes); + fprintf(codegen->out, " pop %%rcx\n"); - fprintf(codegen->out, " cmp %%rcx, %%rax\n"); + fprintf(codegen->out, + " cmp %s, %s\n", + get_reg_for(REG_COUNTER, expr_bytes), + get_reg_for(REG_ACCUMULATOR, expr_bytes)); fprintf(codegen->out, " setle %%al\n"); - fprintf(codegen->out, " movzb %%al, %%rax\n"); + fprintf(codegen->out, " movzb %%al, %s\n", get_reg_for(REG_ACCUMULATOR, expr_bytes)); - return; + return expr_bytes; } case AST_BINOP_CMP_GEQ: { - codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t rhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); fprintf(codegen->out, " push %%rax\n"); - codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t lhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + + size_in_bytes_t expr_bytes = bytes_max(rhs_bytes, lhs_bytes); + fprintf(codegen->out, " pop %%rcx\n"); - fprintf(codegen->out, " cmp %%rcx, %%rax\n"); + fprintf(codegen->out, + " cmp %s, %s\n", + get_reg_for(REG_COUNTER, expr_bytes), + get_reg_for(REG_ACCUMULATOR, expr_bytes)); fprintf(codegen->out, " setge %%al\n"); - fprintf(codegen->out, " movzb %%al, %%rax\n"); + fprintf(codegen->out, " movzb %%al, %s\n", get_reg_for(REG_ACCUMULATOR, expr_bytes)); - return; + return expr_bytes; } case AST_BINOP_BITWISE_LSHIFT: { + fprintf(codegen->out, " xor %%rax, %%rax\n"); codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); fprintf(codegen->out, " push %%rax\n"); - codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t lhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + fprintf(codegen->out, " pop %%rcx\n"); - fprintf(codegen->out, " shl %%cl, %%rax\n"); + fprintf(codegen->out, " shl %%cl, %s\n", get_reg_for(REG_ACCUMULATOR, lhs_bytes)); - return; + return lhs_bytes; } case AST_BINOP_BITWISE_RSHIFT: { + fprintf(codegen->out, " xor %%rax, %%rax\n"); codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); fprintf(codegen->out, " push %%rax\n"); - codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t lhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + fprintf(codegen->out, " pop %%rcx\n"); - fprintf(codegen->out, " shr %%cl, %%rax\n"); + fprintf(codegen->out, " shr %%cl, %s\n", get_reg_for(REG_ACCUMULATOR, lhs_bytes)); - return; + return lhs_bytes; } case AST_BINOP_BITWISE_XOR: { - codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t rhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); fprintf(codegen->out, " push %%rax\n"); - codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t lhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + + size_in_bytes_t expr_bytes = bytes_max(rhs_bytes, lhs_bytes); + fprintf(codegen->out, " pop %%rcx\n"); - fprintf(codegen->out, " xor %%ecx, %%eax\n"); + fprintf(codegen->out, + " xor %s, %s\n", + get_reg_for(REG_COUNTER, expr_bytes), + get_reg_for(REG_ACCUMULATOR, expr_bytes)); - return; + return expr_bytes; } case AST_BINOP_BITWISE_AND: { - codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t rhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); fprintf(codegen->out, " push %%rax\n"); - codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t lhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + + size_in_bytes_t expr_bytes = bytes_max(rhs_bytes, lhs_bytes); + fprintf(codegen->out, " pop %%rcx\n"); - fprintf(codegen->out, " and %%ecx, %%eax\n"); + fprintf(codegen->out, + " and %s, %s\n", + get_reg_for(REG_COUNTER, expr_bytes), + get_reg_for(REG_ACCUMULATOR, expr_bytes)); - return; + return expr_bytes; } case AST_BINOP_BITWISE_OR: { - codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t rhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); fprintf(codegen->out, " push %%rax\n"); - codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t lhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + + size_in_bytes_t expr_bytes = bytes_max(rhs_bytes, lhs_bytes); + fprintf(codegen->out, " pop %%rcx\n"); - fprintf(codegen->out, " or %%ecx, %%eax\n"); + fprintf(codegen->out, + " or %s, %s\n", + get_reg_for(REG_COUNTER, expr_bytes), + get_reg_for(REG_ACCUMULATOR, expr_bytes)); - return; + return expr_bytes; } case AST_BINOP_LOGICAL_AND: { size_t label_exit = codegen_linux_x86_64_get_next_label(codegen); - codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); - fprintf(codegen->out, " cmp $0, %%rax\n"); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t lhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + fprintf(codegen->out, " cmp $0, %s\n", get_reg_for(REG_ACCUMULATOR, lhs_bytes)); fprintf(codegen->out, " je .L%ld\n", label_exit); - codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); - fprintf(codegen->out, " cmp $0, %%rax\n"); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t rhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); + fprintf(codegen->out, " cmp $0, %s\n", get_reg_for(REG_ACCUMULATOR, rhs_bytes)); fprintf(codegen->out, " je .L%ld\n", label_exit); fprintf(codegen->out, " mov $1, %%rax\n"); fprintf(codegen->out, ".L%ld:\n", label_exit); - return; + return 1; } case AST_BINOP_LOGICAL_OR: { size_t label_t = codegen_linux_x86_64_get_next_label(codegen); size_t label_f = codegen_linux_x86_64_get_next_label(codegen); - codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); - fprintf(codegen->out, " cmp $0, %%rax\n"); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t lhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.lhs); + fprintf(codegen->out, " cmp $0, %s\n", get_reg_for(REG_ACCUMULATOR, lhs_bytes)); fprintf(codegen->out, " jne .L%ld\n", label_t); - codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); - fprintf(codegen->out, " cmp $0, %%rax\n"); + fprintf(codegen->out, " xor %%rax, %%rax\n"); + size_in_bytes_t rhs_bytes = codegen_linux_x86_64_emit_expression(codegen, bin_op.rhs); + fprintf(codegen->out, " cmp $0, %s\n", get_reg_for(REG_ACCUMULATOR, rhs_bytes)); fprintf(codegen->out, " je .L%ld\n", label_f); fprintf(codegen->out, ".L%ld:\n", label_t); fprintf(codegen->out, " mov $1, %%rax\n"); fprintf(codegen->out, ".L%ld:\n", label_f); - return; + return 1; } default: { assert(0 && "unsupported binary operation"); - return; + return 0; } } } @@ -521,7 +642,9 @@ calculate_fn_local_size(scope_t *scope) { assert(scope); - size_t local_size = 0; + // The local_size starts with 8 bytes since the first 8 bytes from the + // stack are reserved to store RBP during the prelude + size_t local_size = 8; map_kv_t *kvs[scope->symbols->size]; @@ -578,10 +701,9 @@ codegen_linux_x86_64_emit_function(codegen_x86_64_t *codegen, ast_fn_definition_ map_put(codegen->symbols_stack_offset, symbol_ptr, offset); fprintf(codegen->out, - " mov %s, -%ld(%s)\n", - get_reg_for(x86_call_args[i], 8), - *offset, - get_reg_for(REG_BASE_PTR, 8)); + " mov %s, -%ld(%%rbp)\n", + get_reg_for(x86_call_args[i], symbol->type.as_primitive.size), + *offset); // FIXME: add offset according to the param size codegen->base_offset += 8; diff --git a/tests/olc/0028_function_call.ol b/tests/olc/0028_function_call.ol index cfd06de..b32fbbf 100644 --- a/tests/olc/0028_function_call.ol +++ b/tests/olc/0028_function_call.ol @@ -17,7 +17,7 @@ fn main(): u8 { return add(40, 2) } -fn add(a: u64, b: u64): u8 { +fn add(a: u32, b: u64): u8 { return a + b } @@ -34,7 +34,7 @@ fn add(a: u64, b: u64): u8 { # | |-Literal # | `-Literal # `-Function_Definition -# |-Param_Definition +# |-Param_Definition # |-Param_Definition # `-Block # `-Return_Statement -- 2.34.1