1 ! Copyright (C) 2023 Giftpflanze.
2 ! See https://factorcode.org/license.txt for BSD license.
3 USING: accessors assocs compiler.cfg compiler.cfg.comparisons
4 compiler.cfg.instructions compiler.cfg.intrinsics
5 compiler.cfg.stack-frame compiler.codegen.labels
6 compiler.codegen.relocation compiler.constants continuations
7 cpu.architecture cpu.arm cpu.arm.64.assembler generalizations
8 kernel layouts math math.order sequences system words.symbol ;
13 : words ( n -- n ) 4 * ; inline
15 : temp0 ( -- reg ) X9 ; inline
16 : pic-tail-reg ( -- reg ) X12 ; inline
18 : stack-reg ( -- reg ) SP ; inline
19 M: arm.64 frame-reg X29 ;
20 : vm-reg ( -- reg ) X28 ; inline
21 M: arm.64 ds-reg X27 ;
22 M: arm.64 rs-reg X26 ;
24 ! M: arm.64 vm-stack-space 0 ;
26 M: arm.64 %load-immediate ( reg val -- )
29 tuck -16 * shift 0xffff bitand
30 ] with map>alist [ nip 0 = ] assoc-reject
33 [ first2 rot MOVK ] with each
36 M: arm.64 %load-reference ( reg obj -- )
40 NOP NOP rc-absolute-cell rel-literal
41 ] [ \ f type-number swap MOVwi ] if* ;
43 M: arm.64 %load-float 2drop ;
44 M: arm.64 %load-double 2drop ;
45 M: arm.64 %load-vector 3drop ;
47 M: arm.64 complex-addressing? eh? ; ! x86: t
48 M: arm.64 dummy-fp-params? f ; ! x86.64.windows: t
49 M: arm.64 dummy-int-params? f ; ! ppc.64.linux: t
50 M: arm.64 dummy-stack-params? f ; ! ppc.64.linux: t
51 M: arm.64 float-right-align-on-stack? f ; ! ppc.64.linux: t
52 M: arm.64 fused-unboxing? eh? ; ! x86: t
53 M: arm.64 integer-float-needs-stack-frame? f ; ! x86.sse: f
54 M: arm.64 long-long-odd-register? f ; ! ppc.32: t
55 M: arm.64 long-long-on-stack? f ; ! x86.32: t
56 M: arm.64 return-struct-in-registers? drop eh? ;
57 M: arm.64 struct-return-on-stack? f ; ! x86.32.not-linux: t
58 M: arm.64 test-instruction? t ; ! t
59 M: arm.64 value-struct? drop eh? ;
61 M: arm.64 %add rot ADDr ;
62 M: arm.64 %add-imm spin ADDi ;
63 M: arm.64 %sub spin SUBr ;
64 M: arm.64 %sub-imm spin SUBi ;
65 M: arm.64 %mul rot MUL ;
71 M: arm.64 %neg swap NEG ;
96 M: arm.64 %and rot ANDr ;
97 M: arm.64 %and-imm spin ANDi ;
98 M: arm.64 %not swap MVN ;
99 M: arm.64 %or rot ORRr ;
100 M: arm.64 %or-imm spin ORRi ;
101 M: arm.64 %sar spin ASRr ;
102 M: arm.64 %sar-imm spin ASRi ;
103 M: arm.64 %shl spin LSLr ;
104 M: arm.64 %shl-imm spin LSLi ;
105 M: arm.64 %shr spin LSRr ;
106 M: arm.64 %shr-imm spin LSRi ;
107 M: arm.64 %xor rot EORr ;
108 M: arm.64 %xor-imm spin EORi ;
110 M: arm.64 %copy ( dst src rep -- )
111 2over eq? [ 3drop ] [
112 ! [ [ ?spill-slot ] bi@ ] dip
113 ! 2over [ register? ] both?
114 ! [ copy-register* ] [ copy-memory* ] if
118 : fixnum-overflow ( label dst src1 src2 cc quot -- )
124 M: arm.64 %fixnum-add [ rot ADDr ] fixnum-overflow ;
125 M: arm.64 %fixnum-sub [ spin SUBr ] fixnum-overflow ;
126 M: arm.64 %fixnum-mul [ rot MUL ] fixnum-overflow ;
128 M: arm.64 %add-float rot D FADDs ;
129 M: arm.64 %sub-float spin D FSUBs ;
130 M: arm.64 %mul-float rot D FMULs ;
131 M: arm.64 %div-float spin D FDIVs ;
132 M: arm.64 %min-float rot D FMINs ;
133 M: arm.64 %max-float rot D FMAXs ;
134 M: arm.64 %sqrt swap D FSQRTs ;
136 M: arm.64 %single>double-float swap S D FCVT ;
137 M: arm.64 %double>single-float swap D S FCVT ;
139 M: arm.64 %integer>float swap D SCVTFsi ;
140 M: arm.64 %float>integer swap D FCVTZSsi ;
142 M: arm.64 %zero-vector 2drop ;
143 M: arm.64 %fill-vector 2drop ;
144 M: arm.64 %gather-vector-2 4drop ;
145 M: arm.64 %gather-int-vector-2 4drop ;
146 M: arm.64 %gather-vector-4 6 ndrop ;
147 M: arm.64 %gather-int-vector-4 6 ndrop ;
148 M: arm.64 %select-vector 4drop ;
149 M: arm.64 %shuffle-vector 4drop ;
150 M: arm.64 %shuffle-vector-imm 4drop ;
151 M: arm.64 %shuffle-vector-halves-imm 5drop ;
152 M: arm.64 %tail>head-vector 3drop ;
153 M: arm.64 %merge-vector-head 4drop ;
154 M: arm.64 %merge-vector-tail 4drop ;
155 M: arm.64 %float-pack-vector 3drop ;
156 M: arm.64 %signed-pack-vector 4drop ;
157 M: arm.64 %unsigned-pack-vector 4drop ;
158 M: arm.64 %unpack-vector-head 3drop ;
159 M: arm.64 %unpack-vector-tail 3drop ;
160 M: arm.64 %integer>float-vector 3drop ;
161 M: arm.64 %float>integer-vector 3drop ;
162 M: arm.64 %compare-vector 5drop ;
163 M: arm.64 %move-vector-mask 3drop ;
164 M: arm.64 %test-vector 5drop ;
165 M: arm.64 %test-vector-branch 5drop ;
166 M: arm.64 %add-vector 4drop ;
167 M: arm.64 %saturated-add-vector 4drop ;
168 M: arm.64 %add-sub-vector 4drop ;
169 M: arm.64 %sub-vector 4drop ;
170 M: arm.64 %saturated-sub-vector 4drop ;
171 M: arm.64 %mul-vector 4drop ;
172 M: arm.64 %mul-high-vector 4drop ;
173 M: arm.64 %mul-horizontal-add-vector 4drop ;
174 M: arm.64 %saturated-mul-vector 4drop ;
175 M: arm.64 %div-vector 4drop ;
176 M: arm.64 %min-vector 4drop ;
177 M: arm.64 %max-vector 4drop ;
178 M: arm.64 %avg-vector 4drop ;
179 M: arm.64 %dot-vector 4drop ;
180 M: arm.64 %sad-vector 4drop ;
181 M: arm.64 %sqrt-vector 3drop ;
182 M: arm.64 %horizontal-add-vector 4drop ;
183 M: arm.64 %horizontal-sub-vector 4drop ;
184 M: arm.64 %abs-vector 3drop ;
185 M: arm.64 %and-vector 4drop ;
186 M: arm.64 %andn-vector 4drop ;
187 M: arm.64 %or-vector 4drop ;
188 M: arm.64 %xor-vector 4drop ;
189 M: arm.64 %not-vector 3drop ;
190 M: arm.64 %shl-vector 4drop ;
191 M: arm.64 %shr-vector 4drop ;
192 M: arm.64 %shl-vector-imm 4drop ;
193 M: arm.64 %shr-vector-imm 4drop ;
194 M: arm.64 %horizontal-shl-vector-imm 4drop ;
195 M: arm.64 %horizontal-shr-vector-imm 4drop ;
197 M: arm.64 %integer>scalar 3drop ;
198 M: arm.64 %scalar>integer 3drop ;
199 M: arm.64 %vector>scalar 3drop ;
200 M: arm.64 %scalar>vector 3drop ;
202 M: arm.64 %zero-vector-reps f ;
203 M: arm.64 %fill-vector-reps f ;
204 M: arm.64 %gather-vector-2-reps f ;
205 M: arm.64 %gather-int-vector-2-reps f ;
206 M: arm.64 %gather-vector-4-reps f ;
207 M: arm.64 %gather-int-vector-4-reps f ;
208 M: arm.64 %select-vector-reps f ;
209 M: arm.64 %alien-vector-reps f ;
210 M: arm.64 %shuffle-vector-reps f ;
211 M: arm.64 %shuffle-vector-imm-reps f ;
212 M: arm.64 %shuffle-vector-halves-imm-reps f ;
213 M: arm.64 %merge-vector-reps f ;
214 M: arm.64 %float-pack-vector-reps f ;
215 M: arm.64 %signed-pack-vector-reps f ;
216 M: arm.64 %unsigned-pack-vector-reps f ;
217 M: arm.64 %unpack-vector-head-reps f ;
218 M: arm.64 %unpack-vector-tail-reps f ;
219 M: arm.64 %integer>float-vector-reps f ;
220 M: arm.64 %float>integer-vector-reps f ;
221 M: arm.64 %compare-vector-reps drop f ;
222 M: arm.64 %compare-vector-ccs nip eh? ;
223 M: arm.64 %move-vector-mask-reps f ;
224 M: arm.64 %test-vector-reps f ;
225 M: arm.64 %add-vector-reps f ;
226 M: arm.64 %saturated-add-vector-reps f ;
227 M: arm.64 %add-sub-vector-reps f ;
228 M: arm.64 %sub-vector-reps f ;
229 M: arm.64 %saturated-sub-vector-reps f ;
230 M: arm.64 %mul-vector-reps f ;
231 M: arm.64 %mul-high-vector-reps f ;
232 M: arm.64 %mul-horizontal-add-vector-reps f ;
233 M: arm.64 %saturated-mul-vector-reps f ;
234 M: arm.64 %div-vector-reps f ;
235 M: arm.64 %min-vector-reps f ;
236 M: arm.64 %max-vector-reps f ;
237 M: arm.64 %avg-vector-reps f ;
238 M: arm.64 %dot-vector-reps f ;
239 M: arm.64 %sad-vector-reps f ;
240 M: arm.64 %sqrt-vector-reps f ;
241 M: arm.64 %horizontal-add-vector-reps f ;
242 M: arm.64 %horizontal-sub-vector-reps f ;
243 M: arm.64 %abs-vector-reps f ;
244 M: arm.64 %and-vector-reps f ;
245 M: arm.64 %andn-vector-reps f ;
246 M: arm.64 %or-vector-reps f ;
247 M: arm.64 %xor-vector-reps f ;
248 M: arm.64 %not-vector-reps f ;
249 M: arm.64 %shl-vector-reps f ;
250 M: arm.64 %shr-vector-reps f ;
251 M: arm.64 %shl-vector-imm-reps f ;
252 M: arm.64 %shr-vector-imm-reps f ;
253 M: arm.64 %horizontal-shl-vector-imm-reps f ;
254 M: arm.64 %horizontal-shr-vector-imm-reps f ;
256 M: arm.64 %unbox-alien 2drop ;
257 M: arm.64 %unbox-any-c-ptr 2drop ;
258 M: arm.64 %box-alien 3drop ;
259 M: arm.64 %box-displaced-alien 5drop ;
261 M: arm.64 %convert-integer 3drop ;
263 M: arm.64 %load-memory 7 ndrop ;
264 M: arm.64 %load-memory-imm 5drop ;
265 M: arm.64 %store-memory 7 ndrop ;
266 M: arm.64 %store-memory-imm 5drop ;
268 M: arm.64 %alien-global 3drop ;
269 M: arm.64 %vm-field 2drop ;
270 M: arm.64 %set-vm-field 2drop ;
272 M: arm.64 %allot 4drop ;
273 M: arm.64 %write-barrier 6 ndrop ;
274 M: arm.64 %write-barrier-imm 5drop ;
276 M: arm.64 stack-frame-size
277 (stack-frame-size) cell + 16 align ;
280 -16 stack-reg stack-reg STRpre
281 0 BL rc-relative-arm64-branch rel-word-pic
282 16 stack-reg stack-reg LDRpost ;
285 cell + 16 align [ stack-reg stack-reg ADDr ] unless-zero ;
289 0 Br rc-relative-arm64-branch rel-word-pic-tail ;
291 M: arm.64 %jump-label
292 0 Br rc-relative-arm64-branch label-fixup ;
295 cell - 16 align [ stack-reg stack-reg SUBr ] unless-zero ;
297 M: arm.64 %return f RET ;
303 NOP NOP rc-absolute-cell rel-safepoint ;
305 M: arm.64 %compare 5drop ;
306 M: arm.64 %compare-imm 5drop ;
307 M: arm.64 %compare-integer-imm 5drop ;
308 M: arm.64 %test 5drop ;
309 M: arm.64 %test-imm 5drop ;
310 M: arm.64 %compare-float-ordered 5drop ;
311 M: arm.64 %compare-float-unordered 5drop ;
313 M: arm.64 %compare-branch 4drop ;
314 M: arm.64 %compare-imm-branch 4drop ;
315 M: arm.64 %compare-integer-imm-branch 4drop ;
316 M: arm.64 %test-branch 4drop ;
317 M: arm.64 %test-imm-branch 4drop ;
318 M: arm.64 %compare-float-ordered-branch 4drop ;
319 M: arm.64 %compare-float-unordered-branch 4drop ;
321 M: arm.64 %dispatch 2drop ;
323 M: arm.64 %c-invoke 3drop ;
325 M: arm.64 %call-gc drop ;
326 M: arm.64 %check-nursery-branch 5drop ;
328 M: arm.64 %clear drop ;
329 M: arm.64 %peek 2drop ;
330 M: arm.64 %replace 2drop ;
331 M: arm.64 %replace-imm 2drop ;
332 M: arm.64 %inc drop ;
334 M: arm.64 machine-registers {
337 X0 X1 X2 X3 X4 X5 X6 X7
338 X8 X9 X10 X11 X12 X13 X14 X15
339 X19 X20 X21 X22 X23 X24
343 V0 V1 V2 V3 V4 V5 V6 V7
344 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28
350 M: arm.64 param-regs drop {
351 { int-regs { X0 X1 X2 X3 X4 X5 X6 X7 X8 } }
352 { float-regs { V0 V1 V2 V3 V4 V5 V6 V7 } }
355 M: arm.64 return-regs {
356 { int-regs { X0 X1 X2 X3 X4 X5 X6 X7 X8 } }
357 { float-regs { V0 V1 V2 V3 V4 V5 V6 V7 } }
360 M: arm.64 %set-slot 5drop ;
361 M: arm.64 %set-slot-imm 4drop ;
362 M: arm.64 %slot 5drop ;
363 M: arm.64 %slot-imm 4drop ;
365 M: arm.64 %spill 3drop ;
366 M: arm.64 %reload 3drop ;
367 M: arm.64 gc-root-offset ;
369 M: arm.64 immediate-arithmetic?
370 -2147483648 2147483647 between? ;
372 M: arm.64 immediate-bitwise?
373 [ encode-bitmask drop t ] [ 2drop f ] recover ;
375 M: arm.64 immediate-comparand? drop eh? ;
376 M: arm.64 immediate-store? drop eh? ;
378 M: arm.64 %unbox 4drop ;
379 M: arm.64 %unbox-long-long 4drop ;
380 M: arm.64 %local-allot 4drop ;
381 M: arm.64 %box 5drop ;
382 M: arm.64 %box-long-long 5drop ;
383 M: arm.64 %save-context 2drop ;
385 M: arm.64 %alien-invoke 10 ndrop ;
386 M: arm.64 %alien-indirect 9 ndrop ;
387 M: arm.64 %alien-assembly 8 ndrop ;
388 M: arm.64 %callback-inputs 2drop ;
389 M: arm.64 %callback-outputs drop ;
390 M: arm.64 stack-cleanup 2drop ;
391 M: arm.64 enable-cpu-features
395 enable-alien-4-intrinsics
398 enable-float-intrinsics