1 #define LANGUAGE_ASSEMBLY
7 .import foreign_function_call_active,data
8 .import current_control_stack_pointer,data
9 .import current_control_frame_pointer,data
10 .import current_binding_stack_pointer,data
11 .import dynamic_space_free_pointer,data
15 .import $$dyncall,MILLICODE
22 .export call_into_lisp
25 .callinfo entry_gr=18,save_rp
27 /* %arg0=function, %arg1=cfp, %arg2=nargs */
29 stw %rp,-0x14(%sr0,%sp)
30 stwm %r3,0x40(%sr0,%sp)
31 stw %r4,-0x3c(%sr0,%sp)
32 stw %r5,-0x38(%sr0,%sp)
33 stw %r6,-0x34(%sr0,%sp)
34 stw %r7,-0x30(%sr0,%sp)
35 stw %r8,-0x2c(%sr0,%sp)
36 stw %r9,-0x28(%sr0,%sp)
37 stw %r10,-0x24(%sr0,%sp)
38 stw %r11,-0x20(%sr0,%sp)
39 stw %r12,-0x1c(%sr0,%sp)
40 stw %r13,-0x18(%sr0,%sp)
41 stw %r14,-0x14(%sr0,%sp)
42 stw %r15,-0x10(%sr0,%sp)
43 stw %r16,-0xc(%sr0,%sp)
44 stw %r17,-0x8(%sr0,%sp)
45 stw %r18,-0x4(%sr0,%sp)
47 /* Clear the descriptor regs, moving in args as approporate. */
51 zdep %arg2,29,30,reg_NARGS
66 ldo R%NIL(reg_NULL),reg_NULL
68 /* Turn on pseudo-atomic. */
71 /* No longer in foreign function call land. */
72 addil L%foreign_function_call_active-$global$,%dp
73 stw %r0,R%foreign_function_call_active-$global$(0,%r1)
75 /* Load lisp state. */
76 addil L%dynamic_space_free_pointer-$global$,%dp
77 ldw R%dynamic_space_free_pointer-$global$(0,%r1),%r1
78 add reg_ALLOC,%r1,reg_ALLOC
79 addil L%current_binding_stack_pointer-$global$,%dp
80 ldw R%current_binding_stack_pointer-$global$(0,%r1),reg_BSP
81 addil L%current_control_stack_pointer-$global$,%dp
82 ldw R%current_control_stack_pointer-$global$(0,%r1),reg_CSP
83 addil L%current_control_frame_pointer-$global$,%dp
84 ldw R%current_control_frame_pointer-$global$(0,%r1),reg_OCFP
87 /* End of pseudo-atomic. */
88 addit,od -4,reg_ALLOC,reg_ALLOC
90 /* Establish lisp arguments. */
94 ldw 12(reg_CFP),reg_A3
95 ldw 16(reg_CFP),reg_A4
96 ldw 20(reg_CFP),reg_A5
98 /* Calculate the LRA. */
99 ldil L%lra+OTHER_POINTER_LOWTAG,reg_LRA
100 ldo R%lra+OTHER_POINTER_LOWTAG(reg_LRA),reg_LRA
102 /* Indirect the closure */
103 ldw CLOSURE_FUN_OFFSET(0,reg_LEXENV),reg_CODE
104 addi 6*4-FUN_POINTER_LOWTAG,reg_CODE,reg_LIP
106 /* And into lisp we go. */
115 .word RETURN_PC_HEADER_WIDETAG
116 copy reg_OCFP,reg_CSP
118 /* Copy CFP (%r4) into someplace else and restore r4. */
122 /* Copy the return value. */
125 /* Turn on pseudo-atomic. */
126 addi 4,reg_ALLOC,reg_ALLOC
128 /* Store the lisp state. */
129 copy reg_ALLOC,reg_NL0
131 addil L%dynamic_space_free_pointer-$global$,%dp
132 stw reg_NL0,R%dynamic_space_free_pointer-$global$(0,%r1)
133 addil L%current_binding_stack_pointer-$global$,%dp
134 stw reg_BSP,R%current_binding_stack_pointer-$global$(0,%r1)
135 addil L%current_control_stack_pointer-$global$,%dp
136 stw reg_CSP,R%current_control_stack_pointer-$global$(0,%r1)
137 addil L%current_control_frame_pointer-$global$,%dp
138 stw reg_NL1,R%current_control_frame_pointer-$global$(0,%r1)
140 /* Back in C land. [CSP is just a handy non-zero value.] */
141 addil L%foreign_function_call_active-$global$,%dp
142 stw reg_CSP,R%foreign_function_call_active-$global$(0,%r1)
144 /* Turn off pseudo-atomic and check for traps. */
145 addit,od -4,reg_ALLOC,reg_ALLOC
148 ldw -0x54(%sr0,%sp),%rp
149 ldw -0x4(%sr0,%sp),%r18
150 ldw -0x8(%sr0,%sp),%r17
151 ldw -0xc(%sr0,%sp),%r16
152 ldw -0x10(%sr0,%sp),%r15
153 ldw -0x14(%sr0,%sp),%r14
154 ldw -0x18(%sr0,%sp),%r13
155 ldw -0x1c(%sr0,%sp),%r12
156 ldw -0x20(%sr0,%sp),%r11
157 ldw -0x24(%sr0,%sp),%r10
158 ldw -0x28(%sr0,%sp),%r9
159 ldw -0x2c(%sr0,%sp),%r8
160 ldw -0x30(%sr0,%sp),%r7
161 ldw -0x34(%sr0,%sp),%r6
162 ldw -0x38(%sr0,%sp),%r5
163 ldw -0x3c(%sr0,%sp),%r4
165 ldwm -0x40(%sr0,%sp),%r3
180 /* Set up a lisp stack frame. Note: we convert the raw return pc into
181 * a fixnum pc-offset because we don't have ahold of an lra object.
183 copy reg_CFP, reg_OCFP
184 copy reg_CSP, reg_CFP
185 addi 32, reg_CSP, reg_CSP
186 stw reg_OCFP, 0(0,reg_CFP)
187 sub reg_LIP, reg_CODE, reg_NL5
188 addi 3-OTHER_POINTER_LOWTAG, reg_NL5, reg_NL5
189 stw reg_NL5, 4(0,reg_CFP)
190 stw reg_CODE, 8(0,reg_CFP)
192 /* Turn on pseudo-atomic. */
193 addi 4, reg_ALLOC, reg_ALLOC
195 /* Store the lisp state. */
196 copy reg_ALLOC,reg_NL5
198 addil L%dynamic_space_free_pointer-$global$,%dp
199 stw reg_NL5,R%dynamic_space_free_pointer-$global$(0,%r1)
200 addil L%current_binding_stack_pointer-$global$,%dp
201 stw reg_BSP,R%current_binding_stack_pointer-$global$(0,%r1)
202 addil L%current_control_stack_pointer-$global$,%dp
203 stw reg_CSP,R%current_control_stack_pointer-$global$(0,%r1)
204 addil L%current_control_frame_pointer-$global$,%dp
205 stw reg_CFP,R%current_control_frame_pointer-$global$(0,%r1)
207 /* Back in C land. [CSP is just a handy non-zero value.] */
208 addil L%foreign_function_call_active-$global$,%dp
209 stw reg_CSP,R%foreign_function_call_active-$global$(0,%r1)
211 /* Turn off pseudo-atomic and check for traps. */
212 addit,od -4,reg_ALLOC,reg_ALLOC
214 /* in order to be able to call incrementally linked (ld -A) functions,
215 we have to do some mild trickery here */
220 /* Clear the callee saves descriptor regs. */
226 /* Turn on pseudo-atomic. */
229 /* Turn off foreign function call. */
230 addil L%foreign_function_call_active-$global$,%dp
231 stw %r0,R%foreign_function_call_active-$global$(0,%r1)
234 addil L%dynamic_space_free_pointer-$global$,%dp
235 ldw R%dynamic_space_free_pointer-$global$(0,%r1),%r1
236 add reg_ALLOC,%r1,reg_ALLOC
238 /* We don't need to load OCFP, CFP, CSP, or BSP because they are
239 * in caller saves registers.
242 /* End of pseudo-atomic. */
243 addit,od -4,reg_ALLOC,reg_ALLOC
245 /* Restore CODE. Even though it is in a callee saves register
246 * it might have been GC'ed.
248 ldw 8(0,reg_CFP), reg_CODE
250 /* Restore the return pc. */
251 ldw 4(0,reg_CFP), reg_NL0
252 addi OTHER_POINTER_LOWTAG-3, reg_NL0, reg_NL0
253 add reg_CODE, reg_NL0, reg_LIP
255 /* Pop the lisp stack frame, and back we go. */
256 copy reg_CFP, reg_CSP
258 copy reg_OCFP, reg_CFP
263 * Stuff to sanctify a block of memory for execution.
266 .EXPORT sanctify_for_execution
267 sanctify_for_execution:
271 /* %arg0=start addr, %arg1=length in bytes */
272 add %arg0,%arg1,%arg1
278 ldi 32,%r1 ; bytes per cache line
281 comb,< %arg0,%arg1,sanctify_loop
282 fic,m %r1(%sr1,%arg0)
295 .EXPORT closure_tramp
297 /* reg_FDEFN holds the fdefn object. */
298 ldw FDEFN_FUN_OFFSET(0,reg_FDEFN),reg_LEXENV
299 ldw CLOSURE_FUN_OFFSET(0,reg_LEXENV),reg_L0
300 addi SIMPLE_FUN_CODE_OFFSET, reg_L0, reg_LIP
303 .EXPORT undefined_tramp
307 .byte UNDEFINED_FUN_ERROR
309 .byte (0x20 + sc_DescriptorReg)
315 * Core saving/restoring support
318 .export call_on_stack
320 /* %arg0 = fn to invoke, %arg1 = new stack base */
322 /* Compute the new stack pointer. */
325 /* Zero out the previous stack pointer. */
328 /* Invoke the function. */
338 .callinfo entry_gr=18,entry_fr=21,save_rp,calls
341 stw %rp,-0x14(%sr0,%sp)
342 fstds,ma %fr12,8(%sr0,%sp)
343 fstds,ma %fr13,8(%sr0,%sp)
344 fstds,ma %fr14,8(%sr0,%sp)
345 fstds,ma %fr15,8(%sr0,%sp)
346 fstds,ma %fr16,8(%sr0,%sp)
347 fstds,ma %fr17,8(%sr0,%sp)
348 fstds,ma %fr18,8(%sr0,%sp)
349 fstds,ma %fr19,8(%sr0,%sp)
350 fstds,ma %fr20,8(%sr0,%sp)
351 fstds,ma %fr21,8(%sr0,%sp)
352 stwm %r3,0x70(%sr0,%sp)
353 stw %r4,-0x6c(%sr0,%sp)
354 stw %r5,-0x68(%sr0,%sp)
355 stw %r6,-0x64(%sr0,%sp)
356 stw %r7,-0x60(%sr0,%sp)
357 stw %r8,-0x5c(%sr0,%sp)
358 stw %r9,-0x58(%sr0,%sp)
359 stw %r10,-0x54(%sr0,%sp)
360 stw %r11,-0x50(%sr0,%sp)
361 stw %r12,-0x4c(%sr0,%sp)
362 stw %r13,-0x48(%sr0,%sp)
363 stw %r14,-0x44(%sr0,%sp)
364 stw %r15,-0x40(%sr0,%sp)
365 stw %r16,-0x3c(%sr0,%sp)
366 stw %r17,-0x38(%sr0,%sp)
367 stw %r18,-0x34(%sr0,%sp)
370 /* Remember the function we want to invoke */
373 /* Pass the new stack pointer in as %arg0 */
376 /* Leave %arg1 as %arg1. */
382 .export _restore_state
385 ldw -0xd4(%sr0,%sp),%rp
386 ldw -0x34(%sr0,%sp),%r18
387 ldw -0x38(%sr0,%sp),%r17
388 ldw -0x3c(%sr0,%sp),%r16
389 ldw -0x40(%sr0,%sp),%r15
390 ldw -0x44(%sr0,%sp),%r14
391 ldw -0x48(%sr0,%sp),%r13
392 ldw -0x4c(%sr0,%sp),%r12
393 ldw -0x50(%sr0,%sp),%r11
394 ldw -0x54(%sr0,%sp),%r10
395 ldw -0x58(%sr0,%sp),%r9
396 ldw -0x5c(%sr0,%sp),%r8
397 ldw -0x60(%sr0,%sp),%r7
398 ldw -0x64(%sr0,%sp),%r6
399 ldw -0x68(%sr0,%sp),%r5
400 ldw -0x6c(%sr0,%sp),%r4
401 ldwm -0x70(%sr0,%sp),%r3
402 fldds,mb -8(%sr0,%sp),%fr21
403 fldds,mb -8(%sr0,%sp),%fr20
404 fldds,mb -8(%sr0,%sp),%fr19
405 fldds,mb -8(%sr0,%sp),%fr18
406 fldds,mb -8(%sr0,%sp),%fr17
407 fldds,mb -8(%sr0,%sp),%fr16
408 fldds,mb -8(%sr0,%sp),%fr15
409 fldds,mb -8(%sr0,%sp),%fr14
410 fldds,mb -8(%sr0,%sp),%fr13
412 fldds,mb -8(%sr0,%sp),%fr12
418 .export restore_state
429 .export SingleStepTraps
431 break trap_SingleStepBreakpoint,0
432 break trap_SingleStepBreakpoint,0
434 there's a break 0,0 in the new version here!!!
438 .export fun_end_breakpoint_guts
439 fun_end_breakpoint_guts:
440 .word RETURN_PC_HEADER_WIDETAG
441 /* multiple value return point -- just jump to trap. */
442 b,n fun_end_breakpoint_trap
443 /* single value return point -- convert to multiple w/ n=1 */
444 copy reg_CSP, reg_OCFP
445 addi 4, reg_CSP, reg_CSP
446 addi 4, %r0, reg_NARGS
447 copy reg_NULL, reg_A1
448 copy reg_NULL, reg_A2
449 copy reg_NULL, reg_A3
450 copy reg_NULL, reg_A4
451 copy reg_NULL, reg_A5
453 .export fun_end_breakpoint_trap
454 fun_end_breakpoint_trap:
455 break trap_FunEndBreakpoint,0
456 b,n fun_end_breakpoint_trap
458 .export fun_end_breakpoint_end
459 fun_end_breakpoint_end: