needs arch/core comp/tok unit comp/reg 64 const MAXREGS create memregs MAXREGS 4* allot 0 value regidx : ?regerr if 0 to regidx err"comp/reg inconsistency" then ; : regs$ regidx ?regerr ; : topreg regidx dup not ?regerr 1- ; : newreg doto regidx dup 1+ | MAXREGS > ?regerr ; : freereg doto regidx 1- dup | 0< ?regerr ; arch<< comp/reg.fs : ?regid topreg dup PHYSREGS < if 4* physregs + @ 1 else drop 0 then ; : reg) ?regid if W) swap R) 1 else topreg 4* memregs + m) 0 then ; : reg&) reg) if &) then ; : ?reg>) ?regid if R>) 1 else 0 then ; : usesA? regidx PHYSREGS 1- >= ; : ?pushA, usesA? if RSP) A>) -!, then ; : ?popA, usesA? if RSP) A>) @+, then ; : usesS? regidx PHYSREGS >= ; : ?pushS, usesS? if RSP) S>) -!, then ; : ?popS, usesS? if RSP) S>) @+, then ; \ If there's a lot of memregs to push, it would probably be faster with a \ "move", but doing to involves fiddling around and, most importantly, requires \ saving W somewhere. Most of the time, pushing them one at once is fine. : pushregs, regidx PHYSREGS min 0 do RSP) i 4* physregs + @ R>) -!, loop regidx PHYSREGS > if memregs i) A>) @, regidx PHYSREGS do A) i 4* +) S>) @, RSP) S>) -!, loop then ; : popregs, regidx PHYSREGS > if memregs i) A>) @, PHYSREGS regidx do RSP) S>) @+, A) i 1- 4* +) S>) !, 1 -loop then 0 regidx PHYSREGS min do RSP) i 1- 4* physregs + @ R>) @+, 1 -loop ;