From 07eeed7cffb916dda7ab531b01c5de92bbbf0ea4 Mon Sep 17 00:00:00 2001 From: janis Date: Mon, 3 Nov 2025 16:35:46 +0100 Subject: [PATCH] can do very cool stuff! --- lang/src/codegen.asm | 86 ++++++++++++++++++++++++++----------------- lang/tests/codegen.rs | 2 +- 2 files changed, 53 insertions(+), 35 deletions(-) diff --git a/lang/src/codegen.asm b/lang/src/codegen.asm index 142f2b7..46b0906 100644 --- a/lang/src/codegen.asm +++ b/lang/src/codegen.asm @@ -1310,7 +1310,6 @@ codegen_expr: jmp .done .gen_op: - mov rdi, [rsp + 8] ; &function_ctx mov rsi, [rsp] ; ctx lea rsi, [rsi + 8] ; &ctx.text @@ -1844,25 +1843,40 @@ codegen_binary_op_rm64_rm64: push rbx ; dst [32..48] - sub rsp, 48 + sub rsp, 56 mov [rsp], rdi ; *function_ctx mov [rsp + 8], rsi ; *text mov [rsp + 16], rdx ; lhs mov [rsp + 24], rcx ; rhs mov [rsp + 32], r8 ; op - ; if lhs.kind == REGISTER || lhs.kind < ADDRESS && rhs.kind == REGISTER { + ; match (lhs.kind, rhs.kind) { cmp byte [rdx + 0], OPERAND_REGISTER - je .simple + sete al + cmp byte [rcx + 0], OPERAND_RBP_PVALUE + setb bl + test al, bl + jnz .simple + ; (REGISTER, kind < RBP_PVALUE) => simple cmp byte [rdx + 0], OPERAND_RBP_PVALUE setb al cmp byte [rcx + 0], OPERAND_REGISTER sete bl test al, bl - jne .simple - jmp .complex + jnz .simple + ; (kind < RBP_PVALUE, REGISTER) => simple + test al, al + jnz .rax_lhs + ; (kind < RBP_PVALUE, _) => rax_lhs + cmp byte [rdx + 0], OPERAND_RBP_PVALUE + jb .rax_rhs + ; (_, kind < RBP_PVALUE) => rax_rhs + jmp .rax_dst + ; (_, _) => rax_dst + ; } + .simple: - ; op lhs, rhs + ; { op lhs, rhs; lhs } lea rdi, [rsp + 32] ; op call strlen mov rdi, [rsp + 8] ; *text @@ -1898,11 +1912,9 @@ codegen_binary_op_rm64_rm64: mov rax, [rbx] mov rdx, [rbx + 8] jmp .epilogue - ; } else { -.complex: - ; if lhs.kind < RBP_PVALUE { - cmp byte [rdx + 0], OPERAND_RBP_PVALUE - jae .check_rhs + +.rax_lhs: + ; { mov rax, rhs; op lhs, rax; lhs } ; mov rax, rhs mov rdi, [rsp + 8] ; *text @@ -1928,14 +1940,13 @@ codegen_binary_op_rm64_rm64: mov rdx, [rbx + 8] jmp .epilogue -.check_rhs: - ; } else if rhs.kind < RBP_PVALUE { - cmp byte [rcx + 0], OPERAND_RBP_PVALUE - jae .allocate_dst +.rax_rhs: + ; { mov rax, lhs; op rax, rhs; mov rhs, rax; rhs } + ; mov rax, lhs mov rdi, [rsp + 8] ; *text lea rsi, [rel OPERAND_RAX] - mov rdx, [rsp + 16] ; lhs + mov rdx, [rsp + 16] ; rhs call codegen_move_dst_src ; op rax, rhs @@ -1945,34 +1956,30 @@ codegen_binary_op_rm64_rm64: mov rcx, [rsp + 32] ; op call codegen_binary_op_unchecked - ; mov rhs, rax - mov rdi, [rsp + 8] ; *text - mov rsi, [rsp + 24] ; rhs - lea rdx, [rel OPERAND_RAX] - call codegen_move_dst_src - - ; free lhs + ; free lhs mov rdi, [rsp] ; *function_ctx - mov rsi, [rsp + 16] ; rhs + mov rsi, [rsp + 16] ; lhs call codegen_free_operand - ; ret rhs + ; ret rhs mov rbx, [rsp + 24] ; rhs mov rax, [rbx] mov rdx, [rbx + 8] jmp .epilogue - ; } else { -.allocate_dst: + +.rax_dst: + ; { dst = allocate_value; mov dst, lhs; mov rax, rhs; op dst, rax; dst } + ; dst = allocate_value mov rdi, [rsp] ; *function_ctx mov rsi, 8 ; width = 8 call codegen_allocate_value - mov [rsp + 32], rax ; dst - mov [rsp + 40], rdx - + mov [rsp + 40], rax ; dst + mov [rsp + 48], rdx + ; mov dst, lhs mov rdi, [rsp + 8] ; *text - lea rsi, [rsp + 32] ; dst + lea rsi, [rsp + 40] ; dst mov rdx, [rsp + 16] ; lhs call codegen_move_dst_src @@ -1984,18 +1991,29 @@ codegen_binary_op_rm64_rm64: ; op dst, rax mov rdi, [rsp + 8] ; *text - lea rsi, [rsp + 32] ; dst + lea rsi, [rsp + 40] ; dst lea rdx, [rel OPERAND_RAX] ; rax mov rcx, [rsp + 32] ; op call codegen_binary_op_unchecked + ; free rhs + mov rdi, [rsp] ; *function_ctx + mov rsi, [rsp + 24] ; lhs + call codegen_free_operand + + ; free lhs + mov rdi, [rsp] ; *function_ctx + mov rsi, [rsp + 16] ; lhs + call codegen_free_operand + ; ret dst mov rax, [rsp + 32] ; dst mov rdx, [rsp + 40] ; } + .epilogue: - add rsp, 48 + add rsp, 56 pop rbx pop rbp ret diff --git a/lang/tests/codegen.rs b/lang/tests/codegen.rs index 0188e24..f36a75d 100644 --- a/lang/tests/codegen.rs +++ b/lang/tests/codegen.rs @@ -93,7 +93,7 @@ fn main() { print_ast( b"fn main(a: u32) -> void { - return 2 * 3 + 4 * 5 + a; + return 5 + &a; }", |ast| unsafe { parse_func(ast) }, );