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