]> gitweb.factorcode.org Git - factor.git/blob - basis/compiler/cfg/instructions/instructions.factor
Merge branch 'master' of git://factorcode.org/git/factor
[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 alien byte-arrays
5 compiler.constants combinators compiler.cfg.registers
6 compiler.cfg.instructions.syntax ;
7 IN: compiler.cfg.instructions
8
9 : new-insn ( ... class -- insn ) [ f f ] dip boa ; inline
10
11 ! Virtual CPU instructions, used by CFG and machine IRs
12 TUPLE: insn ;
13
14 ! Instruction with no side effects; if 'out' is never read, we
15 ! can eliminate it.
16 TUPLE: ##flushable < insn { dst vreg } ;
17
18 ! Instruction which is referentially transparent; we can replace
19 ! repeated computation with a reference to a previous value
20 TUPLE: ##pure < ##flushable ;
21
22 TUPLE: ##unary < ##pure { src vreg } ;
23 TUPLE: ##unary/temp < ##unary { temp vreg } ;
24 TUPLE: ##binary < ##pure { src1 vreg } { src2 vreg } ;
25 TUPLE: ##binary-imm < ##pure { src1 vreg } { src2 integer } ;
26 TUPLE: ##commutative < ##binary ;
27 TUPLE: ##commutative-imm < ##binary-imm ;
28
29 ! Instruction only used for its side effect, produces no values
30 TUPLE: ##effect < insn { src vreg } ;
31
32 ! Read/write ops: candidates for alias analysis
33 TUPLE: ##read < ##flushable ;
34 TUPLE: ##write < ##effect ;
35
36 TUPLE: ##alien-getter < ##flushable { src vreg } ;
37 TUPLE: ##alien-setter < ##effect { value vreg } ;
38
39 ! Stack operations
40 INSN: ##load-immediate < ##pure { val integer } ;
41 INSN: ##load-reference < ##pure obj ;
42
43 GENERIC: ##load-literal ( dst value -- )
44
45 M: fixnum ##load-literal tag-fixnum ##load-immediate ;
46 M: f ##load-literal drop \ f tag-number ##load-immediate ;
47 M: object ##load-literal ##load-reference ;
48
49 INSN: ##peek < ##flushable { loc loc } ;
50 INSN: ##replace < ##effect { loc loc } ;
51 INSN: ##inc-d { n integer } ;
52 INSN: ##inc-r { n integer } ;
53
54 ! Subroutine calls
55 INSN: ##call word ;
56 INSN: ##jump word ;
57 INSN: ##return ;
58
59 ! Dummy instruction that simply inhibits TCO
60 INSN: ##no-tco ;
61
62 ! Jump tables
63 INSN: ##dispatch src temp ;
64
65 ! Slot access
66 INSN: ##slot < ##read { obj vreg } { slot vreg } { tag integer } { temp vreg } ;
67 INSN: ##slot-imm < ##read { obj vreg } { slot integer } { tag integer } ;
68 INSN: ##set-slot < ##write { obj vreg } { slot vreg } { tag integer } { temp vreg } ;
69 INSN: ##set-slot-imm < ##write { obj vreg } { slot integer } { tag integer } ;
70
71 ! String element access
72 INSN: ##string-nth < ##flushable { obj vreg } { index vreg } { temp vreg } ;
73 INSN: ##set-string-nth-fast < ##effect { obj vreg } { index vreg } { temp vreg } ;
74
75 ! Integer arithmetic
76 INSN: ##add < ##commutative ;
77 INSN: ##add-imm < ##commutative-imm ;
78 INSN: ##sub < ##binary ;
79 INSN: ##sub-imm < ##binary-imm ;
80 INSN: ##mul < ##commutative ;
81 INSN: ##mul-imm < ##commutative-imm ;
82 INSN: ##and < ##commutative ;
83 INSN: ##and-imm < ##commutative-imm ;
84 INSN: ##or < ##commutative ;
85 INSN: ##or-imm < ##commutative-imm ;
86 INSN: ##xor < ##commutative ;
87 INSN: ##xor-imm < ##commutative-imm ;
88 INSN: ##shl < ##binary ;
89 INSN: ##shl-imm < ##binary-imm ;
90 INSN: ##shr < ##binary ;
91 INSN: ##shr-imm < ##binary-imm ;
92 INSN: ##sar < ##binary ;
93 INSN: ##sar-imm < ##binary-imm ;
94 INSN: ##not < ##unary ;
95 INSN: ##log2 < ##unary ;
96
97 : ##tag-fixnum ( dst src -- ) tag-bits get ##shl-imm ; inline
98 : ##untag-fixnum ( dst src -- ) tag-bits get ##sar-imm ; inline
99
100 ! Bignum/integer conversion
101 INSN: ##integer>bignum < ##unary/temp ;
102 INSN: ##bignum>integer < ##unary/temp ;
103
104 ! Float arithmetic
105 INSN: ##add-float < ##commutative ;
106 INSN: ##sub-float < ##binary ;
107 INSN: ##mul-float < ##commutative ;
108 INSN: ##div-float < ##binary ;
109
110 ! Float/integer conversion
111 INSN: ##float>integer < ##unary ;
112 INSN: ##integer>float < ##unary ;
113
114 ! Boxing and unboxing
115 INSN: ##copy < ##unary ;
116 INSN: ##copy-float < ##unary ;
117 INSN: ##unbox-float < ##unary ;
118 INSN: ##unbox-any-c-ptr < ##unary/temp ;
119 INSN: ##box-float < ##unary/temp ;
120 INSN: ##box-alien < ##unary/temp ;
121
122 : ##unbox-f ( dst src -- ) drop 0 ##load-immediate ;
123 : ##unbox-byte-array ( dst src -- ) byte-array-offset ##add-imm ;
124 : ##unbox-alien ( dst src -- ) 3 object tag-number ##slot-imm ;
125
126 : ##unbox-c-ptr ( dst src class temp -- )
127     {
128         { [ over \ f class<= ] [ 2drop ##unbox-f ] }
129         { [ over simple-alien class<= ] [ 2drop ##unbox-alien ] }
130         { [ over byte-array class<= ] [ 2drop ##unbox-byte-array ] }
131         [ nip ##unbox-any-c-ptr ]
132     } cond ;
133
134 ! Alien accessors
135 INSN: ##alien-unsigned-1 < ##alien-getter ;
136 INSN: ##alien-unsigned-2 < ##alien-getter ;
137 INSN: ##alien-unsigned-4 < ##alien-getter ;
138 INSN: ##alien-signed-1 < ##alien-getter ;
139 INSN: ##alien-signed-2 < ##alien-getter ;
140 INSN: ##alien-signed-4 < ##alien-getter ;
141 INSN: ##alien-cell < ##alien-getter ;
142 INSN: ##alien-float < ##alien-getter ;
143 INSN: ##alien-double < ##alien-getter ;
144
145 INSN: ##set-alien-integer-1 < ##alien-setter ;
146 INSN: ##set-alien-integer-2 < ##alien-setter ;
147 INSN: ##set-alien-integer-4 < ##alien-setter ;
148 INSN: ##set-alien-cell < ##alien-setter ;
149 INSN: ##set-alien-float < ##alien-setter ;
150 INSN: ##set-alien-double < ##alien-setter ;
151
152 ! Memory allocation
153 INSN: ##allot < ##flushable size class { temp vreg } ;
154
155 UNION: ##allocation ##allot ##box-float ##box-alien ##integer>bignum ;
156
157 INSN: ##write-barrier < ##effect card# table ;
158
159 INSN: ##alien-global < ##flushable symbol library ;
160
161 ! FFI
162 INSN: ##alien-invoke params stack-frame ;
163 INSN: ##alien-indirect params stack-frame ;
164 INSN: ##alien-callback params stack-frame ;
165 INSN: ##callback-return params ;
166
167 ! Instructions used by CFG IR only.
168 INSN: ##prologue ;
169 INSN: ##epilogue ;
170
171 INSN: ##branch ;
172
173 INSN: ##phi < ##pure inputs ;
174
175 ! Conditionals
176 TUPLE: ##conditional-branch < insn { src1 vreg } { src2 vreg } cc ;
177
178 INSN: ##compare-branch < ##conditional-branch ;
179 INSN: ##compare-imm-branch { src1 vreg } { src2 integer } cc ;
180
181 INSN: ##compare < ##binary cc temp ;
182 INSN: ##compare-imm < ##binary-imm cc temp ;
183
184 INSN: ##compare-float-branch < ##conditional-branch ;
185 INSN: ##compare-float < ##binary cc temp ;
186
187 ! Overflowing arithmetic
188 TUPLE: ##fixnum-overflow < insn { dst vreg } { src1 vreg } { src2 vreg } ;
189 INSN: ##fixnum-add < ##fixnum-overflow ;
190 INSN: ##fixnum-sub < ##fixnum-overflow ;
191 INSN: ##fixnum-mul < ##fixnum-overflow ;
192
193 INSN: ##gc { temp1 vreg } { temp2 vreg } live-values ;
194
195 ! Instructions used by machine IR only.
196 INSN: _prologue stack-frame ;
197 INSN: _epilogue stack-frame ;
198
199 INSN: _label id ;
200
201 INSN: _branch label ;
202 INSN: _loop-entry ;
203
204 INSN: _dispatch src temp ;
205 INSN: _dispatch-label label ;
206
207 TUPLE: _conditional-branch < insn label { src1 vreg } { src2 vreg } cc ;
208
209 INSN: _compare-branch < _conditional-branch ;
210 INSN: _compare-imm-branch label { src1 vreg } { src2 integer } cc ;
211
212 INSN: _compare-float-branch < _conditional-branch ;
213
214 ! Overflowing arithmetic
215 TUPLE: _fixnum-overflow < insn label { dst vreg } { src1 vreg } { src2 vreg } ;
216 INSN: _fixnum-add < _fixnum-overflow ;
217 INSN: _fixnum-sub < _fixnum-overflow ;
218 INSN: _fixnum-mul < _fixnum-overflow ;
219
220 TUPLE: spill-slot n ; C: <spill-slot> spill-slot
221
222 INSN: _gc { temp1 vreg } { temp2 vreg } gc-roots gc-root-count gc-root-size ;
223
224 ! These instructions operate on machine registers and not
225 ! virtual registers
226 INSN: _spill src class n ;
227 INSN: _reload dst class n ;
228 INSN: _copy dst src class ;
229 INSN: _spill-counts counts ;
230
231 ! Instructions that use vregs
232 UNION: vreg-insn
233     ##flushable
234     ##write-barrier
235     ##dispatch
236     ##effect
237     ##fixnum-overflow
238     ##conditional-branch
239     ##compare-imm-branch
240     ##phi
241     ##gc
242     _conditional-branch
243     _compare-imm-branch
244     _dispatch ;
245
246 ! Instructions that kill all live vregs
247 UNION: kill-vreg-insn
248     ##call
249     ##prologue
250     ##epilogue
251     ##alien-invoke
252     ##alien-indirect
253     ##alien-callback ;
254
255 ! Instructions that have complex expansions and require that the
256 ! output registers are not equal to any of the input registers
257 UNION: def-is-use-insn
258     ##integer>bignum
259     ##bignum>integer
260     ##unbox-any-c-ptr ;