]> gitweb.factorcode.org Git - factor.git/blob - vm/cpu-ppc.S
Merge branch 'master' into experimental
[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 r29
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,9(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 FRAME (RESERVED_SIZE + PARAM_SIZE + SAVED_INT_REGS_SIZE + SAVED_FP_REGS_SIZE + 8)
67    
68 #if defined( __APPLE__)
69         #define LR_SAVE 8
70         #define RESERVED_SIZE 24
71 #else
72         #define LR_SAVE 4
73         #define RESERVED_SIZE 8
74 #endif
75
76 #define SAVE_LR(reg) stw reg,(LR_SAVE + FRAME)(r1)
77
78 #define LOAD_LR(reg) lwz reg,(LR_SAVE + FRAME)(r1)
79
80 #define SAVE_AT(offset) (RESERVED_SIZE + PARAM_SIZE + 4 * offset)
81
82 #define SAVE_INT(register,offset) stw register,SAVE_AT(offset)(r1)
83 #define RESTORE_INT(register,offset) lwz register,SAVE_AT(offset)(r1)
84
85 #define SAVE_FP(register,offset) stfd register,SAVE_AT(offset)(r1)
86 #define RESTORE_FP(register,offset) lfd register,SAVE_AT(offset)(r1)
87
88 #define PROLOGUE \
89         mflr r0 XX         /* get caller's return address */ \
90         stwu r1,-FRAME(r1) XX /* create a stack frame to hold non-volatile registers */ \
91         SAVE_LR(r0)
92
93 #define EPILOGUE \
94         LOAD_LR(r0) XX \
95         lwz r1,0(r1) XX    /* destroy the stack frame */ \
96         mtlr r0            /* get ready to return */
97
98 /* We have to save and restore nonvolatile registers because
99 the Factor compiler treats the entire register file as volatile. */
100 DEF(void,c_to_factor,(CELL quot)):
101         PROLOGUE
102
103         SAVE_INT(r13,0)    /* save GPRs */
104         SAVE_INT(r14,1)
105         SAVE_INT(r15,2)
106         SAVE_INT(r16,3)
107         SAVE_INT(r17,4)
108         SAVE_INT(r18,5)
109         SAVE_INT(r19,6)
110         SAVE_INT(r20,7)
111         SAVE_INT(r21,8)
112         SAVE_INT(r22,9)
113         SAVE_INT(r23,10)
114         SAVE_INT(r24,11)
115         SAVE_INT(r25,12)
116         SAVE_INT(r26,13)
117         SAVE_INT(r27,14)
118         SAVE_INT(r28,15)
119         SAVE_INT(r31,16)
120
121         SAVE_FP(f14,20) /* save FPRs */
122         SAVE_FP(f15,22)
123         SAVE_FP(f16,24)
124         SAVE_FP(f17,26)
125         SAVE_FP(f18,28)
126         SAVE_FP(f19,30)
127         SAVE_FP(f20,32)
128         SAVE_FP(f21,34)
129         SAVE_FP(f22,36)
130         SAVE_FP(f23,38)
131         SAVE_FP(f24,40)
132         SAVE_FP(f25,42)
133         SAVE_FP(f26,44)
134         SAVE_FP(f27,46)
135         SAVE_FP(f28,48)
136         SAVE_FP(f29,50)
137         SAVE_FP(f30,52)
138         SAVE_FP(f31,54)
139
140         SAVE_INT(r3,19)    /* save quotation since we're about to mangle it */
141
142         mr r3,r1           /* pass call stack pointer as an argument */
143         bl MANGLE(save_callstack_bottom)
144
145         RESTORE_INT(r3,19)       /* restore quotation */
146         CALL_QUOT
147
148         RESTORE_FP(f31,54)
149         RESTORE_FP(f30,52)
150         RESTORE_FP(f29,50)
151         RESTORE_FP(f28,48)
152         RESTORE_FP(f27,46)
153         RESTORE_FP(f26,44)
154         RESTORE_FP(f25,42)
155         RESTORE_FP(f24,40)
156         RESTORE_FP(f23,38)
157         RESTORE_FP(f22,36)
158         RESTORE_FP(f21,34)
159         RESTORE_FP(f20,32)
160         RESTORE_FP(f19,30)
161         RESTORE_FP(f18,28)
162         RESTORE_FP(f17,26)
163         RESTORE_FP(f16,24)
164         RESTORE_FP(f15,22)
165         RESTORE_FP(f14,20)      /* save FPRs */
166
167         RESTORE_INT(r31,16)   /* restore GPRs */
168         RESTORE_INT(r28,15)
169         RESTORE_INT(r27,14)
170         RESTORE_INT(r26,13)
171         RESTORE_INT(r25,12)
172         RESTORE_INT(r24,11)
173         RESTORE_INT(r23,10)
174         RESTORE_INT(r22,9)
175         RESTORE_INT(r21,8)
176         RESTORE_INT(r20,7)
177         RESTORE_INT(r19,6)
178         RESTORE_INT(r18,5)
179         RESTORE_INT(r17,4)
180         RESTORE_INT(r16,3)
181         RESTORE_INT(r15,2)
182         RESTORE_INT(r14,1)
183         RESTORE_INT(r13,0)
184
185         EPILOGUE
186         blr
187
188 /* We pass a function pointer to memcpy in r6 to work around a Mac OS X ABI
189 limitation which would otherwise require us to do a bizzaro PC-relative
190 trampoline to retrieve the function address */
191 DEF(void,set_callstack,(F_STACK_FRAME *to, F_STACK_FRAME *from, CELL length, void *memcpy)):
192         sub r1,r3,r5       /* compute new stack pointer */
193         mr r3,r1           /* start of destination of memcpy() */
194         stwu r1,-64(r1)    /* setup fake stack frame for memcpy() */
195         mtlr r6            /* prepare to call memcpy() */
196         blrl               /* go */
197         lwz r1,0(r1)       /* tear down fake stack frame */
198         lwz r0,LR_SAVE(r1) /* we have restored the stack; load return address */
199         mtlr r0            /* prepare to return to restored callstack */
200         blr                /* go */
201
202 DEF(void,throw_impl,(CELL quot, F_STACK_FRAME *rewind_to)):
203         mr r1,r4           /* compute new stack pointer */
204         lwz r0,LR_SAVE(r1) /* we have rewound the stack; load return address */
205         mtlr r0
206         JUMP_QUOT          /* call the quotation */
207
208 DEF(void,lazy_jit_compile,(CELL quot)):
209         mr r4,r1           /* save stack pointer */
210         PROLOGUE
211         bl MANGLE(lazy_jit_compile_impl)
212         EPILOGUE
213         JUMP_QUOT          /* call the quotation */
214
215 /* Thanks to Joshua Grams for this code.
216
217 On PowerPC processors, we must flush the instruction cache manually
218 after writing to the code heap. */
219
220 DEF(void,flush_icache,(void *start, int len)):
221         /* compute number of cache lines to flush */
222         add r4,r4,r3
223         clrrwi r3,r3,5     /* align addr to next lower cache line boundary */
224         sub r4,r4,r3       /* then n_lines = (len + 0x1f) / 0x20 */
225         addi r4,r4,0x1f
226         srwi. r4,r4,5      /* note '.' suffix */
227         beqlr              /* if n_lines == 0, just return. */
228         mtctr r4           /* flush cache lines */
229 0:      dcbf 0,r3          /* for each line... */
230         sync
231         icbi 0,r3
232         addi r3,r3,0x20
233         bdnz 0b
234         sync               /* finish up */
235         isync
236         blr