2 // Mark the object as not requiring an executable stack.
3 .section .note.GNU-stack,"",%progbits
6 #define LANGUAGE_ASSEMBLY
10 #include "genesis/closure.h"
11 #include "genesis/fdefn.h"
12 #include "genesis/simple-fun.h"
13 #include "genesis/return-pc.h"
14 #include "genesis/static-symbols.h"
15 #include "genesis/funcallable-instance.h"
21 .import $$dyncall,MILLICODE
22 .import foreign_function_call_active,data
23 .import current_control_stack_pointer,data
24 .import current_control_frame_pointer,data
25 .import current_binding_stack_pointer,data
26 .import dynamic_space_free_pointer,data
27 /* .import return_from_lisp_function,data */
34 .export call_into_lisp
37 .callinfo entry_gr=18,save_rp
39 /* %arg0=function, %arg1=cfp, %arg2=nargs */
41 stw %rp,-0x14(%sr0,%sp)
42 stwm %r3,0x40(%sr0,%sp)
43 stw %r4,-0x3c(%sr0,%sp)
44 stw %r5,-0x38(%sr0,%sp)
45 stw %r6,-0x34(%sr0,%sp)
46 stw %r7,-0x30(%sr0,%sp)
47 stw %r8,-0x2c(%sr0,%sp)
48 stw %r9,-0x28(%sr0,%sp)
49 stw %r10,-0x24(%sr0,%sp)
50 stw %r11,-0x20(%sr0,%sp)
51 stw %r12,-0x1c(%sr0,%sp)
52 stw %r13,-0x18(%sr0,%sp)
53 stw %r14,-0x14(%sr0,%sp)
54 stw %r15,-0x10(%sr0,%sp)
55 stw %r16,-0xc(%sr0,%sp)
56 stw %r17,-0x8(%sr0,%sp)
57 stw %r18,-0x4(%sr0,%sp)
59 /* Clear the descriptor regs, moving in args as approporate. */
63 zdep %arg2,29,30,reg_NARGS
78 ldo R%NIL(reg_NULL),reg_NULL
80 /* Turn on pseudo-atomic. */
83 /* No longer in foreign function call land. */
84 addil L%foreign_function_call_active-$global$,%dp
85 stw %r0,R%foreign_function_call_active-$global$(0,%r1)
87 /* Load lisp state. */
88 addil L%dynamic_space_free_pointer-$global$,%dp
89 ldw R%dynamic_space_free_pointer-$global$(0,%r1),%r1
90 add reg_ALLOC,%r1,reg_ALLOC
91 addil L%current_binding_stack_pointer-$global$,%dp
92 ldw R%current_binding_stack_pointer-$global$(0,%r1),reg_BSP
93 addil L%current_control_stack_pointer-$global$,%dp
94 ldw R%current_control_stack_pointer-$global$(0,%r1),reg_CSP
95 addil L%current_control_frame_pointer-$global$,%dp
96 ldw R%current_control_frame_pointer-$global$(0,%r1),reg_OCFP
99 /* End of pseudo-atomic. */
100 addit,od -4,reg_ALLOC,reg_ALLOC
102 /* Establish lisp arguments. */
103 ldw 0(reg_CFP),reg_A0
104 ldw 4(reg_CFP),reg_A1
105 ldw 8(reg_CFP),reg_A2
106 ldw 12(reg_CFP),reg_A3
107 ldw 16(reg_CFP),reg_A4
108 ldw 20(reg_CFP),reg_A5
110 /* Calculate the LRA. */
111 ldil L%lra-RETURN_PC_RETURN_POINT_OFFSET,reg_LRA
112 ldo R%lra-RETURN_PC_RETURN_POINT_OFFSET(reg_LRA),reg_LRA
114 /* Indirect the closure */
115 ldw CLOSURE_FUN_OFFSET(0,reg_LEXENV),reg_CODE
116 addi SIMPLE_FUN_CODE_OFFSET,reg_CODE,reg_LIP
118 #ifdef LISP_FEATURE_HPUX
119 /* Get the stub address, ie assembly-routine return-from-lisp */
120 addil L%return_from_lisp_stub-$global$,%dp
121 ldw R%return_from_lisp_stub-$global$(0,%r1),reg_NL0
131 nop /* a few nops because we dont know where we land */
132 nop /* the return convention would govern this */
136 /* Copy CFP (%r4) into someplace else and restore r4. */
140 /* Copy the return value. */
143 /* Turn on pseudo-atomic. */
144 addi 4,reg_ALLOC,reg_ALLOC
146 /* Store the lisp state. */
147 copy reg_ALLOC,reg_NL0
149 addil L%dynamic_space_free_pointer-$global$,%dp
150 stw reg_NL0,R%dynamic_space_free_pointer-$global$(0,%r1)
151 addil L%current_binding_stack_pointer-$global$,%dp
152 stw reg_BSP,R%current_binding_stack_pointer-$global$(0,%r1)
153 addil L%current_control_stack_pointer-$global$,%dp
154 stw reg_CSP,R%current_control_stack_pointer-$global$(0,%r1)
155 addil L%current_control_frame_pointer-$global$,%dp
156 stw reg_NL1,R%current_control_frame_pointer-$global$(0,%r1)
158 /* Back in C land. [CSP is just a handy non-zero value.] */
159 addil L%foreign_function_call_active-$global$,%dp
160 stw reg_CSP,R%foreign_function_call_active-$global$(0,%r1)
162 /* Turn off pseudo-atomic and check for traps. */
163 addit,od -4,reg_ALLOC,reg_ALLOC
165 ldw -0x54(%sr0,%sp),%rp
166 ldw -0x4(%sr0,%sp),%r18
167 ldw -0x8(%sr0,%sp),%r17
168 ldw -0xc(%sr0,%sp),%r16
169 ldw -0x10(%sr0,%sp),%r15
170 ldw -0x14(%sr0,%sp),%r14
171 ldw -0x18(%sr0,%sp),%r13
172 ldw -0x1c(%sr0,%sp),%r12
173 ldw -0x20(%sr0,%sp),%r11
174 ldw -0x24(%sr0,%sp),%r10
175 ldw -0x28(%sr0,%sp),%r9
176 ldw -0x2c(%sr0,%sp),%r8
177 ldw -0x30(%sr0,%sp),%r7
178 ldw -0x34(%sr0,%sp),%r6
179 ldw -0x38(%sr0,%sp),%r5
180 ldw -0x3c(%sr0,%sp),%r4
182 ldwm -0x40(%sr0,%sp),%r3
195 /* Set up a lisp stack frame. */
196 copy reg_CFP, reg_OCFP
197 copy reg_CSP, reg_CFP
198 addi 32, reg_CSP, reg_CSP
199 stw reg_OCFP, 0(0,reg_CFP) ; save old cfp
200 stw reg_CFP, 4(0,reg_CFP) ; save old csp
201 /* convert raw return PC into a fixnum PC-offset, because we dont
202 have ahold of an lra object */
203 sub reg_LIP, reg_CODE, reg_NL5
204 addi 3-OTHER_POINTER_LOWTAG, reg_NL5, reg_NL5
205 stw reg_NL5, 8(0,reg_CFP)
206 stw reg_CODE, 0xc(0,reg_CFP)
208 /* set pseudo-atomic flag */
209 addi 4, reg_ALLOC, reg_ALLOC
211 /* Store the lisp state. */
212 copy reg_ALLOC,reg_NL5
214 addil L%dynamic_space_free_pointer-$global$,%dp
215 stw reg_NL5,R%dynamic_space_free_pointer-$global$(0,%r1)
216 addil L%current_binding_stack_pointer-$global$,%dp
217 stw reg_BSP,R%current_binding_stack_pointer-$global$(0,%r1)
218 addil L%current_control_stack_pointer-$global$,%dp
219 stw reg_CSP,R%current_control_stack_pointer-$global$(0,%r1)
220 addil L%current_control_frame_pointer-$global$,%dp
221 stw reg_CFP,R%current_control_frame_pointer-$global$(0,%r1)
223 /* Back in C land. [CSP is just a handy non-zero value.] */
224 addil L%foreign_function_call_active-$global$,%dp
225 stw reg_CSP,R%foreign_function_call_active-$global$(0,%r1)
227 /* Turn off pseudo-atomic and check for traps. */
228 addit,od -4,reg_ALLOC,reg_ALLOC
230 /* in order to be able to call incrementally linked (ld -A) functions,
231 we have to do some mild trickery here */
236 /* Clear the callee saves descriptor regs. */
242 /* Turn on pseudo-atomic. */
245 /* Turn off foreign function call. */
246 addil L%foreign_function_call_active-$global$,%dp
247 stw %r0,R%foreign_function_call_active-$global$(0,%r1)
250 addil L%dynamic_space_free_pointer-$global$,%dp
251 ldw R%dynamic_space_free_pointer-$global$(0,%r1),%r1
252 add reg_ALLOC,%r1,reg_ALLOC
254 /* We don't need to load OCFP, CFP, CSP, or BSP because they are
255 * in caller saves registers.
258 /* End of pseudo-atomic. */
259 addit,od -4,reg_ALLOC,reg_ALLOC
261 /* Restore CODE. Even though it is in a callee saves register
262 * it might have been GC'ed.
264 ldw 0xc(0,reg_CFP), reg_CODE
266 /* Restore the return pc. */
267 ldw 8(0,reg_CFP), reg_NL0
268 addi OTHER_POINTER_LOWTAG-3, reg_NL0, reg_NL0
270 addi -3, reg_NL0, reg_NL0
271 ldi OTHER_POINTER_LOWTAG, reg_NL1
272 sub reg_NL0, reg_NL1, reg_NL0
274 add reg_CODE, reg_NL0, reg_LIP
276 /* Pop the lisp stack frame, and back we go. */
277 ldw 4(0,reg_CFP), reg_CSP
278 ldw 0(0,reg_CFP), reg_OCFP
279 copy reg_OCFP, reg_CFP
285 * Stuff to sanctify a block of memory for execution.
288 .EXPORT sanctify_for_execution
289 sanctify_for_execution:
293 /* %arg0=start addr, %arg1=length in bytes */
294 add %arg0,%arg1,%arg1
301 ldi 32,%r1 ; bytes per cache line
302 /* parisc 1.1 and 2.0 manuals say to flush the dcache, SYNC,
303 * flush the icache, SYNC again, and burn seven instructions
304 * before executing modified code. */
306 comb,< %arg0,%arg1,sanctify_loop
307 fdc,m %r1(%sr1,%arg0)
310 comb,< %arg2,%arg1,sanctify_loop_2
311 fic,m %r1(%sr1,%arg2)
322 * Core saving/restoring support
325 .export call_on_stack
327 /* %arg0 = fn to invoke, %arg1 = new stack base */
329 /* Compute the new stack pointer. */
332 /* Zero out the previous stack pointer. */
335 /* Invoke the function. */
345 .callinfo entry_gr=18,entry_fr=21,save_rp,calls
348 stw %rp,-0x14(%sr0,%sp)
349 fstds,ma %fr12,8(%sr0,%sp)
350 fstds,ma %fr13,8(%sr0,%sp)
351 fstds,ma %fr14,8(%sr0,%sp)
352 fstds,ma %fr15,8(%sr0,%sp)
353 fstds,ma %fr16,8(%sr0,%sp)
354 fstds,ma %fr17,8(%sr0,%sp)
355 fstds,ma %fr18,8(%sr0,%sp)
356 fstds,ma %fr19,8(%sr0,%sp)
357 fstds,ma %fr20,8(%sr0,%sp)
358 fstds,ma %fr21,8(%sr0,%sp)
359 stwm %r3,0x70(%sr0,%sp)
360 stw %r4,-0x6c(%sr0,%sp)
361 stw %r5,-0x68(%sr0,%sp)
362 stw %r6,-0x64(%sr0,%sp)
363 stw %r7,-0x60(%sr0,%sp)
364 stw %r8,-0x5c(%sr0,%sp)
365 stw %r9,-0x58(%sr0,%sp)
366 stw %r10,-0x54(%sr0,%sp)
367 stw %r11,-0x50(%sr0,%sp)
368 stw %r12,-0x4c(%sr0,%sp)
369 stw %r13,-0x48(%sr0,%sp)
370 stw %r14,-0x44(%sr0,%sp)
371 stw %r15,-0x40(%sr0,%sp)
372 stw %r16,-0x3c(%sr0,%sp)
373 stw %r17,-0x38(%sr0,%sp)
374 stw %r18,-0x34(%sr0,%sp)
377 /* Remember the function we want to invoke */
380 /* Pass the new stack pointer in as %arg0 */
383 /* Leave %arg1 as %arg1. */
389 .export _restore_state
392 ldw -0xd4(%sr0,%sp),%rp
393 ldw -0x34(%sr0,%sp),%r18
394 ldw -0x38(%sr0,%sp),%r17
395 ldw -0x3c(%sr0,%sp),%r16
396 ldw -0x40(%sr0,%sp),%r15
397 ldw -0x44(%sr0,%sp),%r14
398 ldw -0x48(%sr0,%sp),%r13
399 ldw -0x4c(%sr0,%sp),%r12
400 ldw -0x50(%sr0,%sp),%r11
401 ldw -0x54(%sr0,%sp),%r10
402 ldw -0x58(%sr0,%sp),%r9
403 ldw -0x5c(%sr0,%sp),%r8
404 ldw -0x60(%sr0,%sp),%r7
405 ldw -0x64(%sr0,%sp),%r6
406 ldw -0x68(%sr0,%sp),%r5
407 ldw -0x6c(%sr0,%sp),%r4
408 ldwm -0x70(%sr0,%sp),%r3
409 fldds,mb -8(%sr0,%sp),%fr21
410 fldds,mb -8(%sr0,%sp),%fr20
411 fldds,mb -8(%sr0,%sp),%fr19
412 fldds,mb -8(%sr0,%sp),%fr18
413 fldds,mb -8(%sr0,%sp),%fr17
414 fldds,mb -8(%sr0,%sp),%fr16
415 fldds,mb -8(%sr0,%sp),%fr15
416 fldds,mb -8(%sr0,%sp),%fr14
417 fldds,mb -8(%sr0,%sp),%fr13
419 fldds,mb -8(%sr0,%sp),%fr12
425 .export restore_state
436 /* FIX, add support for singlestep
437 break trap_SingleStepBreakpoint,0
438 break trap_SingleStepBreakpoint,0
440 .export SingleStepTraps
444 there's a break 0,0 in the new version here!!!
448 * For an explanation of the magic involved in function-end
449 * breakpoints, see the implementation in ppc-assem.S.
453 .export fun_end_breakpoint_guts
454 fun_end_breakpoint_guts:
455 .word RETURN_PC_WIDETAG + 0x600
456 /* multiple value return point -- just jump to trap. */
457 b,n fun_end_breakpoint_trap
458 /* single value return point -- convert to multiple w/ n=1 */
459 copy reg_CSP, reg_OCFP
460 addi 4, reg_CSP, reg_CSP
461 addi 4, %r0, reg_NARGS
462 copy reg_NULL, reg_A1
463 copy reg_NULL, reg_A2
464 copy reg_NULL, reg_A3
465 copy reg_NULL, reg_A4
466 copy reg_NULL, reg_A5
468 .export fun_end_breakpoint_trap
469 fun_end_breakpoint_trap:
470 break trap_FunEndBreakpoint,0
471 b,n fun_end_breakpoint_trap
473 .export fun_end_breakpoint_end
474 fun_end_breakpoint_end: