Twobit assembly

The MacScheme machine assembly code generated by the code generator is translated to native code by an optimizing assembler. Porting Twobit to a new target architecture is mostly a matter of rewriting the assembler tables.

It would take much, much longer to port the Larceny runtime system than to retarget Twobit.

For the reverse-map example, peephole optimizations convert the MacScheme machine assembly code that is produced by the code generator into

        lambda      *,0
        setglbl     reverse-map
        const       reverse-map
        return
        .proc
        args=       2
        const/setreg (),3
        .align      4
L1001
        .proc
        .proc-doc   #(.loop|2 #f 2 #f #f (l x))
        reg/op1/branchf internal:branchf-pair?,2,1004
        save        3
        store       0,0
        store       1,2
        store       2,3
        store       3,1
        reg/op1/setreg internal:car,2,7
        movereg     1,2
        movereg     7,1
        reg         2
        setrtn      1007
        invoke      1
        .align      4
L1007
        .cont
        load        0,0
        load        7,1
        reg/op2/setreg internal:cons,result,7,3
        load        1,2
        stack       3
        reg/op1/setreg internal:cdr,result,2
        pop         3
        branch      1001,3
L1004
        reg/return  3

Peephole optimization actually occurs during the same pass that translates MacScheme machine assembly language into the SPARC machine code shown below. Comments show the correspondence between the SPARC code and the MacScheme machine assembly code from which it was generated. This correspondence is disguised by delayed branch instructions, whose delay slots are filled by a simple backpatching algorithm.

Segment # #f
0       jmpl    %globals + 1024, %o7       ;lambda      1,0
4       or      %g0, 16, %result        
8       or      %g0, 3326, %tmp0        
12      st      %tmp0, [ %result ]
16      add     %result, 7, %result
20      ld      [ %r0 + 1 ], %tmp0
24      ld      [ %tmp0 + 5 ], %tmp1
28      st      %tmp1, [ %result - 3 ]
32      ld      [ %tmp0 + 9 ], %tmp1
36      st      %tmp1, [ %result + 1 ]
40      st      %r0, [ %result + 5 ]
44      or      %g0, %result, %argreg2
48      ld      [ %r0 + 1 ], %tmp0         ;setglbl     reverse-map
52      ld      [ %tmp0 + 13 ], %result
56      jmpl    %globals + 1048, %o7    
60      st      %argreg2, [ %result - 1 ]
64      ld      [ %r0 + 1 ], %tmp0         ;const       reverse-map
68      ld      [ %tmp0 + 17 ], %result
72      ld      [ %stkp + 4 ], %o7         ;return
76      jmpl    %o7 + 8, %g0
80      nop
------------------------------------------
Constant vector element # 0
Data: #f
------------------------------------------
Constant vector element # 1
Code vector
0       subcc   %result, 8, %g0            ;args=       2
4       be,a    #24
8       or      %g0, 10, %r3
12      jmpl    %globals + 1464, %o7    
16      or      %g0, 8, %argreg2
20      or      %g0, 10, %r3               ;const/setreg (),3
24      and     %r2, 7, %tmp0       ;L1001 ;reg/op1/branchf
28      subcc   %tmp0, 1, %g0              ;    internal:branchf-pair?,2,1004
32      bne,a   #312
36      ld      [ %stkp + 4 ], %o7
40      sub     %stkp, 32, %stkp           ;save        3
44      subcc   %etop, %stkp, %g0
48      ble,a   #68
52      or      %g0, 24, %tmp0  
56      add     %stkp, 32, %stkp        
60      jmpl    %globals + 1056, %o7    
64      add     %o7, -28, %o7
68      st      %tmp0, [ %stkp ]
72      st      %g0, [ %stkp + 4 ]
76      st      %r0, [ %stkp + 12 ]        ;store       0,0
80      st      %r1, [ %stkp + 20 ]        ;store       1,2
84      st      %r2, [ %stkp + 24 ]        ;store       2,3
88      st      %r3, [ %stkp + 16 ]        ;store       3,1
92      and     %r2, 7, %tmp0              ;reg/op1/setreg internal:car,2,7
96      subcc   %tmp0, 1, %g0
100     be,a    #128
104     ld      [ %r2 - 1 ], %r7
108     or      %g0, %r2, %result
112     or      %g0, 0, %tmp0
116     jmpl    %globals + 1384, %o7    
120     add     %o7, -32, %o7
124     ld      [ %r2 - 1 ], %r7
128     or      %g0, %r1, %r2              ;movereg     1,2
132     or      %g0, %r7, %r1              ;movereg     7,1
136     or      %g0, %r2, %result          ;reg         2
140     call    #148                       ;setrtn      1007
144     add     %o7, 56, %o7    
148     st      %o7, [ %stkp + 4 ]
152     subcc   %timer, 1, %timer          ;invoke      1
156     bne     #172
160     and     %result, 7, %tmp0
164     jmpl    %globals + 1376, %o7    
168     add     %o7, -20, %o7
172     subcc   %tmp0, 7, %g0
176     be,a    #192
180     ld      [ %result - 3 ], %tmp0
184     jmpl    %globals + 1448, %o7    
188     add     %o7, -40, %o7
192     or      %g0, %result, %r0
196     jmpl    %tmp0 - 1, %g0
200     or      %g0, 4, %result
204     ld      [ %stkp + 12 ], %r0 ;L1007 ;load        0,0
208     ld      [ %stkp + 16 ], %r7        ;load        7,1
212     add     %etop, 8, %etop            ;reg/op2/setreg
216     subcc   %etop, %stkp, %g0          ;    internal:cons,result,7,3
220     ble,a   #236
224     st      %result, [ %etop - 8 ]
228     jmpl    %globals + 1040, %o7    
232     add     %o7, -24, %o7
236     st      %r7, [ %etop - 4 ]
240     sub     %etop, 7, %r3
244     ld      [ %stkp + 20 ], %r1        ;load        1,2
248     ld      [ %stkp + 24 ], %result    ;stack       3
252     and     %result, 7, %tmp0          ;reg/op1/setreg
256     subcc   %tmp0, 1, %g0              ;    internal:cdr,result,2
260     be,a    #284
264     ld      [ %result + 3 ], %r2
268     or      %g0, 4, %tmp0
272     jmpl    %globals + 1384, %o7    
276     add     %o7, -28, %o7
280     ld      [ %result + 3 ], %r2
284     add     %stkp, 32, %stkp           ;pop         3
288     subcc   %timer, 1, %timer          ;branch      1001,3
292     bne,a   #28
296     and     %r2, 7, %tmp0
300     jmpl    %globals + 1376, %o7    
304     add     %o7, -284, %o7
308     ld      [ %stkp + 4 ], %o7  ;L1004 ;reg/return  3
312     jmpl    %o7 + 8, %g0
316     or      %g0, %r3, %result
------------------------------------------
Constant vector element # 2
Constant vector
------------------------------------------
Constant vector element # 0
Data: ((0 . #(reverse-map #f 2 #f #f (f l)))
       (24 . #(.loop|2 #f 2 #f #f (l x))))
------------------------------------------
Constant vector element # 3
Global: reverse-map
------------------------------------------
Constant vector element # 4
Data: reverse-map
========================================