/[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.1 - (hide annotations)
Sat Feb 12 16:14:15 2005 UTC (9 years, 2 months ago) by rtoy
Branch: ppc_gencgc_branch
Changes since 1.6: +12 -10 lines
Change how pseudo-atomic works on Mac OS X.  Instead of using a
separate register for the flag, and using a negative alloc-tn to mean
the pseudo-atomic section was interrupted, we make it more like sparc,
where the pseudo-atomic interrupted is the least signficant bit of
alloc-tn.

* compiler/ppc/macros.lisp:
  o Make the PSEUDO-ATOMIC macro work as desired.

* lisp/ppc-arch.c
  o Set the LSB of alloc-tn when pseudo-atomic is interrupted.
  o Check for the twnei instruction which is now used to see if
    pseudo-atomic was interrupted.

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

  ViewVC Help
Powered by ViewVC 1.1.5