1.0.4.61: stack-alignment on CALL-OUT VOP on x86/Darwin
[sbcl.git] / src / runtime / ppc-assem.S
1 #define LANGUAGE_ASSEMBLY
2
3 #include "sbcl.h" 
4 #include "lispregs.h"
5 #include "globals.h"
6
7 #include "genesis/simple-fun.h"
8 #include "genesis/fdefn.h"
9 #include "genesis/closure.h"
10 #include "genesis/funcallable-instance.h"
11 #include "genesis/static-symbols.h"
12
13 #ifdef LISP_FEATURE_DARWIN
14 #define CSYMBOL(x) _ ## x
15 #else
16 #define CSYMBOL(x) x
17 #endif
18
19 #if defined LISP_FEATURE_DARWIN
20 #define FUNCDEF(x)      .text @ \
21                         .align 3 @ \
22 _##x:
23
24 #define GFUNCDEF(x)     .globl _/**/x @ \
25         FUNCDEF(x)
26 #else
27 #define FUNCDEF(x)      .text ; \
28                         .align 3 ; \
29                         .type x,@function ; \
30 x:
31
32 #define GFUNCDEF(x)     .globl x ; \
33         FUNCDEF(x)
34 #endif
35
36 #if defined LISP_FEATURE_DARWIN
37 #define SET_SIZE(x)
38 #else
39 #define SET_SIZE(x) .size x,.-x
40 #endif
41
42 /* Load a register from a global, using the register as an intermediary */
43 /* The register will be a fixnum for one instruction, so this is gc-safe */
44
45 #if defined LISP_FEATURE_DARWIN
46 #define load(reg,global) \
47         lis reg,ha16(global) @ \
48         lwz reg,lo16(global)(reg) ; Comment
49 #define store(reg,temp,global) \
50         lis temp,ha16(global) @\
51         stw reg,lo16(global)(temp) ; Comment
52 #else
53 #define load(reg,global) \
54         lis reg,global@ha; lwz reg,global@l(reg)
55 #define store(reg,temp,global) \
56         lis temp,global@ha; stw reg,global@l(temp)
57 #endif
58         
59 #define FIRST_SAVE_FPR  14      /* lowest-numbered non-volatile FPR */
60 #ifdef LISP_FEATURE_DARWIN
61 #define FIRST_SAVE_GPR  13      /* lowest-numbered non-volatile GPR */
62 #define NGPR_SAVE_BYTES(n) ((32-(n))*4)
63 #define FRAME_ARG_BYTES(n)  (((((n)+6)*4)+15)&~15)
64 #else
65 #define FIRST_SAVE_GPR  14      /* lowest-numbered non-volatile GPR */
66 #define NGPR_SAVE_BYTES(n) ((32-(~1&((n)+1)))*4)
67 #define FRAME_ARG_BYTES(n)  (((((n)+2)*4)+15)&~15)
68 #endif
69 #define NFPR_SAVE_BYTES(n) ((32-(n))*8)
70
71 #ifdef LISP_FEATURE_DARWIN
72 #define FRAME_SIZE(first_g,first_f,out_arg_words,savecr) \
73 (NFPR_SAVE_BYTES(first_f)+ NGPR_SAVE_BYTES(first_g)+ FRAME_ARG_BYTES(out_arg_words))
74 #define SAVE_FPR(n) stfd f##n,-8*(32- n)(r11)
75 #define SAVE_GPR(n) stw r##n,-4*(32- n)(r11)
76 #define FULL_FRAME_SIZE (FRAME_SIZE(FIRST_SAVE_GPR,FIRST_SAVE_FPR,8,1)+15&~15)
77 #define RESTORE_FPR(n) lfd f##n,-8*(32- n)(r11)
78 #define RESTORE_GPR(n) lwz r##n,-4*(32- n)(r11)
79 #else
80 #define FRAME_SIZE(first_g,first_f,out_arg_words,savecr) \
81 (NFPR_SAVE_BYTES(first_f)+ NGPR_SAVE_BYTES(first_g)+ FRAME_ARG_BYTES(out_arg_words+savecr))
82 #define SAVE_FPR(n) stfd n,-8*(32-(n))(11)
83 #define SAVE_GPR(n) stw n,-4*(32-(n))(11)
84 #define FULL_FRAME_SIZE FRAME_SIZE(FIRST_SAVE_GPR,FIRST_SAVE_FPR,0,1)
85
86 #define RESTORE_FPR(n) lfd n,-8*(32-(n))(11)
87 #define RESTORE_GPR(n) lwz n,-4*(32-(n))(11)
88 #endif
89
90 #ifdef LISP_FEATURE_DARWIN
91 #define C_FULL_PROLOG \
92         nop @\
93         nop @ \
94         mfcr REG(0) @ \
95         stw REG(0),4(REG(1)) @ \
96         mflr REG(0) @ \
97         stw REG(0),8(REG(1)) @ \
98         mr REG(11),REG(1) @ \
99         stwu REG(1),-FULL_FRAME_SIZE(REG(1)) @ \
100         SAVE_FPR(14) @ \
101         SAVE_FPR(15) @ \
102         SAVE_FPR(16) @ \
103         SAVE_FPR(17) @ \
104         SAVE_FPR(18) @ \
105         SAVE_FPR(19) @ \
106         SAVE_FPR(20) @ \
107         SAVE_FPR(21) @ \
108         SAVE_FPR(22) @ \
109         SAVE_FPR(23) @ \
110         SAVE_FPR(24) @ \
111         SAVE_FPR(25) @ \
112         SAVE_FPR(26) @ \
113         SAVE_FPR(27) @ \
114         SAVE_FPR(28) @ \
115         SAVE_FPR(29) @ \
116         SAVE_FPR(30) @ \
117         SAVE_FPR(31) @ \
118         la REG(11),-NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(11)) @ \
119         SAVE_GPR(13) @ \
120         SAVE_GPR(14) @ \
121         SAVE_GPR(15) @ \
122         SAVE_GPR(16) @ \
123         SAVE_GPR(17) @ \
124         SAVE_GPR(18) @ \
125         SAVE_GPR(19) @ \
126         SAVE_GPR(20) @ \
127         SAVE_GPR(21) @ \
128         SAVE_GPR(22) @ \
129         SAVE_GPR(23) @ \
130         SAVE_GPR(24) @ \
131         SAVE_GPR(25) @ \
132         SAVE_GPR(26) @ \
133         SAVE_GPR(27) @ \
134         SAVE_GPR(28) @ \
135         SAVE_GPR(29) @ \
136         SAVE_GPR(30) @ \
137         SAVE_GPR(31)
138
139
140 #define C_FULL_EPILOG \
141         la REG(11),FULL_FRAME_SIZE-NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(1)) @ \
142         RESTORE_GPR(13) @ \
143         RESTORE_GPR(14) @ \
144         RESTORE_GPR(15) @ \
145         RESTORE_GPR(16) @ \
146         RESTORE_GPR(17) @ \
147         RESTORE_GPR(18) @ \
148         RESTORE_GPR(19) @ \
149         RESTORE_GPR(20) @ \
150         RESTORE_GPR(21) @ \
151         RESTORE_GPR(22) @ \
152         RESTORE_GPR(23) @ \
153         RESTORE_GPR(24) @ \
154         RESTORE_GPR(25) @ \
155         RESTORE_GPR(26) @ \
156         RESTORE_GPR(27) @ \
157         RESTORE_GPR(28) @ \
158         RESTORE_GPR(29) @ \
159         RESTORE_GPR(30) @ \
160         RESTORE_GPR(31) @ \
161         la REG(11),NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(REG(11)) @ \
162         RESTORE_FPR(14) @ \
163         RESTORE_FPR(15) @ \
164         RESTORE_FPR(16) @ \
165         RESTORE_FPR(17) @ \
166         RESTORE_FPR(18) @ \
167         RESTORE_FPR(19) @ \
168         RESTORE_FPR(20) @ \
169         RESTORE_FPR(21) @ \
170         RESTORE_FPR(22) @ \
171         RESTORE_FPR(23) @ \
172         RESTORE_FPR(24) @ \
173         RESTORE_FPR(25) @ \
174         RESTORE_FPR(26) @ \
175         RESTORE_FPR(27) @ \
176         RESTORE_FPR(28) @ \
177         RESTORE_FPR(29) @ \
178         RESTORE_FPR(30) @ \
179         RESTORE_FPR(31) @ \
180         lwz REG(1),0(REG(1)) @ \
181         lwz REG(0),4(REG(1)) @ \
182         mtcr REG(0) @ \
183         lwz REG(0),8(REG(1)) @ \
184         mtlr REG(0) @ \
185         
186 #else   
187
188 #define C_FULL_PROLOG \
189         mflr 0 ; \
190         stw 0,4(1) ; \
191         mr 11,1 ; \
192         stwu 1,-FULL_FRAME_SIZE(1) ; \
193         SAVE_FPR(14) ; \
194         SAVE_FPR(15) ; \
195         SAVE_FPR(16) ; \
196         SAVE_FPR(17) ; \
197         SAVE_FPR(18) ; \
198         SAVE_FPR(19) ; \
199         SAVE_FPR(20) ; \
200         SAVE_FPR(21) ; \
201         SAVE_FPR(22) ; \
202         SAVE_FPR(23) ; \
203         SAVE_FPR(24) ; \
204         SAVE_FPR(25) ; \
205         SAVE_FPR(26) ; \
206         SAVE_FPR(27) ; \
207         SAVE_FPR(28) ; \
208         SAVE_FPR(29) ; \
209         SAVE_FPR(30) ; \
210         SAVE_FPR(31) ; \
211         la 11,-NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(11) ; \
212         SAVE_GPR(14) ; \
213         SAVE_GPR(15) ; \
214         SAVE_GPR(16) ; \
215         SAVE_GPR(17) ; \
216         SAVE_GPR(18) ; \
217         SAVE_GPR(19) ; \
218         SAVE_GPR(20) ; \
219         SAVE_GPR(21) ; \
220         SAVE_GPR(22) ; \
221         SAVE_GPR(23) ; \
222         SAVE_GPR(24) ; \
223         SAVE_GPR(25) ; \
224         SAVE_GPR(26) ; \
225         SAVE_GPR(27) ; \
226         SAVE_GPR(28) ; \
227         SAVE_GPR(29) ; \
228         SAVE_GPR(30) ; \
229         SAVE_GPR(31) ; \
230         mfcr 0  ; \
231         stw 0,8(1)
232
233 #define C_FULL_EPILOG \
234         lwz 5,8(1) ; \
235         mtcrf 255,5 ; \
236         la 11,FULL_FRAME_SIZE-NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(1) ; \
237         RESTORE_GPR(14) ; \
238         RESTORE_GPR(15) ; \
239         RESTORE_GPR(16) ; \
240         RESTORE_GPR(17) ; \
241         RESTORE_GPR(18) ; \
242         RESTORE_GPR(19) ; \
243         RESTORE_GPR(20) ; \
244         RESTORE_GPR(21) ; \
245         RESTORE_GPR(22) ; \
246         RESTORE_GPR(23) ; \
247         RESTORE_GPR(24) ; \
248         RESTORE_GPR(25) ; \
249         RESTORE_GPR(26) ; \
250         RESTORE_GPR(27) ; \
251         RESTORE_GPR(28) ; \
252         RESTORE_GPR(29) ; \
253         RESTORE_GPR(30) ; \
254         RESTORE_GPR(31) ; \
255         la 11,NFPR_SAVE_BYTES(FIRST_SAVE_FPR)(11) ; \
256         RESTORE_FPR(14) ; \
257         RESTORE_FPR(15) ; \
258         RESTORE_FPR(16) ; \
259         RESTORE_FPR(17) ; \
260         RESTORE_FPR(18) ; \
261         RESTORE_FPR(19) ; \
262         RESTORE_FPR(20) ; \
263         RESTORE_FPR(21) ; \
264         RESTORE_FPR(22) ; \
265         RESTORE_FPR(23) ; \
266         RESTORE_FPR(24) ; \
267         RESTORE_FPR(25) ; \
268         RESTORE_FPR(26) ; \
269         RESTORE_FPR(27) ; \
270         RESTORE_FPR(28) ; \
271         RESTORE_FPR(29) ; \
272         RESTORE_FPR(30) ; \
273         RESTORE_FPR(31) ; \
274         lwz 1,0(1) ; \
275         lwz 0,4(1) ; \
276         mtlr 0 ; \
277         
278 #endif
279         
280         .text
281
282 /*
283  * Function to transfer control into lisp.  The lisp object to invoke is
284  * passed as the first argument, which puts it in NL0
285  */
286
287         GFUNCDEF(call_into_lisp)
288         C_FULL_PROLOG
289         /* store(reg_POLL,11,saver2) */
290         /* Initialize tagged registers */
291         li reg_ZERO,0
292         li reg_CODE,0
293         li reg_CNAME,0
294         li reg_LEXENV,0
295         li reg_FDEFN,0
296         li reg_OCFP,0
297         li reg_LRA,0
298         li reg_A0,0
299         li reg_A1,0
300         li reg_A2,0
301         li reg_A3,0
302         li reg_L0,0
303         li reg_L1,0
304         li reg_L2,0
305         li reg_LIP,0
306 #ifdef LISP_FEATURE_DARWIN      
307         lis reg_NULL,hi16(NIL)
308         ori reg_NULL,reg_NULL,lo16(NIL)
309 #else
310         lis reg_NULL,NIL@h
311         ori reg_NULL,reg_NULL,NIL@l
312 #endif
313         /* Turn on pseudo-atomic */
314
315         li reg_ALLOC,4
316         store(reg_ZERO,reg_NL4,CSYMBOL(foreign_function_call_active))
317         load(reg_NL4,CSYMBOL(dynamic_space_free_pointer))
318         add reg_ALLOC,reg_ALLOC,reg_NL4
319         load(reg_BSP,CSYMBOL(current_binding_stack_pointer))
320         load(reg_CSP,CSYMBOL(current_control_stack_pointer))
321         load(reg_OCFP,CSYMBOL(current_control_frame_pointer))
322
323         /* No longer atomic, and check for interrupt */
324         andi. reg_NL3, reg_ALLOC, 1
325         subi reg_ALLOC,reg_ALLOC,4
326         twnei reg_NL3, 0
327
328         /* Pass in the arguments */
329
330         mr reg_CFP,reg_NL1
331         mr reg_LEXENV,reg_NL0
332         lwz reg_A0,0(reg_CFP)
333         lwz reg_A1,4(reg_CFP)
334         lwz reg_A2,8(reg_CFP)
335         lwz reg_A3,12(reg_CFP)
336
337         /* Calculate LRA */
338 #ifdef LISP_FEATURE_DARWIN
339         lis reg_LRA,ha16(lra)
340         addi reg_LRA,reg_LRA,lo16(lra)
341 #else
342         lis reg_LRA,lra@h
343         ori reg_LRA,reg_LRA,lra@l
344 #endif
345         addi reg_LRA,reg_LRA,OTHER_POINTER_LOWTAG
346
347         /* Function is an indirect closure */
348         lwz reg_CODE,SIMPLE_FUN_SELF_OFFSET(reg_LEXENV)
349         addi reg_LIP,reg_CODE,SIMPLE_FUN_CODE_OFFSET
350         mtctr reg_LIP
351         slwi reg_NARGS,reg_NL2,2
352         bctr                    
353         
354         .align 3
355 lra:
356         .long RETURN_PC_HEADER_WIDETAG 
357
358         /* Blow off any extra values. */
359         mr reg_CSP,reg_OCFP
360         nop
361
362         /* Return the one value. */
363
364         mr REG(3),reg_A0
365
366         /* Turn on  pseudo-atomic */
367         la reg_ALLOC,4(reg_ALLOC)
368
369         /* Store lisp state */
370         clrrwi reg_NL1,reg_ALLOC,3
371         store(reg_NL1,reg_NL2,CSYMBOL(dynamic_space_free_pointer))
372         /* store(reg_POLL,reg_NL2,poll_flag) */
373         /* load(reg_NL2,current_thread) */
374         store(reg_BSP,reg_NL2,CSYMBOL(current_binding_stack_pointer))
375         store(reg_CSP,reg_NL2,CSYMBOL(current_control_stack_pointer))
376         store(reg_CFP,reg_NL2,CSYMBOL(current_control_frame_pointer))
377         /* load(reg_POLL,saver2) */
378
379         /* No longer in Lisp. */
380         store(reg_NL1,reg_NL2,CSYMBOL(foreign_function_call_active))
381
382         /* Check for interrupt */
383         andi. reg_NL3, reg_ALLOC, 1
384         subi reg_ALLOC, reg_ALLOC, 4
385         twnei reg_NL3,0
386         
387         /* Back to C */
388         C_FULL_EPILOG
389         blr
390         SET_SIZE(call_into_lisp)
391 \f
392
393         GFUNCDEF(call_into_c)
394         /* We're kind of low on unboxed, non-dedicated registers here:
395         most of the unboxed registers may have outgoing C args in them.
396         CFUNC is going to have to go in the CTR in a moment, anyway
397         so we'll free it up soon.  reg_NFP is preserved by lisp if it
398         has a meaningful value in it, so we can use it.  reg_NARGS is
399         free when it's not holding a copy of the "real" reg_NL3, which
400         gets tied up by the pseudo-atomic mechanism */
401         mtctr reg_CFUNC
402         mflr reg_LIP
403         /* Build a lisp stack frame */
404         mr reg_OCFP,reg_CFP
405         mr reg_CFP,reg_CSP
406         la reg_CSP,32(reg_CSP)
407         stw reg_OCFP,0(reg_CFP)
408         stw reg_CODE,8(reg_CFP)
409         /* The pseudo-atomic mechanism wants to use reg_NL3, but that
410         may be an outgoing C argument.  Copy reg_NL3 to something that's
411         unboxed and -not- one of the C argument registers */
412         mr reg_NARGS,reg_NL3
413
414         /* Turn on pseudo-atomic */
415         la reg_ALLOC,4(reg_ALLOC)
416
417         /* Convert the return address to an offset and save it on the stack. */
418         sub reg_NFP,reg_LIP,reg_CODE
419         la reg_NFP,OTHER_POINTER_LOWTAG(reg_NFP)
420         stw reg_NFP,4(reg_CFP)
421
422         /* Store Lisp state */
423         clrrwi reg_NFP,reg_ALLOC,3
424         store(reg_NFP,reg_CFUNC,CSYMBOL(dynamic_space_free_pointer))
425         /* load(reg_CFUNC,current_thread) */
426         
427         store(reg_BSP,reg_CFUNC,CSYMBOL(current_binding_stack_pointer))
428         store(reg_CSP,reg_CFUNC,CSYMBOL(current_control_stack_pointer))
429         store(reg_CFP,reg_CFUNC,CSYMBOL(current_control_frame_pointer))
430
431         /* No longer in Lisp */
432         store(reg_CSP,reg_CFUNC,CSYMBOL(foreign_function_call_active))
433         /* load(reg_POLL,saver2) */
434         /* Disable pseudo-atomic; check pending interrupt */
435         andi. reg_NL3, reg_ALLOC, 1
436         subi reg_ALLOC, reg_ALLOC, 4
437         twnei reg_NL3, 0
438
439         mr reg_NL3,reg_NARGS
440
441 #ifdef LISP_FEATURE_DARWIN
442         /* PowerOpen (i.e. OS X) requires the callee address in r12
443            (a.k.a. CFUNC), so move it back there, too. */
444         mfctr reg_CFUNC
445 #endif
446         /* Into C we go. */
447         bctrl
448
449         /* Re-establish NIL */
450 #ifdef LISP_FEATURE_DARWIN
451         lis reg_NULL,hi16(NIL)
452         ori reg_NULL,reg_NULL,lo16(NIL)
453 #else
454         lis reg_NULL,NIL@h
455         ori reg_NULL,reg_NULL,NIL@l
456 #endif
457         /* And reg_ZERO */
458         li reg_ZERO,0
459
460         /* If we GC'ed during the FF code (as the result of a callback ?)
461         the tagged lisp registers may now contain garbage (since the
462         registers were saved by C and not seen by the GC.)  Put something
463         harmless in all such registers before allowing an interrupt */
464         li reg_CODE,0
465         li reg_CNAME,0
466         li reg_LEXENV,0
467         /* reg_OCFP was pointing to a control stack frame & was preserved by C */
468         li reg_LRA,0
469         li reg_A0,0
470         li reg_A1,0
471         li reg_A2,0
472         li reg_A3,0
473         li reg_L0,0
474         li reg_L1,0
475         li reg_L2,0
476         li reg_LIP,0
477
478         /* Atomic ... */
479         li reg_NL3,-4        
480         li reg_ALLOC,4
481
482         /* No long in foreign function call. */
483         store(reg_ZERO,reg_NL2,CSYMBOL(foreign_function_call_active))
484
485         /* The free pointer may have moved */
486         load(reg_NL4,CSYMBOL(dynamic_space_free_pointer))
487         add reg_ALLOC,reg_ALLOC,reg_NL4
488
489         /* The BSP wasn't preserved by C, so load it */
490         load(reg_BSP,CSYMBOL(current_binding_stack_pointer))
491
492         /* Other lisp stack/frame pointers were preserved by C.
493         I can't imagine why they'd have moved */
494
495         /* Get the return address back. */
496         lwz reg_LIP,4(reg_CFP)
497         lwz reg_CODE,8(reg_CFP)
498         add reg_LIP,reg_CODE,reg_LIP
499         la reg_LIP,-OTHER_POINTER_LOWTAG(reg_LIP)
500
501         /* No longer atomic */
502         andi. reg_NL3, reg_ALLOC, 1
503         subi reg_ALLOC, reg_ALLOC, 4
504         twnei reg_NL3, 0
505
506         mtlr reg_LIP
507         
508         /* Reset the lisp stack. */
509         mr reg_CSP,reg_CFP
510         mr reg_CFP,reg_OCFP
511         
512         /* And back into Lisp. */
513         blr
514
515         SET_SIZE(call_into_c)
516
517         GFUNCDEF(xundefined_tramp)
518         .globl CSYMBOL(undefined_tramp)
519         .long   SIMPLE_FUN_HEADER_WIDETAG                         /* header */
520         .long   CSYMBOL(undefined_tramp) - SIMPLE_FUN_CODE_OFFSET /* self */
521         .long   NIL                                               /* next */
522         .long   NIL                                               /* name */
523         .long   NIL                                               /* arglist */
524         .long   NIL                                               /* type */
525         .long   NIL                                               /* xref */
526 CSYMBOL(undefined_tramp):
527         /* Point reg_CODE to the header and tag it as function, since
528            the debugger regards a function pointer in reg_CODE which
529            doesn't point to a code object as undefined function.  */
530         bcl 20,31,.+4                  /* get address of the next instruction */
531         mflr reg_CODE                  /* header 1 extra word back from here */
532         addi reg_CODE,reg_CODE,-(SIMPLE_FUN_CODE_OFFSET+4)
533         
534         twllei reg_ZERO,trap_Cerror
535         .byte 4
536         .byte UNDEFINED_FUN_ERROR
537         .byte 254, sc_DescriptorReg+0x40, 1 /* 140?  sparc says sc_descriptorReg */
538         /* This stuff is for the continuable error.  I don't think there's
539          * any support for it on the lisp side */
540         .align 2
541 1:      lwz reg_CODE,FDEFN_RAW_ADDR_OFFSET(reg_FDEFN)
542         la reg_LIP,SIMPLE_FUN_CODE_OFFSET(reg_CODE)
543         mtctr reg_LIP
544         bctr
545         mr reg_CSP,reg_CFP
546         b 1b
547
548         SET_SIZE(xundefined_tramp)
549
550         GFUNCDEF(xclosure_tramp)
551         .globl CSYMBOL(closure_tramp)
552 CSYMBOL(closure_tramp):
553         lwz reg_LEXENV,FDEFN_FUN_OFFSET(reg_FDEFN)
554         lwz reg_CODE,CLOSURE_FUN_OFFSET(reg_LEXENV)
555         la reg_LIP,SIMPLE_FUN_CODE_OFFSET(reg_CODE)
556         mtctr reg_LIP
557         bctr
558
559         SET_SIZE(xclosure_tramp)
560
561         GFUNCDEF(xfuncallable_instance_tramp)
562         .globl CSYMBOL(funcallable_instance_tramp)
563         .long SIMPLE_FUN_HEADER_WIDETAG
564 CSYMBOL(funcallable_instance_tramp) = . + 1
565         .long CSYMBOL(funcallable_instance_tramp)
566         .long NIL
567         .long NIL
568         .long NIL
569         .long NIL
570         .long NIL
571         lwz reg_LEXENV,FUNCALLABLE_INSTANCE_FUNCTION_OFFSET(reg_LEXENV)
572         lwz reg_FDEFN,CLOSURE_FUN_OFFSET(reg_LEXENV)
573         addi reg_LIP,reg_FDEFN,SIMPLE_FUN_CODE_OFFSET
574         mtctr reg_LIP
575         bctr
576         SET_SIZE(funcallable_instance_tramp)
577         
578         GFUNCDEF(fun_end_breakpoint_trap)
579         .long 0
580         SET_SIZE(fun_end_breakpoint_trap)
581
582         GFUNCDEF(fun_end_breakpoint)
583         .long 0
584         SET_SIZE(fun_end_breakpoint)
585
586         GFUNCDEF(fun_end_breakpoint_guts)
587         .long 0
588         SET_SIZE(fun_end_breakpoint_guts)
589
590         GFUNCDEF(fun_end_breakpoint_end)
591         .long 0
592         SET_SIZE(fun_end_breakpoint_end)
593
594
595         GFUNCDEF(ppc_flush_cache_line)
596         dcbf 0,REG(3)
597         sync
598         icbi 0,REG(3)
599         sync
600         isync
601         blr
602         SET_SIZE(ppc_flush_cache_line)
603
604         GFUNCDEF(do_pending_interrupt)
605         twllei  reg_ZERO, trap_PendingInterrupt
606         blr
607 /* King Nato's branch has a nop here. Do we need this? */
608         SET_SIZE(do_pending_interrupt)
609         
610 #if defined LISP_FEATURE_GENCGC
611
612         GFUNCDEF(fpu_save)
613         stfd    FREG(1), 0(REG(3))
614         stfd    FREG(2), 8(REG(3))
615         stfd    FREG(3), 16(REG(3))
616         stfd    FREG(4), 24(REG(3))
617         stfd    FREG(5), 32(REG(3))
618         stfd    FREG(6), 40(REG(3))
619         stfd    FREG(7), 48(REG(3))
620         stfd    FREG(8), 56(REG(3))
621         stfd    FREG(9), 64(REG(3))
622         stfd    FREG(10), 72(REG(3))
623         stfd    FREG(11), 80(REG(3))
624         stfd    FREG(12), 88(REG(3))
625         stfd    FREG(13), 96(REG(3))
626         stfd    FREG(14), 104(REG(3))
627         stfd    FREG(15), 112(REG(3))
628         stfd    FREG(16), 120(REG(3))
629         stfd    FREG(17), 128(REG(3))
630         stfd    FREG(18), 136(REG(3))
631         stfd    FREG(19), 144(REG(3))
632         stfd    FREG(20), 152(REG(3))
633         stfd    FREG(21), 160(REG(3))
634         stfd    FREG(22), 168(REG(3))
635         stfd    FREG(23), 176(REG(3))
636         stfd    FREG(24), 184(REG(3))
637         stfd    FREG(25), 192(REG(3))
638         stfd    FREG(26), 200(REG(3))
639         stfd    FREG(27), 208(REG(3))
640         stfd    FREG(28), 216(REG(3))
641         stfd    FREG(29), 224(REG(3))
642         stfd    FREG(30), 232(REG(3))
643         stfd    FREG(31), 240(REG(3))
644         blr
645         SET_SIZE(fpu_save)
646         
647         GFUNCDEF(fpu_restore)
648         lfd     FREG(1), 0(REG(3))
649         lfd     FREG(2), 8(REG(3))
650         lfd     FREG(3), 16(REG(3))
651         lfd     FREG(4), 24(REG(3))
652         lfd     FREG(5), 32(REG(3))
653         lfd     FREG(6), 40(REG(3))
654         lfd     FREG(7), 48(REG(3))
655         lfd     FREG(8), 56(REG(3))
656         lfd     FREG(9), 64(REG(3))
657         lfd     FREG(10), 72(REG(3))
658         lfd     FREG(11), 80(REG(3))
659         lfd     FREG(12), 88(REG(3))
660         lfd     FREG(13), 96(REG(3))
661         lfd     FREG(14), 104(REG(3))
662         lfd     FREG(15), 112(REG(3))
663         lfd     FREG(16), 120(REG(3))
664         lfd     FREG(17), 128(REG(3))
665         lfd     FREG(18), 136(REG(3))
666         lfd     FREG(19), 144(REG(3))
667         lfd     FREG(20), 152(REG(3))
668         lfd     FREG(21), 160(REG(3))
669         lfd     FREG(22), 168(REG(3))
670         lfd     FREG(23), 176(REG(3))
671         lfd     FREG(24), 184(REG(3))
672         lfd     FREG(25), 192(REG(3))
673         lfd     FREG(26), 200(REG(3))
674         lfd     FREG(27), 208(REG(3))
675         lfd     FREG(28), 216(REG(3))
676         lfd     FREG(29), 224(REG(3))
677         lfd     FREG(30), 232(REG(3))
678         lfd     FREG(31), 240(REG(3))
679         blr
680         SET_SIZE(fpu_restore)
681         
682 #endif