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 /* Nested lisp -> C calls may have clobbered gp. */
184 lw gp, framesize-16(sp)
186 /* Set the pseudo-atomic flag. */
191 /* Save LISP state. */
192 subu reg_NL0, reg_ALLOC, 1
193 sw reg_NL0, dynamic_space_free_pointer
194 sw reg_BSP, current_binding_stack_pointer
195 sw reg_CSP, current_control_stack_pointer
196 sw reg_CFP, current_control_frame_pointer
198 /* Mark us as in C land. */
199 sw reg_CSP, foreign_function_call_active
201 /* Check for interrupt */
208 /* Pass one return value back to C land. For a 64bit value, we may
209 need to clobber v1 aka reg_NL4. */
210 move v0, reg_A0 # reg_CFUNC
211 move v1, reg_A1 # reg_NL4
214 lw ra, framesize-8(sp)
215 lw s8, framesize-12(sp)
216 lw s7, framesize-20(sp)
217 lw s6, framesize-24(sp)
218 lw s5, framesize-28(sp)
219 lw s4, framesize-32(sp)
220 lw s3, framesize-36(sp)
221 lw s2, framesize-40(sp)
222 lw s1, framesize-44(sp)
223 lw s0, framesize-48(sp)
225 /* Restore C stack. */
234 * Transfering control from Lisp into C
236 NESTED(call_into_c, 0, ra)
237 /* The stack frame was already set up from lisp. We have
238 to fake the correct gp value for this function, though. */
241 lui gp, %hi(_gp_disp)
242 addiu gp, %lo(_gp_disp)
243 lui reg_NL3, %hi(call_into_c)
244 addiu reg_NL3, %lo(call_into_c)
249 move reg_OCFP, reg_CFP
250 move reg_CFP, reg_CSP
251 addu reg_CSP, reg_CFP, 32
253 subu reg_LIP, reg_CODE
254 addu reg_LIP, OTHER_POINTER_LOWTAG
255 sw reg_LIP, (reg_CFP)
256 sw reg_CODE, 4(reg_CFP)
259 /* Set the pseudo-atomic flag. */
265 /* Save LISP state. */
266 subu reg_A0, reg_ALLOC, 1
267 sw reg_A0, dynamic_space_free_pointer
268 sw reg_BSP, current_binding_stack_pointer
269 sw reg_CSP, current_control_stack_pointer
270 sw reg_CFP, current_control_frame_pointer
272 /* Mark us as in C land. */
273 sw reg_CSP, foreign_function_call_active
275 /* Check for interrupt */
282 /* Into C land we go. */
288 /* Pass 64bit return value to lisp land. */
289 move reg_NL0, v0 # reg_CFUNC
290 move reg_NL1, v1 # reg_NL4
294 /* Clear unsaved boxed descriptor regs */
302 li reg_LEXENV, 0 # t7
305 /* Turn on pseudo-atomic. */
311 /* Mark us as in Lisp land. */
312 sw zero, foreign_function_call_active
314 /* Load the allocation pointer, preserving the low-bit of alloc */
315 lw reg_BSP, dynamic_space_free_pointer
316 addu reg_ALLOC, reg_BSP
318 lw reg_BSP, current_binding_stack_pointer
320 /* Restore LRA & CODE */
321 lw reg_LIP, (reg_CFP)
322 lw reg_CODE, 4(reg_CFP)
323 subu reg_LIP, OTHER_POINTER_LOWTAG
324 addu reg_LIP, reg_CODE
326 /* Check for interrupt */
333 /* Reset the lisp stack. */
334 /* Note: OCFP and CFP are in saved regs. */
335 move reg_CSP, reg_CFP
336 move reg_CFP, reg_OCFP
338 /* Return to LISP. */
342 EXPORT(start_of_tramps)
345 * The undefined-function trampoline.
347 LEAF(undefined_tramp)
350 .byte UNDEFINED_FUN_ERROR
352 .byte (0xc0 + sc_DescriptorReg)
358 * The closure trampoline.
361 lw reg_LEXENV, FDEFN_FUN_OFFSET(reg_FDEFN)
362 lw reg_L0, CLOSURE_FUN_OFFSET(reg_LEXENV)
363 addu reg_LIP, reg_L0, SIMPLE_FUN_CODE_OFFSET
367 EXPORT(end_of_tramps)
370 * Function-end breakpoint magic.
373 LEAF(fun_end_breakpoint_guts)
375 .word RETURN_PC_HEADER_WIDETAG
377 b multiple_value_return
381 move reg_OCFP, reg_CSP
390 multiple_value_return:
392 FEXPORT(fun_end_breakpoint_trap)
393 break trap_FunEndBreakpoint
394 b multiple_value_return
395 EXPORT(fun_end_breakpoint_end)
396 END(fun_end_breakpoint_guts)