diff --git a/lang/src/codegen.asm b/lang/src/codegen.asm index 9a82189..e7b4f73 100644 --- a/lang/src/codegen.asm +++ b/lang/src/codegen.asm @@ -1307,52 +1307,28 @@ codegen_move_dst_src: je .panic ; address can only be moved to full-sized destinations cmp byte [rsi + 0], OPERAND_REGISTER - je .do_move + je .do_move ; if dst == register, do move + ; If dst != register and src != register, we cannot move directly into memory: + ; there is no MOV m64, m64 or MOV m64, imm64 instruction. + ; A smarter compiler could test for the immediate size and move most + ; immediates directly into memory, but we are quite stupid! cmp byte [rdx + 0], OPERAND_REGISTER - jne .xchg_rax ; if dst != register and src != register, xchg via rax + jne .xchg_rax jmp .do_move .xchg_rax: - ; xchg rax, [src] + ; mov rax, [src] ; mov [dst], rax - ; xchg rax, [src] mov rdi, [rsp] ; *text - lea rsi, [rel XCHG_RAX] - mov rdx, XCHG_RAX_LEN - call vec_extend + lea rsi, [rel OPERAND_RAX] + mov rdx, [rsp + 16] ; src + call codegen_move_dst_src mov rdi, [rsp] ; *text - mov rsi, [rsp + 16] ; src - call codegen_write_operand - - mov rdi, [rsp] ; *text - lea rsi, [rel COMMA_RAX] - mov rdx, COMMA_RAX_LEN - call vec_extend - - mov rdi, [rsp] ; *text - lea rsi, [rel MOV_RAX_COMMA] - mov rdx, 4 - call vec_extend - - mov rdi, [rsp] ; *text - mov rsi, [rsp + 8] ; dst - call codegen_write_operand - - mov rdi, [rsp] ; *text - lea rsi, [rel COMMA_RAX] - mov rdx, COMMA_RAX_LEN - call vec_extend - - mov rdi, [rsp] ; *text - lea rsi, [rel XCHG_RAX] - mov rdx, XCHG_RAX_LEN - call vec_extend - - mov rdi, [rsp] ; *text - mov rsi, [rsp + 16] ; src - call codegen_write_operand + mov rsi, [rsp + 8] ; src + lea rdx, [rel OPERAND_RAX] + call codegen_move_dst_src jmp .epilogue .do_move: @@ -1374,12 +1350,12 @@ codegen_move_dst_src: mov rsi, [rsp + 16] ; src call codegen_write_operand -.epilogue: mov rdi, [rsp] ; *text lea rsi, [rel COLON_NL] inc rsi - mov rdx, 1 - call vec_extend + call vec_push + +.epilogue: add rsp, 24 pop rbx