Remove more disassembler bogosity
[sbcl.git] / src / runtime / sparc-assem.S
blob9a6001ca08fe1d42221c97bd688fa419f43e990e
1 #define _ASM
3 #include "sparc-funcdef.h"
5 #define LANGUAGE_ASSEMBLY
6 #include "lispregs.h"
7 #include "globals.h"
8 #include "sbcl.h"
9 #include "genesis/closure.h"
10 #include "genesis/funcallable-instance.h"
11 #include "genesis/fdefn.h"
12 #include "genesis/static-symbols.h"
13 #include "genesis/simple-fun.h" 
15 #define load(sym, reg) \
16         sethi %hi(sym), reg; ld [reg+%lo(sym)], reg
17 #define store(reg, sym) \
18         sethi %hi(sym), reg_L0; st reg, [reg_L0+%lo(sym)]
20 /* FIXME */
21 #define FRAMESIZE 0x48
22 #define ST_FLUSH_WINDOWS 0x03
23         .seg    "text"
24         .global call_into_lisp
25         FUNCDEF(call_into_lisp)
26 call_into_lisp:
27         save    %sp, -FRAMESIZE, %sp
29         /* Flush all of C's register windows to the stack. */
30         ta      ST_FLUSH_WINDOWS
32         /* Save the return address. */
33         st      %i7, [%fp-4]
35         /* Clear the descriptor regs. (See sparc/vm.lisp) */
36         mov     reg_ZERO, reg_A0
37         mov     reg_ZERO, reg_A1
38         mov     reg_ZERO, reg_A2
39         mov     reg_ZERO, reg_A3
40         mov     reg_ZERO, reg_A4
41         mov     reg_ZERO, reg_A5
42         mov     reg_ZERO, reg_OCFP
43         mov     reg_ZERO, reg_LRA
44         mov     reg_ZERO, reg_CODE
46         /* Establish NIL */
47         set     NIL, reg_NIL
49         /* Set the pseudo-atomic flag. */
50         set     4, reg_ALLOC
52         /* Turn off foreign function call. */
53         sethi   %hi(foreign_function_call_active), reg_NL0
54         st      reg_ZERO, [reg_NL0+%lo(foreign_function_call_active)]
56         /* Load the rest of lisp state. */
57         load(dynamic_space_free_pointer, reg_NL0)
58         add     reg_NL0, reg_ALLOC, reg_ALLOC
59         load(current_binding_stack_pointer, reg_BSP)
60         load(current_control_stack_pointer, reg_CSP)
61         load(current_control_frame_pointer, reg_OCFP)
63         /* No longer atomic, and check for interrupt. */
64         sub     reg_ALLOC, 4, reg_ALLOC
65         andcc   reg_ALLOC, 3, reg_ZERO
66         
67         tne     PSEUDO_ATOMIC_TRAP
68         /* Pass in the args. */
69         sll     %i2, 2, reg_NARGS
70         mov     %i1, reg_CFP
71         mov     %i0, reg_LEXENV
72         ld      [reg_CFP+0], reg_A0
73         ld      [reg_CFP+4], reg_A1
74         ld      [reg_CFP+8], reg_A2
75         ld      [reg_CFP+12], reg_A3
76         ld      [reg_CFP+16], reg_A4
77         ld      [reg_CFP+20], reg_A5
79         /* Calculate LRA */
80         set     lra + OTHER_POINTER_LOWTAG, reg_LRA
82         /* Indirect closure */
83         ld      [reg_LEXENV+CLOSURE_FUN_OFFSET], reg_CODE
85         jmp     reg_CODE+SIMPLE_FUN_CODE_OFFSET
86         nop
88         .align  8
89 lra:
90         .word   RETURN_PC_HEADER_WIDETAG
92         /* Blow off any extra values. */
93         mov     reg_OCFP, reg_CSP
94         nop
96         /* Return the one value. */
97         mov     reg_A0, %i0
99         /* Turn on pseudo_atomic */
100         add     reg_ALLOC, 4, reg_ALLOC
102         /* Store LISP state */
103         andn    reg_ALLOC, 7, reg_NL1
104         store(reg_NL1,dynamic_space_free_pointer)
105         store(reg_BSP,current_binding_stack_pointer)
106         store(reg_CSP,current_control_stack_pointer)
107         store(reg_CFP,current_control_frame_pointer)
109         /* No longer in Lisp. */
110         store(reg_NL1,foreign_function_call_active)
112         /* Were we interrupted? */
113         sub     reg_ALLOC, 4, reg_ALLOC
114         andcc   reg_ALLOC, 3, reg_ZERO
115         tne     PSEUDO_ATOMIC_TRAP
117         /* Back to C we go. */
118         ld      [%sp+FRAMESIZE-4], %i7
119         ret
120         restore %sp, FRAMESIZE, %sp
122         .global call_into_c
123         FUNCDEF(call_into_c)
124 call_into_c:
125         /* Build a lisp stack frame */
126         mov     reg_CFP, reg_OCFP
127         mov     reg_CSP, reg_CFP
128         add     reg_CSP, 32, reg_CSP
129         st      reg_OCFP, [reg_CFP]
130         st      reg_CODE, [reg_CFP+8]
132         /* Turn on pseudo-atomic. */
133         add     reg_ALLOC, 4, reg_ALLOC
135         /* Convert the return address to an offset and save it on the stack. */
136         sub     reg_LIP, reg_CODE, reg_L0
137         add     reg_L0, OTHER_POINTER_LOWTAG, reg_L0
138         st      reg_L0, [reg_CFP+4]
140         /* Store LISP state */
141         store(reg_BSP,current_binding_stack_pointer)
142         store(reg_CSP,current_control_stack_pointer)
143         store(reg_CFP,current_control_frame_pointer)
144         /* Use reg_CFP as a work register, and restore it */
145         andn    reg_ALLOC, 7, reg_CFP
146         store(reg_CFP,dynamic_space_free_pointer)
147                 load(current_control_frame_pointer, reg_CFP)
149         /* No longer in Lisp. */
150         store(reg_CSP,foreign_function_call_active)
152         /* Were we interrupted? */
153         sub     reg_ALLOC, 4, reg_ALLOC
154         andcc   reg_ALLOC, 3, reg_ZERO
155         tne     PSEUDO_ATOMIC_TRAP
157         /* Into C we go. */
158         call    reg_CFUNC
159         nop
161         /*
162          * Note: C calling conventions (32-bit) say that %o0 and %o1
163          * are used to return function results.  In particular 64-bit
164          * results are in %o0 (hi) and %o1 (low).  
165          */
166         
167         /* Re-establish NIL */
168         set     NIL, reg_NIL
170         /* Atomic. */
171         set     4, reg_ALLOC
173         /* No longer in foreign function call. */
174         sethi   %hi(foreign_function_call_active), reg_NL2
175         st      reg_ZERO, [reg_NL2+%lo(foreign_function_call_active)]
177         /* Load the rest of lisp state. */
178         load(dynamic_space_free_pointer, reg_NL2)
179         add     reg_NL2, reg_ALLOC, reg_ALLOC
180         load(current_binding_stack_pointer, reg_BSP)
181         load(current_control_stack_pointer, reg_CSP)
182         load(current_control_frame_pointer, reg_CFP)
184         /* Get the return address back. */
185         ld      [reg_CFP+4], reg_LIP
186         ld      [reg_CFP+8], reg_CODE
187         add     reg_LIP, reg_CODE, reg_LIP
188         sub     reg_LIP, OTHER_POINTER_LOWTAG, reg_LIP
190         /* No longer atomic. */
191         sub     reg_ALLOC, 4, reg_ALLOC
192         andcc   reg_ALLOC, 3, reg_ZERO
193         tne     PSEUDO_ATOMIC_TRAP
195         /* Reset the lisp stack. */
196         /* Note: OCFP is in one of the locals, it gets preserved across C. */
197         mov     reg_CFP, reg_CSP
198         mov     reg_OCFP, reg_CFP
200         /* And back into lisp. */
201         ret
202         nop
205  * Function-end breakpoint magic.
206  */
209  * For an explanation of the magic involved in function-end
210  * breakpoints, see the implementation in ppc-assem.S.
211  */
213         .text
214         .align  8
215         .global fun_end_breakpoint_guts
216 fun_end_breakpoint_guts:
217         .word   RETURN_PC_HEADER_WIDETAG + 0x600
218         b       1f
219         nop
220         mov     reg_CSP, reg_OCFP
221         add     4, reg_CSP, reg_CSP
222         mov     4, reg_NARGS
223         mov     reg_NIL, reg_A1
224         mov     reg_NIL, reg_A2
225         mov     reg_NIL, reg_A3
226         mov     reg_NIL, reg_A4
227         mov     reg_NIL, reg_A5
230         .global fun_end_breakpoint_trap
231 fun_end_breakpoint_trap:
232         unimp   trap_FunEndBreakpoint
233         b       1b
234         nop
236         .global fun_end_breakpoint_end
237 fun_end_breakpoint_end:
239         .global sparc_flush_icache
240         FUNCDEF(sparc_flush_icache)
241 sparc_flush_icache:
242         add %o0,%o1,%o2
243 1:      iflush %o0                      ! flush instruction cache
244         add %o0,8,%o0
245         cmp %o0,%o2
246         blt 1b
247         nop
248         retl                            ! return from leaf routine
249         nop
251         .global do_pending_interrupt
252         FUNCDEF(do_pending_interrupt)
253 do_pending_interrupt:
254         unimp   trap_PendingInterrupt
255         retl
256         nop
258         .global save_context
259         FUNCDEF(save_context)
260 save_context:
261         ta      ST_FLUSH_WINDOWS        ! flush register windows
262         retl                            ! return from leaf routine
263         nop