/[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.4 - (hide annotations)
Fri Jul 30 00:53:41 2004 UTC (9 years, 8 months ago) by rtoy
Branch: MAIN
CVS Tags: snapshot-2004-10, snapshot-2004-09, snapshot-2004-12, snapshot-2004-11, snapshot-2005-01, snapshot-2005-02
Changes since 1.3: +11 -0 lines
lispregs.h, sparc-lispregs.h:
  o Move the SC_OFFSET_{HI,LO} macros from sparc-lispregs to
    lispregs.h, so they can be used elsewhere.

ppc-lispregs.h:
  o Define the register numbers so they can be used in the SC_OFFSET
    macros.

ppc-assem.S:
  o Document what the byte 18<<2, 0, 0, 24 is supposed to do.
  o Use the SC_OFFSET macros in undefined_tramp instead of hard-wiring
    the register number.
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    

  ViewVC Help
Powered by ViewVC 1.1.5