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