2 // Mark the object as not requiring an executable stack.
3 .section .note.GNU-stack,"",%progbits
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
27 #define FRAMESIZE 0x48
28 #define ST_FLUSH_WINDOWS 0x03
30 .global call_into_lisp
32 save %sp, -FRAMESIZE, %sp
34 /* Flush all of C's register windows to the stack. */
37 /* Save the return address. */
40 /* Clear the descriptor regs. (See sparc/vm.lisp) */
47 mov reg_ZERO, reg_OCFP
49 mov reg_ZERO, reg_CODE
53 load(all_threads, reg_THREAD)
55 /* Set the pseudo-atomic flag. */
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. */
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
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
92 .word RETURN_PC_WIDETAG
94 /* Blow off any extra values. */
98 /* Return the one value. */
101 /* Turn on 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
118 restore %sp, FRAMESIZE, %sp
122 /* Build a lisp stack frame */
123 mov reg_CFP, reg_OCFP
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. */
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)
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).
158 /* Re-establish NIL */
160 load(all_threads, reg_THREAD)
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. */
186 mov reg_OCFP, reg_CFP
188 /* And back into lisp. */
193 * Function-end breakpoint magic.
197 * For an explanation of the magic involved in function-end
198 * breakpoints, see the implementation in ppc-assem.S.
203 .global fun_end_breakpoint_guts
204 fun_end_breakpoint_guts:
207 mov reg_CSP, reg_OCFP
208 add 4, reg_CSP, reg_CSP
217 .global fun_end_breakpoint_trap
218 fun_end_breakpoint_trap:
219 unimp trap_FunEndBreakpoint
223 .global fun_end_breakpoint_end
224 fun_end_breakpoint_end:
226 .global sparc_flush_icache
229 1: iflush %o0 ! flush instruction cache
234 retl ! return from leaf routine
237 .global do_pending_interrupt
238 do_pending_interrupt:
239 unimp trap_PendingInterrupt
245 ta ST_FLUSH_WINDOWS ! flush register windows
246 retl ! return from leaf routine