2 * This software is part of the SBCL system. See the README file for
5 * This software is derived from the CMU CL system, which was
6 * written at Carnegie Mellon University and released into the
7 * public domain. The software is in the public domain and is
8 * provided with absolutely no warranty. See the COPYING and CREDITS
9 * files for more information.
13 #include <alpha/regdef.h>
17 #include <alpha/pal.h>
21 #include "genesis/fdefn.h"
22 #include "genesis/closure.h"
23 #include "genesis/simple-fun.h"
24 #include "genesis/static-symbols.h"
26 /* #include "globals.h" */
29 * Function to transfer control into lisp.
38 /* Save all the C regs. */
40 stq ra, framesize-8*8(sp)
41 stq s0, framesize-8*7(sp)
42 stq s1, framesize-8*6(sp)
43 stq s2, framesize-8*5(sp)
44 stq s3, framesize-8*4(sp)
45 stq s4, framesize-8*3(sp)
46 stq s5, framesize-8*2(sp)
47 stq s6, framesize-8*1(sp)
48 .mask 0x0fc001fe, -framesize
49 .frame sp,framesize,ra
51 /* Clear descriptor regs */
65 /* The CMUCL comment here is "Start pseudo-atomic.", but */
66 /* there's no obvious code that would have that effect */
68 /* No longer in foreign call. */
69 stl zero,foreign_function_call_active
71 /* Load lisp state. */
72 ldq reg_ALLOC,dynamic_space_free_pointer
73 ldq reg_BSP,current_binding_stack_pointer
74 ldq reg_CSP,current_control_stack_pointer
75 ldq reg_OCFP,current_control_frame_pointer
82 /* End of pseudo-atomic. */
84 /* Establish lisp arguments. */
88 ldl reg_A3,12(reg_CFP)
89 ldl reg_A4,16(reg_CFP)
90 ldl reg_A5,20(reg_CFP)
92 /* This call will 'return' into the LRA page below */
93 lda reg_LRA,call_into_lisp_LRA_page+OTHER_POINTER_LOWTAG
95 /* Indirect the closure */
96 ldl reg_CODE, CLOSURE_FUN_OFFSET(reg_LEXENV)
97 addl reg_CODE,6*4-FUN_POINTER_LOWTAG, reg_LIP
99 /* And into lisp we go. */
100 jsr reg_ZERO,(reg_LIP)
103 /* a page of the following code (from call_into_lisp_LRA
104 onwards) is copied into the LRA page at arch_init() time. */
108 .globl call_into_lisp_LRA
111 .long RETURN_PC_HEADER_WIDETAG
113 /* execution resumes here*/
117 /* return value already there */
120 /* Turn on pseudo-atomic. */
122 /* Save LISP registers */
123 stq reg_ALLOC, dynamic_space_free_pointer
124 stq reg_BSP,current_binding_stack_pointer
125 stq reg_CSP,current_control_stack_pointer
126 stq reg_CFP,current_control_frame_pointer
128 /* Back in C land. [CSP is just a handy non-zero value.] */
129 stl reg_CSP,foreign_function_call_active
131 /* Turn off pseudo-atomic and check for traps. */
134 ldq ra, framesize-8*8(sp)
135 ldq s0, framesize-8*7(sp)
136 ldq s1, framesize-8*6(sp)
137 ldq s2, framesize-8*5(sp)
138 ldq s3, framesize-8*4(sp)
139 ldq s4, framesize-8*3(sp)
140 ldq s5, framesize-8*2(sp)
141 ldq s6, framesize-8*1(sp)
143 /* Restore the C stack! */
144 lda sp, framesize(sp)
147 .globl call_into_lisp_end
152 * Transfering control from Lisp into C. reg_CFUNC (t10, 24) contains
153 * the address of the C function to call
161 .mask 0x0fc001fe, -12
163 mov reg_CFP, reg_OCFP
165 addq reg_CFP, 32, reg_CSP
166 stl reg_OCFP, 0(reg_CFP)
167 subl reg_LIP, reg_CODE, reg_L1
168 addl reg_L1, OTHER_POINTER_LOWTAG, reg_L1
169 stl reg_L1, 4(reg_CFP)
170 stl reg_CODE, 8(reg_CFP)
171 stl reg_NULL, 12(reg_CFP)
173 /* Set the pseudo-atomic flag. */
174 addq reg_ALLOC,1,reg_ALLOC
176 /* Get the top two register args and fix the NSP to point to arg 7 */
177 ldq reg_NL4,0(reg_NSP)
178 ldq reg_NL5,8(reg_NSP)
179 addq reg_NSP,16,reg_NSP
181 /* Save lisp state. */
182 subq reg_ALLOC,1,reg_L1
183 stq reg_L1, dynamic_space_free_pointer
185 stq reg_BSP, current_binding_stack_pointer
186 stq reg_CSP, current_control_stack_pointer
187 stq reg_CFP, current_control_frame_pointer
189 /* Mark us as in C land. */
190 stl reg_CSP, foreign_function_call_active
192 /* Were we interrupted? */
193 subq reg_ALLOC,1,reg_ALLOC
194 stl reg_ZERO,0(reg_ALLOC)
196 /* Into C land we go. */
198 mov reg_CFUNC, reg_L1 /* L1=pv: this is a hint to the cache */
204 subq reg_NSP,16,reg_NSP
206 /* Clear unsaved descriptor regs */
207 mov reg_ZERO, reg_NARGS
219 /* Turn on pseudo-atomic. */
220 lda reg_ALLOC,1(reg_ZERO)
222 /* Mark us at in Lisp land. */
223 stl reg_ZERO, foreign_function_call_active
225 /* Restore ALLOC, preserving pseudo-atomic-atomic */
226 ldq reg_NL0,dynamic_space_free_pointer
227 addq reg_ALLOC,reg_NL0,reg_ALLOC
229 /* Check for interrupt */
230 subq reg_ALLOC,1,reg_ALLOC
231 stl reg_ZERO,0(reg_ALLOC)
233 ldl reg_NULL, 12(reg_CFP)
235 /* Restore LRA & CODE (they may have been GC'ed) */
236 /* can you see anything here which touches LRA? I can't ...*/
237 ldl reg_CODE, 8(reg_CFP)
238 ldl reg_NL0, 4(reg_CFP)
239 subq reg_NL0, OTHER_POINTER_LOWTAG, reg_NL0
240 addq reg_CODE, reg_NL0, reg_NL0
243 mov reg_OCFP, reg_CFP
245 ret zero, (reg_NL0), 1
250 .globl start_of_tramps
254 * The undefined-function trampoline. Causes a trap_Error trap which
255 * sigtrap_handler catches and eventaully calls the Lisp
256 * INTERNAL-ERROR function
259 .globl start_of_tramps
260 .globl undefined_tramp
261 .globl undefined_tramp_offset
262 .ent undefined_tramp_offset
263 undefined_tramp_offset:
264 /* an explanation is called for here. 0x140 is the difference
265 * between undefined_tramp_offset and call_into_lisp_LRA, but
266 * the assembler is too dumb to allow that as an expression.
267 * So, change this number whenever you add or remove any code
270 undefined_tramp= call_into_lisp_LRA_page+0x140
273 .byte 4 /* what are these numbers? */
274 .byte UNDEFINED_FUN_ERROR
276 .byte (0xe0 + sc_DescriptorReg)
279 .end undefined_tramp_offset
282 /* The closure trampoline. */
285 .globl closure_tramp_offset
286 .ent closure_tramp_offset
287 closure_tramp_offset:
288 closure_tramp= call_into_lisp_LRA_page+0x150
289 ldl reg_LEXENV, FDEFN_FUN_OFFSET(reg_FDEFN)
290 ldl reg_L0, CLOSURE_FUN_OFFSET(reg_LEXENV)
291 addl reg_L0, SIMPLE_FUN_CODE_OFFSET, reg_LIP
292 jmp reg_ZERO,(reg_LIP)
293 .end closure_tramp_offset
301 * fun-end breakpoint magic.
307 .globl fun_end_breakpoint_guts
308 fun_end_breakpoint_guts:
309 .long RETURN_PC_HEADER_WIDETAG
310 br zero, fun_end_breakpoint_trap
312 mov reg_CSP, reg_OCFP
313 addl reg_CSP, 4, reg_CSP
314 addl zero, 4, reg_NARGS
322 .globl fun_end_breakpoint_trap
323 fun_end_breakpoint_trap:
325 .long trap_FunEndBreakpoint
326 br zero, fun_end_breakpoint_trap
328 .globl fun_end_breakpoint_end
329 fun_end_breakpoint_end: