summary refs log tree commit diff
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2025-11-08 14:43:24 -0800
committerIrene Knapp <ireneista@irenes.space>2025-11-08 14:43:24 -0800
commitc879ce48776e75c45792ef1f85c7de2264b6a959 (patch)
treed927b64b74dd843e8b7079cbeac960b0ebde7323
parent7b28a68eb9fb032f5e71193ac858b1cc9848156b (diff)
added assembly-in-forth implementation of roll
also fixed scalefield

the testing bar we're applying for these next changes is that it runs successfully, we aren't actually calling the generated funcions yet. we'll need to invent some methodology for checking they're generated correctly.

Force-Push: yes
Change-Id: I820e5671d74fa3bd4342e5d5b26b867e053ba3ca
-rw-r--r--quine.asm37
1 files changed, 23 insertions, 14 deletions
diff --git a/quine.asm b/quine.asm
index 54e9d2f..b4edf5b 100644
--- a/quine.asm
+++ b/quine.asm
@@ -2007,25 +2007,34 @@ cold_start:
 
   dq litstring, "exit", early_create, early_self_codeword, early_here, fetch
   dq rsi, pack_popcontrol, pack_next
-  ; TODO
   dq lit, 8, packalign, early_here_store
 
   dq litstring, "swap", early_create, early_self_codeword, early_here, fetch
-  ; TODO
-  dq lit, 8, packalign, early_here_store
+  dq rax, pop_reg64, rbx, pop_reg64, rax, push_reg64, rbx, push_reg64
+  dq pack_next, lit, 8, packalign, early_here_store
 
   dq litstring, "drop", early_create, early_self_codeword, early_here, fetch
-  ; TODO
-  dq lit, 8, packalign, early_here_store
+  dq rax, pop_reg64
+  dq pack_next, lit, 8, packalign, early_here_store
 
   ; This was "drop2".
   dq litstring, "2drop", early_create, early_self_codeword, early_here, fetch
-  ; TODO
-  dq lit, 8, packalign, early_here_store
+  dq rax, pop_reg64, rax, pop_reg64
+  dq pack_next, lit, 8, packalign, early_here_store
 
   dq litstring, "roll", early_create, early_self_codeword, early_here, fetch
-  ; TODO
-  dq lit, 8, packalign, early_here_store
+  dq rcx, pop_reg64
+  dq rcx, dec_reg64
+  dq rsp, rcx, lit, 8, rbx, mov_reg64_indexed_reg64
+  dq rsi, push_reg64
+  dq rsp, rcx, lit, 8, rsi, lea_reg64_indexed_reg64
+  dq rsp, rcx, lit, 8, lit, 8, rdi, lea_reg64_disp8_indexed_reg64
+  dq std
+  dq rep_movs64
+  dq cld
+  dq rsi, pop_reg64
+  dq rbx, rsi, mov_reg64_indirect_reg64
+  dq pack_next, lit, 8, packalign, early_here_store
 
   ; Jonesforth calls this "-roll" and we could do that, but honestly the name
   ; unroll sounds nicer and it's only a single character longer. You might say
@@ -3423,10 +3432,10 @@ defword reg8, 0
 ;   2-bit encoded value for scale field in SIB byte
 defword scalefield, 0
   dq docol
-  dq dup, 1, eq, zbranch, 5*8, drop, lit, 0, exit
-  dq dup, 2, eq, zbranch, 5*8, drop, lit, 1, exit
-  dq dup, 4, eq, zbranch, 5*8, drop, lit, 2, exit
-  dq dup, 8, eq, zbranch, 5*8, drop, lit, 3, exit
+  dq dup, lit, 1, eq, zbranch, 5*8, drop, lit, 0, exit
+  dq dup, lit, 2, eq, zbranch, 5*8, drop, lit, 1, exit
+  dq dup, lit, 4, eq, zbranch, 5*8, drop, lit, 2, exit
+  dq dup, lit, 8, eq, zbranch, 5*8, drop, lit, 3, exit
   dq litstring, "Parameter to scalefield is not 1, 2, 4, or 8.", emitstring
   dq lit, 1, sys_exit
 
@@ -3572,7 +3581,7 @@ defword addressing_disp8_reg64, 0
 defword addressing_indexed_reg64, 0
   dq docol
   ; Exit with an error if the base register is rbp.
-  dq dup, rbp, ne, zbranch, 17*8
+  dq dup, rbp, ne, zbranch, 5*8;, 17*8
   ; Reg/mem value 4 means to use an SIB byte (at least, with this mode).
   dq lit, 5, roll, lit, 0, lit, 6, roll, lit, 4, modrm, lit, 4, unroll
   dq reg64, unroll3, reg64, unroll3, scalefield, unroll3, sib