]> gitweb.factorcode.org Git - factor.git/blob - vm/cpu-ppc.S
0a0f3356163c3ef9cc75c622c436137be263e181
[factor.git] / vm / cpu-ppc.S
1 /* Parts of this file were snarfed from SBCL src/runtime/ppc-assem.S, which is
2 in the public domain. */
3 #include "asm.h"
4
5 #define DS_REG r13
6
7 DEF(void,primitive_fixnum_add,(void)):
8         lwz r3,0(DS_REG)
9         lwz r4,-4(DS_REG)
10         subi DS_REG,DS_REG,4
11         li r0,0
12         mtxer r0
13         addo. r5,r3,r4
14         bso add_overflow
15         stw r5,0(DS_REG)
16         blr
17 add_overflow:
18         b MANGLE(overflow_fixnum_add)
19
20 DEF(void,primitive_fixnum_subtract,(void)):
21         lwz r3,-4(DS_REG)
22         lwz r4,0(DS_REG)
23         subi DS_REG,DS_REG,4
24         li r0,0
25         mtxer r0
26         subfo. r5,r4,r3
27         bso sub_overflow
28         stw r5,0(DS_REG)
29         blr
30 sub_overflow:
31         b MANGLE(overflow_fixnum_subtract)
32
33 DEF(void,primitive_fixnum_multiply,(void)):
34         lwz r3,0(DS_REG)
35         lwz r4,-4(DS_REG)
36         subi DS_REG,DS_REG,4
37         srawi r3,r3,3
38         mullwo. r5,r3,r4
39         bso multiply_overflow
40         stw r5,0(DS_REG)
41         blr
42 multiply_overflow:
43         srawi r4,r4,3
44         b MANGLE(overflow_fixnum_multiply)
45         
46 /* Note that the XT is passed to the quotation in r11 */
47 #define CALL_OR_JUMP_QUOT \
48         lwz r11,12(r3)     /* load quotation-xt slot */ XX \
49
50 #define CALL_QUOT \
51         CALL_OR_JUMP_QUOT XX \
52         mtlr r11           /* prepare to call XT with quotation in r3 */ XX \
53         blrl               /* go */
54
55 #define JUMP_QUOT \
56         CALL_OR_JUMP_QUOT XX \
57         mtctr r11          /* prepare to call XT with quotation in r3 */ XX \
58         bctr               /* go */
59
60 #define PARAM_SIZE 32
61
62 #define SAVED_INT_REGS_SIZE 96
63
64 #define SAVED_FP_REGS_SIZE 144
65
66 #define SAVED_V_REGS_SIZE 208
67
68 #define FRAME (RESERVED_SIZE + PARAM_SIZE + SAVED_INT_REGS_SIZE + SAVED_FP_REGS_SIZE + SAVED_V_REGS_SIZE + 8)
69    
70 #if defined( __APPLE__)
71         #define LR_SAVE 8
72         #define RESERVED_SIZE 24
73 #else
74         #define LR_SAVE 4
75         #define RESERVED_SIZE 8
76 #endif
77
78 #define SAVE_LR(reg) stw reg,(LR_SAVE + FRAME)(r1)
79
80 #define LOAD_LR(reg) lwz reg,(LR_SAVE + FRAME)(r1)
81
82 #define SAVE_AT(offset) (RESERVED_SIZE + PARAM_SIZE + 4 * offset)
83
84 #define SAVE_INT(register,offset) stw register,SAVE_AT(offset)(r1)
85 #define RESTORE_INT(register,offset) lwz register,SAVE_AT(offset)(r1)
86
87 #define SAVE_FP(register,offset) stfd register,SAVE_AT(offset)(r1)
88 #define RESTORE_FP(register,offset) lfd register,SAVE_AT(offset)(r1)
89
90 #define SAVE_V(register,offset) \
91         li r2,SAVE_AT(offset) XX \
92         stvxl register,r2,r1
93
94 #define RESTORE_V(register,offset) \
95         li r2,SAVE_AT(offset) XX \
96         lvxl register,r2,r1
97
98 #define PROLOGUE \
99         mflr r0 XX         /* get caller's return address */ \
100         stwu r1,-FRAME(r1) XX /* create a stack frame to hold non-volatile registers */ \
101         SAVE_LR(r0)
102
103 #define EPILOGUE \
104         LOAD_LR(r0) XX \
105         lwz r1,0(r1) XX    /* destroy the stack frame */ \
106         mtlr r0            /* get ready to return */
107
108 /* We have to save and restore nonvolatile registers because
109 the Factor compiler treats the entire register file as volatile. */
110 DEF(void,c_to_factor,(CELL quot)):
111         PROLOGUE
112
113         SAVE_INT(r15,0)    /* save GPRs */
114         SAVE_INT(r16,1)
115         SAVE_INT(r17,2)
116         SAVE_INT(r18,3)
117         SAVE_INT(r19,4)
118         SAVE_INT(r20,5)
119         SAVE_INT(r21,6)
120         SAVE_INT(r22,7)
121         SAVE_INT(r23,8)
122         SAVE_INT(r24,9)
123         SAVE_INT(r25,10)
124         SAVE_INT(r26,11)
125         SAVE_INT(r27,12)
126         SAVE_INT(r28,13)
127         SAVE_INT(r29,14)
128         SAVE_INT(r30,15)
129         SAVE_INT(r31,16)
130
131         SAVE_FP(f14,20) /* save FPRs */
132         SAVE_FP(f15,22)
133         SAVE_FP(f16,24)
134         SAVE_FP(f17,26)
135         SAVE_FP(f18,28)
136         SAVE_FP(f19,30)
137         SAVE_FP(f20,32)
138         SAVE_FP(f21,34)
139         SAVE_FP(f22,36)
140         SAVE_FP(f23,38)
141         SAVE_FP(f24,40)
142         SAVE_FP(f25,42)
143         SAVE_FP(f26,44)
144         SAVE_FP(f27,46)
145         SAVE_FP(f28,48)
146         SAVE_FP(f29,50)
147         SAVE_FP(f30,52)
148         SAVE_FP(f31,54)
149
150         SAVE_V(v20,56)
151         SAVE_V(v21,60)
152         SAVE_V(v22,64)
153         SAVE_V(v23,68)
154         SAVE_V(v24,72)
155         SAVE_V(v25,76)
156         SAVE_V(v26,80)
157         SAVE_V(v27,84)
158         SAVE_V(v28,88)
159         SAVE_V(v29,92)
160         SAVE_V(v30,96)
161         SAVE_V(v31,100)
162
163         mfvscr v0
164         li r2,SAVE_AT(104)
165         stvxl v0,r2,r1
166         addi r2,r2,0xc
167         lwzx r4,r2,r1
168         lis r5,0x1
169         andc r4,r4,r5
170         stwx r4,r2,r1
171         subi r2,r2,0xc
172         lvxl v0,r2,r1
173         mtvscr v0
174
175         SAVE_INT(r3,19)    /* save quotation since we're about to mangle it */
176
177         mr r3,r1           /* pass call stack pointer as an argument */
178         bl MANGLE(save_callstack_bottom)
179
180         RESTORE_INT(r3,19)       /* restore quotation */
181         CALL_QUOT
182
183         RESTORE_V(v0,104)
184         mtvscr v0
185
186         RESTORE_V(v31,100)
187         RESTORE_V(v30,96)
188         RESTORE_V(v29,92)
189         RESTORE_V(v28,88)
190         RESTORE_V(v27,84)
191         RESTORE_V(v26,80)
192         RESTORE_V(v25,76)
193         RESTORE_V(v24,72)
194         RESTORE_V(v23,68)
195         RESTORE_V(v22,64)
196         RESTORE_V(v21,60)
197         RESTORE_V(v20,56)
198
199         RESTORE_FP(f31,54)
200         RESTORE_FP(f30,52)
201         RESTORE_FP(f29,50)
202         RESTORE_FP(f28,48)
203         RESTORE_FP(f27,46)
204         RESTORE_FP(f26,44)
205         RESTORE_FP(f25,42)
206         RESTORE_FP(f24,40)
207         RESTORE_FP(f23,38)
208         RESTORE_FP(f22,36)
209         RESTORE_FP(f21,34)
210         RESTORE_FP(f20,32)
211         RESTORE_FP(f19,30)
212         RESTORE_FP(f18,28)
213         RESTORE_FP(f17,26)
214         RESTORE_FP(f16,24)
215         RESTORE_FP(f15,22)
216         RESTORE_FP(f14,20)      /* save FPRs */
217
218         RESTORE_INT(r31,16)   /* restore GPRs */
219         RESTORE_INT(r30,15)
220         RESTORE_INT(r29,14)
221         RESTORE_INT(r28,13)
222         RESTORE_INT(r27,12)
223         RESTORE_INT(r26,11)
224         RESTORE_INT(r25,10)
225         RESTORE_INT(r24,9)
226         RESTORE_INT(r23,8)
227         RESTORE_INT(r22,7)
228         RESTORE_INT(r21,6)
229         RESTORE_INT(r20,5)
230         RESTORE_INT(r19,4)
231         RESTORE_INT(r18,3)
232         RESTORE_INT(r17,2)
233         RESTORE_INT(r16,1)
234         RESTORE_INT(r15,0)
235
236         EPILOGUE
237         blr
238
239 /* We pass a function pointer to memcpy in r6 to work around a Mac OS X ABI
240 limitation which would otherwise require us to do a bizzaro PC-relative
241 trampoline to retrieve the function address */
242 DEF(void,set_callstack,(F_STACK_FRAME *to, F_STACK_FRAME *from, CELL length, void *memcpy)):
243         sub r1,r3,r5       /* compute new stack pointer */
244         mr r3,r1           /* start of destination of memcpy() */
245         stwu r1,-64(r1)    /* setup fake stack frame for memcpy() */
246         mtlr r6            /* prepare to call memcpy() */
247         blrl               /* go */
248         lwz r1,0(r1)       /* tear down fake stack frame */
249         lwz r0,LR_SAVE(r1) /* we have restored the stack; load return address */
250         mtlr r0            /* prepare to return to restored callstack */
251         blr                /* go */
252
253 DEF(void,throw_impl,(CELL quot, F_STACK_FRAME *rewind_to, void *vm)):
254         mr r1,r4           /* compute new stack pointer */
255         mr r4,r5           /* make vm ptr 2nd arg in case quot_xt = lazy_jit_compile */
256         lwz r0,LR_SAVE(r1) /* we have rewound the stack; load return address */
257         mtlr r0
258         JUMP_QUOT          /* call the quotation */
259
260 DEF(void,lazy_jit_compile,(CELL quot, void *vm)):
261         mr r5,r4           /* vm ptr is 3rd arg */
262         mr r4,r1           /* save stack pointer */
263         PROLOGUE
264         bl MANGLE(lazy_jit_compile_impl)
265         EPILOGUE
266         JUMP_QUOT          /* call the quotation */
267
268 /* Thanks to Joshua Grams for this code.
269
270 On PowerPC processors, we must flush the instruction cache manually
271 after writing to the code heap. */
272
273 DEF(void,flush_icache,(void *start, int len)):
274         /* compute number of cache lines to flush */
275         add r4,r4,r3
276         clrrwi r3,r3,5     /* align addr to next lower cache line boundary */
277         sub r4,r4,r3       /* then n_lines = (len + 0x1f) / 0x20 */
278         addi r4,r4,0x1f
279         srwi. r4,r4,5      /* note '.' suffix */
280         beqlr              /* if n_lines == 0, just return. */
281         mtctr r4           /* flush cache lines */
282 0:      dcbf 0,r3          /* for each line... */
283         sync
284         icbi 0,r3
285         addi r3,r3,0x20
286         bdnz 0b
287         sync               /* finish up */
288         isync
289         blr
290
291 DEF(void,primitive_inline_cache_miss,(void)):
292         mflr r6
293 DEF(void,primitive_inline_cache_miss_tail,(void)):
294         PROLOGUE
295         mr r3,r6
296         bl MANGLE(inline_cache_miss)
297         EPILOGUE
298         mtctr r3
299         bctr
300
301 DEF(void,get_ppc_fpu_env,(void*)):
302         mffs f0
303         stfd f0,0(r3)
304         blr
305
306 DEF(void,set_ppc_fpu_env,(const void*)):
307         lfd f0,0(r3)
308         mtfsf 0xff,f0
309         blr
310
311 DEF(void,get_ppc_vmx_env,(void*)):
312         mfvscr v0
313         subi r4,r1,16
314         li r5,0xf
315         andc r4,r4,r5
316         stvxl v0,0,r4
317         li r5,0xc
318         lwzx r6,r5,r4
319         stw r6,0(r3)
320         blr
321
322 DEF(void,set_ppc_vmx_env,(const void*)):
323         subi r4,r1,16
324         li r5,0xf
325         andc r4,r4,r5
326         li r5,0xc
327         lwz r6,0(r3)
328         stwx r6,r5,r4
329         lvxl v0,0,r4
330         mtvscr v0
331         blr
332