boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs

commit c8d59c8c378681b5799b96b8d8abf7fc0e2b9fd5
parent a89381df54a7bf1c25fd87cb298997ec806019a2
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Tue, 21 Apr 2026 12:05:54 -0700

lisp.M1: collapse MOV_R3_SP + R3-base mem ops to SP-relative forms

The P1 SP-relative LD/ST/LB/SB encodings added in the earlier refactor
let callees read/write frame slots directly, bypassing the MOV_R3_SP
trampoline that used to bridge P1 regs to sp-base. Sweep the interpreter
for all eligible blocks: drop 89 redundant MOV_R3_SP lines and rewrite
176 mem ops from R3-base to SP-base.

Safe to collapse only where the scope (MOV_R3_SP → next R3 clobber /
CALL / RET / B / TAIL / EPILOGUE / label) contains no conditional
branch — a conditional branch can land on a label whose code still
relies on R3 = SP (see :apply_prim_fixed), and dropping the MOV would
break that. In those cases we leave the MOV but still rewrite the
mem ops, which is always safe since SP-relative forms don't use R3.

8/8 tests pass on aarch64, amd64, riscv64.

Diffstat:
Msrc/lisp.M1 | 441++++++++++++++++++++++++++++++++-----------------------------------------------
1 file changed, 176 insertions(+), 265 deletions(-)

