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