]> gitweb.factorcode.org Git - factor.git/blob - basis/compiler/cfg/instructions/instructions.factor
cleaned up vm-field-ptr compiler code
[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 literal: tag
68 temp: temp/int-rep ;
69
70 INSN: ##slot-imm
71 def: dst/int-rep
72 use: obj/int-rep
73 literal: slot tag ;
74
75 INSN: ##set-slot
76 use: src/int-rep obj/int-rep slot/int-rep
77 literal: tag
78 temp: temp/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: ##log2
194 def: dst/int-rep
195 use: src/int-rep ;
196
197 ! Bignum/integer conversion
198 PURE-INSN: ##integer>bignum
199 def: dst/int-rep
200 use: src/int-rep
201 temp: temp/int-rep ;
202
203 PURE-INSN: ##bignum>integer
204 def: dst/int-rep
205 use: src/int-rep
206 temp: temp/int-rep ;
207
208 ! Float arithmetic
209 PURE-INSN: ##unbox-float
210 def: dst/double-rep
211 use: src/int-rep ;
212
213 PURE-INSN: ##box-float
214 def: dst/int-rep
215 use: src/double-rep
216 temp: temp/int-rep ;
217
218 PURE-INSN: ##add-float
219 def: dst/double-rep
220 use: src1/double-rep src2/double-rep ;
221
222 PURE-INSN: ##sub-float
223 def: dst/double-rep
224 use: src1/double-rep src2/double-rep ;
225
226 PURE-INSN: ##mul-float
227 def: dst/double-rep
228 use: src1/double-rep src2/double-rep ;
229
230 PURE-INSN: ##div-float
231 def: dst/double-rep
232 use: src1/double-rep src2/double-rep ;
233
234 PURE-INSN: ##min-float
235 def: dst/double-rep
236 use: src1/double-rep src2/double-rep ;
237
238 PURE-INSN: ##max-float
239 def: dst/double-rep
240 use: src1/double-rep src2/double-rep ;
241
242 PURE-INSN: ##sqrt
243 def: dst/double-rep
244 use: src/double-rep ;
245
246 ! libc intrinsics
247 PURE-INSN: ##unary-float-function
248 def: dst/double-rep
249 use: src/double-rep
250 literal: func ;
251
252 PURE-INSN: ##binary-float-function
253 def: dst/double-rep
254 use: src1/double-rep src2/double-rep
255 literal: func ;
256
257 ! Single/double float conversion
258 PURE-INSN: ##single>double-float
259 def: dst/double-rep
260 use: src/float-rep ;
261
262 PURE-INSN: ##double>single-float
263 def: dst/float-rep
264 use: src/double-rep ;
265
266 ! Float/integer conversion
267 PURE-INSN: ##float>integer
268 def: dst/int-rep
269 use: src/double-rep ;
270
271 PURE-INSN: ##integer>float
272 def: dst/double-rep
273 use: src/int-rep ;
274
275 ! SIMD operations
276
277 PURE-INSN: ##box-vector
278 def: dst/int-rep
279 use: src
280 literal: rep
281 temp: temp/int-rep ;
282
283 PURE-INSN: ##unbox-vector
284 def: dst
285 use: src/int-rep
286 literal: rep ;
287
288 PURE-INSN: ##broadcast-vector
289 def: dst
290 use: src/scalar-rep
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-vector-4
299 def: dst
300 use: src1/scalar-rep src2/scalar-rep src3/scalar-rep src4/scalar-rep
301 literal: rep ;
302
303 PURE-INSN: ##add-vector
304 def: dst
305 use: src1 src2
306 literal: rep ;
307
308 PURE-INSN: ##saturated-add-vector
309 def: dst
310 use: src1 src2
311 literal: rep ;
312
313 PURE-INSN: ##add-sub-vector
314 def: dst
315 use: src1 src2
316 literal: rep ;
317
318 PURE-INSN: ##sub-vector
319 def: dst
320 use: src1 src2
321 literal: rep ;
322
323 PURE-INSN: ##saturated-sub-vector
324 def: dst
325 use: src1 src2
326 literal: rep ;
327
328 PURE-INSN: ##mul-vector
329 def: dst
330 use: src1 src2
331 literal: rep ;
332
333 PURE-INSN: ##saturated-mul-vector
334 def: dst
335 use: src1 src2
336 literal: rep ;
337
338 PURE-INSN: ##div-vector
339 def: dst
340 use: src1 src2
341 literal: rep ;
342
343 PURE-INSN: ##min-vector
344 def: dst
345 use: src1 src2
346 literal: rep ;
347
348 PURE-INSN: ##max-vector
349 def: dst
350 use: src1 src2
351 literal: rep ;
352
353 PURE-INSN: ##horizontal-add-vector
354 def: dst/scalar-rep
355 use: src
356 literal: rep ;
357
358 PURE-INSN: ##abs-vector
359 def: dst
360 use: src
361 literal: rep ;
362
363 PURE-INSN: ##sqrt-vector
364 def: dst
365 use: src
366 literal: rep ;
367
368 PURE-INSN: ##and-vector
369 def: dst
370 use: src1 src2
371 literal: rep ;
372
373 PURE-INSN: ##or-vector
374 def: dst
375 use: src1 src2
376 literal: rep ;
377
378 PURE-INSN: ##xor-vector
379 def: dst
380 use: src1 src2
381 literal: rep ;
382
383 ! Boxing and unboxing aliens
384 PURE-INSN: ##box-alien
385 def: dst/int-rep
386 use: src/int-rep
387 temp: temp/int-rep ;
388
389 PURE-INSN: ##box-displaced-alien
390 def: dst/int-rep
391 use: displacement/int-rep base/int-rep
392 temp: temp1/int-rep temp2/int-rep
393 literal: base-class ;
394
395 PURE-INSN: ##unbox-any-c-ptr
396 def: dst/int-rep
397 use: src/int-rep
398 temp: temp/int-rep ;
399
400 : ##unbox-f ( dst src -- ) drop 0 ##load-immediate ;
401 : ##unbox-byte-array ( dst src -- ) byte-array-offset ##add-imm ;
402
403 PURE-INSN: ##unbox-alien
404 def: dst/int-rep
405 use: src/int-rep ;
406
407 : ##unbox-c-ptr ( dst src class temp -- )
408     {
409         { [ over \ f class<= ] [ 2drop ##unbox-f ] }
410         { [ over simple-alien class<= ] [ 2drop ##unbox-alien ] }
411         { [ over byte-array class<= ] [ 2drop ##unbox-byte-array ] }
412         [ nip ##unbox-any-c-ptr ]
413     } cond ;
414
415 ! Alien accessors
416 INSN: ##alien-unsigned-1
417 def: dst/int-rep
418 use: src/int-rep ;
419
420 INSN: ##alien-unsigned-2
421 def: dst/int-rep
422 use: src/int-rep ;
423
424 INSN: ##alien-unsigned-4
425 def: dst/int-rep
426 use: src/int-rep ;
427
428 INSN: ##alien-signed-1
429 def: dst/int-rep
430 use: src/int-rep ;
431
432 INSN: ##alien-signed-2
433 def: dst/int-rep
434 use: src/int-rep ;
435
436 INSN: ##alien-signed-4
437 def: dst/int-rep
438 use: src/int-rep ;
439
440 INSN: ##alien-cell
441 def: dst/int-rep
442 use: src/int-rep ;
443
444 INSN: ##alien-float
445 def: dst/float-rep
446 use: src/int-rep ;
447
448 INSN: ##alien-double
449 def: dst/double-rep
450 use: src/int-rep ;
451
452 INSN: ##alien-vector
453 def: dst
454 use: src/int-rep
455 literal: rep ;
456
457 INSN: ##set-alien-integer-1
458 use: src/int-rep value/int-rep ;
459
460 INSN: ##set-alien-integer-2
461 use: src/int-rep value/int-rep ;
462
463 INSN: ##set-alien-integer-4
464 use: src/int-rep value/int-rep ;
465
466 INSN: ##set-alien-cell
467 use: src/int-rep value/int-rep ;
468
469 INSN: ##set-alien-float
470 use: src/int-rep value/float-rep ;
471
472 INSN: ##set-alien-double
473 use: src/int-rep value/double-rep ;
474
475 INSN: ##set-alien-vector
476 use: src/int-rep value
477 literal: rep ;
478
479 ! Memory allocation
480 INSN: ##allot
481 def: dst/int-rep
482 literal: size class
483 temp: temp/int-rep ;
484
485 INSN: ##write-barrier
486 use: src/int-rep
487 temp: card#/int-rep table/int-rep ;
488
489 INSN: ##alien-global
490 def: dst/int-rep
491 literal: symbol library ;
492
493 INSN: ##vm-field-ptr
494 def: dst/int-rep
495 literal: field-name ;
496
497 ! FFI
498 INSN: ##alien-invoke
499 literal: params stack-frame ;
500
501 INSN: ##alien-indirect
502 literal: params stack-frame ;
503
504 INSN: ##alien-callback
505 literal: params stack-frame ;
506
507 INSN: ##callback-return
508 literal: params ;
509
510 ! Instructions used by CFG IR only.
511 INSN: ##prologue ;
512 INSN: ##epilogue ;
513
514 INSN: ##branch ;
515
516 INSN: ##phi
517 def: dst
518 literal: inputs ;
519
520 ! Conditionals
521 INSN: ##compare-branch
522 use: src1/int-rep src2/int-rep
523 literal: cc ;
524
525 INSN: ##compare-imm-branch
526 use: src1/int-rep
527 constant: src2
528 literal: cc ;
529
530 PURE-INSN: ##compare
531 def: dst/int-rep
532 use: src1/int-rep src2/int-rep
533 literal: cc
534 temp: temp/int-rep ;
535
536 PURE-INSN: ##compare-imm
537 def: dst/int-rep
538 use: src1/int-rep
539 constant: src2
540 literal: cc
541 temp: temp/int-rep ;
542
543 INSN: ##compare-float-ordered-branch
544 use: src1/double-rep src2/double-rep
545 literal: cc ;
546
547 INSN: ##compare-float-unordered-branch
548 use: src1/double-rep src2/double-rep
549 literal: cc ;
550
551 PURE-INSN: ##compare-float-ordered
552 def: dst/int-rep
553 use: src1/double-rep src2/double-rep
554 literal: cc
555 temp: temp/int-rep ;
556
557 PURE-INSN: ##compare-float-unordered
558 def: dst/int-rep
559 use: src1/double-rep src2/double-rep
560 literal: cc
561 temp: temp/int-rep ;
562
563 ! Overflowing arithmetic
564 INSN: ##fixnum-add
565 def: dst/int-rep
566 use: src1/int-rep src2/int-rep ;
567
568 INSN: ##fixnum-sub
569 def: dst/int-rep
570 use: src1/int-rep src2/int-rep ;
571
572 INSN: ##fixnum-mul
573 def: dst/int-rep
574 use: src1/int-rep src2/int-rep ;
575
576 INSN: ##gc
577 temp: temp1/int-rep temp2/int-rep
578 literal: data-values tagged-values uninitialized-locs ;
579
580 INSN: ##save-context
581 temp: temp1/int-rep temp2/int-rep
582 literal: callback-allowed? ;
583
584 ! Instructions used by machine IR only.
585 INSN: _prologue
586 literal: stack-frame ;
587
588 INSN: _epilogue
589 literal: stack-frame ;
590
591 INSN: _label
592 literal: label ;
593
594 INSN: _branch
595 literal: label ;
596
597 INSN: _loop-entry ;
598
599 INSN: _dispatch
600 use: src/int-rep
601 temp: temp ;
602
603 INSN: _dispatch-label
604 literal: label ;
605
606 INSN: _compare-branch
607 literal: label
608 use: src1/int-rep src2/int-rep
609 literal: cc ;
610
611 INSN: _compare-imm-branch
612 literal: label
613 use: src1/int-rep
614 constant: src2
615 literal: cc ;
616
617 INSN: _compare-float-unordered-branch
618 literal: label
619 use: src1/int-rep src2/int-rep
620 literal: cc ;
621
622 INSN: _compare-float-ordered-branch
623 literal: label
624 use: src1/int-rep src2/int-rep
625 literal: cc ;
626
627 ! Overflowing arithmetic
628 INSN: _fixnum-add
629 literal: label
630 def: dst/int-rep
631 use: src1/int-rep src2/int-rep ;
632
633 INSN: _fixnum-sub
634 literal: label
635 def: dst/int-rep
636 use: src1/int-rep src2/int-rep ;
637
638 INSN: _fixnum-mul
639 literal: label
640 def: dst/int-rep
641 use: src1/int-rep src2/int-rep ;
642
643 TUPLE: spill-slot n ; C: <spill-slot> spill-slot
644
645 INSN: _gc
646 temp: temp1 temp2
647 literal: data-values tagged-values uninitialized-locs ;
648
649 ! These instructions operate on machine registers and not
650 ! virtual registers
651 INSN: _spill
652 use: src
653 literal: rep n ;
654
655 INSN: _reload
656 def: dst
657 literal: rep n ;
658
659 INSN: _spill-area-size
660 literal: n ;
661
662 UNION: ##allocation
663 ##allot
664 ##box-float
665 ##box-vector
666 ##box-alien
667 ##box-displaced-alien
668 ##integer>bignum ;
669
670 ! For alias analysis
671 UNION: ##read ##slot ##slot-imm ;
672 UNION: ##write ##set-slot ##set-slot-imm ;
673
674 ! Instructions that kill all live vregs but cannot trigger GC
675 UNION: partial-sync-insn
676 ##unary-float-function
677 ##binary-float-function ;
678
679 ! Instructions that kill all live vregs
680 UNION: kill-vreg-insn
681 ##call
682 ##prologue
683 ##epilogue
684 ##alien-invoke
685 ##alien-indirect
686 ##alien-callback ;
687
688 ! Instructions that have complex expansions and require that the
689 ! output registers are not equal to any of the input registers
690 UNION: def-is-use-insn
691 ##integer>bignum
692 ##bignum>integer
693 ##unbox-any-c-ptr ;
694
695 SYMBOL: vreg-insn
696
697 [
698     vreg-insn
699     insn-classes get [
700         "insn-slots" word-prop [ type>> { def use temp } memq? ] any?
701     ] filter
702     define-union-class
703 ] with-compilation-unit