Sparc Disassembly Example
The disassembly on sparc for the function
(defun foo (x y) (declare (optimize (speed 3) (space 0) (safety 0) (debug 0)) (type (unsigned-byte 32) x y)) (logand (logior x y) (logxor x y)))
is
41AEAF58: .ENTRY FOO() ; FUNCTION AF70: ADD -18, %CODE AF74: ADD %CFP, 32, %CSP AF78: ANDCC %A0, 3, %NL0 AF7C: BPEQ %ICC, L0 AF80: SRA %A0, 2, %NL1 AF84: LDUW [%A0-3], %NL1 AF88: L0: ANDCC %A1, 3, %NL0 AF8C: BPEQ %ICC, L1 AF90: SRA %A1, 2, %NL2 AF94: LDUW [%A1-3], %NL2 AF98: L1: OR %NL1, %NL2, %NL0 ; No-arg-parsing entry point AF9C: XOR %NL1, %NL2, %NL2 AFA0: AND %NL2, %NL0 AFA4: SRA %NL0, 29, %NL1 AFA8: CMP %NL1, %ZERO AFAC: BPEQ %ICC, L2 AFB0: SLL %NL0, 2, %A0 AFB4: OR 4, %ALLOC ; Set pseudo-atomic flag AFB8: ADD 16, %ALLOC ; Allocating 16 bytes AFBC: ANDN %ALLOC, 7, %NL1 AFC0: LDUW [%NULL+673], %A0 ; SPARC::*CURRENT-REGION-END-ADDR* AFC4: CMP %NL1, %A0 AFC8: SUB %NL1, 16, %A0 AFCC: TGT %ICC, 31 ; Allocation trap AFD0: ADD %ZERO, 522, %NL1 ; Header word BIGNUM-TYPE, size 2? AFD4: CMP %NL0, %ZERO AFD8: MOVGE %ICC, 266, %NL1 AFDC: OR 7, %A0 AFE0: ST %NL1, [%A0-7] AFE4: ST %NL0, [%A0-3] AFE8: ANDN 4, %ALLOC ; Reset pseudo-atomic flag AFEC: ANDCC %ALLOC, 1, %ZERO AFF0: TNE %ICC, 16 ; Pseudo atomic interrupted trap? AFF4: L2: MOV %CFP, %CSP AFF8: MOV %OCFP, %CFP AFFC: J %LRA+5 B000: MOV %LRA, %CODE B004: ILLTRAP #x0
The first line is the entry point of the function at address
#x41AEAF8. This is followed by the standard function prologue that
sets up the Lisp stack frame and loads the single 32-bit argument
(either a fixnum or a heap-allocated bignum) into the register
%NL2
. (Note that the register names do not follow the standard
sparc names; the register names denote the specific type of register.
In this case %NL<n>
means non-descriptor register <n>
).
At label L1
, the heart of the routine starts. The next three
instructions implement the logior
, logxor
and logand
functions. Afterwards, the code is allocating space in case the
result is a bignum. As in the x86 version, care is taken to make sure
the allocation is done pseudo-atomically.
Finally, at label L2
, we have the standard function epilogue
that destroys our stack frame and returns to the caller.