/[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.8 - (hide annotations)
Fri Mar 18 05:30:50 2005 UTC (9 years, 1 month ago) by rtoy
Branch: MAIN
CVS Tags: snapshot-2005-04
Changes since 1.7: +26 -15 lines
Port Helmut's trace/known-return to ppc.  Fix some bugs along the way
as well.

lisp/breakpoint.c:
o Enable function-end stuff in compute_offset for DARWIN too.
o Lots of printf's so we can see what's happening on ppc since gdb is
  majorly broken there.

lisp/ppc-assem.S:
o Actually implement the function-end breakpoint template.  Basically
  copied the sparc version, with appropriate mods.

lisp/ppc-arch.c:
o Add TWLLEI_R0 macro to create the appropriate trap instructions that
  we need, and use as appropriate.
o arch_install_breakpoint was actually broken and installed a twllgei
  instruction instead of twllei.
o arch_do_displaced_inst was also broken.  It didn't install the
  after-break-point trap after the breakpoint trap.  And it also
  didn't continue running the code and returned instead.  That's
  wrong.
o The trap_AfterBreakpoint case in sigill_handler was inserting the
  wrong instruction back.  (Probably too much copying of the sparc
  port.)
1 pmai 1.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     add reg_ALLOC,reg_ALLOC,reg_NL3
217     twlti reg_ALLOC,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 rtoy 1.7 #ifdef PPC_FUN_HACK
236 pmai 1.1 mtctr reg_CODE
237     #else
238     addi reg_LIP,reg_CODE,6*4-type_FunctionPointer
239     mtctr reg_LIP
240     #endif
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     add reg_ALLOC,reg_ALLOC,reg_NL3
274     twlti reg_ALLOC,0
275    
276     /* Back to C */
277     C_FULL_EPILOG
278     blr
279     SET_SIZE(call_into_lisp)
280    
281    
282     GFUNCDEF(call_into_c)
283     /* We're kind of low on unboxed, non-dedicated registers here:
284     most of the unboxed registers may have outgoing C args in them.
285     CFUNC is going to have to go in the CTR in a moment, anyway
286     so we'll free it up soon. reg_NFP is preserved by lisp if it
287     has a meaningful value in it, so we can use it. reg_NARGS is
288     free when it's not holding a copy of the "real" reg_NL3, which
289     gets tied up by the pseudo-atomic mechanism */
290     mtctr reg_CFUNC
291     mflr reg_LIP
292     /* Build a lisp stack frame */
293     mr reg_OCFP,reg_CFP
294     mr reg_CFP,reg_CSP
295     la reg_CSP,32(reg_CSP)
296     stw reg_OCFP,0(reg_CFP)
297     stw reg_CODE,8(reg_CFP)
298     /* The pseudo-atomic mechanism wants to use reg_NL3, but that
299     may be an outgoing C argument. Copy reg_NL3 to something that's
300     unboxed and -not- one of the C argument registers */
301     mr reg_NARGS,reg_NL3
302    
303     /* Turn on pseudo-atomic */
304     li reg_NL3,-4
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     add reg_ALLOC,reg_ALLOC,reg_NL3
326     twlti reg_ALLOC,0
327     mr reg_NL3,reg_NARGS
328    
329     /* PowerOpen (i.e. OS X) requires the callee address in r12
330     (a.k.a. CFUNC), so move it back there, too. */
331     mfctr reg_CFUNC
332     /* Into C we go. */
333     bctrl
334    
335     /* Re-establish NIL */
336     lis reg_NULL,hi16(NIL)
337     ori reg_NULL,reg_NULL,lo16(NIL)
338     /* And reg_ZERO */
339     li reg_ZERO,0
340    
341     /* If we GC'ed during the FF code (as the result of a callback ?)
342     the tagged lisp registers may now contain garbage (since the
343     registers were saved by C and not seen by the GC.) Put something
344     harmless in all such registers before allowing an interrupt */
345     li reg_CODE,0
346     li reg_CNAME,0
347     li reg_LEXENV,0
348     /* reg_OCFP was pointing to a control stack frame & was preserved by C */
349     li reg_LRA,0
350     li reg_A0,0
351     li reg_A1,0
352     li reg_A2,0
353     li reg_A3,0
354     li reg_L0,0
355     li reg_L1,0
356     li reg_L2,0
357     li reg_LIP,0
358    
359     /* Atomic ... */
360     li reg_NL3,-4
361     li reg_ALLOC,4
362    
363     /* No long in foreign function call. */
364     store(reg_ZERO,reg_NL2,_foreign_function_call_active)
365    
366     /* The free pointer may have moved */
367     load(reg_NL4,_current_dynamic_space_free_pointer)
368     add reg_ALLOC,reg_ALLOC,reg_NL4
369    
370     /* The BSP wasn't preserved by C, so load it */
371     load(reg_BSP,_current_binding_stack_pointer)
372    
373     /* Other lisp stack/frame pointers were preserved by C.
374     I can't imagine why they'd have moved */
375    
376     /* Get the return address back. */
377     lwz reg_LIP,4(reg_CFP)
378     lwz reg_CODE,8(reg_CFP)
379     add reg_LIP,reg_CODE,reg_LIP
380     la reg_LIP,-type_OtherPointer(reg_LIP)
381    
382     /* No longer atomic */
383     add reg_ALLOC,reg_ALLOC,reg_NL3
384     twlti reg_ALLOC,0
385     mtlr reg_LIP
386    
387     /* Reset the lisp stack. */
388     mr reg_CSP,reg_CFP
389     mr reg_CFP,reg_OCFP
390    
391     /* And back into Lisp. */
392     blr
393    
394     SET_SIZE(call_into_c)
395    
396     GFUNCDEF(xundefined_tramp)
397     .globl _undefined_tramp
398     .byte 0,0,0,type_FunctionHeader
399    
400 rtoy 1.7 #ifdef PPC_FUN_HACK
401 rtoy 1.4 /*
402     * The next 4 bytes are the encoding for a PPC jump instruction.
403     * The jump should go to the twllei instruction below.
404     */
405 pmai 1.1 .byte 18<<2
406     _undefined_tramp:
407 rtoy 1.3 .byte 0,0,24
408 rtoy 1.7 #endif
409 pmai 1.1 .long _undefined_tramp
410     .long NIL
411     .long NIL
412     .long NIL
413     .long NIL
414 rtoy 1.7 #ifndef PPC_FUN_HACK
415     _undefined_tramp:
416     #endif
417 pmai 1.1 twllei reg_ZERO,trap_Cerror
418 rtoy 1.4 /* Number of argument bytes */
419 rtoy 1.2 .byte 4
420     .byte UNDEFINED_SYMBOL_ERROR
421 rtoy 1.4 /* Escape to create 16bit number from following two bytes,
422     in little-endian order */
423 rtoy 1.2 .byte 254
424 rtoy 1.4 .byte SC_OFFSET_LO(sc_DescriptorReg, reg_FDEFN_NUM)
425     .byte SC_OFFSET_HI(sc_DescriptorReg, reg_FDEFN_NUM)
426     /*
427 rtoy 1.2 .byte sc_DescriptorReg+0x40
428     .byte 1
429 rtoy 1.4 */
430 pmai 1.1 .align 2
431     #ifdef PPC_FUN_HACK_MAYBE
432     1: lwz reg_CODE,FDEFN_RAW_ADDR_OFFSET(reg_CNAME)
433     #else
434     1: lwz reg_CODE,FDEFN_RAW_ADDR_OFFSET(reg_FDEFN)
435     #endif
436     la reg_LIP,FUNCTION_CODE_OFFSET(reg_CODE)
437     mtctr reg_LIP
438     bctr
439 rtoy 1.2
440     mr reg_CSP, reg_CFP
441     b 1b
442 pmai 1.1
443     SET_SIZE(xundefined_tramp)
444    
445     GFUNCDEF(xclosure_tramp)
446     .globl _closure_tramp
447     .byte 0,0,0,type_FunctionHeader
448 rtoy 1.7 #ifdef PPC_FUN_HACK
449 pmai 1.1 .byte 18<<2
450     _closure_tramp:
451     .byte 0,0,24
452 rtoy 1.7 #endif
453 pmai 1.1 .long _closure_tramp
454     .long NIL
455     .long NIL
456     .long NIL
457     .long NIL
458 rtoy 1.7 #ifndef PPC_FUN_HACK
459     _closure_tramp:
460     #endif
461 pmai 1.1 #ifdef PPC_FUN_HACK_MAYBE
462     lwz reg_LEXENV,FDEFN_FUNCTION_OFFSET(reg_CNAME)
463     #else
464     lwz reg_LEXENV,FDEFN_FUNCTION_OFFSET(reg_FDEFN)
465     #endif
466     lwz reg_CODE,CLOSURE_FUNCTION_OFFSET(reg_LEXENV)
467     la reg_LIP,FUNCTION_CODE_OFFSET(reg_CODE)
468     mtctr reg_LIP
469     bctr
470    
471     SET_SIZE(xclosure_tramp)
472    
473 rtoy 1.8 /*
474     * Function-end breakpoint magic. See MAKE-BOGUS-LRA in
475     * code/debug-int.lisp.
476     */
477     .text
478     .align 3
479     .globl _function_end_breakpoint_guts
480     _function_end_breakpoint_guts:
481     .long type_ReturnPcHeader
482     b 1f
483     /*
484     * Are these really necessary? I'm cargo-culting from the sparc port
485     */
486     mr reg_OCFP, reg_CSP
487     addi reg_CSP, reg_CSP, 4
488     li reg_NARGS, 4
489     mr reg_A1, reg_NULL
490     mr reg_A2, reg_NULL
491     mr reg_A3, reg_NULL
492     1:
493     .globl _function_end_breakpoint_trap
494     _function_end_breakpoint_trap:
495     twllei reg_ZERO, trap_FunctionEndBreakpoint
496     b 1b
497     .globl _function_end_breakpoint_end
498     _function_end_breakpoint_end:
499 pmai 1.1
500    
501     GFUNCDEF(ppc_flush_cache_line)
502     dcbf 0,REG(3)
503     sync
504     icbi 0,REG(3)
505     sync
506     isync
507     blr
508     SET_SIZE(ppc_flush_cache_line)
509    
510 rtoy 1.5 #ifdef LINKAGE_TABLE
511     /*
512     * Call into C code to resolve a linkage entry.
513     *
514     * We get here by Lisp calling call_into_c with an address of the
515     * desired function which is contained in the register reg_CFUNC (aka
516     * %i4, aka %r28). This is the address of the entry in the linkage
517     * table, which is what we need to figure out what function we really
518     * wanted.
519     *
520     * Note that because we get here from call_into_c, all necessary live
521     * registers have been saved, including FP registers. Hence, no need
522     * to save them.
523     */
524     .globl _lazy_resolve_linkage
525     GFUNCDEF(resolve_linkage_tramp)
526     /*
527     * We need to call lazy_resolve_linkage. reg_A0 (= r24)
528     * (see ppc-arch.c) contains the address of the linkage entry.
529     */
530     /*
531     * Need to save all parameter regs to the stack because we
532 rtoy 1.6 * need them for later. We save the FP registers too. (Do
533     * we really need to? lazy_resolve_linkage shouldn't call
534     * anything that uses FP registers. It's safe to do so.)
535 rtoy 1.5 */
536 rtoy 1.6 subi r1, r1, 8*4+8+8*13
537     stfd f1, 0(r1)
538     stfd f2, 8(r1)
539     stfd f3, 16(r1)
540     stfd f4, 24(r1)
541     stfd f5, 32(r1)
542     stfd f6, 40(r1)
543     stfd f7, 48(r1)
544     stfd f8, 56(r1)
545     stfd f9, 64(r1)
546     stfd f10, 72(r1)
547     stfd f11, 80(r1)
548     stfd f12, 88(r1)
549     stfd f13, 96(r1)
550    
551     stw r3, 104+0(r1)
552     stw r4, 104+4(r1)
553     stw r5, 104+8(r1)
554     stw r6, 104+12(r1)
555     stw r7, 104+16(r1)
556     stw r8, 104+20(r1)
557     stw r9, 104+24(r1)
558     stw r10, 104+28(r1)
559    
560 rtoy 1.5
561     mr reg_NL0, reg_A0
562    
563     stwu r1, (-(24+4))(r1)
564     /*
565     * At this point reg_NIL should be available to us.
566     * Call lazy_resolve_linkage to figure out the real function address.
567     */
568     lis reg_NULL, hi16(_lazy_resolve_linkage)
569     ori reg_NULL, reg_NULL, lo16(_lazy_resolve_linkage)
570     mtctr reg_NULL
571     mflr reg_CODE
572     bctrl
573    
574     addi r1,r1,24+4
575    
576     /*
577     * The desired function is in r3 (NL0), so save it
578     * and restore the real arg parameters
579     */
580    
581     mtctr reg_NL0
582 rtoy 1.6 lfd f1, 0(r1)
583     lfd f2, 8(r1)
584     lfd f3, 16(r1)
585     lfd f4, 24(r1)
586     lfd f5, 32(r1)
587     lfd f6, 40(r1)
588     lfd f7, 48(r1)
589     lfd f8, 56(r1)
590     lfd f9, 64(r1)
591     lfd f10, 72(r1)
592     lfd f11, 80(r1)
593     lfd f12, 88(r1)
594     lfd f13, 96(r1)
595    
596     lwz r3, 104+0(r1)
597     lwz r4, 104+4(r1)
598     lwz r5, 104+8(r1)
599     lwz r6, 104+12(r1)
600     lwz r7, 104+16(r1)
601     lwz r8, 104+20(r1)
602     lwz r9, 104+24(r1)
603     lwz r10, 104+28(r1)
604    
605     addi r1,r1,8*4+8+8*13
606 rtoy 1.5
607     /*
608     * Got it, so we can now jump directly to the desired function.
609     * reg_NL0 contains the result. Restore the stack and go!
610     */
611    
612     mtlr reg_CODE
613    
614     /* Back to C */
615     /* mtlr reg_CODE*/
616     bctr
617    
618     SET_SIZE(resolve_linkage_tramp)
619    
620    
621     /*
622     * When we get called, r3 (reg_NL0) contains the address of the
623     * data_vector object which is a string naming the bad symbol.
624     */
625     GFUNCDEF(undefined_foreign_symbol_trap)
626    
627     /*
628     Need to restore all the global registers with the Lisp values that
629     were saved away in call_into_c. (This routine is only called from
630     os_link_one_symbol, which is called from resolve_linkage_tramp, which
631     is called from call_into_c.)
632    
633     The global registers are volatile across function calls, so who
634     knows what values have been they contain now!
635    
636     */
637    
638     load(reg_ALLOC, _current_dynamic_space_free_pointer)
639     load(reg_BSP, _current_binding_stack_pointer)
640     load(reg_CSP, _current_control_stack_pointer)
641     load(reg_CFP, _current_control_frame_pointer)
642    
643     lis reg_NULL,hi16(NIL)
644     ori reg_NULL,reg_NULL,lo16(NIL)
645     /* And reg_ZERO */
646     li reg_ZERO,0
647    
648     mr reg_NL0, reg_A0
649     twllei reg_ZERO, trap_Error
650     .byte 4 /* Number of argument bytes */
651     .byte UNDEFINED_FOREIGN_SYMBOL_ERROR
652     /* Escape to create 16bit number from following two bytes, in
653     little-endian order */
654     .byte 254
655     .byte SC_OFFSET_LO(sc_DescriptorReg, reg_A0_NUM)
656     .byte SC_OFFSET_HI(sc_DescriptorReg, reg_A0_NUM)
657     .align 4
658    
659     #endif

  ViewVC Help
Powered by ViewVC 1.1.5