4 #include "genesis/fdefn.h"
5 #include "genesis/closure.h"
6 #include "genesis/simple-fun.h"
7 #include "genesis/static-symbols.h"
43 * LEAF - declare leaf routine
45 #define LEAF(symbol) \
48 .type symbol,@function; \
50 symbol: .frame sp,0,ra
53 * NESTED - declare nested routine entry point
55 #define NESTED(symbol, framesize, rpc) \
58 .type symbol,@function; \
60 symbol: .frame sp, framesize, rpc
63 * END - mark end of function
65 #define END(function) \
67 .size function,.-function
70 * EXPORT - export definition of symbol
72 #define EXPORT(symbol) \
77 * FEXPORT - export definition of a function symbol
79 #define FEXPORT(symbol) \
81 .type symbol,@function; \
88 * Function to transfer control into lisp.
90 #define framesize 16*4
91 NESTED(call_into_lisp, framesize, ra)
97 /* Save all the C regs. */
99 sw ra, framesize-8(sp)
100 sw s8, framesize-12(sp)
101 /* No .cprestore, we don't want automatic gp restauration. */
102 sw gp, framesize-16(sp)
103 sw s7, framesize-20(sp)
104 sw s6, framesize-24(sp)
105 sw s5, framesize-28(sp)
106 sw s4, framesize-32(sp)
107 sw s3, framesize-36(sp)
108 sw s2, framesize-40(sp)
109 sw s1, framesize-44(sp)
110 sw s0, framesize-48(sp)
114 /* Clear unsaved boxed descriptor regs */
118 /* Turn on pseudo-atomic. */
124 /* Mark us as in Lisp land. */
125 sw zero, foreign_function_call_active
127 /* Load the allocation pointer, preserving the low-bit of alloc */
128 lw reg_BSP, dynamic_space_free_pointer
129 addu reg_ALLOC, reg_BSP
131 /* Load the rest of the LISP state. */
132 lw reg_BSP, current_binding_stack_pointer
133 lw reg_CSP, current_control_stack_pointer
134 lw reg_OCFP, current_control_frame_pointer
136 /* Check for interrupt */
147 lw reg_A0, 0(reg_CFP)
148 lw reg_A1, 4(reg_CFP)
149 lw reg_A2, 8(reg_CFP)
150 lw reg_A3, 12(reg_CFP)
151 lw reg_A4, 16(reg_CFP)
152 lw reg_A5, 20(reg_CFP)
155 la reg_LRA, lra + OTHER_POINTER_LOWTAG
157 /* Indirect closure */
158 lw reg_CODE, -1(reg_LEXENV)
160 /* Jump into lisp land. */
161 addu reg_LIP, reg_CODE, 6*4 - FUN_POINTER_LOWTAG
167 /* This particular KLUDGE is kept here as a reminder; for more
168 details, see irix-asm-munge.c from CMUCL's lisp directory.
169 Other examples have been deleted from later in the file in the
170 hope that they will not be needed. */
171 .globl mipsmungelra /* for our munging afterwards in irix-asm-munge */
175 .word RETURN_PC_HEADER_WIDETAG
177 /* Multiple value return spot, clear stack. */
178 move reg_CSP, reg_OCFP
181 /* Single value return spot. */
183 /* Pass one return value back to C land. */
184 move v0, reg_A0 # reg_CFUNC
186 /* Nested lisp -> C calls may have clobbered gp. */
187 lw gp, framesize-16(sp)
189 /* Set the pseudo-atomic flag. */
194 /* Save LISP state. */
195 subu reg_NL0, reg_ALLOC, 1
196 sw reg_NL0, dynamic_space_free_pointer
197 sw reg_BSP, current_binding_stack_pointer
198 sw reg_CSP, current_control_stack_pointer
199 sw reg_CFP, current_control_frame_pointer
201 /* Mark us as in C land. */
202 sw reg_CSP, foreign_function_call_active
204 /* Check for interrupt */
212 lw ra, framesize-8(sp)
213 lw s8, framesize-12(sp)
214 lw s7, framesize-20(sp)
215 lw s6, framesize-24(sp)
216 lw s5, framesize-28(sp)
217 lw s4, framesize-32(sp)
218 lw s3, framesize-36(sp)
219 lw s2, framesize-40(sp)
220 lw s1, framesize-44(sp)
221 lw s0, framesize-48(sp)
223 /* Restore C stack. */
232 * Transfering control from Lisp into C
234 NESTED(call_into_c, 0, ra)
235 /* The stack frame was already set up from lisp. We have
236 to fake the correct gp value for this function, though. */
239 lui gp, %hi(_gp_disp)
240 addiu gp, %lo(_gp_disp)
241 lui reg_NL3, %hi(call_into_c)
242 addiu reg_NL3, %lo(call_into_c)
247 move reg_OCFP, reg_CFP
248 move reg_CFP, reg_CSP
249 addu reg_CSP, reg_CFP, 32
251 subu reg_LIP, reg_CODE
252 addu reg_LIP, OTHER_POINTER_LOWTAG
253 sw reg_LIP, (reg_CFP)
254 sw reg_CODE, 4(reg_CFP)
257 /* Set the pseudo-atomic flag. */
263 /* Save LISP state. */
264 subu reg_A0, reg_ALLOC, 1
265 sw reg_A0, dynamic_space_free_pointer
266 sw reg_BSP, current_binding_stack_pointer
267 sw reg_CSP, current_control_stack_pointer
268 sw reg_CFP, current_control_frame_pointer
270 /* Mark us as in C land. */
271 sw reg_CSP, foreign_function_call_active
273 /* Check for interrupt */
280 /* Into C land we go. */
288 /* Clear unsaved boxed descriptor regs */
296 li reg_LEXENV, 0 # t7
299 /* Turn on pseudo-atomic. */
305 /* Mark us as in Lisp land. */
306 sw zero, foreign_function_call_active
308 /* Load the allocation pointer, preserving the low-bit of alloc */
309 lw reg_BSP, dynamic_space_free_pointer
310 addu reg_ALLOC, reg_BSP
312 lw reg_BSP, current_binding_stack_pointer
314 /* Restore LRA & CODE */
315 lw reg_LIP, (reg_CFP)
316 lw reg_CODE, 4(reg_CFP)
317 subu reg_LIP, OTHER_POINTER_LOWTAG
318 addu reg_LIP, reg_CODE
320 /* Check for interrupt */
327 /* Reset the lisp stack. */
328 /* Note: OCFP and CFP are in saved regs. */
329 move reg_CSP, reg_CFP
330 move reg_CFP, reg_OCFP
332 /* Return to LISP. */
336 EXPORT(start_of_tramps)
339 * The undefined-function trampoline.
341 LEAF(undefined_tramp)
344 .byte UNDEFINED_FUN_ERROR
346 .byte (0xc0 + sc_DescriptorReg)
352 * The closure trampoline.
355 lw reg_LEXENV, FDEFN_FUN_OFFSET(reg_FDEFN)
356 lw reg_L0, CLOSURE_FUN_OFFSET(reg_LEXENV)
357 addu reg_LIP, reg_L0, SIMPLE_FUN_CODE_OFFSET
361 EXPORT(end_of_tramps)
364 * Function-end breakpoint magic.
366 LEAF(fun_end_breakpoint_guts)
369 .word RETURN_PC_HEADER_WIDETAG
371 b multiple_value_return
374 move reg_OCFP, reg_CSP
383 multiple_value_return:
385 FEXPORT(fun_end_breakpoint_trap)
386 break trap_FunEndBreakpoint
390 EXPORT(fun_end_breakpoint_end)
392 END(fun_end_breakpoint_guts)