proc iselect save pop [gp1] pop [gp0] adjust [gp1] 0 ; test for zero in-place cond zero jmp $retz push 1 ; i push 0 ; t label $loop over push [gp1] bitand drop cond zero jmp $else over ; i t i push [gp0] ; i t i a bitand ; i t (i&a) bitor ; i (t|(i&a)) over ; i t i push [gp1] ; i t i b bitxor pop [gp1] swap ; t i push 1 ; t i 1 shll ; t 2i swap ; i t jmp $while label $else push [gp0] push 1 shlr pop [gp0] push [gp1] push 1 shlr pop [gp1] label $while push [gp1] popbool cond jmp $loop swap drop jmp $ret label $retz push 0 label $ret restore set [arg] 1 return ; r end proc iinterleave save ; extract lower halfwords explode 2 ; a b_h b_l pop [gp1] ; a b_h swap ; b_h a explode 2 ; b_h a_h a_l pop [gp0] ; b_h a_h bitor ; the entire result is in the lower halfwords movesh ; stash the overflow value set [counter] 0 ; used for holding the shift amount set [arg] 1 ; holds the mask push 0 ; result label $loop bitand [gp1] [arg] ; res Bbit shl %P [counter] ; res Bbit< set [gp0] [gp0]+1 end ; 8 words macro bf+ pushptr load_ua [PSV] [SV] wadd 1 store_ua %P %P end ; 8 words macro bf- pushptr load_ua [PSV] [SV] wadd -1 store_ua %P %P end ; 6+? words macro bf. pushptr load_ua %P %P ; output end macro writeEOF .if OnEOF == 0 ; 7 words push [zero] pushptr store_ua %P %P .elseif OnEOF == -1 ; 7 words push 255 pushptr store_ua %P %P .else OnEOF == 1 ; unchanged - no writeback ; 0 words .endif end ; 11+[0,7]+? words macro bf, ; input dup cmpne EOF cond jmp $$EOF pushptr store_ua %P %P jmp $$end $$EOF: drop ; 7 or 0 words writeEOF $$end: end ; 8 words before macro bfLB (here) (dest) pushptr load_ua %P %P popbool cond 0Eh jmp (dest) label (here) end ; arguments inverted so that they are in the same order as the ; matching bfLB ; 8 words before macro bfRB (dest) (here) pushptr load_ua %P %P popbool cond jmp (dest) label (here) end ; For the BF code >>[-]<<[->>+<<] ; 64 words total proc bfcode bf> bf> bfLB BL1 BR1 bf- bfRB BL1 BR2 bf< bf< bfLB BL2 BR2 bf- bf> bf> bf+ bf< bf< bfRB BL2 BR2 ret end ; brainfuck macros (64-bit words, with anding) ; 1 word macro bf< set [gp0] [gp0#-1] end ; 1 word macro bf> set [gp0] [gp0]+1 end ; 4 words macro bf+ push *[gp0] wadd 1 bitand 255 pop *[gp0] end ; 4 words macro bf- push *[gp0] wsub 1 bitand 255 pop *[gp0] end ; 1+? words macro bf. push *[gp0] ; output end macro writeEOF .if OnEOF == 0 ; 1 word set *[gp0] [zero] .elseif OnEOF == -1 ; 1 word set *[gp0] 255 .else OnEOF == 1 ; unchanged - no writeback ; 0 words .endif end ; 6+[0,1]+? words macro bf, ; input dup cmpne EOF cond jmp $$EOF pop *[gp0] jmp $$end $$EOF: drop ; 1 or 0 words writeEOF $$end: end ; 3 words before macro bfLB (here) (dest) push *[gp0] popbool cond 0Eh jmp (dest) label (here) end ; arguments inverted so that they are in the same order as the ; matching bfLB ; 3 words before macro bfRB (dest) (here) push *[gp0] popbool cond jmp (dest) label (here) end ; For the BF code >>[-]<<[->>+<<] ; 32 words total ; could likely be hand-optimiaed after macro expansion proc bfcode_compact bf> bf> bfLB BL1 BR1 bf- bfRB BL1 BR2 bf< bf< bfLB BL2 BR2 bf- bf> bf> bf+ bf< bf< bfRB BL2 BR2 ret end ; 32 words proc bfcode_expanded set [gp0] [gp0]+1 set [gp0] [gp0]+1 push *[gp0] popbool cond 0Eh jmp BR1 BL1: push *[gp0] wsub 1 bitand 255 pop *[gp0] push *[gp0] popbool cond jmp BL1 BR2: set [gp0] [gp0#-1] set [gp0] [gp0#-1] push *[gp0] popbool cond 0Eh jmp BR2 BL2: push *[gp0] wsub 1 bitand 255 pop *[gp0] set [gp0] [gp0]+1 set [gp0] [gp0]+1 push *[gp0] wadd 1 bitand 255 pop *[gp0] set [gp0] [gp0#-1] set [gp0] [gp0#-1] push *[gp0] popbool cond jmp BL2 BR2: ret end ; optimizations applied: ; [-] -> set 0 ; >..N..>(...)<..N..< -> operate on [gp0]+N ; pop *A then push *A -> peek *A (no change here) ; 15 words proc bfcode_optimized1 set *[gp0]+2 0 push *[gp0] popbool cond 0Eh jmp BR2 BL2: push *[gp0] wsub 1 bitand 255 pop *[gp0] push *[gp0]+2 wadd 1 bitand 255 pop *[gp0]+2 push *[gp0] popbool cond 2 jmp BL2 BR2: ret end