diff --git a/src/lisp.M1 b/src/lisp.M1 @@ -388,8 +388,7 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' ## every top-level form, then restore the outer reader state. :eval_source P1_PROLOGUE - P1_MOV_R3_SP - P1_ST_R4_R3_8 ## save caller's r4 + P1_ST_R4_SP_8 ## save caller's r4 P1_LI_R3 &src_base @@ -506,8 +505,7 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' P1_ST_R0_R1_0 P1_MOV_R0_R4 - P1_MOV_R3_SP - P1_LD_R4_R3_8 + P1_LD_R4_SP_8 P1_EPILOGUE P1_RET @@ -697,8 +695,7 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' ## leaves the payload for the caller to fill. :alloc_string P1_PROLOGUE - P1_MOV_R3_SP - P1_ST_R1_R3_8 + P1_ST_R1_SP_8 P1_ADDI_R1_R1_7 P1_SHRI_R1_R1_3 @@ -708,8 +705,7 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' &alloc P1_CALL - P1_MOV_R3_SP - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_ST_R1_R0_0 P1_LI_R1 %1 @@ -722,27 +718,24 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' ## ---- make_string(r1=src, r2=len) -> r0 = tagged string ------------- :make_string P1_PROLOGUE_N3 - P1_MOV_R3_SP - P1_ST_R1_R3_8 - P1_ST_R2_R3_16 + P1_ST_R1_SP_8 + P1_ST_R2_SP_16 P1_MOV_R1_R2 P1_LI_BR &alloc_string P1_CALL - P1_MOV_R3_SP - P1_ST_R0_R3_24 + P1_ST_R0_SP_24 P1_ADDI_R1_R0_NEG4 ## raw string ptr P1_ADDI_R1_R1_8 ## dst payload - P1_LD_R2_R3_8 ## src payload - P1_LD_R3_R3_16 ## len + P1_LD_R2_SP_8 ## src payload + P1_LD_R3_SP_16 ## len P1_LI_BR &byte_copy P1_CALL - P1_MOV_R3_SP - P1_LD_R0_R3_24 + P1_LD_R0_SP_24 P1_EPILOGUE_N3 P1_RET @@ -752,9 +745,8 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' ## element with `init`. :make_vector P1_PROLOGUE_N2 - P1_MOV_R3_SP - P1_ST_R1_R3_8 - P1_ST_R2_R3_16 + P1_ST_R1_SP_8 + P1_ST_R2_SP_16 P1_SHLI_R1_R1_3 P1_ADDI_R1_R1_8 @@ -762,17 +754,15 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' &alloc P1_CALL - P1_MOV_R3_SP - P1_LD_R1_R3_8 ## len_raw - P1_ST_R0_R3_8 ## overwrite slot1 = raw ptr + P1_LD_R1_SP_8 ## len_raw + P1_ST_R0_SP_8 ## overwrite slot1 = raw ptr P1_ST_R1_R0_0 P1_LI_R1 %3 P1_SB_R1_R0_7 - P1_MOV_R3_SP - P1_LD_R1_R3_8 ## raw ptr - P1_LD_R2_R3_16 ## init + P1_LD_R1_SP_8 ## raw ptr + P1_LD_R2_SP_16 ## init P1_LD_R0_R1_0 ## len_raw from header P1_ADDI_R1_R1_8 ## payload cursor P1_LI_R3 @@ -788,8 +778,7 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' &make_vector_loop P1_B :make_vector_done - P1_MOV_R3_SP - P1_LD_R0_R3_8 + P1_LD_R0_SP_8 P1_ORI_R0_R0_2 P1_ORI_R0_R0_1 ## tag = 011 (vector) P1_EPILOGUE_N2 @@ -842,9 +831,8 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' ## probe index h. :intern P1_PROLOGUE_N3 - P1_MOV_R3_SP - P1_ST_R6_R3_8 - P1_ST_R7_R3_16 + P1_ST_R6_SP_8 + P1_ST_R7_SP_16 P1_MOV_R6_R1 ## r6 = name_ptr (callee-saved copy) P1_MOV_R7_R2 ## r7 = name_len @@ -856,11 +844,10 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' P1_SHRI_R0_R0_52 ## r0 = h & 4095 P1_MOV_R3_SP - P1_ST_R0_R3_24 ## slot 3 = h + P1_ST_R0_SP_24 ## slot 3 = h :intern_probe - P1_MOV_R3_SP - P1_LD_R0_R3_24 + P1_LD_R0_SP_24 P1_SHLI_R0_R0_3 ## r0 = h * 8 P1_LI_R2 &symbol_table @@ -884,12 +871,11 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' P1_BNEZ_R0 ## Advance h = (h+1) & 4095. - P1_MOV_R3_SP - P1_LD_R0_R3_24 + P1_LD_R0_SP_24 P1_ADDI_R0_R0_1 P1_SHLI_R0_R0_52 P1_SHRI_R0_R0_52 - P1_ST_R0_R3_24 + P1_ST_R0_SP_24 P1_LI_BR &intern_probe P1_B @@ -902,8 +888,7 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' &make_symbol P1_CALL ## r0 = tagged sym - P1_MOV_R3_SP - P1_LD_R1_R3_24 + P1_LD_R1_SP_24 P1_SHLI_R1_R1_3 P1_LI_R2 &symbol_table @@ -916,7 +901,7 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' :intern_hit P1_MOV_R3_SP - P1_LD_R0_R3_24 + P1_LD_R0_SP_24 P1_SHLI_R0_R0_3 P1_LI_R2 &symbol_table @@ -924,9 +909,8 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' P1_LD_R0_R2_0 ## r0 = existing tagged sym :intern_done - P1_MOV_R3_SP - P1_LD_R6_R3_8 - P1_LD_R7_R3_16 + P1_LD_R6_SP_8 + P1_LD_R7_SP_16 P1_EPILOGUE_N3 P1_RET @@ -934,18 +918,16 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' ## ---- cons / car / cdr (preserved from step 2) ----------------------- :cons P1_PROLOGUE_N2 - P1_MOV_R3_SP - P1_ST_R1_R3_8 - P1_ST_R2_R3_16 + P1_ST_R1_SP_8 + P1_ST_R2_SP_16 P1_LI_R1 %16 P1_LI_BR &alloc P1_CALL - P1_MOV_R3_SP - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_ST_R1_R0_0 - P1_LD_R2_R3_16 + P1_LD_R2_SP_16 P1_ST_R2_R0_8 P1_ORI_R0_R0_2 P1_EPILOGUE_N2 @@ -1382,7 +1364,7 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' :read_number P1_PROLOGUE P1_MOV_R3_SP - P1_ST_R6_R3_8 + P1_ST_R6_SP_8 P1_LI_R6 %0 ## r6 = 0 (accumulator) @@ -1426,8 +1408,7 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' ## Tag as fixnum (low 3 bits = 001 = shift-left-3 + OR 1). P1_SHLI_R0_R6_3 P1_ORI_R0_R0_1 - P1_MOV_R3_SP - P1_LD_R6_R3_8 + P1_LD_R6_SP_8 P1_EPILOGUE P1_RET @@ -1490,8 +1471,8 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' :read_symbol P1_PROLOGUE_N2 P1_MOV_R3_SP - P1_ST_R6_R3_8 - P1_ST_R7_R3_16 + P1_ST_R6_SP_8 + P1_ST_R7_SP_16 ## r7 = &src[cursor] (stored start) P1_LI_R1 @@ -1542,9 +1523,8 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' &intern P1_CALL - P1_MOV_R3_SP - P1_LD_R6_R3_8 - P1_LD_R7_R3_16 + P1_LD_R6_SP_8 + P1_LD_R7_SP_16 P1_EPILOGUE_N2 P1_RET @@ -1554,9 +1534,8 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' ## four escape forms the seed needs: \n, \t, \\, and \". :read_string P1_PROLOGUE_N2 - P1_MOV_R3_SP - P1_ST_R6_R3_8 - P1_ST_R7_R3_16 + P1_ST_R6_SP_8 + P1_ST_R7_SP_16 P1_LI_BR &advance_char @@ -1691,9 +1670,8 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' &make_string P1_CALL - P1_MOV_R3_SP - P1_LD_R6_R3_8 - P1_LD_R7_R3_16 + P1_LD_R6_SP_8 + P1_LD_R7_SP_16 P1_EPILOGUE_N2 P1_RET @@ -1731,23 +1709,20 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' P1_BEQ_R0_R1 ## Read head element, then tail, then cons them. - P1_MOV_R3_SP - P1_ST_R6_R3_8 ## save outer r6 (if any) + P1_ST_R6_SP_8 ## save outer r6 (if any) P1_LI_BR &read_expr P1_CALL ## r0 = head - P1_MOV_R3_SP - P1_ST_R0_R3_8 ## slot 1 = head (spill across next call) + P1_ST_R0_SP_8 ## slot 1 = head (spill across next call) P1_LI_BR &read_list P1_CALL ## r0 = tail (recursive) ## cons(head, tail) - P1_MOV_R3_SP - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_MOV_R2_R0 P1_LI_BR &cons @@ -2135,9 +2110,8 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' :display_pair ## r2 = tagged pair. Shares display's PROLOGUE_N2 frame. - P1_MOV_R3_SP - P1_ST_R6_R3_8 ## save r6 into display's slot 1 - P1_ST_R7_R3_16 ## save r7 into display's slot 2 + P1_ST_R6_SP_8 ## save r6 into display's slot 1 + P1_ST_R7_SP_16 ## save r7 into display's slot 2 P1_MOV_R6_R2 ## r6 = tagged pair (we'll walk cdr chain) @@ -2492,9 +2466,8 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' ## fall out naturally because lookup_alist returns the leftmost match. :gset P1_PROLOGUE_N2 - P1_MOV_R3_SP - P1_ST_R1_R3_8 ## save sym - P1_ST_R2_R3_16 ## save val + P1_ST_R1_SP_8 ## save sym + P1_ST_R2_SP_16 ## save val P1_LI_BR &cons @@ -2521,12 +2494,12 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' :lookup_alist P1_PROLOGUE_N3 P1_MOV_R3_SP - P1_ST_R1_R3_8 ## slot 1 = sym - P1_ST_R2_R3_16 ## slot 2 = cursor + P1_ST_R1_SP_8 ## slot 1 = sym + P1_ST_R2_SP_16 ## slot 2 = cursor :lookup_alist_loop P1_MOV_R3_SP - P1_LD_R2_R3_16 + P1_LD_R2_SP_16 P1_LI_R1 %7 P1_LI_BR @@ -2539,8 +2512,7 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' &car P1_CALL ## r0 = (k . v) - P1_MOV_R3_SP - P1_ST_R0_R3_24 ## slot 3 = pair + P1_ST_R0_SP_24 ## slot 3 = pair P1_MOV_R1_R0 P1_LI_BR @@ -2548,25 +2520,23 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' P1_CALL ## r0 = key P1_MOV_R3_SP - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_LI_BR &lookup_alist_hit P1_BEQ_R0_R1 ## advance cursor := cdr(cursor) - P1_LD_R1_R3_16 + P1_LD_R1_SP_16 P1_LI_BR &cdr P1_CALL - P1_MOV_R3_SP - P1_ST_R0_R3_16 + P1_ST_R0_SP_16 P1_LI_BR &lookup_alist_loop P1_B :lookup_alist_hit - P1_MOV_R3_SP - P1_LD_R0_R3_24 + P1_LD_R0_SP_24 P1_EPILOGUE_N3 P1_RET @@ -2581,8 +2551,7 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' ## Local first, global second. Errors out via &err_unbound on miss. :lookup P1_PROLOGUE_N2 - P1_MOV_R3_SP - P1_ST_R1_R3_8 ## save sym for possible global retry + P1_ST_R1_SP_8 ## save sym for possible global retry P1_LI_BR &lookup_alist @@ -2602,8 +2571,7 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' P1_RET :lookup_global - P1_MOV_R3_SP - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_LI_R2 &global_env_cell P1_LD_R2_R2_0 @@ -2634,20 +2602,20 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' P1_PROLOGUE_N4 P1_MOV_R0_R3 ## save env before clobbering r3 P1_MOV_R3_SP - P1_ST_R1_R3_8 ## slot 1 = names - P1_ST_R2_R3_16 ## slot 2 = vals - P1_ST_R0_R3_24 ## slot 3 = env accumulator + P1_ST_R1_SP_8 ## slot 1 = names + P1_ST_R2_SP_16 ## slot 2 = vals + P1_ST_R0_SP_24 ## slot 3 = env accumulator :env_extend_loop P1_MOV_R3_SP - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_LI_R2 %7 P1_LI_BR &env_extend_done P1_BEQ_R1_R2 ## names == nil → done - P1_LD_R1_R3_16 + P1_LD_R1_SP_16 P1_LI_R2 %7 P1_LI_BR @@ -2655,62 +2623,54 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' P1_BEQ_R1_R2 ## vals == nil → arity error ## name = car(names) - P1_MOV_R3_SP - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_LI_BR &car P1_CALL ## r0 = name - P1_MOV_R3_SP - P1_ST_R0_R3_32 ## slot 4 = name + P1_ST_R0_SP_32 ## slot 4 = name ## val = car(vals) - P1_LD_R1_R3_16 + P1_LD_R1_SP_16 P1_LI_BR &car P1_CALL ## r0 = val ## pair = cons(name, val) P1_MOV_R2_R0 - P1_MOV_R3_SP - P1_LD_R1_R3_32 + P1_LD_R1_SP_32 P1_LI_BR &cons P1_CALL ## r0 = (name . val) ## env := cons(pair, env) P1_MOV_R1_R0 - P1_MOV_R3_SP - P1_LD_R2_R3_24 + P1_LD_R2_SP_24 P1_LI_BR &cons P1_CALL ## r0 = new env - P1_MOV_R3_SP - P1_ST_R0_R3_24 + P1_ST_R0_SP_24 ## names := cdr(names) - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_LI_BR &cdr P1_CALL - P1_MOV_R3_SP - P1_ST_R0_R3_8 + P1_ST_R0_SP_8 ## vals := cdr(vals) - P1_LD_R1_R3_16 + P1_LD_R1_SP_16 P1_LI_BR &cdr P1_CALL - P1_MOV_R3_SP - P1_ST_R0_R3_16 + P1_ST_R0_SP_16 P1_LI_BR &env_extend_loop P1_B :env_extend_done - P1_MOV_R3_SP - P1_LD_R0_R3_24 + P1_LD_R0_SP_24 P1_EPILOGUE_N4 P1_RET @@ -2723,10 +2683,9 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' :make_closure P1_PROLOGUE_N3 P1_MOV_R0_R3 ## save env - P1_MOV_R3_SP - P1_ST_R1_R3_8 ## slot 1 = params - P1_ST_R2_R3_16 ## slot 2 = body - P1_ST_R0_R3_24 ## slot 3 = env + P1_ST_R1_SP_8 ## slot 1 = params + P1_ST_R2_SP_16 ## slot 2 = body + P1_ST_R0_SP_24 ## slot 3 = env P1_LI_R1 %32 ## 32 bytes @@ -2738,12 +2697,11 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' %4 P1_SB_R1_R0_7 ## type = 4 (closure) - P1_MOV_R3_SP - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_ST_R1_R0_8 - P1_LD_R1_R3_16 + P1_LD_R1_SP_16 P1_ST_R1_R0_16 - P1_LD_R1_R3_24 + P1_LD_R1_SP_24 P1_ST_R1_R0_24 P1_ORI_R0_R0_4 @@ -2761,10 +2719,9 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' :make_primitive P1_PROLOGUE_N3 P1_MOV_R0_R3 ## save type → r0 (frees r3) - P1_MOV_R3_SP - P1_ST_R1_R3_8 ## slot 1 = code_id - P1_ST_R2_R3_16 ## slot 2 = arity - P1_ST_R0_R3_24 ## slot 3 = type + P1_ST_R1_SP_8 ## slot 1 = code_id + P1_ST_R2_SP_16 ## slot 2 = arity + P1_ST_R0_SP_24 ## slot 3 = type P1_LI_R1 %16 ## 16 bytes @@ -2772,12 +2729,11 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' &alloc P1_CALL ## r0 = raw ptr - P1_MOV_R3_SP - P1_LD_R1_R3_24 + P1_LD_R1_SP_24 P1_SB_R1_R0_7 ## byte 7 = type - P1_LD_R1_R3_16 + P1_LD_R1_SP_16 P1_SB_R1_R0_0 ## byte 0 = arity - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_ST_R1_R0_8 ## +8 = code id P1_ORI_R0_R0_4 @@ -2792,8 +2748,8 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' :eval_args P1_PROLOGUE_N3 P1_MOV_R3_SP - P1_ST_R1_R3_8 ## slot 1 = args cursor - P1_ST_R2_R3_16 ## slot 2 = env + P1_ST_R1_SP_8 ## slot 1 = args cursor + P1_ST_R2_SP_16 ## slot 2 = env P1_LI_R2 %7 @@ -2806,30 +2762,26 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' &car P1_CALL P1_MOV_R1_R0 - P1_MOV_R3_SP - P1_LD_R2_R3_16 + P1_LD_R2_SP_16 P1_LI_BR &eval P1_CALL ## r0 = head value - P1_MOV_R3_SP - P1_ST_R0_R3_24 + P1_ST_R0_SP_24 ## tail = eval_args(cdr(args), env) - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_LI_BR &cdr P1_CALL P1_MOV_R1_R0 - P1_MOV_R3_SP - P1_LD_R2_R3_16 + P1_LD_R2_SP_16 P1_LI_BR &eval_args P1_CALL ## r0 = tail P1_MOV_R2_R0 - P1_MOV_R3_SP - P1_LD_R1_R3_24 + P1_LD_R1_SP_24 P1_LI_BR &cons ## tail: cons is last work in this frame P1_TAIL_N3 @@ -2850,8 +2802,8 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' :apply P1_PROLOGUE_N4 P1_MOV_R3_SP - P1_ST_R1_R3_8 ## slot 1 = callee (tagged) - P1_ST_R2_R3_16 ## slot 2 = args + P1_ST_R1_SP_8 ## slot 1 = callee (tagged) + P1_ST_R2_SP_16 ## slot 2 = args P1_ANDI_R1_R1_7 P1_LI_R0 @@ -2861,7 +2813,7 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' P1_BNE_R1_R0 P1_MOV_R3_SP - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_ADDI_R1_R1_NEG6 ## r1 = raw ptr ## Fork on header type byte. @@ -2879,23 +2831,22 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' ## Fall through: type == 4 (closure). P1_LD_R0_R1_8 ## params - P1_ST_R0_R3_8 ## slot 1 = params (overwrite) + P1_ST_R0_SP_8 ## slot 1 = params (overwrite) P1_LD_R0_R1_16 ## body - P1_ST_R0_R3_24 ## slot 3 = body + P1_ST_R0_SP_24 ## slot 3 = body P1_LD_R0_R1_24 ## closure env - P1_ST_R0_R3_32 ## slot 4 = closure env + P1_ST_R0_SP_32 ## slot 4 = closure env ## env_extend(params, args, closure_env) - P1_LD_R1_R3_8 - P1_LD_R2_R3_16 - P1_LD_R3_R3_32 + P1_LD_R1_SP_8 + P1_LD_R2_SP_16 + P1_LD_R3_SP_32 P1_LI_BR &env_extend P1_CALL ## r0 = new env P1_MOV_R2_R0 - P1_MOV_R3_SP - P1_LD_R1_R3_24 ## r1 = body + P1_LD_R1_SP_24 ## r1 = body P1_LI_BR &eval P1_TAIL_N4 ## Scheme tail call: closure body @@ -2919,13 +2870,13 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' P1_CALL ## r0 = argc, r2 = &prim_argv P1_MOV_R3_SP - P1_LD_R1_R3_32 + P1_LD_R1_SP_32 P1_LI_BR &err_arity P1_BNE_R0_R1 P1_MOV_R1_R0 - P1_LD_R3_R3_24 ## r3 = code id + P1_LD_R3_SP_24 ## r3 = code id P1_EPILOGUE_N4 P1_LI_BR &prim_dispatch @@ -2943,8 +2894,7 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' P1_CALL ## r0 = argc, r2 = &prim_argv P1_MOV_R1_R0 - P1_MOV_R3_SP - P1_LD_R3_R3_24 ## r3 = code id + P1_LD_R3_SP_24 ## r3 = code id P1_EPILOGUE_N4 P1_LI_BR &prim_dispatch @@ -3783,33 +3733,31 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' P1_MOV_R3_SP P1_LI_R0 NIL ## nil - P1_ST_R0_R3_8 ## slot1 = accumulator - P1_ST_R2_R3_24 ## slot3 = base + P1_ST_R0_SP_8 ## slot1 = accumulator + P1_ST_R2_SP_24 ## slot3 = base P1_SHLI_R1_R1_3 ## r1 = argc * 8 P1_ADD_R1_R1_R2 ## r1 = end ptr (one past last) - P1_ST_R1_R3_16 ## slot2 = cursor + P1_ST_R1_SP_16 ## slot2 = cursor :prim_list_loop P1_MOV_R3_SP - P1_LD_R0_R3_16 ## cursor - P1_LD_R1_R3_24 ## base + P1_LD_R0_SP_16 ## cursor + P1_LD_R1_SP_24 ## base P1_LI_BR &prim_list_done P1_BEQ_R0_R1 P1_ADDI_R0_R0_NEG8 ## cursor -= 8 - P1_ST_R0_R3_16 + P1_ST_R0_SP_16 P1_LD_R1_R0_0 ## r1 = arg - P1_LD_R2_R3_8 ## r2 = accumulator + P1_LD_R2_SP_8 ## r2 = accumulator P1_LI_BR &cons P1_CALL - P1_MOV_R3_SP - P1_ST_R0_R3_8 ## accumulator = new pair + P1_ST_R0_SP_8 ## accumulator = new pair P1_LI_BR &prim_list_loop P1_B :prim_list_done - P1_MOV_R3_SP - P1_LD_R0_R3_8 + P1_LD_R0_SP_8 P1_EPILOGUE_N3 P1_RET @@ -3876,17 +3824,15 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' P1_LI_BR &append_one_base P1_BEQ_R1_R0 - P1_MOV_R3_SP - P1_ST_R1_R3_8 ## save xs - P1_ST_R2_R3_16 ## save ys + P1_ST_R1_SP_8 ## save xs + P1_ST_R2_SP_16 ## save ys P1_ADDI_R0_R1_NEG2 P1_LD_R1_R0_8 ## r1 = cdr(xs) P1_LI_BR &append_one P1_CALL ## r0 = appended tail P1_MOV_R2_R0 - P1_MOV_R3_SP - P1_LD_R0_R3_8 + P1_LD_R0_SP_8 P1_ADDI_R0_R0_NEG2 P1_LD_R1_R0_0 ## r1 = car(xs) P1_LI_BR @@ -3908,35 +3854,33 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' &prim_append_zero P1_BEQZ_R1 P1_MOV_R3_SP - P1_ST_R2_R3_8 ## slot1 = argv base + P1_ST_R2_SP_8 ## slot1 = argv base P1_ADDI_R1_R1_NEG1 ## r1 = argc-1 P1_SHLI_R1_R1_3 ## r1 = (argc-1)*8 P1_ADD_R1_R1_R2 ## r1 = &argv[argc-1] - P1_ST_R1_R3_24 ## slot3 = cursor + P1_ST_R1_SP_24 ## slot3 = cursor P1_LD_R0_R1_0 ## r0 = last arg - P1_ST_R0_R3_16 ## slot2 = result + P1_ST_R0_SP_16 ## slot2 = result :prim_append_loop P1_MOV_R3_SP - P1_LD_R0_R3_24 ## cursor - P1_LD_R1_R3_8 ## base + P1_LD_R0_SP_24 ## cursor + P1_LD_R1_SP_8 ## base P1_LI_BR &prim_append_done P1_BEQ_R0_R1 P1_ADDI_R0_R0_NEG8 - P1_ST_R0_R3_24 + P1_ST_R0_SP_24 P1_LD_R1_R0_0 ## r1 = arg at cursor - P1_LD_R2_R3_16 ## r2 = result + P1_LD_R2_SP_16 ## r2 = result P1_LI_BR &append_one P1_CALL - P1_MOV_R3_SP - P1_ST_R0_R3_16 + P1_ST_R0_SP_16 P1_LI_BR &prim_append_loop P1_B :prim_append_done - P1_MOV_R3_SP - P1_LD_R0_R3_16 + P1_LD_R0_SP_16 P1_EPILOGUE_N3 P1_RET :prim_append_zero @@ -3951,13 +3895,13 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' P1_PROLOGUE_N2 P1_LD_R0_R2_0 P1_MOV_R3_SP - P1_ST_R0_R3_8 ## slot1 = current + P1_ST_R0_SP_8 ## slot1 = current P1_LI_R0 %7 - P1_ST_R0_R3_16 ## slot2 = accumulator (nil) + P1_ST_R0_SP_16 ## slot2 = accumulator (nil) :prim_reverse_loop P1_MOV_R3_SP - P1_LD_R0_R3_8 + P1_LD_R0_SP_8 P1_LI_R1 %7 P1_LI_BR @@ -3966,20 +3910,17 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' P1_ADDI_R0_R0_NEG2 P1_LD_R1_R0_0 ## r1 = car P1_LD_R2_R0_8 ## r2 = cdr (next current) - P1_MOV_R3_SP - P1_ST_R2_R3_8 ## slot1 = next - P1_LD_R2_R3_16 ## r2 = accumulator + P1_ST_R2_SP_8 ## slot1 = next + P1_LD_R2_SP_16 ## r2 = accumulator P1_LI_BR &cons P1_CALL - P1_MOV_R3_SP - P1_ST_R0_R3_16 + P1_ST_R0_SP_16 P1_LI_BR &prim_reverse_loop P1_B :prim_reverse_done - P1_MOV_R3_SP - P1_LD_R0_R3_16 + P1_LD_R0_SP_16 P1_EPILOGUE_N2 P1_RET @@ -4049,8 +3990,8 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' :eval P1_PROLOGUE_N3 P1_MOV_R3_SP - P1_ST_R1_R3_8 ## slot 1 = expr - P1_ST_R2_R3_16 ## slot 2 = env + P1_ST_R1_SP_8 ## slot 1 = expr + P1_ST_R2_SP_16 ## slot 2 = env P1_LI_R2 %7 @@ -4084,15 +4025,13 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' P1_B :eval_self_slot1 - P1_MOV_R3_SP - P1_LD_R0_R3_8 + P1_LD_R0_SP_8 P1_EPILOGUE_N3 P1_RET :eval_sym - P1_MOV_R3_SP - P1_LD_R1_R3_8 - P1_LD_R2_R3_16 + P1_LD_R1_SP_8 + P1_LD_R2_SP_16 P1_LI_BR &lookup P1_TAIL_N3 @@ -4100,8 +4039,7 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' :eval_pair ## Compound expression. Dispatch on car against cached sym_* ## pointers; otherwise treat as function application. - P1_MOV_R3_SP - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_LI_BR &car P1_CALL ## r0 = callee-expr @@ -4143,30 +4081,26 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' ## Application: callee = eval(callee-expr, env) P1_MOV_R1_R0 - P1_MOV_R3_SP - P1_LD_R2_R3_16 + P1_LD_R2_SP_16 P1_LI_BR &eval P1_CALL ## r0 = callee value - P1_MOV_R3_SP - P1_ST_R0_R3_24 ## slot 3 = callee + P1_ST_R0_SP_24 ## slot 3 = callee ## args = eval_args(cdr(expr), env) - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_LI_BR &cdr P1_CALL P1_MOV_R1_R0 - P1_MOV_R3_SP - P1_LD_R2_R3_16 + P1_LD_R2_SP_16 P1_LI_BR &eval_args P1_CALL ## r0 = args list P1_MOV_R2_R0 - P1_MOV_R3_SP - P1_LD_R1_R3_24 + P1_LD_R1_SP_24 P1_LI_BR &apply P1_TAIL_N3 ## Scheme tail call: application @@ -4176,8 +4110,7 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' ## All run inside eval's PROLOGUE_N3 frame: slot 1 = expr, slot 2 = ## env, slot 3 = per-form scratch. :eval_quote - P1_MOV_R3_SP - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_LI_BR &cdr P1_CALL ## r0 = (x) @@ -4189,8 +4122,7 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' :eval_if ## (if cond then else). Save (then else) tail into slot 3, eval ## cond, branch to the correct arm. - P1_MOV_R3_SP - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_LI_BR &cdr P1_CALL ## r0 = (cond then else) @@ -4198,10 +4130,9 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' P1_LI_BR &cdr P1_CALL ## r0 = (then else) - P1_MOV_R3_SP - P1_ST_R0_R3_24 + P1_ST_R0_SP_24 - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_LI_BR &cdr P1_CALL ## r0 = (cond then else) @@ -4210,8 +4141,7 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' &car P1_CALL ## r0 = cond expr P1_MOV_R1_R0 - P1_MOV_R3_SP - P1_LD_R2_R3_16 + P1_LD_R2_SP_16 P1_LI_BR &eval P1_CALL ## r0 = cond value @@ -4223,22 +4153,19 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' P1_BEQ_R0_R1 ## Then branch: eval car(slot3) - P1_MOV_R3_SP - P1_LD_R1_R3_24 + P1_LD_R1_SP_24 P1_LI_BR &car P1_CALL P1_MOV_R1_R0 - P1_MOV_R3_SP - P1_LD_R2_R3_16 + P1_LD_R2_SP_16 P1_LI_BR &eval ## Scheme tail: then-branch P1_TAIL_N3 :eval_if_else ## Else branch: eval car(cdr(slot3)) - P1_MOV_R3_SP - P1_LD_R1_R3_24 + P1_LD_R1_SP_24 P1_LI_BR &cdr P1_CALL @@ -4247,8 +4174,7 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' &car P1_CALL P1_MOV_R1_R0 - P1_MOV_R3_SP - P1_LD_R2_R3_16 + P1_LD_R2_SP_16 P1_LI_BR &eval ## Scheme tail: else-branch P1_TAIL_N3 @@ -4259,17 +4185,16 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' ## cdr(cursor): nil next → TAIL eval the current head; otherwise ## CALL eval and advance. Slot 3 bridges the saved next-cursor ## across the CALL eval in the non-tail branch. - P1_MOV_R3_SP - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_LI_BR &cdr P1_CALL ## r0 = body list P1_MOV_R3_SP - P1_ST_R0_R3_8 ## slot 1 := cursor + P1_ST_R0_SP_8 ## slot 1 := cursor :eval_begin_loop P1_MOV_R3_SP - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_LI_R2 %7 P1_LI_BR @@ -4289,36 +4214,31 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' ## Non-tail: stash next in slot 3, CALL eval(car(cursor), env), ## discard result, advance cursor := next. - P1_MOV_R3_SP - P1_ST_R0_R3_24 ## slot 3 := next - P1_LD_R1_R3_8 + P1_ST_R0_SP_24 ## slot 3 := next + P1_LD_R1_SP_8 P1_LI_BR &car P1_CALL P1_MOV_R1_R0 - P1_MOV_R3_SP - P1_LD_R2_R3_16 + P1_LD_R2_SP_16 P1_LI_BR &eval P1_CALL - P1_MOV_R3_SP - P1_LD_R0_R3_24 - P1_ST_R0_R3_8 ## cursor := next + P1_LD_R0_SP_24 + P1_ST_R0_SP_8 ## cursor := next P1_LI_BR &eval_begin_loop P1_B :eval_begin_tail ## Scheme tail: TAIL eval(car(cursor), env). Frame torn down. - P1_MOV_R3_SP - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_LI_BR &car P1_CALL ## r0 = head expr P1_MOV_R1_R0 - P1_MOV_R3_SP - P1_LD_R2_R3_16 + P1_LD_R2_SP_16 P1_LI_BR &eval P1_TAIL_N3 @@ -4332,22 +4252,19 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' :eval_lambda ## (lambda params body). Slot 1 gets repurposed to hold params ## once we no longer need the original expr. - P1_MOV_R3_SP - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_LI_BR &cdr P1_CALL ## r0 = (params body) - P1_MOV_R3_SP - P1_ST_R0_R3_24 ## slot 3 = (params body) + P1_ST_R0_SP_24 ## slot 3 = (params body) P1_MOV_R1_R0 P1_LI_BR &car P1_CALL ## r0 = params - P1_MOV_R3_SP - P1_ST_R0_R3_8 ## slot 1 := params + P1_ST_R0_SP_8 ## slot 1 := params - P1_LD_R1_R3_24 + P1_LD_R1_SP_24 P1_LI_BR &cdr P1_CALL ## r0 = (body) @@ -4357,9 +4274,8 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' P1_CALL ## r0 = body P1_MOV_R2_R0 - P1_MOV_R3_SP - P1_LD_R1_R3_8 ## r1 = params - P1_LD_R3_R3_16 ## r3 = env + P1_LD_R1_SP_8 ## r1 = params + P1_LD_R3_SP_16 ## r3 = env P1_LI_BR &make_closure ## tail: no Scheme-visible work after P1_TAIL_N3 @@ -4367,22 +4283,19 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' :eval_define ## (define sym val-expr). gset-binds the evaluated val into the ## global alist, returns nil. - P1_MOV_R3_SP - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_LI_BR &cdr P1_CALL ## r0 = (sym val-expr) - P1_MOV_R3_SP - P1_ST_R0_R3_24 ## slot 3 := (sym val-expr) + P1_ST_R0_SP_24 ## slot 3 := (sym val-expr) P1_MOV_R1_R0 P1_LI_BR &car P1_CALL ## r0 = sym - P1_MOV_R3_SP - P1_ST_R0_R3_8 ## slot 1 := sym + P1_ST_R0_SP_8 ## slot 1 := sym - P1_LD_R1_R3_24 + P1_LD_R1_SP_24 P1_LI_BR &cdr P1_CALL ## r0 = (val-expr) @@ -4391,15 +4304,13 @@ DEFINE ZERO32 '0000000000000000000000000000000000000000000000000000000000000000' &car P1_CALL ## r0 = val-expr P1_MOV_R1_R0 - P1_MOV_R3_SP - P1_LD_R2_R3_16 + P1_LD_R2_SP_16 P1_LI_BR &eval P1_CALL ## r0 = val P1_MOV_R2_R0 - P1_MOV_R3_SP - P1_LD_R1_R3_8 + P1_LD_R1_SP_8 P1_LI_BR &gset P1_CALL