]> gitweb.factorcode.org Git - factor.git/blob - basis/compiler/cfg/instructions/instructions.factor
FFI rewrite part 5: return value boxing and callback parameter boxing now uses vregs...
[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: ##shuffle-vector
314 def: dst
315 use: src shuffle
316 literal: rep ;
317
318 PURE-INSN: ##shuffle-vector-halves-imm
319 def: dst
320 use: src1 src2
321 literal: shuffle rep ;
322
323 PURE-INSN: ##shuffle-vector-imm
324 def: dst
325 use: src
326 literal: shuffle rep ;
327
328 PURE-INSN: ##tail>head-vector
329 def: dst
330 use: src
331 literal: rep ;
332
333 PURE-INSN: ##merge-vector-head
334 def: dst
335 use: src1 src2
336 literal: rep ;
337
338 PURE-INSN: ##merge-vector-tail
339 def: dst
340 use: src1 src2
341 literal: rep ;
342
343 PURE-INSN: ##signed-pack-vector
344 def: dst
345 use: src1 src2
346 literal: rep ;
347
348 PURE-INSN: ##unsigned-pack-vector
349 def: dst
350 use: src1 src2
351 literal: rep ;
352
353 PURE-INSN: ##unpack-vector-head
354 def: dst
355 use: src
356 literal: rep ;
357
358 PURE-INSN: ##unpack-vector-tail
359 def: dst
360 use: src
361 literal: rep ;
362
363 PURE-INSN: ##integer>float-vector
364 def: dst
365 use: src
366 literal: rep ;
367
368 PURE-INSN: ##float>integer-vector
369 def: dst
370 use: src
371 literal: rep ;
372
373 PURE-INSN: ##compare-vector
374 def: dst
375 use: src1 src2
376 literal: rep cc ;
377
378 PURE-INSN: ##test-vector
379 def: dst/tagged-rep
380 use: src1
381 temp: temp/int-rep
382 literal: rep vcc ;
383
384 INSN: ##test-vector-branch
385 use: src1
386 temp: temp/int-rep
387 literal: rep vcc ;
388
389 PURE-INSN: ##add-vector
390 def: dst
391 use: src1 src2
392 literal: rep ;
393
394 PURE-INSN: ##saturated-add-vector
395 def: dst
396 use: src1 src2
397 literal: rep ;
398
399 PURE-INSN: ##add-sub-vector
400 def: dst
401 use: src1 src2
402 literal: rep ;
403
404 PURE-INSN: ##sub-vector
405 def: dst
406 use: src1 src2
407 literal: rep ;
408
409 PURE-INSN: ##saturated-sub-vector
410 def: dst
411 use: src1 src2
412 literal: rep ;
413
414 PURE-INSN: ##mul-vector
415 def: dst
416 use: src1 src2
417 literal: rep ;
418
419 PURE-INSN: ##mul-high-vector
420 def: dst
421 use: src1 src2
422 literal: rep ;
423
424 PURE-INSN: ##mul-horizontal-add-vector
425 def: dst
426 use: src1 src2
427 literal: rep ;
428
429 PURE-INSN: ##saturated-mul-vector
430 def: dst
431 use: src1 src2
432 literal: rep ;
433
434 PURE-INSN: ##div-vector
435 def: dst
436 use: src1 src2
437 literal: rep ;
438
439 PURE-INSN: ##min-vector
440 def: dst
441 use: src1 src2
442 literal: rep ;
443
444 PURE-INSN: ##max-vector
445 def: dst
446 use: src1 src2
447 literal: rep ;
448
449 PURE-INSN: ##avg-vector
450 def: dst
451 use: src1 src2
452 literal: rep ;
453
454 PURE-INSN: ##dot-vector
455 def: dst/scalar-rep
456 use: src1 src2
457 literal: rep ;
458
459 PURE-INSN: ##sad-vector
460 def: dst
461 use: src1 src2
462 literal: rep ;
463
464 PURE-INSN: ##horizontal-add-vector
465 def: dst
466 use: src1 src2
467 literal: rep ;
468
469 PURE-INSN: ##horizontal-sub-vector
470 def: dst
471 use: src1 src2
472 literal: rep ;
473
474 PURE-INSN: ##horizontal-shl-vector-imm
475 def: dst
476 use: src1
477 literal: src2 rep ;
478
479 PURE-INSN: ##horizontal-shr-vector-imm
480 def: dst
481 use: src1
482 literal: src2 rep ;
483
484 PURE-INSN: ##abs-vector
485 def: dst
486 use: src
487 literal: rep ;
488
489 PURE-INSN: ##sqrt-vector
490 def: dst
491 use: src
492 literal: rep ;
493
494 PURE-INSN: ##and-vector
495 def: dst
496 use: src1 src2
497 literal: rep ;
498
499 PURE-INSN: ##andn-vector
500 def: dst
501 use: src1 src2
502 literal: rep ;
503
504 PURE-INSN: ##or-vector
505 def: dst
506 use: src1 src2
507 literal: rep ;
508
509 PURE-INSN: ##xor-vector
510 def: dst
511 use: src1 src2
512 literal: rep ;
513
514 PURE-INSN: ##not-vector
515 def: dst
516 use: src
517 literal: rep ;
518
519 PURE-INSN: ##shl-vector-imm
520 def: dst
521 use: src1
522 literal: src2 rep ;
523
524 PURE-INSN: ##shr-vector-imm
525 def: dst
526 use: src1
527 literal: src2 rep ;
528
529 PURE-INSN: ##shl-vector
530 def: dst
531 use: src1 src2/int-scalar-rep
532 literal: rep ;
533
534 PURE-INSN: ##shr-vector
535 def: dst
536 use: src1 src2/int-scalar-rep
537 literal: rep ;
538
539 ! Scalar/vector conversion
540 PURE-INSN: ##scalar>integer
541 def: dst/int-rep
542 use: src
543 literal: rep ;
544
545 PURE-INSN: ##integer>scalar
546 def: dst
547 use: src/int-rep
548 literal: rep ;
549
550 PURE-INSN: ##vector>scalar
551 def: dst/scalar-rep
552 use: src
553 literal: rep ;
554
555 PURE-INSN: ##scalar>vector
556 def: dst
557 use: src/scalar-rep
558 literal: rep ;
559
560 ! Boxing and unboxing aliens
561 PURE-INSN: ##box-alien
562 def: dst/tagged-rep
563 use: src/int-rep
564 temp: temp/int-rep ;
565
566 PURE-INSN: ##box-displaced-alien
567 def: dst/tagged-rep
568 use: displacement/int-rep base/tagged-rep
569 temp: temp/int-rep
570 literal: base-class ;
571
572 PURE-INSN: ##unbox-any-c-ptr
573 def: dst/int-rep
574 use: src/tagged-rep ;
575
576 PURE-INSN: ##unbox-alien
577 def: dst/int-rep
578 use: src/tagged-rep ;
579
580 ! Raw memory accessors
581 INSN: ##load-memory
582 def: dst
583 use: base/int-rep displacement/int-rep
584 literal: scale offset rep c-type ;
585
586 INSN: ##load-memory-imm
587 def: dst
588 use: base/int-rep
589 literal: offset rep c-type ;
590
591 INSN: ##store-memory
592 use: src base/int-rep displacement/int-rep
593 literal: scale offset rep c-type ;
594
595 INSN: ##store-memory-imm
596 use: src base/int-rep
597 literal: offset rep c-type ;
598
599 ! Memory allocation
600 INSN: ##allot
601 def: dst/tagged-rep
602 literal: size class
603 temp: temp/int-rep ;
604
605 INSN: ##write-barrier
606 use: src/tagged-rep slot/int-rep
607 literal: scale tag
608 temp: temp1/int-rep temp2/int-rep ;
609
610 INSN: ##write-barrier-imm
611 use: src/tagged-rep
612 literal: slot tag
613 temp: temp1/int-rep temp2/int-rep ;
614
615 INSN: ##alien-global
616 def: dst/int-rep
617 literal: symbol library ;
618
619 INSN: ##vm-field
620 def: dst/tagged-rep
621 literal: offset ;
622
623 INSN: ##set-vm-field
624 use: src/tagged-rep
625 literal: offset ;
626
627 ! FFI
628 INSN: ##stack-frame
629 literal: stack-frame ;
630
631 INSN: ##unbox
632 def: dst
633 use: src/tagged-rep
634 literal: unboxer rep ;
635
636 INSN: ##store-reg-param
637 use: src
638 literal: reg rep ;
639
640 INSN: ##store-stack-param
641 use: src
642 literal: n rep ;
643
644 INSN: ##load-reg-param
645 def: dst
646 literal: reg rep ;
647
648 INSN: ##load-stack-param
649 def: dst
650 literal: n rep ;
651
652 INSN: ##prepare-struct-caller
653 def: dst/int-rep ;
654
655 INSN: ##box
656 def: dst/tagged-rep
657 use: src
658 literal: boxer rep ;
659
660 INSN: ##box-long-long
661 def: dst/tagged-rep
662 use: src1/int-rep src2/int-rep
663 literal: boxer ;
664
665 INSN: ##allot-byte-array
666 def: dst/tagged-rep
667 literal: size ;
668
669 INSN: ##alien-invoke
670 literal: symbols dll ;
671
672 INSN: ##cleanup
673 literal: n ;
674
675 INSN: ##alien-indirect
676 use: src/int-rep ;
677
678 INSN: ##alien-assembly
679 literal: quot ;
680
681 INSN: ##begin-callback ;
682
683 INSN: ##alien-callback
684 literal: quot ;
685
686 INSN: ##end-callback ;
687
688 ! Control flow
689 INSN: ##phi
690 def: dst
691 literal: inputs ;
692
693 INSN: ##branch ;
694
695 ! Tagged conditionals
696 INSN: ##compare-branch
697 use: src1/tagged-rep src2/tagged-rep
698 literal: cc ;
699
700 INSN: ##compare-imm-branch
701 use: src1/tagged-rep
702 literal: src2 cc ;
703
704 PURE-INSN: ##compare
705 def: dst/tagged-rep
706 use: src1/tagged-rep src2/tagged-rep
707 literal: cc
708 temp: temp/int-rep ;
709
710 PURE-INSN: ##compare-imm
711 def: dst/tagged-rep
712 use: src1/tagged-rep
713 literal: src2 cc
714 temp: temp/int-rep ;
715
716 ! Integer conditionals
717 INSN: ##compare-integer-branch
718 use: src1/int-rep src2/int-rep
719 literal: cc ;
720
721 INSN: ##compare-integer-imm-branch
722 use: src1/int-rep
723 literal: src2 cc ;
724
725 INSN: ##test-branch
726 use: src1/int-rep src2/int-rep
727 literal: cc ;
728
729 INSN: ##test-imm-branch
730 use: src1/int-rep
731 literal: src2 cc ;
732
733 PURE-INSN: ##compare-integer
734 def: dst/tagged-rep
735 use: src1/int-rep src2/int-rep
736 literal: cc
737 temp: temp/int-rep ;
738
739 PURE-INSN: ##compare-integer-imm
740 def: dst/tagged-rep
741 use: src1/int-rep
742 literal: src2 cc
743 temp: temp/int-rep ;
744
745 PURE-INSN: ##test
746 def: dst/tagged-rep
747 use: src1/int-rep src2/int-rep
748 literal: cc
749 temp: temp/int-rep ;
750
751 PURE-INSN: ##test-imm
752 def: dst/tagged-rep
753 use: src1/int-rep
754 literal: src2 cc
755 temp: temp/int-rep ;
756
757 ! Float conditionals
758 INSN: ##compare-float-ordered-branch
759 use: src1/double-rep src2/double-rep
760 literal: cc ;
761
762 INSN: ##compare-float-unordered-branch
763 use: src1/double-rep src2/double-rep
764 literal: cc ;
765
766 PURE-INSN: ##compare-float-ordered
767 def: dst/tagged-rep
768 use: src1/double-rep src2/double-rep
769 literal: cc
770 temp: temp/int-rep ;
771
772 PURE-INSN: ##compare-float-unordered
773 def: dst/tagged-rep
774 use: src1/double-rep src2/double-rep
775 literal: cc
776 temp: temp/int-rep ;
777
778 ! Overflowing arithmetic
779 INSN: ##fixnum-add
780 def: dst/tagged-rep
781 use: src1/tagged-rep src2/tagged-rep
782 literal: cc ;
783
784 INSN: ##fixnum-sub
785 def: dst/tagged-rep
786 use: src1/tagged-rep src2/tagged-rep
787 literal: cc ;
788
789 INSN: ##fixnum-mul
790 def: dst/tagged-rep
791 use: src1/tagged-rep src2/int-rep
792 literal: cc ;
793
794 INSN: ##save-context
795 temp: temp1/int-rep temp2/int-rep ;
796
797 INSN: ##restore-context
798 temp: temp1/int-rep temp2/int-rep ;
799
800 ! GC checks
801 INSN: ##check-nursery-branch
802 literal: size cc
803 temp: temp1/int-rep temp2/int-rep ;
804
805 INSN: ##call-gc
806 literal: gc-roots ;
807
808 ! Spills and reloads, inserted by register allocator
809 TUPLE: spill-slot { n integer } ;
810 C: <spill-slot> spill-slot
811
812 INSN: ##spill
813 use: src
814 literal: rep dst ;
815
816 INSN: ##reload
817 def: dst
818 literal: rep src ;
819
820 UNION: ##allocation
821 ##allot
822 ##box-alien
823 ##box-displaced-alien ;
824
825 UNION: conditional-branch-insn
826 ##compare-branch
827 ##compare-imm-branch
828 ##compare-integer-branch
829 ##compare-integer-imm-branch
830 ##test-branch
831 ##test-imm-branch
832 ##compare-float-ordered-branch
833 ##compare-float-unordered-branch
834 ##test-vector-branch
835 ##check-nursery-branch
836 ##fixnum-add
837 ##fixnum-sub
838 ##fixnum-mul ;
839
840 ! For alias analysis
841 UNION: ##read ##slot ##slot-imm ##vm-field ##alien-global ;
842 UNION: ##write ##set-slot ##set-slot-imm ##set-vm-field ;
843
844 ! Instructions that clobber registers. They receive inputs and
845 ! produce outputs in spill slots.
846 UNION: hairy-clobber-insn
847 ##load-reg-param
848 ##store-reg-param
849 ##call-gc
850 ##alien-invoke
851 ##alien-indirect
852 ##alien-assembly
853 ##begin-callback
854 ##end-callback ;
855
856 ! Instructions that clobber registers but are allowed to produce
857 ! outputs in registers. Inputs are in spill slots, except for
858 ! inputs coalesced with the output, in which case that input
859 ! will be in a register.
860 UNION: clobber-insn
861 hairy-clobber-insn
862 ##unary-float-function
863 ##binary-float-function
864 ##unbox
865 ##box
866 ##box-long-long
867 ##allot-byte-array ;
868
869 ! Instructions that have complex expansions and require that the
870 ! output registers are not equal to any of the input registers
871 UNION: def-is-use-insn
872 ##box-alien
873 ##box-displaced-alien
874 ##unbox-any-c-ptr ;