/[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.12 - (hide annotations)
Fri Oct 21 02:36:42 2005 UTC (8 years, 6 months ago) by rtoy
Branch: MAIN
CVS Tags: snapshot-2005-11, snapshot-2005-12
Changes since 1.11: +2 -1 lines
The stack pointer is supposed to be on a 16-byte boundary, so make
sure FULL_FRAME_SIZE is a multiple of 16.  (From a patch to sbcl from
Cyrus Harmon.)
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 rtoy 1.11 _/**/x:
11 pmai 1.1 #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 rtoy 1.11 #define SAVE_FPR(n) stfd f/**/n,-8*(32- n)(r11)
60     #define SAVE_GPR(n) stw r/**/n,-4*(32- n)(r11)
61 rtoy 1.12 /* 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 pmai 1.1 #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 rtoy 1.11 #define RESTORE_FPR(n) lfd f/**/n,-8*(32- n)(r11)
73     #define RESTORE_GPR(n) lwz r/**/n,-4*(32- n)(r11)
74 pmai 1.1 #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_L2,0
201     li reg_LIP,0
202     lis reg_NULL,hi16(NIL)
203     ori reg_NULL,reg_NULL,lo16(NIL)
204    
205     /* Turn on pseudo-atomic */
206    
207 rtoy 1.10 #if 0
208 pmai 1.1 li reg_NL3,-4
209 rtoy 1.10 #endif
210 pmai 1.1 li reg_ALLOC,4
211     store(reg_ZERO,reg_NL4,_foreign_function_call_active)
212     load(reg_NL4,_current_dynamic_space_free_pointer)
213     add reg_ALLOC,reg_ALLOC,reg_NL4
214     load(reg_BSP,_current_binding_stack_pointer)
215     load(reg_CSP,_current_control_stack_pointer)
216     load(reg_OCFP,_current_control_frame_pointer)
217    
218     /* No longer atomic, and check for interrupt */
219 rtoy 1.10 andi. reg_NL3, reg_ALLOC, 1
220     subi reg_ALLOC,reg_ALLOC,4
221     twnei reg_NL3, 0
222    
223 pmai 1.1 /* Pass in the arguments */
224    
225     mr reg_CFP,reg_NL1
226     mr reg_LEXENV,reg_NL0
227     lwz reg_A0,0(reg_CFP)
228     lwz reg_A1,4(reg_CFP)
229     lwz reg_A2,8(reg_CFP)
230     lwz reg_A3,12(reg_CFP)
231    
232     /* Calculate LRA */
233     lis reg_LRA,ha16(lra)
234     addi reg_LRA,reg_LRA,lo16(lra)
235     addi reg_LRA,reg_LRA,type_OtherPointer
236    
237     /* Function is an indirect closure */
238     lwz reg_CODE,CLOSURE_FUNCTION_OFFSET(reg_LEXENV)
239 rtoy 1.9 /*
240     * The 6 is vm:function-code-offset, the 4 is
241     * the number of bytes in a lispobj.
242     */
243 pmai 1.1 addi reg_LIP,reg_CODE,6*4-type_FunctionPointer
244     mtctr reg_LIP
245     slwi reg_NARGS,reg_NL2,2
246     bctr
247     .align 3
248     lra:
249     .long type_ReturnPcHeader
250    
251     /* Blow off any extra values. */
252     mr reg_CSP,reg_OCFP
253     nop
254    
255     /* Return the one value. */
256    
257     mr REG(3),reg_A0
258    
259     /* Turn on pseudo-atomic */
260     li reg_NL3,-4
261     la reg_ALLOC,4(reg_ALLOC)
262    
263     /* Store lisp state */
264     clrrwi reg_NL1,reg_ALLOC,3
265     store(reg_NL1,reg_NL2,_current_dynamic_space_free_pointer)
266     /* store(reg_POLL,reg_NL2,poll_flag) */
267     /* load(reg_NL2,current_thread) */
268     store(reg_BSP,reg_NL2,_current_binding_stack_pointer)
269     store(reg_CSP,reg_NL2,_current_control_stack_pointer)
270     store(reg_CFP,reg_NL2,_current_control_frame_pointer)
271     /* load(reg_POLL,saver2) */
272    
273     /* No longer in Lisp. */
274     store(reg_NL1,reg_NL2,_foreign_function_call_active)
275    
276     /* Check for interrupt */
277 rtoy 1.10 andi. reg_NL3, reg_ALLOC, 1
278     subi reg_ALLOC, reg_ALLOC, 4
279     twnei reg_NL3,0
280    
281 pmai 1.1 /* Back to C */
282     C_FULL_EPILOG
283     blr
284     SET_SIZE(call_into_lisp)
285    
286    
287     GFUNCDEF(call_into_c)
288     /* We're kind of low on unboxed, non-dedicated registers here:
289     most of the unboxed registers may have outgoing C args in them.
290     CFUNC is going to have to go in the CTR in a moment, anyway
291     so we'll free it up soon. reg_NFP is preserved by lisp if it
292     has a meaningful value in it, so we can use it. reg_NARGS is
293     free when it's not holding a copy of the "real" reg_NL3, which
294     gets tied up by the pseudo-atomic mechanism */
295     mtctr reg_CFUNC
296     mflr reg_LIP
297     /* Build a lisp stack frame */
298     mr reg_OCFP,reg_CFP
299     mr reg_CFP,reg_CSP
300     la reg_CSP,32(reg_CSP)
301     stw reg_OCFP,0(reg_CFP)
302     stw reg_CODE,8(reg_CFP)
303     /* The pseudo-atomic mechanism wants to use reg_NL3, but that
304     may be an outgoing C argument. Copy reg_NL3 to something that's
305     unboxed and -not- one of the C argument registers */
306     mr reg_NARGS,reg_NL3
307    
308     /* Turn on pseudo-atomic */
309 rtoy 1.10 #if 0
310 pmai 1.1 li reg_NL3,-4
311 rtoy 1.10 #endif
312 pmai 1.1 la reg_ALLOC,4(reg_ALLOC)
313    
314     /* Convert the return address to an offset and save it on the stack. */
315     sub reg_NFP,reg_LIP,reg_CODE
316     la reg_NFP,type_OtherPointer(reg_NFP)
317     stw reg_NFP,4(reg_CFP)
318    
319     /* Store Lisp state */
320     clrrwi reg_NFP,reg_ALLOC,3
321     store(reg_NFP,reg_CFUNC,_current_dynamic_space_free_pointer)
322     /* load(reg_CFUNC,current_thread) */
323    
324     store(reg_BSP,reg_CFUNC,_current_binding_stack_pointer)
325     store(reg_CSP,reg_CFUNC,_current_control_stack_pointer)
326     store(reg_CFP,reg_CFUNC,_current_control_frame_pointer)
327    
328     /* No longer in Lisp */
329     store(reg_CSP,reg_CFUNC,_foreign_function_call_active)
330     /* load(reg_POLL,saver2) */
331     /* Disable pseudo-atomic; check pending interrupt */
332 rtoy 1.10 andi. reg_NL3, reg_ALLOC, 1
333     subi reg_ALLOC, reg_ALLOC, 4
334     twnei reg_NL3, 0
335    
336 pmai 1.1 mr reg_NL3,reg_NARGS
337    
338     /* PowerOpen (i.e. OS X) requires the callee address in r12
339     (a.k.a. CFUNC), so move it back there, too. */
340     mfctr reg_CFUNC
341     /* Into C we go. */
342     bctrl
343    
344     /* Re-establish NIL */
345     lis reg_NULL,hi16(NIL)
346     ori reg_NULL,reg_NULL,lo16(NIL)
347     /* And reg_ZERO */
348     li reg_ZERO,0
349    
350     /* If we GC'ed during the FF code (as the result of a callback ?)
351     the tagged lisp registers may now contain garbage (since the
352     registers were saved by C and not seen by the GC.) Put something
353     harmless in all such registers before allowing an interrupt */
354     li reg_CODE,0
355     li reg_CNAME,0
356     li reg_LEXENV,0
357     /* reg_OCFP was pointing to a control stack frame & was preserved by C */
358     li reg_LRA,0
359     li reg_A0,0
360     li reg_A1,0
361     li reg_A2,0
362     li reg_A3,0
363     li reg_L0,0
364     li reg_L1,0
365     li reg_L2,0
366     li reg_LIP,0
367    
368     /* Atomic ... */
369 rtoy 1.10 #if 0
370 pmai 1.1 li reg_NL3,-4
371 rtoy 1.10 #endif
372 pmai 1.1 li reg_ALLOC,4
373    
374     /* No long in foreign function call. */
375     store(reg_ZERO,reg_NL2,_foreign_function_call_active)
376    
377     /* The free pointer may have moved */
378     load(reg_NL4,_current_dynamic_space_free_pointer)
379     add reg_ALLOC,reg_ALLOC,reg_NL4
380    
381     /* The BSP wasn't preserved by C, so load it */
382     load(reg_BSP,_current_binding_stack_pointer)
383    
384     /* Other lisp stack/frame pointers were preserved by C.
385     I can't imagine why they'd have moved */
386    
387     /* Get the return address back. */
388     lwz reg_LIP,4(reg_CFP)
389     lwz reg_CODE,8(reg_CFP)
390     add reg_LIP,reg_CODE,reg_LIP
391     la reg_LIP,-type_OtherPointer(reg_LIP)
392    
393     /* No longer atomic */
394 rtoy 1.10 andi. reg_NL3, reg_ALLOC, 1
395     subi reg_ALLOC, reg_ALLOC, 4
396     twnei reg_NL3, 0
397    
398 pmai 1.1 mtlr reg_LIP
399    
400     /* Reset the lisp stack. */
401     mr reg_CSP,reg_CFP
402     mr reg_CFP,reg_OCFP
403    
404     /* And back into Lisp. */
405     blr
406    
407     SET_SIZE(call_into_c)
408    
409     GFUNCDEF(xundefined_tramp)
410     .globl _undefined_tramp
411 rtoy 1.9 .byte 0,0,0,type_FunctionHeader /* Header */
412 pmai 1.1
413 rtoy 1.9 .long _undefined_tramp /* self slot */
414     .long NIL /* next slot */
415     .long NIL /* name slot */
416     .long NIL /* arglist slot */
417     .long NIL /* type slot */
418 rtoy 1.7 _undefined_tramp:
419 pmai 1.1 twllei reg_ZERO,trap_Cerror
420 rtoy 1.4 /* Number of argument bytes */
421 rtoy 1.2 .byte 4
422     .byte UNDEFINED_SYMBOL_ERROR
423 rtoy 1.4 /* Escape to create 16bit number from following two bytes,
424     in little-endian order */
425 rtoy 1.2 .byte 254
426 rtoy 1.4 .byte SC_OFFSET_LO(sc_DescriptorReg, reg_FDEFN_NUM)
427     .byte SC_OFFSET_HI(sc_DescriptorReg, reg_FDEFN_NUM)
428     /*
429 rtoy 1.2 .byte sc_DescriptorReg+0x40
430     .byte 1
431 rtoy 1.4 */
432 pmai 1.1 .align 2
433     1: lwz reg_CODE,FDEFN_RAW_ADDR_OFFSET(reg_FDEFN)
434     la reg_LIP,FUNCTION_CODE_OFFSET(reg_CODE)
435     mtctr reg_LIP
436     bctr
437 rtoy 1.2
438     mr reg_CSP, reg_CFP
439     b 1b
440 pmai 1.1
441     SET_SIZE(xundefined_tramp)
442    
443     GFUNCDEF(xclosure_tramp)
444     .globl _closure_tramp
445 rtoy 1.9 .byte 0,0,0,type_FunctionHeader /* Header */
446 pmai 1.1 .long _closure_tramp
447     .long NIL
448     .long NIL
449     .long NIL
450     .long NIL
451 rtoy 1.7 _closure_tramp:
452 pmai 1.1 lwz reg_LEXENV,FDEFN_FUNCTION_OFFSET(reg_FDEFN)
453     lwz reg_CODE,CLOSURE_FUNCTION_OFFSET(reg_LEXENV)
454     la reg_LIP,FUNCTION_CODE_OFFSET(reg_CODE)
455     mtctr reg_LIP
456     bctr
457    
458     SET_SIZE(xclosure_tramp)
459    
460 rtoy 1.8 /*
461     * Function-end breakpoint magic. See MAKE-BOGUS-LRA in
462     * code/debug-int.lisp.
463     */
464     .text
465     .align 3
466     .globl _function_end_breakpoint_guts
467     _function_end_breakpoint_guts:
468     .long type_ReturnPcHeader
469     b 1f
470     /*
471     * Are these really necessary? I'm cargo-culting from the sparc port
472     */
473     mr reg_OCFP, reg_CSP
474     addi reg_CSP, reg_CSP, 4
475     li reg_NARGS, 4
476     mr reg_A1, reg_NULL
477     mr reg_A2, reg_NULL
478     mr reg_A3, reg_NULL
479     1:
480     .globl _function_end_breakpoint_trap
481     _function_end_breakpoint_trap:
482     twllei reg_ZERO, trap_FunctionEndBreakpoint
483     b 1b
484     .globl _function_end_breakpoint_end
485     _function_end_breakpoint_end:
486 pmai 1.1
487    
488     GFUNCDEF(ppc_flush_cache_line)
489     dcbf 0,REG(3)
490     sync
491     icbi 0,REG(3)
492     sync
493     isync
494     blr
495     SET_SIZE(ppc_flush_cache_line)
496    
497 rtoy 1.5 #ifdef LINKAGE_TABLE
498     /*
499     * Call into C code to resolve a linkage entry.
500     *
501     * We get here by Lisp calling call_into_c with an address of the
502     * desired function which is contained in the register reg_CFUNC (aka
503     * %i4, aka %r28). This is the address of the entry in the linkage
504     * table, which is what we need to figure out what function we really
505     * wanted.
506     *
507     * Note that because we get here from call_into_c, all necessary live
508     * registers have been saved, including FP registers. Hence, no need
509     * to save them.
510     */
511     .globl _lazy_resolve_linkage
512     GFUNCDEF(resolve_linkage_tramp)
513     /*
514     * We need to call lazy_resolve_linkage. reg_A0 (= r24)
515     * (see ppc-arch.c) contains the address of the linkage entry.
516     */
517     /*
518     * Need to save all parameter regs to the stack because we
519 rtoy 1.6 * need them for later. We save the FP registers too. (Do
520     * we really need to? lazy_resolve_linkage shouldn't call
521     * anything that uses FP registers. It's safe to do so.)
522 rtoy 1.5 */
523 rtoy 1.6 subi r1, r1, 8*4+8+8*13
524     stfd f1, 0(r1)
525     stfd f2, 8(r1)
526     stfd f3, 16(r1)
527     stfd f4, 24(r1)
528     stfd f5, 32(r1)
529     stfd f6, 40(r1)
530     stfd f7, 48(r1)
531     stfd f8, 56(r1)
532     stfd f9, 64(r1)
533     stfd f10, 72(r1)
534     stfd f11, 80(r1)
535     stfd f12, 88(r1)
536     stfd f13, 96(r1)
537    
538     stw r3, 104+0(r1)
539     stw r4, 104+4(r1)
540     stw r5, 104+8(r1)
541     stw r6, 104+12(r1)
542     stw r7, 104+16(r1)
543     stw r8, 104+20(r1)
544     stw r9, 104+24(r1)
545     stw r10, 104+28(r1)
546    
547 rtoy 1.5
548     mr reg_NL0, reg_A0
549    
550     stwu r1, (-(24+4))(r1)
551     /*
552     * At this point reg_NIL should be available to us.
553     * Call lazy_resolve_linkage to figure out the real function address.
554     */
555     lis reg_NULL, hi16(_lazy_resolve_linkage)
556     ori reg_NULL, reg_NULL, lo16(_lazy_resolve_linkage)
557     mtctr reg_NULL
558     mflr reg_CODE
559     bctrl
560    
561     addi r1,r1,24+4
562    
563     /*
564     * The desired function is in r3 (NL0), so save it
565     * and restore the real arg parameters
566     */
567    
568     mtctr reg_NL0
569 rtoy 1.6 lfd f1, 0(r1)
570     lfd f2, 8(r1)
571     lfd f3, 16(r1)
572     lfd f4, 24(r1)
573     lfd f5, 32(r1)
574     lfd f6, 40(r1)
575     lfd f7, 48(r1)
576     lfd f8, 56(r1)
577     lfd f9, 64(r1)
578     lfd f10, 72(r1)
579     lfd f11, 80(r1)
580     lfd f12, 88(r1)
581     lfd f13, 96(r1)
582    
583     lwz r3, 104+0(r1)
584     lwz r4, 104+4(r1)
585     lwz r5, 104+8(r1)
586     lwz r6, 104+12(r1)
587     lwz r7, 104+16(r1)
588     lwz r8, 104+20(r1)
589     lwz r9, 104+24(r1)
590     lwz r10, 104+28(r1)
591    
592     addi r1,r1,8*4+8+8*13
593 rtoy 1.5
594     /*
595     * Got it, so we can now jump directly to the desired function.
596     * reg_NL0 contains the result. Restore the stack and go!
597     */
598    
599     mtlr reg_CODE
600    
601     /* Back to C */
602     /* mtlr reg_CODE*/
603     bctr
604    
605     SET_SIZE(resolve_linkage_tramp)
606    
607    
608     /*
609     * When we get called, r3 (reg_NL0) contains the address of the
610     * data_vector object which is a string naming the bad symbol.
611     */
612     GFUNCDEF(undefined_foreign_symbol_trap)
613    
614     /*
615     Need to restore all the global registers with the Lisp values that
616     were saved away in call_into_c. (This routine is only called from
617     os_link_one_symbol, which is called from resolve_linkage_tramp, which
618     is called from call_into_c.)
619    
620     The global registers are volatile across function calls, so who
621     knows what values have been they contain now!
622    
623     */
624    
625     load(reg_ALLOC, _current_dynamic_space_free_pointer)
626     load(reg_BSP, _current_binding_stack_pointer)
627     load(reg_CSP, _current_control_stack_pointer)
628     load(reg_CFP, _current_control_frame_pointer)
629    
630     lis reg_NULL,hi16(NIL)
631     ori reg_NULL,reg_NULL,lo16(NIL)
632     /* And reg_ZERO */
633     li reg_ZERO,0
634    
635     mr reg_NL0, reg_A0
636     twllei reg_ZERO, trap_Error
637     .byte 4 /* Number of argument bytes */
638     .byte UNDEFINED_FOREIGN_SYMBOL_ERROR
639     /* Escape to create 16bit number from following two bytes, in
640     little-endian order */
641     .byte 254
642     .byte SC_OFFSET_LO(sc_DescriptorReg, reg_A0_NUM)
643     .byte SC_OFFSET_HI(sc_DescriptorReg, reg_A0_NUM)
644     .align 4
645    
646 rtoy 1.11 #endif

  ViewVC Help
Powered by ViewVC 1.1.5