]> gitweb.factorcode.org Git - factor.git/blob - basis/cpu/ppc/bootstrap.factor
Merge branch 'master' of git://factorcode.org/git/factor
[factor.git] / basis / cpu / ppc / bootstrap.factor
1 ! Copyright (C) 2007, 2008 Slava Pestov.\r
2 ! See http://factorcode.org/license.txt for BSD license.\r
3 USING: bootstrap.image.private kernel kernel.private namespaces\r
4 system cpu.ppc.assembler compiler.codegen.fixup compiler.units\r
5 compiler.constants math math.private layouts words\r
6 vocabs slots.private locals.backend ;\r
7 IN: bootstrap.ppc\r
8 \r
9 4 \ cell set\r
10 big-endian on\r
11 \r
12 CONSTANT: ds-reg 13\r
13 CONSTANT: rs-reg 14\r
14 \r
15 : factor-area-size ( -- n ) 4 bootstrap-cells ;\r
16 \r
17 : stack-frame ( -- n )\r
18     factor-area-size c-area-size + 4 bootstrap-cells align ;\r
19 \r
20 : next-save ( -- n ) stack-frame bootstrap-cell - ;\r
21 : xt-save ( -- n ) stack-frame 2 bootstrap-cells - ;\r
22 \r
23 [\r
24     0 6 LOAD32 rc-absolute-ppc-2/2 rt-immediate jit-rel\r
25     11 6 profile-count-offset LWZ\r
26     11 11 1 tag-fixnum ADDI\r
27     11 6 profile-count-offset STW\r
28     11 6 word-code-offset LWZ\r
29     11 11 compiled-header-size ADDI\r
30     11 MTCTR\r
31     BCTR\r
32 ] jit-profiling jit-define\r
33 \r
34 [\r
35     0 6 LOAD32 rc-absolute-ppc-2/2 rt-this jit-rel\r
36     0 MFLR\r
37     1 1 stack-frame SUBI\r
38     6 1 xt-save STW\r
39     stack-frame 6 LI\r
40     6 1 next-save STW\r
41     0 1 lr-save stack-frame + STW\r
42 ] jit-prolog jit-define\r
43 \r
44 [\r
45     0 6 LOAD32 rc-absolute-ppc-2/2 rt-immediate jit-rel\r
46     6 ds-reg 4 STWU\r
47 ] jit-push-immediate jit-define\r
48 \r
49 [\r
50     0 6 LOAD32 rc-absolute-ppc-2/2 rt-stack-chain jit-rel\r
51     7 6 0 LWZ\r
52     1 7 0 STW\r
53 ] jit-save-stack jit-define\r
54 \r
55 [\r
56     0 6 LOAD32 rc-absolute-ppc-2/2 rt-primitive jit-rel\r
57     6 MTCTR\r
58     BCTR\r
59 ] jit-primitive jit-define\r
60 \r
61 [ 0 BL rc-relative-ppc-3 rt-xt-direct jit-rel ] jit-word-call jit-define\r
62 \r
63 [ 0 B rc-relative-ppc-3 rt-xt jit-rel ] jit-word-jump jit-define\r
64 \r
65 [\r
66     3 ds-reg 0 LWZ\r
67     ds-reg dup 4 SUBI\r
68     0 3 \ f tag-number CMPI\r
69     2 BEQ\r
70     0 B rc-relative-ppc-3 rt-xt jit-rel\r
71 ] jit-if-1 jit-define\r
72 \r
73 [\r
74     0 B rc-relative-ppc-3 rt-xt jit-rel\r
75 ] jit-if-2 jit-define\r
76 \r
77 : jit->r ( -- )\r
78     4 ds-reg 0 LWZ\r
79     ds-reg dup 4 SUBI\r
80     4 rs-reg 4 STWU ;\r
81 \r
82 : jit-2>r ( -- )\r
83     4 ds-reg 0 LWZ\r
84     5 ds-reg -4 LWZ\r
85     ds-reg dup 8 SUBI\r
86     rs-reg dup 8 ADDI\r
87     4 rs-reg 0 STW\r
88     5 rs-reg -4 STW ;\r
89 \r
90 : jit-3>r ( -- )\r
91     4 ds-reg 0 LWZ\r
92     5 ds-reg -4 LWZ\r
93     6 ds-reg -8 LWZ\r
94     ds-reg dup 12 SUBI\r
95     rs-reg dup 12 ADDI\r
96     4 rs-reg 0 STW\r
97     5 rs-reg -4 STW\r
98     6 rs-reg -8 STW ;\r
99 \r
100 : jit-r> ( -- )\r
101     4 rs-reg 0 LWZ\r
102     rs-reg dup 4 SUBI\r
103     4 ds-reg 4 STWU ;\r
104 \r
105 : jit-2r> ( -- )\r
106     4 rs-reg 0 LWZ\r
107     5 rs-reg -4 LWZ\r
108     rs-reg dup 8 SUBI\r
109     ds-reg dup 8 ADDI\r
110     4 ds-reg 0 STW\r
111     5 ds-reg -4 STW ;\r
112 \r
113 : jit-3r> ( -- )\r
114     4 rs-reg 0 LWZ\r
115     5 rs-reg -4 LWZ\r
116     6 rs-reg -8 LWZ\r
117     rs-reg dup 12 SUBI\r
118     ds-reg dup 12 ADDI\r
119     4 ds-reg 0 STW\r
120     5 ds-reg -4 STW\r
121     6 ds-reg -8 STW ;\r
122 \r
123 [\r
124     jit->r\r
125     0 BL rc-relative-ppc-3 rt-xt jit-rel\r
126     jit-r>\r
127 ] jit-dip jit-define\r
128 \r
129 [\r
130     jit-2>r\r
131     0 BL rc-relative-ppc-3 rt-xt jit-rel\r
132     jit-2r>\r
133 ] jit-2dip jit-define\r
134 \r
135 [\r
136     jit-3>r\r
137     0 BL rc-relative-ppc-3 rt-xt jit-rel\r
138     jit-3r>\r
139 ] jit-3dip jit-define\r
140 \r
141 : prepare-(execute) ( -- operand )\r
142     3 ds-reg 0 LWZ\r
143     ds-reg dup 4 SUBI\r
144     4 3 word-xt-offset LWZ\r
145     4 ;\r
146 \r
147 [ prepare-(execute) MTCTR BCTR ] jit-execute-jump jit-define\r
148 \r
149 [ prepare-(execute) MTLR BLRL ] jit-execute-call jit-define\r
150 \r
151 [\r
152     0 1 lr-save stack-frame + LWZ\r
153     1 1 stack-frame ADDI\r
154     0 MTLR\r
155 ] jit-epilog jit-define\r
156 \r
157 [ BLR ] jit-return jit-define\r
158 \r
159 ! ! ! Polymorphic inline caches\r
160 \r
161 ! Load a value from a stack position\r
162 [\r
163     4 ds-reg 0 LWZ rc-absolute-ppc-2 rt-untagged jit-rel\r
164 ] pic-load jit-define\r
165 \r
166 ! Tag\r
167 : load-tag ( -- )\r
168     4 4 tag-mask get ANDI\r
169     4 4 tag-bits get SLWI ;\r
170 \r
171 [ load-tag ] pic-tag jit-define\r
172 \r
173 ! Hi-tag\r
174 [\r
175     3 4 MR\r
176     load-tag\r
177     0 4 object tag-number tag-fixnum CMPI\r
178     2 BNE\r
179     4 3 object tag-number neg LWZ\r
180 ] pic-hi-tag jit-define\r
181 \r
182 ! Tuple\r
183 [\r
184     3 4 MR\r
185     load-tag\r
186     0 4 tuple tag-number tag-fixnum CMPI\r
187     2 BNE\r
188     4 3 tuple tag-number neg bootstrap-cell + LWZ\r
189 ] pic-tuple jit-define\r
190 \r
191 ! Hi-tag and tuple\r
192 [\r
193     3 4 MR\r
194     load-tag\r
195     ! If bits 2 and 3 are set, the tag is either 6 (object) or 7 (tuple)\r
196     0 4 BIN: 110 tag-fixnum CMPI\r
197     5 BLT\r
198     ! Untag r3\r
199     3 3 0 0 31 tag-bits get - RLWINM\r
200     ! Set r4 to 0 for objects, and bootstrap-cell for tuples\r
201     4 4 1 tag-fixnum ANDI\r
202     4 4 1 SRAWI\r
203     ! Load header cell or tuple layout cell\r
204     4 4 3 LWZX\r
205 ] pic-hi-tag-tuple jit-define\r
206 \r
207 [\r
208     0 4 0 CMPI rc-absolute-ppc-2 rt-immediate jit-rel\r
209 ] pic-check-tag jit-define\r
210 \r
211 [\r
212     0 5 LOAD32 rc-absolute-ppc-2/2 rt-immediate jit-rel\r
213     4 0 5 CMP\r
214 ] pic-check jit-define\r
215 \r
216 [ 2 BNE 0 B rc-relative-ppc-3 rt-xt jit-rel ] pic-hit jit-define\r
217 \r
218 ! ! ! Megamorphic caches\r
219 \r
220 [\r
221     ! cache = ...\r
222     0 3 LOAD32 rc-absolute-ppc-2/2 rt-immediate jit-rel\r
223     ! key = class\r
224     5 4 MR\r
225     ! key &= cache.length - 1\r
226     5 5 mega-cache-size get 1- bootstrap-cell * ANDI\r
227     ! cache += array-start-offset\r
228     3 3 array-start-offset ADDI\r
229     ! cache += key\r
230     3 3 5 ADD\r
231     ! if(get(cache) == class)\r
232     6 3 0 LWZ\r
233     6 0 4 CMP\r
234     5 BNE\r
235     ! ... goto get(cache + bootstrap-cell)\r
236     3 3 4 LWZ\r
237     3 3 word-xt-offset LWZ\r
238     3 MTCTR\r
239     BCTR\r
240     ! fall-through on miss\r
241 ] mega-lookup jit-define\r
242 \r
243 ! ! ! Sub-primitives\r
244 \r
245 ! Quotations and words\r
246 [\r
247     3 ds-reg 0 LWZ\r
248     ds-reg dup 4 SUBI\r
249     4 3 quot-xt-offset LWZ\r
250     4 MTCTR\r
251     BCTR\r
252 ] \ (call) define-sub-primitive\r
253 \r
254 ! Objects\r
255 [\r
256     3 ds-reg 0 LWZ\r
257     3 3 tag-mask get ANDI\r
258     3 3 tag-bits get SLWI\r
259     3 ds-reg 0 STW\r
260 ] \ tag define-sub-primitive\r
261 \r
262 [\r
263     3 ds-reg 0 LWZ\r
264     4 ds-reg -4 LWZU\r
265     3 3 1 SRAWI\r
266     4 4 0 0 31 tag-bits get - RLWINM\r
267     4 3 3 LWZX\r
268     3 ds-reg 0 STW\r
269 ] \ slot define-sub-primitive\r
270 \r
271 ! Shufflers\r
272 [\r
273     ds-reg dup 4 SUBI\r
274 ] \ drop define-sub-primitive\r
275 \r
276 [\r
277     ds-reg dup 8 SUBI\r
278 ] \ 2drop define-sub-primitive\r
279 \r
280 [\r
281     ds-reg dup 12 SUBI\r
282 ] \ 3drop define-sub-primitive\r
283 \r
284 [\r
285     3 ds-reg 0 LWZ\r
286     3 ds-reg 4 STWU\r
287 ] \ dup define-sub-primitive\r
288 \r
289 [\r
290     3 ds-reg 0 LWZ\r
291     4 ds-reg -4 LWZ\r
292     ds-reg dup 8 ADDI\r
293     3 ds-reg 0 STW\r
294     4 ds-reg -4 STW\r
295 ] \ 2dup define-sub-primitive\r
296 \r
297 [\r
298     3 ds-reg 0 LWZ\r
299     4 ds-reg -4 LWZ\r
300     5 ds-reg -8 LWZ\r
301     ds-reg dup 12 ADDI\r
302     3 ds-reg 0 STW\r
303     4 ds-reg -4 STW\r
304     5 ds-reg -8 STW\r
305 ] \ 3dup define-sub-primitive\r
306 \r
307 [\r
308     3 ds-reg 0 LWZ\r
309     ds-reg dup 4 SUBI\r
310     3 ds-reg 0 STW\r
311 ] \ nip define-sub-primitive\r
312 \r
313 [\r
314     3 ds-reg 0 LWZ\r
315     ds-reg dup 8 SUBI\r
316     3 ds-reg 0 STW\r
317 ] \ 2nip define-sub-primitive\r
318 \r
319 [\r
320     3 ds-reg -4 LWZ\r
321     3 ds-reg 4 STWU\r
322 ] \ over define-sub-primitive\r
323 \r
324 [\r
325     3 ds-reg -8 LWZ\r
326     3 ds-reg 4 STWU\r
327 ] \ pick define-sub-primitive\r
328 \r
329 [\r
330     3 ds-reg 0 LWZ\r
331     4 ds-reg -4 LWZ\r
332     4 ds-reg 0 STW\r
333     3 ds-reg 4 STWU\r
334 ] \ dupd define-sub-primitive\r
335 \r
336 [\r
337     3 ds-reg 0 LWZ\r
338     4 ds-reg -4 LWZ\r
339     3 ds-reg 4 STWU\r
340     4 ds-reg -4 STW\r
341     3 ds-reg -8 STW\r
342 ] \ tuck define-sub-primitive\r
343 \r
344 [\r
345     3 ds-reg 0 LWZ\r
346     4 ds-reg -4 LWZ\r
347     3 ds-reg -4 STW\r
348     4 ds-reg 0 STW\r
349 ] \ swap define-sub-primitive\r
350 \r
351 [\r
352     3 ds-reg -4 LWZ\r
353     4 ds-reg -8 LWZ\r
354     3 ds-reg -8 STW\r
355     4 ds-reg -4 STW\r
356 ] \ swapd define-sub-primitive\r
357 \r
358 [\r
359     3 ds-reg 0 LWZ\r
360     4 ds-reg -4 LWZ\r
361     5 ds-reg -8 LWZ\r
362     4 ds-reg -8 STW\r
363     3 ds-reg -4 STW\r
364     5 ds-reg 0 STW\r
365 ] \ rot define-sub-primitive\r
366 \r
367 [\r
368     3 ds-reg 0 LWZ\r
369     4 ds-reg -4 LWZ\r
370     5 ds-reg -8 LWZ\r
371     3 ds-reg -8 STW\r
372     5 ds-reg -4 STW\r
373     4 ds-reg 0 STW\r
374 ] \ -rot define-sub-primitive\r
375 \r
376 [ jit->r ] \ load-local define-sub-primitive\r
377 \r
378 ! Comparisons\r
379 : jit-compare ( insn -- )\r
380     0 3 LOAD32 rc-absolute-ppc-2/2 rt-immediate jit-rel\r
381     4 ds-reg 0 LWZ\r
382     5 ds-reg -4 LWZU\r
383     5 0 4 CMP\r
384     2 swap execute( offset -- ) ! magic number\r
385     \ f tag-number 3 LI\r
386     3 ds-reg 0 STW ;\r
387 \r
388 : define-jit-compare ( insn word -- )\r
389     [ [ jit-compare ] curry ] dip define-sub-primitive ;\r
390 \r
391 \ BEQ \ eq? define-jit-compare\r
392 \ BGE \ fixnum>= define-jit-compare\r
393 \ BLE \ fixnum<= define-jit-compare\r
394 \ BGT \ fixnum> define-jit-compare\r
395 \ BLT \ fixnum< define-jit-compare\r
396 \r
397 ! Math\r
398 [\r
399     3 ds-reg 0 LWZ\r
400     ds-reg ds-reg 4 SUBI\r
401     4 ds-reg 0 LWZ\r
402     3 3 4 OR\r
403     3 3 tag-mask get ANDI\r
404     \ f tag-number 4 LI\r
405     0 3 0 CMPI\r
406     2 BNE\r
407     1 tag-fixnum 4 LI\r
408     4 ds-reg 0 STW\r
409 ] \ both-fixnums? define-sub-primitive\r
410 \r
411 : jit-math ( insn -- )\r
412     3 ds-reg 0 LWZ\r
413     4 ds-reg -4 LWZU\r
414     [ 5 3 4 ] dip execute( dst src1 src2 -- )\r
415     5 ds-reg 0 STW ;\r
416 \r
417 [ \ ADD jit-math ] \ fixnum+fast define-sub-primitive\r
418 \r
419 [ \ SUBF jit-math ] \ fixnum-fast define-sub-primitive\r
420 \r
421 [\r
422     3 ds-reg 0 LWZ\r
423     4 ds-reg -4 LWZU\r
424     4 4 tag-bits get SRAWI\r
425     5 3 4 MULLW\r
426     5 ds-reg 0 STW\r
427 ] \ fixnum*fast define-sub-primitive\r
428 \r
429 [ \ AND jit-math ] \ fixnum-bitand define-sub-primitive\r
430 \r
431 [ \ OR jit-math ] \ fixnum-bitor define-sub-primitive\r
432 \r
433 [ \ XOR jit-math ] \ fixnum-bitxor define-sub-primitive\r
434 \r
435 [\r
436     3 ds-reg 0 LWZ\r
437     3 3 NOT\r
438     3 3 tag-mask get XORI\r
439     3 ds-reg 0 STW\r
440 ] \ fixnum-bitnot define-sub-primitive\r
441 \r
442 [\r
443     3 ds-reg 0 LWZ\r
444     3 3 tag-bits get SRAWI\r
445     ds-reg ds-reg 4 SUBI\r
446     4 ds-reg 0 LWZ\r
447     5 4 3 SLW\r
448     6 3 NEG\r
449     7 4 6 SRAW\r
450     7 7 0 0 31 tag-bits get - RLWINM\r
451     0 3 0 CMPI\r
452     2 BGT\r
453     5 7 MR\r
454     5 ds-reg 0 STW\r
455 ] \ fixnum-shift-fast define-sub-primitive\r
456 \r
457 [\r
458     3 ds-reg 0 LWZ\r
459     ds-reg ds-reg 4 SUBI\r
460     4 ds-reg 0 LWZ\r
461     5 4 3 DIVW\r
462     6 5 3 MULLW\r
463     7 6 4 SUBF\r
464     7 ds-reg 0 STW\r
465 ] \ fixnum-mod define-sub-primitive\r
466 \r
467 [\r
468     3 ds-reg 0 LWZ\r
469     ds-reg ds-reg 4 SUBI\r
470     4 ds-reg 0 LWZ\r
471     5 4 3 DIVW\r
472     5 5 tag-bits get SLWI\r
473     5 ds-reg 0 STW\r
474 ] \ fixnum/i-fast define-sub-primitive\r
475 \r
476 [\r
477     3 ds-reg 0 LWZ\r
478     4 ds-reg -4 LWZ\r
479     5 4 3 DIVW\r
480     6 5 3 MULLW\r
481     7 6 4 SUBF\r
482     5 5 tag-bits get SLWI\r
483     5 ds-reg -4 STW\r
484     7 ds-reg 0 STW\r
485 ] \ fixnum/mod-fast define-sub-primitive\r
486 \r
487 [\r
488     3 ds-reg 0 LWZ\r
489     3 3 1 SRAWI\r
490     rs-reg 3 3 LWZX\r
491     3 ds-reg 0 STW\r
492 ] \ get-local define-sub-primitive\r
493 \r
494 [\r
495     3 ds-reg 0 LWZ\r
496     ds-reg ds-reg 4 SUBI\r
497     3 3 1 SRAWI\r
498     rs-reg 3 rs-reg SUBF\r
499 ] \ drop-locals define-sub-primitive\r
500 \r
501 [ "bootstrap.ppc" forget-vocab ] with-compilation-unit\r