]> gitweb.factorcode.org Git - factor.git/blob - vm/cpu-ppc.S
Merge branch 'master' into experimental (untested!)
[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
120         SAVE_FP(f14,20)    /* save FPRs */
121         SAVE_FP(f15,22)
122         SAVE_FP(f16,24)
123         SAVE_FP(f17,26)
124         SAVE_FP(f18,28)
125         SAVE_FP(f19,30)
126         SAVE_FP(f20,32)
127         SAVE_FP(f21,34)
128         SAVE_FP(f22,36)
129         SAVE_FP(f23,38)
130         SAVE_FP(f24,40)
131         SAVE_FP(f25,42)
132         SAVE_FP(f26,44)
133         SAVE_FP(f27,46)
134         SAVE_FP(f28,48)
135         SAVE_FP(f29,50)
136         SAVE_FP(f30,52)
137         SAVE_FP(f31,54)
138
139         SAVE_INT(r3,19)    /* save quotation since we're about to mangle it */
140
141         mr r3,r1           /* pass call stack pointer as an argument */
142         bl MANGLE(save_callstack_bottom)
143
144         RESTORE_INT(r3,19)     /* restore quotation */
145         CALL_QUOT
146
147         RESTORE_FP(f31,54)
148         RESTORE_FP(f30,52)
149         RESTORE_FP(f29,50)
150         RESTORE_FP(f28,48)
151         RESTORE_FP(f27,46)
152         RESTORE_FP(f26,44)
153         RESTORE_FP(f25,42)
154         RESTORE_FP(f24,40)
155         RESTORE_FP(f23,38)
156         RESTORE_FP(f22,36)
157         RESTORE_FP(f21,34)
158         RESTORE_FP(f20,32)
159         RESTORE_FP(f19,30)
160         RESTORE_FP(f18,28)
161         RESTORE_FP(f17,26)
162         RESTORE_FP(f16,24)
163         RESTORE_FP(f15,22)
164         RESTORE_FP(f14,20)    /* save FPRs */
165
166         RESTORE_INT(r28,15)   /* restore GPRs */
167         RESTORE_INT(r27,14)
168         RESTORE_INT(r26,13)
169         RESTORE_INT(r25,12)
170         RESTORE_INT(r24,11)
171         RESTORE_INT(r23,10)
172         RESTORE_INT(r22,9)
173         RESTORE_INT(r21,8)
174         RESTORE_INT(r20,7)
175         RESTORE_INT(r19,6)
176         RESTORE_INT(r18,5)
177         RESTORE_INT(r17,4)
178         RESTORE_INT(r16,3)
179         RESTORE_INT(r15,2)
180         RESTORE_INT(r14,1)
181         RESTORE_INT(r13,0)
182
183         EPILOGUE
184         blr
185
186 /* We pass a function pointer to memcpy in r6 to work around a Mac OS X ABI
187 limitation which would otherwise require us to do a bizzaro PC-relative
188 trampoline to retrieve the function address */
189 DEF(void,set_callstack,(F_STACK_FRAME *to, F_STACK_FRAME *from, CELL length, void *memcpy)):
190         sub r1,r3,r5       /* compute new stack pointer */
191         mr r3,r1           /* start of destination of memcpy() */
192         stwu r1,-64(r1)    /* setup fake stack frame for memcpy() */
193         mtlr r6            /* prepare to call memcpy() */
194         blrl               /* go */
195         lwz r1,0(r1)       /* tear down fake stack frame */
196         lwz r0,LR_SAVE(r1) /* we have restored the stack; load return address */
197         mtlr r0            /* prepare to return to restored callstack */
198         blr                /* go */
199
200 DEF(void,throw_impl,(CELL quot, F_STACK_FRAME *rewind_to)):
201         mr r1,r4           /* compute new stack pointer */
202         lwz r0,LR_SAVE(r1) /* we have rewound the stack; load return address */
203         mtlr r0
204         JUMP_QUOT          /* call the quotation */
205
206 DEF(void,lazy_jit_compile,(CELL quot)):
207         mr r4,r1           /* save stack pointer */
208         PROLOGUE
209         bl MANGLE(lazy_jit_compile_impl)
210         EPILOGUE
211         JUMP_QUOT          /* call the quotation */
212
213 /* Thanks to Joshua Grams for this code.
214
215 On PowerPC processors, we must flush the instruction cache manually
216 after writing to the code heap. */
217
218 DEF(void,flush_icache,(void *start, int len)):
219         /* compute number of cache lines to flush */
220         add r4,r4,r3
221         clrrwi r3,r3,5     /* align addr to next lower cache line boundary */
222         sub r4,r4,r3       /* then n_lines = (len + 0x1f) / 0x20 */
223         addi r4,r4,0x1f
224         srwi. r4,r4,5      /* note '.' suffix */
225         beqlr              /* if n_lines == 0, just return. */
226         mtctr r4           /* flush cache lines */
227 0:      dcbf 0,r3          /* for each line... */
228         sync
229         icbi 0,r3
230         addi r3,r3,0x20
231         bdnz 0b
232         sync               /* finish up */
233         isync
234         blr