Draft NEWS for sbcl-2.4.7
[sbcl.git] / src / runtime / sparc-assem.S
blob2a9745f175ca25a4283ad115c048ffe5d779673f
1 #ifdef __linux__
2 // Mark the object as not requiring an executable stack.
3 .section .note.GNU-stack,"",%progbits
4 #endif
6 #define _ASM
8 #include "lispregs.h"
9 #include "genesis/sbcl.h"
10 #include "genesis/closure.h"
11 #include "genesis/static-symbols.h"
12 #include "genesis/thread.h"
14 #define load(sym, reg) \
15         sethi %hi(sym), reg; ld [reg+%lo(sym)], reg
16 #define store(reg, sym) \
17         sethi %hi(sym), reg_L0; st reg, [reg_L0+%lo(sym)]
19 #define BEGIN_PSEUDO_ATOMIC stb reg_NULL, [reg_THREAD+THREAD_PSEUDO_ATOMIC_BITS_OFFSET]
20 #define END_PSEUDO_ATOMIC(temp) \
21  stb reg_ZERO, [reg_THREAD+THREAD_PSEUDO_ATOMIC_BITS_OFFSET] ; \
22  ldub [reg_THREAD+THREAD_PSEUDO_ATOMIC_BITS_OFFSET+2], temp ; \
23  andcc temp, temp, reg_ZERO ; \
24  tne PSEUDO_ATOMIC_TRAP
26 /* FIXME */
27 #define FRAMESIZE 0x48
28 #define ST_FLUSH_WINDOWS 0x03
29         .seg    "text"
30         .global call_into_lisp
31 call_into_lisp:
32         save    %sp, -FRAMESIZE, %sp
34         /* Flush all of C's register windows to the stack. */
35         ta      ST_FLUSH_WINDOWS
37         /* Save the return address. */
38         st      %i7, [%fp-4]
40         /* Clear the descriptor regs. (See sparc/vm.lisp) */
41         mov     reg_ZERO, reg_A0
42         mov     reg_ZERO, reg_A1
43         mov     reg_ZERO, reg_A2
44         mov     reg_ZERO, reg_A3
45         mov     reg_ZERO, reg_A4
46         mov     reg_ZERO, reg_A5
47         mov     reg_ZERO, reg_OCFP
48         mov     reg_ZERO, reg_LRA
49         mov     reg_ZERO, reg_CODE
51         /* Establish NIL */
52         set     NIL, reg_NULL
53         load(all_threads, reg_THREAD)
55         /* Set the pseudo-atomic flag. */
56         BEGIN_PSEUDO_ATOMIC
58         /* Turn off foreign function call. */
59         sethi   %hi(foreign_function_call_active), reg_NL0
60         st      reg_ZERO, [reg_NL0+%lo(foreign_function_call_active)]
62         /* Load the rest of lisp state. */
63         load(current_binding_stack_pointer, reg_BSP)
64         load(current_control_stack_pointer, reg_CSP)
65         load(current_control_frame_pointer, reg_OCFP)
67         /* No longer atomic, and check for interrupt. */
68         END_PSEUDO_ATOMIC(reg_NL0)
70         /* Pass in the args. */
71         sll     %i2, 2, reg_NARGS
72         mov     %i1, reg_CFP
73         mov     %i0, reg_LEXENV
74         ld      [reg_CFP+0], reg_A0
75         ld      [reg_CFP+4], reg_A1
76         ld      [reg_CFP+8], reg_A2
77         ld      [reg_CFP+12], reg_A3
78         ld      [reg_CFP+16], reg_A4
79         ld      [reg_CFP+20], reg_A5
81         /* Calculate LRA */
82         set     lra + OTHER_POINTER_LOWTAG, reg_LRA
84         /* Indirect closure */
85         ld      [reg_LEXENV+CLOSURE_FUN_OFFSET], reg_CODE
87         jmp     reg_CODE+SIMPLE_FUN_INSTS_OFFSET
88         nop
90         .align  8
91 lra:
92         .word   RETURN_PC_WIDETAG
94         /* Blow off any extra values. */
95         mov     reg_OCFP, reg_CSP
96         nop
98         /* Return the one value. */
99         mov     reg_A0, %i0
101         /* Turn on pseudo_atomic */
102         BEGIN_PSEUDO_ATOMIC
104         /* Store LISP state */
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         END_PSEUDO_ATOMIC(reg_NL1)
115         /* Back to C we go. */
116         ld      [%sp+FRAMESIZE-4], %i7
117         ret
118         restore %sp, FRAMESIZE, %sp
120         .global call_into_c
121 call_into_c:
122         /* Build a lisp stack frame */
123         mov     reg_CFP, reg_OCFP
124         mov     reg_CSP, reg_CFP
125         add     reg_CSP, 32, reg_CSP
126         st      reg_OCFP, [reg_CFP]
127         st      reg_CODE, [reg_CFP+8]
129         /* Turn on pseudo-atomic. */
130         BEGIN_PSEUDO_ATOMIC
132         /* Convert the return address to an offset and save it on the stack. */
133         sub     reg_LIP, reg_CODE, reg_L0
134         add     reg_L0, OTHER_POINTER_LOWTAG, reg_L0
135         st      reg_L0, [reg_CFP+4]
137         /* Store LISP state */
138         store(reg_BSP,current_binding_stack_pointer)
139         store(reg_CSP,current_control_stack_pointer)
140         store(reg_CFP,current_control_frame_pointer)
142         /* No longer in Lisp. */
143         store(reg_CSP,foreign_function_call_active)
145         /* Were we interrupted? */
146         END_PSEUDO_ATOMIC(reg_L0)
148         /* Into C we go. */
149         call    reg_CFUNC
150         nop
152         /*
153          * Note: C calling conventions (32-bit) say that %o0 and %o1
154          * are used to return function results.  In particular 64-bit
155          * results are in %o0 (hi) and %o1 (low).
156          */
158         /* Re-establish NIL */
159         set     NIL, reg_NULL
160         load(all_threads, reg_THREAD)
162         /* Atomic. */
163         BEGIN_PSEUDO_ATOMIC
165         /* No longer in foreign function call. */
166         sethi   %hi(foreign_function_call_active), reg_NL2
167         st      reg_ZERO, [reg_NL2+%lo(foreign_function_call_active)]
169         /* Load the rest of lisp state. */
170         load(current_binding_stack_pointer, reg_BSP)
171         load(current_control_stack_pointer, reg_CSP)
172         load(current_control_frame_pointer, reg_CFP)
174         /* Get the return address back. */
175         ld      [reg_CFP+4], reg_LIP
176         ld      [reg_CFP+8], reg_CODE
177         add     reg_LIP, reg_CODE, reg_LIP
178         sub     reg_LIP, OTHER_POINTER_LOWTAG, reg_LIP
180         /* No longer atomic. */
181         END_PSEUDO_ATOMIC(reg_NL2)
183         /* Reset the lisp stack. */
184         /* Note: OCFP is in one of the locals, it gets preserved across C. */
185         mov     reg_CFP, reg_CSP
186         mov     reg_OCFP, reg_CFP
188         /* And back into lisp. */
189         ret
190         nop
193  * Function-end breakpoint magic.
194  */
197  * For an explanation of the magic involved in function-end
198  * breakpoints, see the implementation in ppc-assem.S.
199  */
201         .text
202         .align  8
203         .global fun_end_breakpoint_guts
204 fun_end_breakpoint_guts:
205         b       1f
206         nop
207         mov     reg_CSP, reg_OCFP
208         add     4, reg_CSP, reg_CSP
209         mov     4, reg_NARGS
210         mov     reg_NULL, reg_A1
211         mov     reg_NULL, reg_A2
212         mov     reg_NULL, reg_A3
213         mov     reg_NULL, reg_A4
214         mov     reg_NULL, reg_A5
217         .global fun_end_breakpoint_trap
218 fun_end_breakpoint_trap:
219         unimp   trap_FunEndBreakpoint
220         b       1b
221         nop
223         .global fun_end_breakpoint_end
224 fun_end_breakpoint_end:
226         .global sparc_flush_icache
227 sparc_flush_icache:
228         add %o0,%o1,%o2
229 1:      iflush %o0                      ! flush instruction cache
230         add %o0,8,%o0
231         cmp %o0,%o2
232         blt 1b
233         nop
234         retl                            ! return from leaf routine
235         nop
237         .global do_pending_interrupt
238 do_pending_interrupt:
239         unimp   trap_PendingInterrupt
240         retl
241         nop
243         .global save_context
244 save_context:
245         ta      ST_FLUSH_WINDOWS        ! flush register windows
246         retl                            ! return from leaf routine
247         nop