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