]> gitweb.factorcode.org Git - factor.git/blob - basis/compiler/cfg/instructions/instructions.factor
Merge branch 'master' into more_aggressive_coalescing
[factor.git] / basis / compiler / cfg / instructions / instructions.factor
1 ! Copyright (C) 2008, 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: assocs accessors arrays kernel sequences namespaces words
4 math math.order layouts classes.algebra classes.union
5 compiler.units alien byte-arrays compiler.constants combinators
6 compiler.cfg.registers compiler.cfg.instructions.syntax ;
7 IN: compiler.cfg.instructions
8
9 <<
10 SYMBOL: insn-classes
11 V{ } clone insn-classes set-global
12 >>
13
14 : new-insn ( ... class -- insn ) f swap boa ; inline
15
16 ! Virtual CPU instructions, used by CFG and machine IRs
17 TUPLE: insn ;
18
19 ! Instructions which are referentially transparent; used for
20 ! value numbering
21 TUPLE: pure-insn < insn ;
22
23 ! Stack operations
24 INSN: ##load-immediate
25 def: dst/int-rep
26 constant: val ;
27
28 INSN: ##load-reference
29 def: dst/int-rep
30 constant: obj ;
31
32 INSN: ##peek
33 def: dst/int-rep
34 literal: loc ;
35
36 INSN: ##replace
37 use: src/int-rep
38 literal: loc ;
39
40 INSN: ##inc-d
41 literal: n ;
42
43 INSN: ##inc-r
44 literal: n ;
45
46 ! Subroutine calls
47 INSN: ##call
48 literal: word ;
49
50 INSN: ##jump
51 literal: word ;
52
53 INSN: ##return ;
54
55 ! Dummy instruction that simply inhibits TCO
56 INSN: ##no-tco ;
57
58 ! Jump tables
59 INSN: ##dispatch
60 use: src/int-rep
61 temp: temp/int-rep ;
62
63 ! Slot access
64 INSN: ##slot
65 def: dst/int-rep
66 use: obj/int-rep slot/int-rep ;
67
68 INSN: ##slot-imm
69 def: dst/int-rep
70 use: obj/int-rep
71 literal: slot tag ;
72
73 INSN: ##set-slot
74 use: src/int-rep obj/int-rep slot/int-rep ;
75
76 INSN: ##set-slot-imm
77 use: src/int-rep obj/int-rep
78 literal: slot tag ;
79
80 ! String element access
81 INSN: ##string-nth
82 def: dst/int-rep
83 use: obj/int-rep index/int-rep
84 temp: temp/int-rep ;
85
86 INSN: ##set-string-nth-fast
87 use: src/int-rep obj/int-rep index/int-rep
88 temp: temp/int-rep ;
89
90 PURE-INSN: ##copy
91 def: dst
92 use: src
93 literal: rep ;
94
95 ! Integer arithmetic
96 PURE-INSN: ##add
97 def: dst/int-rep
98 use: src1/int-rep src2/int-rep ;
99
100 PURE-INSN: ##add-imm
101 def: dst/int-rep
102 use: src1/int-rep
103 constant: src2 ;
104
105 PURE-INSN: ##sub
106 def: dst/int-rep
107 use: src1/int-rep src2/int-rep ;
108
109 PURE-INSN: ##sub-imm
110 def: dst/int-rep
111 use: src1/int-rep
112 constant: src2 ;
113
114 PURE-INSN: ##mul
115 def: dst/int-rep
116 use: src1/int-rep src2/int-rep ;
117
118 PURE-INSN: ##mul-imm
119 def: dst/int-rep
120 use: src1/int-rep
121 constant: src2 ;
122
123 PURE-INSN: ##and
124 def: dst/int-rep
125 use: src1/int-rep src2/int-rep ;
126
127 PURE-INSN: ##and-imm
128 def: dst/int-rep
129 use: src1/int-rep
130 constant: src2 ;
131
132 PURE-INSN: ##or
133 def: dst/int-rep
134 use: src1/int-rep src2/int-rep ;
135
136 PURE-INSN: ##or-imm
137 def: dst/int-rep
138 use: src1/int-rep
139 constant: src2 ;
140
141 PURE-INSN: ##xor
142 def: dst/int-rep
143 use: src1/int-rep src2/int-rep ;
144
145 PURE-INSN: ##xor-imm
146 def: dst/int-rep
147 use: src1/int-rep
148 constant: src2 ;
149
150 PURE-INSN: ##shl
151 def: dst/int-rep
152 use: src1/int-rep src2/int-rep ;
153
154 PURE-INSN: ##shl-imm
155 def: dst/int-rep
156 use: src1/int-rep
157 constant: src2 ;
158
159 PURE-INSN: ##shr
160 def: dst/int-rep
161 use: src1/int-rep src2/int-rep ;
162
163 PURE-INSN: ##shr-imm
164 def: dst/int-rep
165 use: src1/int-rep
166 constant: src2 ;
167
168 PURE-INSN: ##sar
169 def: dst/int-rep
170 use: src1/int-rep src2/int-rep ;
171
172 PURE-INSN: ##sar-imm
173 def: dst/int-rep
174 use: src1/int-rep
175 constant: src2 ;
176
177 PURE-INSN: ##min
178 def: dst/int-rep
179 use: src1/int-rep src2/int-rep ;
180
181 PURE-INSN: ##max
182 def: dst/int-rep
183 use: src1/int-rep src2/int-rep ;
184
185 PURE-INSN: ##not
186 def: dst/int-rep
187 use: src/int-rep ;
188
189 PURE-INSN: ##log2
190 def: dst/int-rep
191 use: src/int-rep ;
192
193 ! Bignum/integer conversion
194 PURE-INSN: ##integer>bignum
195 def: dst/int-rep
196 use: src/int-rep
197 temp: temp/int-rep ;
198
199 PURE-INSN: ##bignum>integer
200 def: dst/int-rep
201 use: src/int-rep
202 temp: temp/int-rep ;
203
204 ! Float arithmetic
205 PURE-INSN: ##unbox-float
206 def: dst/double-rep
207 use: src/int-rep ;
208
209 PURE-INSN: ##box-float
210 def: dst/int-rep
211 use: src/double-rep
212 temp: temp/int-rep ;
213
214 PURE-INSN: ##add-float
215 def: dst/double-rep
216 use: src1/double-rep src2/double-rep ;
217
218 PURE-INSN: ##sub-float
219 def: dst/double-rep
220 use: src1/double-rep src2/double-rep ;
221
222 PURE-INSN: ##mul-float
223 def: dst/double-rep
224 use: src1/double-rep src2/double-rep ;
225
226 PURE-INSN: ##div-float
227 def: dst/double-rep
228 use: src1/double-rep src2/double-rep ;
229
230 PURE-INSN: ##min-float
231 def: dst/double-rep
232 use: src1/double-rep src2/double-rep ;
233
234 PURE-INSN: ##max-float
235 def: dst/double-rep
236 use: src1/double-rep src2/double-rep ;
237
238 PURE-INSN: ##sqrt
239 def: dst/double-rep
240 use: src/double-rep ;
241
242 ! libc intrinsics
243 PURE-INSN: ##unary-float-function
244 def: dst/double-rep
245 use: src/double-rep
246 literal: func ;
247
248 PURE-INSN: ##binary-float-function
249 def: dst/double-rep
250 use: src1/double-rep src2/double-rep
251 literal: func ;
252
253 ! Single/double float conversion
254 PURE-INSN: ##single>double-float
255 def: dst/double-rep
256 use: src/float-rep ;
257
258 PURE-INSN: ##double>single-float
259 def: dst/float-rep
260 use: src/double-rep ;
261
262 ! Float/integer conversion
263 PURE-INSN: ##float>integer
264 def: dst/int-rep
265 use: src/double-rep ;
266
267 PURE-INSN: ##integer>float
268 def: dst/double-rep
269 use: src/int-rep ;
270
271 ! SIMD operations
272
273 PURE-INSN: ##box-vector
274 def: dst/int-rep
275 use: src
276 literal: rep
277 temp: temp/int-rep ;
278
279 PURE-INSN: ##unbox-vector
280 def: dst
281 use: src/int-rep
282 literal: rep ;
283
284 PURE-INSN: ##broadcast-vector
285 def: dst
286 use: src/scalar-rep
287 literal: rep ;
288
289 PURE-INSN: ##gather-vector-2
290 def: dst
291 use: src1/scalar-rep src2/scalar-rep
292 literal: rep ;
293
294 PURE-INSN: ##gather-vector-4
295 def: dst
296 use: src1/scalar-rep src2/scalar-rep src3/scalar-rep src4/scalar-rep
297 literal: rep ;
298
299 PURE-INSN: ##add-vector
300 def: dst
301 use: src1 src2
302 literal: rep ;
303
304 PURE-INSN: ##saturated-add-vector
305 def: dst
306 use: src1 src2
307 literal: rep ;
308
309 PURE-INSN: ##add-sub-vector
310 def: dst
311 use: src1 src2
312 literal: rep ;
313
314 PURE-INSN: ##sub-vector
315 def: dst
316 use: src1 src2
317 literal: rep ;
318
319 PURE-INSN: ##saturated-sub-vector
320 def: dst
321 use: src1 src2
322 literal: rep ;
323
324 PURE-INSN: ##mul-vector
325 def: dst
326 use: src1 src2
327 literal: rep ;
328
329 PURE-INSN: ##saturated-mul-vector
330 def: dst
331 use: src1 src2
332 literal: rep ;
333
334 PURE-INSN: ##div-vector
335 def: dst
336 use: src1 src2
337 literal: rep ;
338
339 PURE-INSN: ##min-vector
340 def: dst
341 use: src1 src2
342 literal: rep ;
343
344 PURE-INSN: ##max-vector
345 def: dst
346 use: src1 src2
347 literal: rep ;
348
349 PURE-INSN: ##horizontal-add-vector
350 def: dst/scalar-rep
351 use: src
352 literal: rep ;
353
354 PURE-INSN: ##abs-vector
355 def: dst
356 use: src
357 literal: rep ;
358
359 PURE-INSN: ##sqrt-vector
360 def: dst
361 use: src
362 literal: rep ;
363
364 PURE-INSN: ##and-vector
365 def: dst
366 use: src1 src2
367 literal: rep ;
368
369 PURE-INSN: ##or-vector
370 def: dst
371 use: src1 src2
372 literal: rep ;
373
374 PURE-INSN: ##xor-vector
375 def: dst
376 use: src1 src2
377 literal: rep ;
378
379 PURE-INSN: ##shl-vector
380 def: dst
381 use: src1 src2/scalar-rep
382 literal: rep ;
383
384 PURE-INSN: ##shr-vector
385 def: dst
386 use: src1 src2/scalar-rep
387 literal: rep ;
388
389 ! Scalar/integer conversion
390 PURE-INSN: ##scalar>integer
391 def: dst/int-rep
392 use: src
393 literal: rep ;
394
395 PURE-INSN: ##integer>scalar
396 def: dst
397 use: src/int-rep
398 literal: rep ;
399
400 ! Boxing and unboxing aliens
401 PURE-INSN: ##box-alien
402 def: dst/int-rep
403 use: src/int-rep
404 temp: temp/int-rep ;
405
406 PURE-INSN: ##box-displaced-alien
407 def: dst/int-rep
408 use: displacement/int-rep base/int-rep
409 temp: temp1/int-rep temp2/int-rep
410 literal: base-class ;
411
412 PURE-INSN: ##unbox-any-c-ptr
413 def: dst/int-rep
414 use: src/int-rep
415 temp: temp/int-rep ;
416
417 : ##unbox-f ( dst src -- ) drop 0 ##load-immediate ;
418 : ##unbox-byte-array ( dst src -- ) byte-array-offset ##add-imm ;
419
420 PURE-INSN: ##unbox-alien
421 def: dst/int-rep
422 use: src/int-rep ;
423
424 : ##unbox-c-ptr ( dst src class temp -- )
425     {
426         { [ over \ f class<= ] [ 2drop ##unbox-f ] }
427         { [ over simple-alien class<= ] [ 2drop ##unbox-alien ] }
428         { [ over byte-array class<= ] [ 2drop ##unbox-byte-array ] }
429         [ nip ##unbox-any-c-ptr ]
430     } cond ;
431
432 ! Alien accessors
433 INSN: ##alien-unsigned-1
434 def: dst/int-rep
435 use: src/int-rep ;
436
437 INSN: ##alien-unsigned-2
438 def: dst/int-rep
439 use: src/int-rep ;
440
441 INSN: ##alien-unsigned-4
442 def: dst/int-rep
443 use: src/int-rep ;
444
445 INSN: ##alien-signed-1
446 def: dst/int-rep
447 use: src/int-rep ;
448
449 INSN: ##alien-signed-2
450 def: dst/int-rep
451 use: src/int-rep ;
452
453 INSN: ##alien-signed-4
454 def: dst/int-rep
455 use: src/int-rep ;
456
457 INSN: ##alien-cell
458 def: dst/int-rep
459 use: src/int-rep ;
460
461 INSN: ##alien-float
462 def: dst/float-rep
463 use: src/int-rep ;
464
465 INSN: ##alien-double
466 def: dst/double-rep
467 use: src/int-rep ;
468
469 INSN: ##alien-vector
470 def: dst
471 use: src/int-rep
472 literal: rep ;
473
474 INSN: ##set-alien-integer-1
475 use: src/int-rep value/int-rep ;
476
477 INSN: ##set-alien-integer-2
478 use: src/int-rep value/int-rep ;
479
480 INSN: ##set-alien-integer-4
481 use: src/int-rep value/int-rep ;
482
483 INSN: ##set-alien-cell
484 use: src/int-rep value/int-rep ;
485
486 INSN: ##set-alien-float
487 use: src/int-rep value/float-rep ;
488
489 INSN: ##set-alien-double
490 use: src/int-rep value/double-rep ;
491
492 INSN: ##set-alien-vector
493 use: src/int-rep value
494 literal: rep ;
495
496 ! Memory allocation
497 INSN: ##allot
498 def: dst/int-rep
499 literal: size class
500 temp: temp/int-rep ;
501
502 INSN: ##write-barrier
503 use: src/int-rep
504 temp: card#/int-rep table/int-rep ;
505
506 INSN: ##alien-global
507 def: dst/int-rep
508 literal: symbol library ;
509
510 INSN: ##vm-field-ptr
511 def: dst/int-rep
512 literal: field-name ;
513
514 ! FFI
515 INSN: ##alien-invoke
516 literal: params stack-frame ;
517
518 INSN: ##alien-indirect
519 literal: params stack-frame ;
520
521 INSN: ##alien-callback
522 literal: params stack-frame ;
523
524 INSN: ##callback-return
525 literal: params ;
526
527 ! Instructions used by CFG IR only.
528 INSN: ##prologue ;
529 INSN: ##epilogue ;
530
531 INSN: ##branch ;
532
533 INSN: ##phi
534 def: dst
535 literal: inputs ;
536
537 ! Conditionals
538 INSN: ##compare-branch
539 use: src1/int-rep src2/int-rep
540 literal: cc ;
541
542 INSN: ##compare-imm-branch
543 use: src1/int-rep
544 constant: src2
545 literal: cc ;
546
547 PURE-INSN: ##compare
548 def: dst/int-rep
549 use: src1/int-rep src2/int-rep
550 literal: cc
551 temp: temp/int-rep ;
552
553 PURE-INSN: ##compare-imm
554 def: dst/int-rep
555 use: src1/int-rep
556 constant: src2
557 literal: cc
558 temp: temp/int-rep ;
559
560 INSN: ##compare-float-ordered-branch
561 use: src1/double-rep src2/double-rep
562 literal: cc ;
563
564 INSN: ##compare-float-unordered-branch
565 use: src1/double-rep src2/double-rep
566 literal: cc ;
567
568 PURE-INSN: ##compare-float-ordered
569 def: dst/int-rep
570 use: src1/double-rep src2/double-rep
571 literal: cc
572 temp: temp/int-rep ;
573
574 PURE-INSN: ##compare-float-unordered
575 def: dst/int-rep
576 use: src1/double-rep src2/double-rep
577 literal: cc
578 temp: temp/int-rep ;
579
580 ! Overflowing arithmetic
581 INSN: ##fixnum-add
582 def: dst/int-rep
583 use: src1/int-rep src2/int-rep ;
584
585 INSN: ##fixnum-sub
586 def: dst/int-rep
587 use: src1/int-rep src2/int-rep ;
588
589 INSN: ##fixnum-mul
590 def: dst/int-rep
591 use: src1/int-rep src2/int-rep ;
592
593 INSN: ##gc
594 temp: temp1/int-rep temp2/int-rep
595 literal: data-values tagged-values uninitialized-locs ;
596
597 INSN: ##save-context
598 temp: temp1/int-rep temp2/int-rep
599 literal: callback-allowed? ;
600
601 ! Instructions used by machine IR only.
602 INSN: _prologue
603 literal: stack-frame ;
604
605 INSN: _epilogue
606 literal: stack-frame ;
607
608 INSN: _label
609 literal: label ;
610
611 INSN: _branch
612 literal: label ;
613
614 INSN: _loop-entry ;
615
616 INSN: _dispatch
617 use: src/int-rep
618 temp: temp ;
619
620 INSN: _dispatch-label
621 literal: label ;
622
623 INSN: _compare-branch
624 literal: label
625 use: src1/int-rep src2/int-rep
626 literal: cc ;
627
628 INSN: _compare-imm-branch
629 literal: label
630 use: src1/int-rep
631 constant: src2
632 literal: cc ;
633
634 INSN: _compare-float-unordered-branch
635 literal: label
636 use: src1/int-rep src2/int-rep
637 literal: cc ;
638
639 INSN: _compare-float-ordered-branch
640 literal: label
641 use: src1/int-rep src2/int-rep
642 literal: cc ;
643
644 ! Overflowing arithmetic
645 INSN: _fixnum-add
646 literal: label
647 def: dst/int-rep
648 use: src1/int-rep src2/int-rep ;
649
650 INSN: _fixnum-sub
651 literal: label
652 def: dst/int-rep
653 use: src1/int-rep src2/int-rep ;
654
655 INSN: _fixnum-mul
656 literal: label
657 def: dst/int-rep
658 use: src1/int-rep src2/int-rep ;
659
660 TUPLE: spill-slot { n integer } ;
661 C: <spill-slot> spill-slot
662
663 INSN: _gc
664 temp: temp1 temp2
665 literal: data-values tagged-values uninitialized-locs ;
666
667 ! These instructions operate on machine registers and not
668 ! virtual registers
669 INSN: _spill
670 use: src
671 literal: rep dst ;
672
673 INSN: _reload
674 def: dst
675 literal: rep src ;
676
677 INSN: _spill-area-size
678 literal: n ;
679
680 UNION: ##allocation
681 ##allot
682 ##box-float
683 ##box-vector
684 ##box-alien
685 ##box-displaced-alien
686 ##integer>bignum ;
687
688 ! For alias analysis
689 UNION: ##read ##slot ##slot-imm ;
690 UNION: ##write ##set-slot ##set-slot-imm ;
691
692 ! Instructions that kill all live vregs but cannot trigger GC
693 UNION: partial-sync-insn
694 ##unary-float-function
695 ##binary-float-function ;
696
697 ! Instructions that kill all live vregs
698 UNION: kill-vreg-insn
699 ##call
700 ##prologue
701 ##epilogue
702 ##alien-invoke
703 ##alien-indirect
704 ##alien-callback ;
705
706 ! Instructions that have complex expansions and require that the
707 ! output registers are not equal to any of the input registers
708 UNION: def-is-use-insn
709 ##integer>bignum
710 ##bignum>integer
711 ##string-nth
712 ##unbox-any-c-ptr
713 ##unary-float-function
714 ##binary-float-function ;
715
716 SYMBOL: vreg-insn
717
718 [
719     vreg-insn
720     insn-classes get [
721         "insn-slots" word-prop [ type>> { def use temp } memq? ] any?
722     ] filter
723     define-union-class
724 ] with-compilation-unit