/[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.5 - (hide annotations)
Sun Feb 6 19:43:15 2005 UTC (9 years, 2 months ago) by rtoy
Branch: MAIN
Changes since 1.4: +117 -0 lines
Initial support for linkage-tables on PPC/Darwin.  This is a
relatively straightforward port of the sparc version of
linkage-tables.  Some refinements are probably still needed, as well
as some testing.

Use boot-2005-02-ppc-linkage.lisp to bootstrap this change from the
2005-02 snapshot.

* code/ppc-vm.lisp
  o Add appropriate FOREIGN-SYMBOL-ADDRESS-AUX and FIND-FOREIGN-SYMBOL
    functions for linkage-table.

* compiler/generic/new-genesis.lisp
  o Basically do the same as the sparc port for linkage-tables.
  o need to extern-alien-name on the cold linkages since they C names
    depend on the backend conventions.

* compiler/ppc/alloc.lisp
  o Load "undefined_tramp" appropriately for linkage-tables.

* compiler/ppc/c-call.lisp
  o Define new vops (FOREIGN-SYMBOL-CODE-ADDRESS,
    FOREIGN-SYMBOL-DATA-ADDRESS) for linkage-tables so we can access
    correctly.

* compiler/ppc/cell.lisp
  o Load "closure_tramp" appropriately for linkage-tables
  o Load "undefined_tramp" appropriately for linkage-tables

* compiler/ppc/parms.lisp
  o Put the foreign linkage space start at the end of the static space
    to make it easier to bootstrap.  (We need already mapped memory.)
    We can move this later.
  o Correct TARGET-FOREIGN-LINKAGE-ENTRY-SIZE.
  o Add new static-symbol *linkage-table-data*
  o While were at it, add SPARE-9 and SPARE-0 static symbols so we
    have 10 spares.

* lisp/Config.ppc_darwin
  o Add -DLINKAGE_TABLE to CFLAGS/ASFLAGS if we have linkage-table
    support.

* lisp/Darwin-os.c
  o Add os_dlsym to support linkage-tables.  (This nees a little
    refactoring because we just copied the #defines for dlopen modes.)

* lisp/os-common.c
  o The checking of the linkage tables that is done for sparc almost
    works for ppc, but not quite.  Implement one for ppc.

* lisp/ppc-arch.c
  o Add PPC version of arch_make_jump_entry, arch_make_linkage_entry,
    arch_linkage_entry.

* lisp/ppc-assem.S
  o Add lazy_resolve_linkage to support linkage-tables.  This needs
    some more work.
  o Add undefined_foreign_symbol_trap.  This probably needs work, and
    definitely needs testing.

* lisp/ppc-validate.h
  o Define the start of the linkage space and size.
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     #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     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.4 /*
401     * The next 4 bytes are the encoding for a PPC jump instruction.
402     * The jump should go to the twllei instruction below.
403     */
404 pmai 1.1 .byte 18<<2
405     _undefined_tramp:
406 rtoy 1.3 .byte 0,0,24
407 pmai 1.1 .long _undefined_tramp
408     .long NIL
409     .long NIL
410     .long NIL
411     .long NIL
412     twllei reg_ZERO,trap_Cerror
413 rtoy 1.4 /* Number of argument bytes */
414 rtoy 1.2 .byte 4
415     .byte UNDEFINED_SYMBOL_ERROR
416 rtoy 1.4 /* Escape to create 16bit number from following two bytes,
417     in little-endian order */
418 rtoy 1.2 .byte 254
419 rtoy 1.4 .byte SC_OFFSET_LO(sc_DescriptorReg, reg_FDEFN_NUM)
420     .byte SC_OFFSET_HI(sc_DescriptorReg, reg_FDEFN_NUM)
421     /*
422 rtoy 1.2 .byte sc_DescriptorReg+0x40
423     .byte 1
424 rtoy 1.4 */
425 pmai 1.1 .align 2
426     #ifdef PPC_FUN_HACK_MAYBE
427     1: lwz reg_CODE,FDEFN_RAW_ADDR_OFFSET(reg_CNAME)
428     #else
429     1: lwz reg_CODE,FDEFN_RAW_ADDR_OFFSET(reg_FDEFN)
430     #endif
431     la reg_LIP,FUNCTION_CODE_OFFSET(reg_CODE)
432     mtctr reg_LIP
433     bctr
434 rtoy 1.2
435     mr reg_CSP, reg_CFP
436     b 1b
437 pmai 1.1
438     SET_SIZE(xundefined_tramp)
439    
440     GFUNCDEF(xclosure_tramp)
441     .globl _closure_tramp
442     .byte 0,0,0,type_FunctionHeader
443     .byte 18<<2
444     _closure_tramp:
445     .byte 0,0,24
446     .long _closure_tramp
447     .long NIL
448     .long NIL
449     .long NIL
450     .long NIL
451     #ifdef PPC_FUN_HACK_MAYBE
452     lwz reg_LEXENV,FDEFN_FUNCTION_OFFSET(reg_CNAME)
453     #else
454     lwz reg_LEXENV,FDEFN_FUNCTION_OFFSET(reg_FDEFN)
455     #endif
456     lwz reg_CODE,CLOSURE_FUNCTION_OFFSET(reg_LEXENV)
457     la reg_LIP,FUNCTION_CODE_OFFSET(reg_CODE)
458     mtctr reg_LIP
459     bctr
460    
461     SET_SIZE(xclosure_tramp)
462    
463     GFUNCDEF(function_end_breakpoint_trap)
464     .long 0
465     SET_SIZE(function_end_breakpoint_trap)
466    
467     GFUNCDEF(function_end_breakpoint)
468     .long 0
469     SET_SIZE(function_end_breakpoint)
470    
471     GFUNCDEF(function_end_breakpoint_guts)
472     .long 0
473     SET_SIZE(function_end_breakpoint_guts)
474    
475     GFUNCDEF(function_end_breakpoint_end)
476     .long 0
477     SET_SIZE(function_end_breakpoint_end)
478    
479    
480     GFUNCDEF(ppc_flush_cache_line)
481     dcbf 0,REG(3)
482     sync
483     icbi 0,REG(3)
484     sync
485     isync
486     blr
487     SET_SIZE(ppc_flush_cache_line)
488    
489 rtoy 1.5 #ifdef LINKAGE_TABLE
490     /*
491     * Call into C code to resolve a linkage entry.
492     *
493     * We get here by Lisp calling call_into_c with an address of the
494     * desired function which is contained in the register reg_CFUNC (aka
495     * %i4, aka %r28). This is the address of the entry in the linkage
496     * table, which is what we need to figure out what function we really
497     * wanted.
498     *
499     * Note that because we get here from call_into_c, all necessary live
500     * registers have been saved, including FP registers. Hence, no need
501     * to save them.
502     */
503     .globl _lazy_resolve_linkage
504     GFUNCDEF(resolve_linkage_tramp)
505     /*
506     * We need to call lazy_resolve_linkage. reg_A0 (= r24)
507     * (see ppc-arch.c) contains the address of the linkage entry.
508     */
509     /*
510     * Need to save all parameter regs to the stack because we
511     * need them for later.
512     */
513     subi r1, r1, 8*4+8
514     stw r3, 0(r1)
515     stw r4, 4(r1)
516     stw r5, 8(r1)
517     stw r6, 12(r1)
518     stw r7, 16(r1)
519     stw r8, 20(r1)
520     stw r9, 24(r1)
521     stw r10, 28(r1)
522    
523     mr reg_NL0, reg_A0
524    
525     stwu r1, (-(24+4))(r1)
526     /*
527     * At this point reg_NIL should be available to us.
528     * Call lazy_resolve_linkage to figure out the real function address.
529     */
530     lis reg_NULL, hi16(_lazy_resolve_linkage)
531     ori reg_NULL, reg_NULL, lo16(_lazy_resolve_linkage)
532     mtctr reg_NULL
533     mflr reg_CODE
534     bctrl
535    
536     addi r1,r1,24+4
537    
538     /*
539     * The desired function is in r3 (NL0), so save it
540     * and restore the real arg parameters
541     */
542    
543     mtctr reg_NL0
544     lwz r3, 0(r1)
545     lwz r4, 4(r1)
546     lwz r5, 8(r1)
547     lwz r6, 12(r1)
548     lwz r7, 16(r1)
549     lwz r8, 20(r1)
550     lwz r9, 24(r1)
551     lwz r10, 28(r1)
552    
553     /*
554     * Got it, so we can now jump directly to the desired function.
555     * reg_NL0 contains the result. Restore the stack and go!
556     */
557    
558     mtlr reg_CODE
559    
560     /* Back to C */
561     /* mtlr reg_CODE*/
562     bctr
563    
564     SET_SIZE(resolve_linkage_tramp)
565    
566    
567     /*
568     * When we get called, r3 (reg_NL0) contains the address of the
569     * data_vector object which is a string naming the bad symbol.
570     */
571     GFUNCDEF(undefined_foreign_symbol_trap)
572    
573     /*
574     Need to restore all the global registers with the Lisp values that
575     were saved away in call_into_c. (This routine is only called from
576     os_link_one_symbol, which is called from resolve_linkage_tramp, which
577     is called from call_into_c.)
578    
579     The global registers are volatile across function calls, so who
580     knows what values have been they contain now!
581    
582     */
583    
584     load(reg_ALLOC, _current_dynamic_space_free_pointer)
585     load(reg_BSP, _current_binding_stack_pointer)
586     load(reg_CSP, _current_control_stack_pointer)
587     load(reg_CFP, _current_control_frame_pointer)
588    
589     lis reg_NULL,hi16(NIL)
590     ori reg_NULL,reg_NULL,lo16(NIL)
591     /* And reg_ZERO */
592     li reg_ZERO,0
593    
594     mr reg_NL0, reg_A0
595     twllei reg_ZERO, trap_Error
596     .byte 4 /* Number of argument bytes */
597     .byte UNDEFINED_FOREIGN_SYMBOL_ERROR
598     /* Escape to create 16bit number from following two bytes, in
599     little-endian order */
600     .byte 254
601     .byte SC_OFFSET_LO(sc_DescriptorReg, reg_A0_NUM)
602     .byte SC_OFFSET_HI(sc_DescriptorReg, reg_A0_NUM)
603     .align 4
604    
605     #endif

  ViewVC Help
Powered by ViewVC 1.1.5