From 28746ff68d5c35fa3e6b1157e5c473bb2d97a158 Mon Sep 17 00:00:00 2001 From: Irene Knapp Date: Sat, 8 Nov 2025 15:41:19 -0800 Subject: assembly-in-Forth arithmetic words; also fixed the implementations some basic mistakes in those Force-Push: yes Change-Id: Ife797b31962c26fc8a8ab741f4d97bd3da3c0612 --- quine.asm | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/quine.asm b/quine.asm index cf6076d..20a3c23 100644 --- a/quine.asm +++ b/quine.asm @@ -2090,24 +2090,38 @@ cold_start: ; This was "add". dq litstring, "+", early_create, early_self_codeword, early_here, fetch - ; TODO - dq lit, 8, packalign, early_here_store + dq rbx, pop_reg64 + dq rax, pop_reg64 + dq rbx, rax, add_reg64_reg64 + dq rax, push_reg64 + dq pack_next, lit, 8, packalign, early_here_store ; This was "sub". dq litstring, "-", early_create, early_self_codeword, early_here, fetch - ; TODO - dq lit, 8, packalign, early_here_store + dq rbx, pop_reg64 + dq rax, pop_reg64 + dq rbx, rax, sub_reg64_reg64 + dq rax, push_reg64 + dq pack_next, lit, 8, packalign, early_here_store ; This was "mul". dq litstring, "*", early_create, early_self_codeword, early_here, fetch - ; TODO - dq lit, 8, packalign, early_here_store + dq rax, pop_reg64 + dq rbx, pop_reg64 + dq rbx, mul_reg64 + dq rax, push_reg64 + dq pack_next, lit, 8, packalign, early_here_store ; This was "divmod". Jonesforth calls it "/mod" but % is widely recognized ; and has no special Forth significance. dq litstring, "/%", early_create, early_self_codeword, early_here, fetch - ; TODO - dq lit, 8, packalign, early_here_store + dq rdx, rdx, xor_reg64_reg64 + dq rbx, pop_reg64 + dq rax, pop_reg64 + dq rbx, divmod_reg64 + dq rdx, push_reg64 + dq rax, push_reg64 + dq pack_next, lit, 8, packalign, early_here_store ; This was "eq". Jonesforth calls it "="; most languages would call it "==". dq litstring, "=", early_create, early_self_codeword, early_here, fetch @@ -3991,6 +4005,7 @@ defword sub_reg64_reg64, 0 dq docol dq roll3, rex_w, lit, 0x2B, pack8, unroll3 dq swap, reg64, swap, addressing_reg64 + dq exit ; Stack: ; output point @@ -4001,14 +4016,15 @@ defword sub_indirect_reg64_reg64, 0 dq roll3, rex_w, lit, 0x2B, pack8, unroll3 dq swap, reg64, swap, addressing_indirect_reg64 +; The target register is always rax. +; ; Stack: ; output point ; source register name -; target register name -defword mul_reg64_reg64, 0 +defword mul_reg64, 0 dq docol - dq roll3, rex_w, lit, 0xF7, pack8, unroll3 - dq swap, reg64, swap, addressing_reg64 + dq swap, rex_w, lit, 0xF7, pack8, swap + dq lit, 4, swap, addressing_reg64 dq exit ; The dividend is 128 bits, and is formed from rdx as the high half and rax @@ -4025,6 +4041,7 @@ defword divmod_reg64, 0 dq docol dq swap, rex_w, lit, 0xF7, pack8, swap dq lit, 6, swap, addressing_reg64 + dq exit ; Same as divmod, but signed. ; @@ -4035,6 +4052,7 @@ defword idivmod_reg64, 0 dq docol dq swap, rex_w, lit, 0xF7, pack8, swap dq lit, 7, swap, addressing_reg64 + dq exit ; Stack: ; output point -- cgit 1.4.1