/[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.6.2.2 - (show annotations)
Tue Apr 5 03:41:10 2005 UTC (9 years ago) by rtoy
Branch: ppc_gencgc_branch
CVS Tags: ppc_gencgc_snap_2005-05-14
Changes since 1.6.2.1: +40 -2 lines
Checkin the current code for gencgc.  This is a basic port of sparc
gencgc for ppc.  This is not yet functional.  Allocation seems to
work, but GC does not.  We're just making a checkpoint now.

compiler/ppc/macros.lisp:
o Update allocation macro to support gencgc.  Need a temp-tn as a
  scratch register for inline allocation.
o Update with-fixed-allocation to use allocation macro correctly for
  gencgc.

assembly/ppc/array.lisp:
o Update for new allocation macro for gencgc.

code/ppc-vm.lisp:
o Define *scavenge-read-only-space*

compiler/ppc/alloc.lisp:
compiler/ppc/array.lisp:
compiler/ppc/call.lisp:
o Update to use new allocation macro for gencgc.

compiler/ppc/parms.lisp:
o Add necessary static symbols to support gencgc.

lisp/Config.ppc_darwin:
o Update to build with gencgc as needed.

lisp/Darwin-os.c:
o Update C code for gencgc.  Mostly for checking if pointer is in the
  dynamic space.
o Many debugging printf's enabled.

lisp/gencgc.c:
o Adjust sparc version appropriately for ppc.
o Enable many gencgc self-checks.

lisp/gencgc.h:
o Update PAGE_SIZE for ppc, which is 4K.

lisp/ppc-arch.c:
o Add necessary code to handle the allocation traps for gencgc.
  Basically ported sparc version for ppc.

lisp/ppc-assem.S:
o The way pseudo-atomic is done has been changed, so make the assembly
  code match.  PA is now more like sparc where the LSB is the
  PA-interrupted bit.
o do_pending_interrupt may need work.

lisp/ppc-validate.h:
o Make the READ_ONLY_SPACE_SIZE right.
o Define CONTROL_STACK_END.

lisp/purify.c:
o Enable debugging printfs
o Adjust purify for gencgc, basically copying sparc version.
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 #define FULL_FRAME_SIZE FRAME_SIZE(FIRST_SAVE_GPR,FIRST_SAVE_FPR,8,1)
62 #else
63 #define FRAME_SIZE(first_g,first_f,out_arg_words,savecr) \
64 (NFPR_SAVE_BYTES(first_f)+ NGPR_SAVE_BYTES(first_g)+ FRAME_ARG_BYTES(out_arg_words+savecr))
65 #define SAVE_FPR(n) stfd n,-8*(32-(n))(11)
66 #define SAVE_GPR(n) stw n,-4*(32-(n))(11)
67 #define FULL_FRAME_SIZE FRAME_SIZE(FIRST_SAVE_GPR,FIRST_SAVE_FPR,0,1)
68 #endif
69
70 #if defined DARWIN
71 #define RESTORE_FPR(n) lfd f##n,-8*(32- n)(r11)
72 #define RESTORE_GPR(n) lwz r##n,-4*(32- n)(r11)
73 #else
74 #define RESTORE_FPR(n) lfd f##n,-8*(32-(r##n))(r11)
75 #define RESTORE_GPR(n) lwz r##n,-4*(32-(r##n))(r11)
76 #endif
77 #define C_FULL_PROLOG \
78 nop @\
79 nop @ \
80 mfcr REG(0) @ \
81 stw REG(0),4(REG(1)) @ \
82 mflr REG(0) @ \
83 stw REG(0),8(REG(1)) @ \
84 mr REG(11),REG(1) @ \
85 stwu REG(1),-FULL_FRAME_SIZE(REG(1)) @ \
86 SAVE_FPR(14) @ \
87 SAVE_FPR(15) @ \
88 SAVE_FPR(16) @ \
89 SAVE_FPR(17) @ \
90 SAVE_FPR(18) @ \
91 SAVE_FPR(19) @ \
92 SAVE_FPR(20) @ \
93 SAVE_FPR(21) @ \
94 SAVE_FPR(22) @ \
95 SAVE_FPR(23) @ \
96 SAVE_FPR(24) @ \
97 SAVE_FPR(25) @ \
98 SAVE_FPR(26) @ \
99 SAVE_FPR(27) @ \
100 SAVE_FPR(28) @ \
101 SAVE_FPR(29) @ \
102 SAVE_FPR(30) @ \
103 SAVE_FPR(31) @ \
104 la REG(11),-NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(11)) @ \
105 SAVE_GPR(13) @ \
106 SAVE_GPR(14) @ \
107 SAVE_GPR(15) @ \
108 SAVE_GPR(16) @ \
109 SAVE_GPR(17) @ \
110 SAVE_GPR(18) @ \
111 SAVE_GPR(19) @ \
112 SAVE_GPR(20) @ \
113 SAVE_GPR(21) @ \
114 SAVE_GPR(22) @ \
115 SAVE_GPR(23) @ \
116 SAVE_GPR(24) @ \
117 SAVE_GPR(25) @ \
118 SAVE_GPR(26) @ \
119 SAVE_GPR(27) @ \
120 SAVE_GPR(28) @ \
121 SAVE_GPR(29) @ \
122 SAVE_GPR(30) @ \
123 SAVE_GPR(31)
124
125
126 #define C_FULL_EPILOG \
127 la REG(11),FULL_FRAME_SIZE-NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(1)) @ \
128 RESTORE_GPR(13) @ \
129 RESTORE_GPR(14) @ \
130 RESTORE_GPR(15) @ \
131 RESTORE_GPR(16) @ \
132 RESTORE_GPR(17) @ \
133 RESTORE_GPR(18) @ \
134 RESTORE_GPR(19) @ \
135 RESTORE_GPR(20) @ \
136 RESTORE_GPR(21) @ \
137 RESTORE_GPR(22) @ \
138 RESTORE_GPR(23) @ \
139 RESTORE_GPR(24) @ \
140 RESTORE_GPR(25) @ \
141 RESTORE_GPR(26) @ \
142 RESTORE_GPR(27) @ \
143 RESTORE_GPR(28) @ \
144 RESTORE_GPR(29) @ \
145 RESTORE_GPR(30) @ \
146 RESTORE_GPR(31) @ \
147 la REG(11),NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(11)) @ \
148 RESTORE_FPR(14) @ \
149 RESTORE_FPR(15) @ \
150 RESTORE_FPR(16) @ \
151 RESTORE_FPR(17) @ \
152 RESTORE_FPR(18) @ \
153 RESTORE_FPR(19) @ \
154 RESTORE_FPR(20) @ \
155 RESTORE_FPR(21) @ \
156 RESTORE_FPR(22) @ \
157 RESTORE_FPR(23) @ \
158 RESTORE_FPR(24) @ \
159 RESTORE_FPR(25) @ \
160 RESTORE_FPR(26) @ \
161 RESTORE_FPR(27) @ \
162 RESTORE_FPR(28) @ \
163 RESTORE_FPR(29) @ \
164 RESTORE_FPR(30) @ \
165 RESTORE_FPR(31) @ \
166 lwz REG(1),0(REG(1)) @ \
167 lwz REG(0),4(REG(1)) @ \
168 mtcr REG(0) @ \
169 lwz REG(0),8(REG(1)) @ \
170 mtlr REG(0) @ \
171
172
173
174
175 .text
176
177 /*
178 * Function to transfer control into lisp. The lisp object to invoke is
179 * passed as the first argument, which puts it in NL0
180 */
181
182 GFUNCDEF(call_into_lisp)
183 C_FULL_PROLOG
184 /* store(reg_POLL,11,saver2) */
185 /* Initialize tagged registers */
186 li reg_ZERO,0
187 li reg_CODE,0
188 li reg_CNAME,0
189 li reg_LEXENV,0
190 li reg_FDEFN,0
191 li reg_OCFP,0
192 li reg_LRA,0
193 li reg_A0,0
194 li reg_A1,0
195 li reg_A2,0
196 li reg_A3,0
197 li reg_L0,0
198 li reg_L1,0
199 li reg_L2,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_NL3,-4
207 li reg_ALLOC,4
208 store(reg_ZERO,reg_NL4,_foreign_function_call_active)
209 load(reg_NL4,_current_dynamic_space_free_pointer)
210 add reg_ALLOC,reg_ALLOC,reg_NL4
211 load(reg_BSP,_current_binding_stack_pointer)
212 load(reg_CSP,_current_control_stack_pointer)
213 load(reg_OCFP,_current_control_frame_pointer)
214
215 /* No longer atomic, and check for interrupt */
216 #if 1
217 andi. reg_NL3, reg_ALLOC, 1
218 subi reg_ALLOC,reg_ALLOC,4
219 twnei reg_NL3, 0
220 #else
221 add reg_ALLOC,reg_ALLOC,reg_NL3
222 twlti reg_ALLOC,0
223 #endif
224 /* Pass in the arguments */
225
226 mr reg_CFP,reg_NL1
227 mr reg_LEXENV,reg_NL0
228 lwz reg_A0,0(reg_CFP)
229 lwz reg_A1,4(reg_CFP)
230 lwz reg_A2,8(reg_CFP)
231 lwz reg_A3,12(reg_CFP)
232
233 /* Calculate LRA */
234 lis reg_LRA,ha16(lra)
235 addi reg_LRA,reg_LRA,lo16(lra)
236 addi reg_LRA,reg_LRA,type_OtherPointer
237
238 /* Function is an indirect closure */
239 lwz reg_CODE,CLOSURE_FUNCTION_OFFSET(reg_LEXENV)
240 #ifdef PPC_FUN-HACK
241 mtctr reg_CODE
242 #else
243 addi reg_LIP,reg_CODE,6*4-type_FunctionPointer
244 mtctr reg_LIP
245 #endif
246 slwi reg_NARGS,reg_NL2,2
247 bctr
248 .align 3
249 lra:
250 .long type_ReturnPcHeader
251
252 /* Blow off any extra values. */
253 mr reg_CSP,reg_OCFP
254 nop
255
256 /* Return the one value. */
257
258 mr REG(3),reg_A0
259
260 /* Turn on pseudo-atomic */
261 li reg_NL3,-4
262 la reg_ALLOC,4(reg_ALLOC)
263
264 /* Store lisp state */
265 clrrwi reg_NL1,reg_ALLOC,3
266 store(reg_NL1,reg_NL2,_current_dynamic_space_free_pointer)
267 /* store(reg_POLL,reg_NL2,poll_flag) */
268 /* load(reg_NL2,current_thread) */
269 store(reg_BSP,reg_NL2,_current_binding_stack_pointer)
270 store(reg_CSP,reg_NL2,_current_control_stack_pointer)
271 store(reg_CFP,reg_NL2,_current_control_frame_pointer)
272 /* load(reg_POLL,saver2) */
273
274 /* No longer in Lisp. */
275 store(reg_NL1,reg_NL2,_foreign_function_call_active)
276
277 /* Check for interrupt */
278 #if 1
279 andi. reg_NL3, reg_ALLOC, 1
280 subi reg_ALLOC, reg_ALLOC, 4
281 twnei reg_NL3,0
282 #else
283 add reg_ALLOC,reg_ALLOC,reg_NL3
284 twlti reg_ALLOC,0
285 #endif
286 /* Back to C */
287 C_FULL_EPILOG
288 blr
289 SET_SIZE(call_into_lisp)
290
291
292 GFUNCDEF(call_into_c)
293 /* We're kind of low on unboxed, non-dedicated registers here:
294 most of the unboxed registers may have outgoing C args in them.
295 CFUNC is going to have to go in the CTR in a moment, anyway
296 so we'll free it up soon. reg_NFP is preserved by lisp if it
297 has a meaningful value in it, so we can use it. reg_NARGS is
298 free when it's not holding a copy of the "real" reg_NL3, which
299 gets tied up by the pseudo-atomic mechanism */
300 mtctr reg_CFUNC
301 mflr reg_LIP
302 /* Build a lisp stack frame */
303 mr reg_OCFP,reg_CFP
304 mr reg_CFP,reg_CSP
305 la reg_CSP,32(reg_CSP)
306 stw reg_OCFP,0(reg_CFP)
307 stw reg_CODE,8(reg_CFP)
308 /* The pseudo-atomic mechanism wants to use reg_NL3, but that
309 may be an outgoing C argument. Copy reg_NL3 to something that's
310 unboxed and -not- one of the C argument registers */
311 mr reg_NARGS,reg_NL3
312
313 /* Turn on pseudo-atomic */
314 li reg_NL3,-4
315 la reg_ALLOC,4(reg_ALLOC)
316
317 /* Convert the return address to an offset and save it on the stack. */
318 sub reg_NFP,reg_LIP,reg_CODE
319 la reg_NFP,type_OtherPointer(reg_NFP)
320 stw reg_NFP,4(reg_CFP)
321
322 /* Store Lisp state */
323 clrrwi reg_NFP,reg_ALLOC,3
324 store(reg_NFP,reg_CFUNC,_current_dynamic_space_free_pointer)
325 /* load(reg_CFUNC,current_thread) */
326
327 store(reg_BSP,reg_CFUNC,_current_binding_stack_pointer)
328 store(reg_CSP,reg_CFUNC,_current_control_stack_pointer)
329 store(reg_CFP,reg_CFUNC,_current_control_frame_pointer)
330
331 /* No longer in Lisp */
332 store(reg_CSP,reg_CFUNC,_foreign_function_call_active)
333 /* load(reg_POLL,saver2) */
334 /* Disable pseudo-atomic; check pending interrupt */
335 #if 1
336 andi. reg_NL3, reg_ALLOC, 1
337 subi reg_ALLOC, reg_ALLOC, 4
338 twnei reg_NL3, 0
339 #else
340 add reg_ALLOC,reg_ALLOC,reg_NL3
341 twlti reg_ALLOC,0
342 #endif
343 mr reg_NL3,reg_NARGS
344
345 /* PowerOpen (i.e. OS X) requires the callee address in r12
346 (a.k.a. CFUNC), so move it back there, too. */
347 mfctr reg_CFUNC
348 /* Into C we go. */
349 bctrl
350
351 /* Re-establish NIL */
352 lis reg_NULL,hi16(NIL)
353 ori reg_NULL,reg_NULL,lo16(NIL)
354 /* And reg_ZERO */
355 li reg_ZERO,0
356
357 /* If we GC'ed during the FF code (as the result of a callback ?)
358 the tagged lisp registers may now contain garbage (since the
359 registers were saved by C and not seen by the GC.) Put something
360 harmless in all such registers before allowing an interrupt */
361 li reg_CODE,0
362 li reg_CNAME,0
363 li reg_LEXENV,0
364 /* reg_OCFP was pointing to a control stack frame & was preserved by C */
365 li reg_LRA,0
366 li reg_A0,0
367 li reg_A1,0
368 li reg_A2,0
369 li reg_A3,0
370 li reg_L0,0
371 li reg_L1,0
372 li reg_L2,0
373 li reg_LIP,0
374
375 /* Atomic ... */
376 li reg_NL3,-4
377 li reg_ALLOC,4
378
379 /* No long in foreign function call. */
380 store(reg_ZERO,reg_NL2,_foreign_function_call_active)
381
382 /* The free pointer may have moved */
383 load(reg_NL4,_current_dynamic_space_free_pointer)
384 add reg_ALLOC,reg_ALLOC,reg_NL4
385
386 /* The BSP wasn't preserved by C, so load it */
387 load(reg_BSP,_current_binding_stack_pointer)
388
389 /* Other lisp stack/frame pointers were preserved by C.
390 I can't imagine why they'd have moved */
391
392 /* Get the return address back. */
393 lwz reg_LIP,4(reg_CFP)
394 lwz reg_CODE,8(reg_CFP)
395 add reg_LIP,reg_CODE,reg_LIP
396 la reg_LIP,-type_OtherPointer(reg_LIP)
397
398 /* No longer atomic */
399 #if 1
400 andi. reg_NL3, reg_ALLOC, 1
401 subi reg_ALLOC, reg_ALLOC, 4
402 twnei reg_NL3, 0
403 #else
404 add reg_ALLOC,reg_ALLOC,reg_NL3
405 twlti reg_ALLOC,0
406 #endif
407 mtlr reg_LIP
408
409 /* Reset the lisp stack. */
410 mr reg_CSP,reg_CFP
411 mr reg_CFP,reg_OCFP
412
413 /* And back into Lisp. */
414 blr
415
416 SET_SIZE(call_into_c)
417
418 GFUNCDEF(xundefined_tramp)
419 .globl _undefined_tramp
420 .byte 0,0,0,type_FunctionHeader
421
422 /*
423 * The next 4 bytes are the encoding for a PPC jump instruction.
424 * The jump should go to the twllei instruction below.
425 */
426 #if 0
427 .byte 18<<2
428 _undefined_tramp:
429 .byte 0,0,24
430 .long _undefined_tramp+1
431 #else
432 .long _xundefined_tramp + 1
433 #endif
434 .long NIL
435 .long NIL
436 .long NIL
437 .long NIL
438 #if 1
439 _undefined_tramp:
440 #endif
441 twllei reg_ZERO,trap_Cerror
442 /* Number of argument bytes */
443 .byte 4
444 .byte UNDEFINED_SYMBOL_ERROR
445 /* Escape to create 16bit number from following two bytes,
446 in little-endian order */
447 .byte 254
448 .byte SC_OFFSET_LO(sc_DescriptorReg, reg_FDEFN_NUM)
449 .byte SC_OFFSET_HI(sc_DescriptorReg, reg_FDEFN_NUM)
450 /*
451 .byte sc_DescriptorReg+0x40
452 .byte 1
453 */
454 .align 2
455 #ifdef PPC_FUN_HACK_MAYBE
456 1: lwz reg_CODE,FDEFN_RAW_ADDR_OFFSET(reg_CNAME)
457 #else
458 1: lwz reg_CODE,FDEFN_RAW_ADDR_OFFSET(reg_FDEFN)
459 #endif
460 la reg_LIP,FUNCTION_CODE_OFFSET(reg_CODE)
461 mtctr reg_LIP
462 bctr
463
464 mr reg_CSP, reg_CFP
465 b 1b
466
467 SET_SIZE(xundefined_tramp)
468
469 GFUNCDEF(xclosure_tramp)
470 .globl _closure_tramp
471 .byte 0,0,0,type_FunctionHeader
472 #if 0
473 .byte 18<<2
474 _closure_tramp:
475 .byte 0,0,24
476 .long _closure_tramp+1
477 #else
478 .long _xclosure_tramp+1
479 #endif
480 .long NIL
481 .long NIL
482 .long NIL
483 .long NIL
484 #if 1
485 _closure_tramp:
486 #endif
487 #ifdef PPC_FUN_HACK_MAYBE
488 lwz reg_LEXENV,FDEFN_FUNCTION_OFFSET(reg_CNAME)
489 #else
490 lwz reg_LEXENV,FDEFN_FUNCTION_OFFSET(reg_FDEFN)
491 #endif
492 lwz reg_CODE,CLOSURE_FUNCTION_OFFSET(reg_LEXENV)
493 la reg_LIP,FUNCTION_CODE_OFFSET(reg_CODE)
494 mtctr reg_LIP
495 bctr
496
497 SET_SIZE(xclosure_tramp)
498
499 GFUNCDEF(function_end_breakpoint_trap)
500 .long 0
501 SET_SIZE(function_end_breakpoint_trap)
502
503 GFUNCDEF(function_end_breakpoint)
504 .long 0
505 SET_SIZE(function_end_breakpoint)
506
507 GFUNCDEF(function_end_breakpoint_guts)
508 .long 0
509 SET_SIZE(function_end_breakpoint_guts)
510
511 GFUNCDEF(function_end_breakpoint_end)
512 .long 0
513 SET_SIZE(function_end_breakpoint_end)
514
515
516 GFUNCDEF(ppc_flush_cache_line)
517 dcbf 0,REG(3)
518 sync
519 icbi 0,REG(3)
520 sync
521 isync
522 blr
523 SET_SIZE(ppc_flush_cache_line)
524
525 GFUNCDEF(do_pending_interrupt)
526 .long 0
527 SET_SIZE(do_pending_interrupt)
528
529 #ifdef LINKAGE_TABLE
530 /*
531 * Call into C code to resolve a linkage entry.
532 *
533 * We get here by Lisp calling call_into_c with an address of the
534 * desired function which is contained in the register reg_CFUNC (aka
535 * %i4, aka %r28). This is the address of the entry in the linkage
536 * table, which is what we need to figure out what function we really
537 * wanted.
538 *
539 * Note that because we get here from call_into_c, all necessary live
540 * registers have been saved, including FP registers. Hence, no need
541 * to save them.
542 */
543 .globl _lazy_resolve_linkage
544 GFUNCDEF(resolve_linkage_tramp)
545 /*
546 * We need to call lazy_resolve_linkage. reg_A0 (= r24)
547 * (see ppc-arch.c) contains the address of the linkage entry.
548 */
549 /*
550 * Need to save all parameter regs to the stack because we
551 * need them for later. We save the FP registers too. (Do
552 * we really need to? lazy_resolve_linkage shouldn't call
553 * anything that uses FP registers. It's safe to do so.)
554 */
555 subi r1, r1, 8*4+8+8*13
556 stfd f1, 0(r1)
557 stfd f2, 8(r1)
558 stfd f3, 16(r1)
559 stfd f4, 24(r1)
560 stfd f5, 32(r1)
561 stfd f6, 40(r1)
562 stfd f7, 48(r1)
563 stfd f8, 56(r1)
564 stfd f9, 64(r1)
565 stfd f10, 72(r1)
566 stfd f11, 80(r1)
567 stfd f12, 88(r1)
568 stfd f13, 96(r1)
569
570 stw r3, 104+0(r1)
571 stw r4, 104+4(r1)
572 stw r5, 104+8(r1)
573 stw r6, 104+12(r1)
574 stw r7, 104+16(r1)
575 stw r8, 104+20(r1)
576 stw r9, 104+24(r1)
577 stw r10, 104+28(r1)
578
579
580 mr reg_NL0, reg_A0
581
582 stwu r1, (-(24+4))(r1)
583 /*
584 * At this point reg_NIL should be available to us.
585 * Call lazy_resolve_linkage to figure out the real function address.
586 */
587 lis reg_NULL, hi16(_lazy_resolve_linkage)
588 ori reg_NULL, reg_NULL, lo16(_lazy_resolve_linkage)
589 mtctr reg_NULL
590 mflr reg_CODE
591 bctrl
592
593 addi r1,r1,24+4
594
595 /*
596 * The desired function is in r3 (NL0), so save it
597 * and restore the real arg parameters
598 */
599
600 mtctr reg_NL0
601 lfd f1, 0(r1)
602 lfd f2, 8(r1)
603 lfd f3, 16(r1)
604 lfd f4, 24(r1)
605 lfd f5, 32(r1)
606 lfd f6, 40(r1)
607 lfd f7, 48(r1)
608 lfd f8, 56(r1)
609 lfd f9, 64(r1)
610 lfd f10, 72(r1)
611 lfd f11, 80(r1)
612 lfd f12, 88(r1)
613 lfd f13, 96(r1)
614
615 lwz r3, 104+0(r1)
616 lwz r4, 104+4(r1)
617 lwz r5, 104+8(r1)
618 lwz r6, 104+12(r1)
619 lwz r7, 104+16(r1)
620 lwz r8, 104+20(r1)
621 lwz r9, 104+24(r1)
622 lwz r10, 104+28(r1)
623
624 addi r1,r1,8*4+8+8*13
625
626 /*
627 * Got it, so we can now jump directly to the desired function.
628 * reg_NL0 contains the result. Restore the stack and go!
629 */
630
631 mtlr reg_CODE
632
633 /* Back to C */
634 /* mtlr reg_CODE*/
635 bctr
636
637 SET_SIZE(resolve_linkage_tramp)
638
639
640 /*
641 * When we get called, r3 (reg_NL0) contains the address of the
642 * data_vector object which is a string naming the bad symbol.
643 */
644 GFUNCDEF(undefined_foreign_symbol_trap)
645
646 /*
647 Need to restore all the global registers with the Lisp values that
648 were saved away in call_into_c. (This routine is only called from
649 os_link_one_symbol, which is called from resolve_linkage_tramp, which
650 is called from call_into_c.)
651
652 The global registers are volatile across function calls, so who
653 knows what values have been they contain now!
654
655 */
656
657 load(reg_ALLOC, _current_dynamic_space_free_pointer)
658 load(reg_BSP, _current_binding_stack_pointer)
659 load(reg_CSP, _current_control_stack_pointer)
660 load(reg_CFP, _current_control_frame_pointer)
661
662 lis reg_NULL,hi16(NIL)
663 ori reg_NULL,reg_NULL,lo16(NIL)
664 /* And reg_ZERO */
665 li reg_ZERO,0
666
667 mr reg_NL0, reg_A0
668 twllei reg_ZERO, trap_Error
669 .byte 4 /* Number of argument bytes */
670 .byte UNDEFINED_FOREIGN_SYMBOL_ERROR
671 /* Escape to create 16bit number from following two bytes, in
672 little-endian order */
673 .byte 254
674 .byte SC_OFFSET_LO(sc_DescriptorReg, reg_A0_NUM)
675 .byte SC_OFFSET_HI(sc_DescriptorReg, reg_A0_NUM)
676 .align 4
677
678 #endif

  ViewVC Help
Powered by ViewVC 1.1.5