/[cmucl]/src/lisp/ppc-assem.S
ViewVC logotype

Contents of /src/lisp/ppc-assem.S

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.19 - (show annotations)
Sat Feb 25 04:35:58 2006 UTC (8 years, 1 month ago) by rtoy
Branch: MAIN
CVS Tags: sparc-tramp-assem-base, double-double-array-base, post-merge-intl-branch, merged-unicode-utf16-extfmt-2009-06-11, double-double-init-sparc-2, unicode-utf16-extfmt-2009-03-27, double-double-base, snapshot-2007-09, snapshot-2007-08, snapshot-2008-08, snapshot-2008-09, sse2-packed-2008-11-12, snapshot-2008-05, snapshot-2008-06, snapshot-2008-07, snapshot-2007-05, snapshot-2008-01, snapshot-2008-02, snapshot-2008-03, intl-branch-working-2010-02-19-1000, snapshot-2006-11, snapshot-2006-10, double-double-init-sparc, snapshot-2006-12, unicode-string-buffer-impl-base, sse2-base, release-20b-pre1, release-20b-pre2, unicode-string-buffer-base, sse2-packed-base, sparc-tramp-assem-2010-07-19, amd64-dd-start, release-19f-pre1, snapshot-2008-12, snapshot-2008-11, intl-2-branch-base, snapshot-2007-01, snapshot-2007-02, release-19e, release-19d, GIT-CONVERSION, double-double-init-ppc, unicode-utf16-sync-2008-12, cross-sol-x86-merged, label-2009-03-16, release-19f-base, merge-sse2-packed, merge-with-19f, intl-branch-working-2010-02-11-1000, unicode-snapshot-2009-05, unicode-snapshot-2009-06, double-double-init-%make-sparc, unicode-utf16-sync-2008-07, unicode-utf16-sync-2008-09, unicode-utf16-extfmts-sync-2008-12, RELEASE_20b, snapshot-2008-04, unicode-utf16-sync-label-2009-03-16, RELEASE_19f, snapshot-2007-03, release-20a-base, cross-sol-x86-base, unicode-utf16-char-support-2009-03-26, unicode-utf16-char-support-2009-03-25, unicode-utf16-extfmts-pre-sync-2008-11, snapshot-2008-10, snapshot-2007-04, snapshot-2010-12, snapshot-2010-11, unicode-utf16-sync-2008-11, snapshot-2007-07, snapshot-2011-09, snapshot-2011-06, snapshot-2011-07, snapshot-2011-04, snapshot-2007-06, snapshot-2011-02, snapshot-2011-03, snapshot-2011-01, pre-merge-intl-branch, double-double-array-checkpoint, double-double-reader-checkpoint-1, release-19d-base, release-19e-pre1, double-double-irrat-end, release-19e-pre2, snapshot-2010-05, snapshot-2010-04, snapshot-2010-07, snapshot-2010-06, snapshot-2010-01, snapshot-2010-03, snapshot-2010-02, release-19d-pre2, release-19d-pre1, snapshot-2010-08, double-double-init-checkpoint-1, double-double-reader-base, label-2009-03-25, cross-sol-x86-2010-12-20, double-double-init-x86, sse2-checkpoint-2008-10-01, intl-branch-2010-03-18-1300, double-double-sparc-checkpoint-1, sse2-merge-with-2008-11, sse2-merge-with-2008-10, RELEASE_20a, release-20a-pre1, snapshot-2009-11, snapshot-2009-12, unicode-utf16-extfmt-2009-06-11, portable-clx-import-2009-06-16, unicode-utf16-string-support, cross-sparc-branch-base, release-19e-base, intl-branch-base, double-double-irrat-start, unicode-utf16-base, portable-clx-base, snapshot-2009-08, snapshot-2007-12, snapshot-2007-10, snapshot-2007-11, snapshot-2009-02, snapshot-2009-01, snapshot-2009-07, snapshot-2009-05, snapshot-2009-04, snapshot-2006-03, snapshot-2006-06, snapshot-2006-07, snapshot-2006-04, snapshot-2006-05, pre-telent-clx, snapshot-2006-08, snapshot-2006-09, HEAD
Branch point for: double-double-reader-branch, double-double-array-branch, RELEASE-19F-BRANCH, portable-clx-branch, cross-sparc-branch, RELEASE-20B-BRANCH, unicode-string-buffer-branch, sparc-tramp-assem-branch, release-19d-branch, sse2-packed-branch, RELEASE-20A-BRANCH, amd64-dd-branch, double-double-branch, unicode-string-buffer-impl-branch, intl-branch, unicode-utf16-branch, cross-sol-x86-branch, release-19e-branch, sse2-branch, intl-2-branch, unicode-utf16-extfmt-branch
Changes since 1.18: +1 -1 lines
Oops. Register A0 was not properly initialized for the undefined
foreign symbol error trap.
1 #define LANGUAGE_ASSEMBLY
2
3 #include "internals.h"
4 #include "lispregs.h"
5 #include "globals.h"
6
7 #if defined DARWIN
8 #define FUNCDEF(x) .text @ \
9 .align 3 @ \
10 _/**/x:
11 #define GFUNCDEF(x) .globl _/**/x @ \
12 FUNCDEF(x)
13 #else
14 #define FUNCDEF(x) .text ; \
15 .align 3 ; \
16 .type x,@function ; \
17 x:
18 #define GFUNCDEF(x) .globl _/**/x @ \
19 FUNCDEF(x)
20 #endif
21
22 #if defined DARWIN
23 #define SET_SIZE(x)
24 #else
25 #define SET_SIZE(x) .size x,.-x
26 #endif
27
28 /* Load a register from a global, using the register as an intermediary */
29 /* The register will be a fixnum for one instruction, so this is gc-safe */
30
31 #if defined DARWIN
32 #define load(reg,global) \
33 lis reg,ha16(global) @ \
34 lwz reg,lo16(global)(reg) ; Comment
35 #define store(reg,temp,global) \
36 lis temp,ha16(global) @\
37 stw reg,lo16(global)(temp) ; Comment
38 #else
39 #define load(reg,global) \
40 lis reg,global@ha; lwz reg,global@l(reg)
41 #define store(reg,temp,global) \
42 lis temp,global@ha; stw reg,global@l(temp)
43 #endif
44
45 #define FIRST_SAVE_FPR 14 /* lowest-numbered non-volatile FPR */
46 #define FIRST_SAVE_GPR 13 /* lowest-numbered non-volatile GPR */
47 #define NFPR_SAVE_BYTES(n) ((32-(n))*8)
48 #if defined DARWIN
49 #define NGPR_SAVE_BYTES(n) ((32-(n))*4)
50 #define FRAME_ARG_BYTES(n) (((((n)+6)*4)+15)&~15)
51 #else
52 #define NGPR_SAVE_BYTES(n) ((32-(~1&((n)+1)))*4)
53 #define FRAME_ARG_BYTES(n) (((((n)+2)*4)+15)&~15)
54 #endif
55
56 #if defined DARWIN
57 #define FRAME_SIZE(first_g,first_f,out_arg_words,savecr) \
58 (NFPR_SAVE_BYTES(first_f)+ NGPR_SAVE_BYTES(first_g)+ FRAME_ARG_BYTES(out_arg_words))
59 #define SAVE_FPR(n) stfd f/**/n,-8*(32- n)(r11)
60 #define SAVE_GPR(n) stw r/**/n,-4*(32- n)(r11)
61 /* Make sure FULL_FRAME_SIZE is on a 16-byte boundary */
62 #define FULL_FRAME_SIZE ((FRAME_SIZE(FIRST_SAVE_GPR,FIRST_SAVE_FPR,8,1) + 15) & ~15)
63 #else
64 #define FRAME_SIZE(first_g,first_f,out_arg_words,savecr) \
65 (NFPR_SAVE_BYTES(first_f)+ NGPR_SAVE_BYTES(first_g)+ FRAME_ARG_BYTES(out_arg_words+savecr))
66 #define SAVE_FPR(n) stfd n,-8*(32-(n))(11)
67 #define SAVE_GPR(n) stw n,-4*(32-(n))(11)
68 #define FULL_FRAME_SIZE FRAME_SIZE(FIRST_SAVE_GPR,FIRST_SAVE_FPR,0,1)
69 #endif
70
71 #if defined DARWIN
72 #define RESTORE_FPR(n) lfd f/**/n,-8*(32- n)(r11)
73 #define RESTORE_GPR(n) lwz r/**/n,-4*(32- n)(r11)
74 #else
75 #define RESTORE_FPR(n) lfd f##n,-8*(32-(r##n))(r11)
76 #define RESTORE_GPR(n) lwz r##n,-4*(32-(r##n))(r11)
77 #endif
78 #define C_FULL_PROLOG \
79 nop @\
80 nop @ \
81 mfcr REG(0) @ \
82 stw REG(0),4(REG(1)) @ \
83 mflr REG(0) @ \
84 stw REG(0),8(REG(1)) @ \
85 mr REG(11),REG(1) @ \
86 stwu REG(1),-FULL_FRAME_SIZE(REG(1)) @ \
87 SAVE_FPR(14) @ \
88 SAVE_FPR(15) @ \
89 SAVE_FPR(16) @ \
90 SAVE_FPR(17) @ \
91 SAVE_FPR(18) @ \
92 SAVE_FPR(19) @ \
93 SAVE_FPR(20) @ \
94 SAVE_FPR(21) @ \
95 SAVE_FPR(22) @ \
96 SAVE_FPR(23) @ \
97 SAVE_FPR(24) @ \
98 SAVE_FPR(25) @ \
99 SAVE_FPR(26) @ \
100 SAVE_FPR(27) @ \
101 SAVE_FPR(28) @ \
102 SAVE_FPR(29) @ \
103 SAVE_FPR(30) @ \
104 SAVE_FPR(31) @ \
105 la REG(11),-NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(11)) @ \
106 SAVE_GPR(13) @ \
107 SAVE_GPR(14) @ \
108 SAVE_GPR(15) @ \
109 SAVE_GPR(16) @ \
110 SAVE_GPR(17) @ \
111 SAVE_GPR(18) @ \
112 SAVE_GPR(19) @ \
113 SAVE_GPR(20) @ \
114 SAVE_GPR(21) @ \
115 SAVE_GPR(22) @ \
116 SAVE_GPR(23) @ \
117 SAVE_GPR(24) @ \
118 SAVE_GPR(25) @ \
119 SAVE_GPR(26) @ \
120 SAVE_GPR(27) @ \
121 SAVE_GPR(28) @ \
122 SAVE_GPR(29) @ \
123 SAVE_GPR(30) @ \
124 SAVE_GPR(31)
125
126
127 #define C_FULL_EPILOG \
128 la REG(11),FULL_FRAME_SIZE-NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(1)) @ \
129 RESTORE_GPR(13) @ \
130 RESTORE_GPR(14) @ \
131 RESTORE_GPR(15) @ \
132 RESTORE_GPR(16) @ \
133 RESTORE_GPR(17) @ \
134 RESTORE_GPR(18) @ \
135 RESTORE_GPR(19) @ \
136 RESTORE_GPR(20) @ \
137 RESTORE_GPR(21) @ \
138 RESTORE_GPR(22) @ \
139 RESTORE_GPR(23) @ \
140 RESTORE_GPR(24) @ \
141 RESTORE_GPR(25) @ \
142 RESTORE_GPR(26) @ \
143 RESTORE_GPR(27) @ \
144 RESTORE_GPR(28) @ \
145 RESTORE_GPR(29) @ \
146 RESTORE_GPR(30) @ \
147 RESTORE_GPR(31) @ \
148 la REG(11),NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(11)) @ \
149 RESTORE_FPR(14) @ \
150 RESTORE_FPR(15) @ \
151 RESTORE_FPR(16) @ \
152 RESTORE_FPR(17) @ \
153 RESTORE_FPR(18) @ \
154 RESTORE_FPR(19) @ \
155 RESTORE_FPR(20) @ \
156 RESTORE_FPR(21) @ \
157 RESTORE_FPR(22) @ \
158 RESTORE_FPR(23) @ \
159 RESTORE_FPR(24) @ \
160 RESTORE_FPR(25) @ \
161 RESTORE_FPR(26) @ \
162 RESTORE_FPR(27) @ \
163 RESTORE_FPR(28) @ \
164 RESTORE_FPR(29) @ \
165 RESTORE_FPR(30) @ \
166 RESTORE_FPR(31) @ \
167 lwz REG(1),0(REG(1)) @ \
168 lwz REG(0),4(REG(1)) @ \
169 mtcr REG(0) @ \
170 lwz REG(0),8(REG(1)) @ \
171 mtlr REG(0) @ \
172
173
174
175
176 .text
177
178 /*
179 * Function to transfer control into lisp. The lisp object to invoke is
180 * passed as the first argument, which puts it in NL0
181 */
182
183 GFUNCDEF(call_into_lisp)
184 C_FULL_PROLOG
185 /* store(reg_POLL,11,saver2) */
186 /* Initialize tagged registers */
187 li reg_ZERO,0
188 li reg_CODE,0
189 li reg_CNAME,0
190 li reg_LEXENV,0
191 li reg_FDEFN,0
192 li reg_OCFP,0
193 li reg_LRA,0
194 li reg_A0,0
195 li reg_A1,0
196 li reg_A2,0
197 li reg_A3,0
198 li reg_L0,0
199 li reg_L1,0
200 li reg_LIP,0
201 lis reg_NULL,hi16(NIL)
202 ori reg_NULL,reg_NULL,lo16(NIL)
203
204 /* Turn on pseudo-atomic */
205
206 li reg_ALLOC,4
207 store(reg_ZERO,reg_NL4,_foreign_function_call_active)
208 load(reg_NL4,_current_dynamic_space_free_pointer)
209 add reg_ALLOC,reg_ALLOC,reg_NL4
210 load(reg_BSP,_current_binding_stack_pointer)
211 load(reg_CSP,_current_control_stack_pointer)
212 load(reg_OCFP,_current_control_frame_pointer)
213
214 /* No longer atomic, and check for interrupt */
215 andi. reg_NL3, reg_ALLOC, 1
216 subi reg_ALLOC,reg_ALLOC,4
217 twnei reg_NL3, 0
218
219 /* Pass in the arguments */
220
221 mr reg_CFP,reg_NL1
222 mr reg_LEXENV,reg_NL0
223 lwz reg_A0,0(reg_CFP)
224 lwz reg_A1,4(reg_CFP)
225 lwz reg_A2,8(reg_CFP)
226 lwz reg_A3,12(reg_CFP)
227
228 /* Calculate LRA */
229 lis reg_LRA,ha16(lra)
230 addi reg_LRA,reg_LRA,lo16(lra)
231 addi reg_LRA,reg_LRA,type_OtherPointer
232
233 /* Function is an indirect closure */
234 lwz reg_CODE,CLOSURE_FUNCTION_OFFSET(reg_LEXENV)
235 /*
236 * The 6 is vm:function-code-offset, the 4 is
237 * the number of bytes in a lispobj.
238 */
239 addi reg_LIP,reg_CODE,6*4-type_FunctionPointer
240 mtctr reg_LIP
241 slwi reg_NARGS,reg_NL2,2
242 bctr
243 .align 3
244 lra:
245 .long type_ReturnPcHeader
246
247 /* Blow off any extra values. */
248 mr reg_CSP,reg_OCFP
249 nop
250
251 /* Return the one value. */
252
253 mr REG(3),reg_A0
254
255 /* Turn on pseudo-atomic */
256 li reg_NL3,-4
257 la reg_ALLOC,4(reg_ALLOC)
258
259 /* Store lisp state */
260 clrrwi reg_NL1,reg_ALLOC,3
261 store(reg_NL1,reg_NL2,_current_dynamic_space_free_pointer)
262 /* store(reg_POLL,reg_NL2,poll_flag) */
263 /* load(reg_NL2,current_thread) */
264 store(reg_BSP,reg_NL2,_current_binding_stack_pointer)
265 store(reg_CSP,reg_NL2,_current_control_stack_pointer)
266 store(reg_CFP,reg_NL2,_current_control_frame_pointer)
267 /* load(reg_POLL,saver2) */
268
269 /* No longer in Lisp. */
270 store(reg_NL1,reg_NL2,_foreign_function_call_active)
271
272 /* Check for interrupt */
273 andi. reg_NL3, reg_ALLOC, 1
274 subi reg_ALLOC, reg_ALLOC, 4
275 twnei reg_NL3,0
276
277 /* Back to C */
278 C_FULL_EPILOG
279 blr
280 SET_SIZE(call_into_lisp)
281
282
283 GFUNCDEF(call_into_c)
284 /* We're kind of low on unboxed, non-dedicated registers here:
285 most of the unboxed registers may have outgoing C args in them.
286 CFUNC is going to have to go in the CTR in a moment, anyway
287 so we'll free it up soon. reg_NFP is preserved by lisp if it
288 has a meaningful value in it, so we can use it. reg_NARGS is
289 free when it's not holding a copy of the "real" reg_NL3, which
290 gets tied up by the pseudo-atomic mechanism */
291 mtctr reg_CFUNC
292 mflr reg_LIP
293 /* Build a lisp stack frame */
294 mr reg_OCFP,reg_CFP
295 mr reg_CFP,reg_CSP
296 la reg_CSP,32(reg_CSP)
297 stw reg_OCFP,0(reg_CFP)
298 stw reg_CODE,8(reg_CFP)
299 /* The pseudo-atomic mechanism wants to use reg_NL3, but that
300 may be an outgoing C argument. Copy reg_NL3 to something that's
301 unboxed and -not- one of the C argument registers */
302 mr reg_NARGS,reg_NL3
303
304 /* Turn on pseudo-atomic */
305 la reg_ALLOC,4(reg_ALLOC)
306
307 /* Convert the return address to an offset and save it on the stack. */
308 sub reg_NFP,reg_LIP,reg_CODE
309 la reg_NFP,type_OtherPointer(reg_NFP)
310 stw reg_NFP,4(reg_CFP)
311
312 /* Store Lisp state */
313 clrrwi reg_NFP,reg_ALLOC,3
314 store(reg_NFP,reg_CFUNC,_current_dynamic_space_free_pointer)
315 /* load(reg_CFUNC,current_thread) */
316
317 store(reg_BSP,reg_CFUNC,_current_binding_stack_pointer)
318 store(reg_CSP,reg_CFUNC,_current_control_stack_pointer)
319 store(reg_CFP,reg_CFUNC,_current_control_frame_pointer)
320
321 /* No longer in Lisp */
322 store(reg_CSP,reg_CFUNC,_foreign_function_call_active)
323 /* load(reg_POLL,saver2) */
324 /* Disable pseudo-atomic; check pending interrupt */
325 andi. reg_NL3, reg_ALLOC, 1
326 subi reg_ALLOC, reg_ALLOC, 4
327 twnei reg_NL3, 0
328
329 mr reg_NL3,reg_NARGS
330
331 /* PowerOpen (i.e. OS X) requires the callee address in r12
332 (a.k.a. CFUNC), so move it back there, too. */
333 mfctr reg_CFUNC
334 /* Into C we go. */
335 bctrl
336
337 /* Re-establish NIL */
338 lis reg_NULL,hi16(NIL)
339 ori reg_NULL,reg_NULL,lo16(NIL)
340 /* And reg_ZERO */
341 li reg_ZERO,0
342
343 /* If we GC'ed during the FF code (as the result of a callback ?)
344 the tagged lisp registers may now contain garbage (since the
345 registers were saved by C and not seen by the GC.) Put something
346 harmless in all such registers before allowing an interrupt */
347 li reg_CODE,0
348 li reg_CNAME,0
349 li reg_LEXENV,0
350 /* reg_OCFP was pointing to a control stack frame & was preserved by C */
351 li reg_LRA,0
352 li reg_A0,0
353 li reg_A1,0
354 li reg_A2,0
355 li reg_A3,0
356 li reg_L0,0
357 li reg_L1,0
358 li reg_LIP,0
359
360 /* Atomic ... */
361 #if 0
362 li reg_NL3,-4
363 #endif
364 li reg_ALLOC,4
365
366 /* No long in foreign function call. */
367 store(reg_ZERO,reg_NL2,_foreign_function_call_active)
368
369 /* The free pointer may have moved */
370 load(reg_NL4,_current_dynamic_space_free_pointer)
371 add reg_ALLOC,reg_ALLOC,reg_NL4
372
373 /* The BSP wasn't preserved by C, so load it */
374 load(reg_BSP,_current_binding_stack_pointer)
375
376 /* Other lisp stack/frame pointers were preserved by C.
377 I can't imagine why they'd have moved */
378
379 /* Get the return address back. */
380 lwz reg_LIP,4(reg_CFP)
381 lwz reg_CODE,8(reg_CFP)
382 add reg_LIP,reg_CODE,reg_LIP
383 la reg_LIP,-type_OtherPointer(reg_LIP)
384
385 /* No longer atomic */
386 andi. reg_NL3, reg_ALLOC, 1
387 subi reg_ALLOC, reg_ALLOC, 4
388 twnei reg_NL3, 0
389
390 mtlr reg_LIP
391
392 /* Reset the lisp stack. */
393 mr reg_CSP,reg_CFP
394 mr reg_CFP,reg_OCFP
395
396 /* And back into Lisp. */
397 blr
398
399 SET_SIZE(call_into_c)
400
401 GFUNCDEF(xundefined_tramp)
402 .globl _undefined_tramp
403 .byte 0
404 _undefined_tramp:
405 .byte 0, 0, type_FunctionHeader
406 .long _undefined_tramp /* self slot */
407 .long NIL /* next slot */
408 .long NIL /* name slot */
409 .long NIL /* arglist slot */
410 .long NIL /* type slot */
411
412 twllei reg_ZERO,trap_Cerror
413 /* Number of argument bytes */
414 .byte 4
415 .byte UNDEFINED_SYMBOL_ERROR
416 /* Escape to create 16bit number from following two bytes,
417 in little-endian order */
418 .byte 254
419 .byte SC_OFFSET_LO(sc_DescriptorReg, reg_FDEFN_NUM)
420 .byte SC_OFFSET_HI(sc_DescriptorReg, reg_FDEFN_NUM)
421 /*
422 .byte sc_DescriptorReg+0x40
423 .byte 1
424 */
425 .align 2
426 1: lwz reg_CODE,FDEFN_RAW_ADDR_OFFSET(reg_FDEFN)
427 la reg_LIP,FUNCTION_CODE_OFFSET(reg_CODE)
428 mtctr reg_LIP
429 bctr
430
431 mr reg_CSP, reg_CFP
432 b 1b
433
434 SET_SIZE(xundefined_tramp)
435
436 GFUNCDEF(xclosure_tramp)
437 .globl _closure_tramp
438 .byte 0
439 _closure_tramp:
440 .byte 0,0,type_FunctionHeader /* Header */
441 .long _closure_tramp
442 .long NIL
443 .long NIL
444 .long NIL
445 .long NIL
446
447 lwz reg_LEXENV,FDEFN_FUNCTION_OFFSET(reg_FDEFN)
448 lwz reg_CODE,CLOSURE_FUNCTION_OFFSET(reg_LEXENV)
449 la reg_LIP,FUNCTION_CODE_OFFSET(reg_CODE)
450 mtctr reg_LIP
451 bctr
452
453 SET_SIZE(xclosure_tramp)
454
455 /*
456 * Function-end breakpoint magic. See MAKE-BOGUS-LRA in
457 * code/debug-int.lisp.
458 */
459 .text
460 .align 3
461 .globl _function_end_breakpoint_guts
462 _function_end_breakpoint_guts:
463 .long type_ReturnPcHeader
464 b 1f
465 /* This NOP is necessary for the return convention, I think */
466 nop
467 /*
468 * Are these really necessary? I'm cargo-culting from the sparc port
469 */
470 mr reg_OCFP, reg_CSP
471 addi reg_CSP, reg_CSP, 4
472 li reg_NARGS, 4
473 mr reg_A1, reg_NULL
474 mr reg_A2, reg_NULL
475 mr reg_A3, reg_NULL
476 1:
477 .globl _function_end_breakpoint_trap
478 _function_end_breakpoint_trap:
479 twllei reg_ZERO, trap_FunctionEndBreakpoint
480 b 1b
481 .globl _function_end_breakpoint_end
482 _function_end_breakpoint_end:
483
484
485 GFUNCDEF(ppc_flush_cache_line)
486 dcbf 0,REG(3)
487 sync
488 icbi 0,REG(3)
489 sync
490 isync
491 blr
492 SET_SIZE(ppc_flush_cache_line)
493
494 GFUNCDEF(do_pending_interrupt)
495 twllei reg_ZERO, trap_PendingInterrupt
496 blr
497 SET_SIZE(do_pending_interrupt)
498
499 #ifdef LINKAGE_TABLE
500 /*
501 * Call into C code to resolve a linkage entry.
502 *
503 * We get here by Lisp calling call_into_c with an address of the
504 * desired function which is contained in the register reg_CFUNC (aka
505 * %i4, aka %r28). This is the address of the entry in the linkage
506 * table, which is what we need to figure out what function we really
507 * wanted.
508 *
509 * Note that because we get here from call_into_c, all necessary live
510 * registers have been saved, including FP registers. Hence, no need
511 * to save them.
512 */
513 .globl _lazy_resolve_linkage
514 GFUNCDEF(resolve_linkage_tramp)
515 /*
516 * We need to call lazy_resolve_linkage. reg_A0 (= r24)
517 * (see ppc-arch.c) contains the address of the linkage entry.
518 */
519 /*
520 * Need to save all parameter regs to the stack because we
521 * need them for later. We save the FP registers too. (Do
522 * we really need to? lazy_resolve_linkage shouldn't call
523 * anything that uses FP registers. It's safe to do so.)
524 */
525 subi r1, r1, 8*4+8+8*13
526 stfd f1, 0(r1)
527 stfd f2, 8(r1)
528 stfd f3, 16(r1)
529 stfd f4, 24(r1)
530 stfd f5, 32(r1)
531 stfd f6, 40(r1)
532 stfd f7, 48(r1)
533 stfd f8, 56(r1)
534 stfd f9, 64(r1)
535 stfd f10, 72(r1)
536 stfd f11, 80(r1)
537 stfd f12, 88(r1)
538 stfd f13, 96(r1)
539
540 stw r3, 104+0(r1)
541 stw r4, 104+4(r1)
542 stw r5, 104+8(r1)
543 stw r6, 104+12(r1)
544 stw r7, 104+16(r1)
545 stw r8, 104+20(r1)
546 stw r9, 104+24(r1)
547 stw r10, 104+28(r1)
548
549
550 mr reg_NL0, reg_A0
551
552 stwu r1, (-(24+4))(r1)
553 /*
554 * At this point reg_NIL should be available to us.
555 * Call lazy_resolve_linkage to figure out the real function address.
556 */
557 lis reg_NULL, hi16(_lazy_resolve_linkage)
558 ori reg_NULL, reg_NULL, lo16(_lazy_resolve_linkage)
559 mtctr reg_NULL
560 mflr reg_CODE
561 bctrl
562
563 addi r1,r1,24+4
564
565 /*
566 * The desired function is in r3 (NL0), so save it
567 * and restore the real arg parameters
568 */
569
570 mtctr reg_NL0
571 lfd f1, 0(r1)
572 lfd f2, 8(r1)
573 lfd f3, 16(r1)
574 lfd f4, 24(r1)
575 lfd f5, 32(r1)
576 lfd f6, 40(r1)
577 lfd f7, 48(r1)
578 lfd f8, 56(r1)
579 lfd f9, 64(r1)
580 lfd f10, 72(r1)
581 lfd f11, 80(r1)
582 lfd f12, 88(r1)
583 lfd f13, 96(r1)
584
585 lwz r3, 104+0(r1)
586 lwz r4, 104+4(r1)
587 lwz r5, 104+8(r1)
588 lwz r6, 104+12(r1)
589 lwz r7, 104+16(r1)
590 lwz r8, 104+20(r1)
591 lwz r9, 104+24(r1)
592 lwz r10, 104+28(r1)
593
594 addi r1,r1,8*4+8+8*13
595
596 /*
597 * Got it, so we can now jump directly to the desired function.
598 * reg_NL0 contains the result. Restore the stack and go!
599 */
600
601 mtlr reg_CODE
602
603 /* Back to C */
604 /* mtlr reg_CODE*/
605 bctr
606
607 SET_SIZE(resolve_linkage_tramp)
608
609
610 /*
611 * When we get called, r3 (reg_NL0) contains the address of the
612 * data_vector object which is a string naming the bad symbol.
613 */
614 GFUNCDEF(undefined_foreign_symbol_trap)
615
616 /*
617 Need to restore all the global registers with the Lisp values that
618 were saved away in call_into_c. (This routine is only called from
619 os_link_one_symbol, which is called from resolve_linkage_tramp, which
620 is called from call_into_c.)
621
622 The global registers are volatile across function calls, so who
623 knows what values have been they contain now!
624
625 */
626
627 load(reg_ALLOC, _current_dynamic_space_free_pointer)
628 load(reg_BSP, _current_binding_stack_pointer)
629 load(reg_CSP, _current_control_stack_pointer)
630 load(reg_CFP, _current_control_frame_pointer)
631
632 lis reg_NULL,hi16(NIL)
633 ori reg_NULL,reg_NULL,lo16(NIL)
634 /* And reg_ZERO */
635 li reg_ZERO,0
636
637 mr reg_A0, reg_NL0
638 twllei reg_ZERO, trap_Error
639 .byte 4 /* Number of argument bytes */
640 .byte UNDEFINED_FOREIGN_SYMBOL_ERROR
641 /* Escape to create 16bit number from following two bytes, in
642 little-endian order */
643 .byte 254
644 .byte SC_OFFSET_LO(sc_DescriptorReg, reg_A0_NUM)
645 .byte SC_OFFSET_HI(sc_DescriptorReg, reg_A0_NUM)
646 .align 4
647
648 #endif
649
650 #ifdef GENCGC
651 .globl _fpu_save
652 GFUNCDEF(fpu_save)
653 stfd f1, 0(r3)
654 stfd f2, 8(r3)
655 stfd f3, 16(r3)
656 stfd f4, 24(r3)
657 stfd f5, 32(r3)
658 stfd f6, 40(r3)
659 stfd f7, 48(r3)
660 stfd f8, 56(r3)
661 stfd f9, 64(r3)
662 stfd f10, 72(r3)
663 stfd f11, 80(r3)
664 stfd f12, 88(r3)
665 stfd f13, 96(r3)
666 stfd f14, 104(r3)
667 stfd f15, 112(r3)
668 stfd f16, 120(r3)
669 stfd f17, 128(r3)
670 stfd f18, 136(r3)
671 stfd f19, 144(r3)
672 stfd f20, 152(r3)
673 stfd f21, 160(r3)
674 stfd f22, 168(r3)
675 stfd f23, 176(r3)
676 stfd f24, 184(r3)
677 stfd f25, 192(r3)
678 stfd f26, 200(r3)
679 stfd f27, 208(r3)
680 stfd f28, 216(r3)
681 stfd f29, 224(r3)
682 stfd f30, 232(r3)
683 stfd f31, 240(r3)
684 blr
685 SET_SIZE(fpu_save)
686
687 .globl _fpu_restore
688 GFUNCDEF(fpu_restore)
689 lfd f1, 0(r3)
690 lfd f2, 8(r3)
691 lfd f3, 16(r3)
692 lfd f4, 24(r3)
693 lfd f5, 32(r3)
694 lfd f6, 40(r3)
695 lfd f7, 48(r3)
696 lfd f8, 56(r3)
697 lfd f9, 64(r3)
698 lfd f10, 72(r3)
699 lfd f11, 80(r3)
700 lfd f12, 88(r3)
701 lfd f13, 96(r3)
702 lfd f14, 104(r3)
703 lfd f15, 112(r3)
704 lfd f16, 120(r3)
705 lfd f17, 128(r3)
706 lfd f18, 136(r3)
707 lfd f19, 144(r3)
708 lfd f20, 152(r3)
709 lfd f21, 160(r3)
710 lfd f22, 168(r3)
711 lfd f23, 176(r3)
712 lfd f24, 184(r3)
713 lfd f25, 192(r3)
714 lfd f26, 200(r3)
715 lfd f27, 208(r3)
716 lfd f28, 216(r3)
717 lfd f29, 224(r3)
718 lfd f30, 232(r3)
719 lfd f31, 240(r3)
720 blr
721 SET_SIZE(fpu_restore)
722
723 #endif

  ViewVC Help
Powered by ViewVC 1.1.5