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