]> gitweb.factorcode.org Git - factor.git/blob - basis/cpu/arm/64/64.factor
6335146dd3d35821ca9e83a62a76e4b1df822a19
[factor.git] / basis / cpu / arm / 64 / 64.factor
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 ;
9 IN: cpu.arm.64
10
11 << ALIAS: eh? f >>
12
13 : words ( n -- n ) 4 * ; inline
14
15 : temp0 ( -- reg ) X9 ; inline
16 : pic-tail-reg ( -- reg ) X12 ; inline
17
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 ;
23
24 ! M: arm.64 vm-stack-space 0 ;
25
26 M: arm.64 %load-immediate ( reg val -- )
27     [ XZR MOVr ] [
28         { 0 1 2 3 } [
29             tuck -16 * shift 0xffff bitand
30         ] with map>alist [ nip 0 = ] assoc-reject
31         unclip
32         overd first2 rot MOVZ
33         [ first2 rot MOVK ] with each
34     ] if-zero ;
35
36 M: arm.64 %load-reference ( reg obj -- )
37     [
38         3 words rot LDRl
39         3 words Br
40         NOP NOP rc-absolute-cell rel-literal
41     ] [ \ f type-number swap MOVwi ] if* ;
42
43 M: arm.64 %load-float 2drop ;
44 M: arm.64 %load-double 2drop ;
45 M: arm.64 %load-vector 3drop ;
46
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? ;
60
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 ;
66
67 M: arm.64 %mul-imm
68     XZR X9 ADDi
69     X9 rot MUL ;
70
71 M: arm.64 %neg swap NEG ;
72
73 M: arm.64 %min
74     2dup CMPr
75     rot LT CSEL ;
76
77 M: arm.64 %max
78     2dup CMPr
79     rot GT CSEL ;
80
81 M: arm.64 %log2
82     over CLZ
83     63 over dup SUBi
84     dup NEG ;
85
86 M: arm.64 %bit-count
87     D0 XD FMOVgen
88     D0 D0 8B CNT
89     D0 D0 8B ADDV
90     D0 swap DX FMOVgen ;
91
92 M: arm.64 %bit-test
93     [ 2^ swap TSTi ] dip
94     swap dup EQ CSEL ;
95
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 ;
109
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
115         3drop
116     ] if ;
117
118 : fixnum-overflow ( label dst src1 src2 cc quot -- )
119     [ call ] curry dip {
120         { cc-o VS }
121         { cc/o VC }
122     } at B.cond ; inline
123
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 ;
127
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 ;
135
136 M: arm.64 %single>double-float swap S D FCVT ;
137 M: arm.64 %double>single-float swap D S FCVT ;
138
139 M: arm.64 %integer>float swap D SCVTFsi ;
140 M: arm.64 %float>integer swap D FCVTZSsi ;
141
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 ;
196
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 ;
201
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 ;
255
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 ;
260
261 M: arm.64 %convert-integer 3drop ;
262
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 ;
267
268 M: arm.64 %alien-global 3drop ;
269 M: arm.64 %vm-field 2drop ;
270 M: arm.64 %set-vm-field 2drop ;
271
272 M: arm.64 %allot 4drop ;
273 M: arm.64 %write-barrier 6 ndrop ;
274 M: arm.64 %write-barrier-imm 5drop ;
275
276 M: arm.64 stack-frame-size
277     (stack-frame-size) cell + 16 align ;
278
279 M: arm.64 %call
280     -16 stack-reg stack-reg STRpre
281     0 BL rc-relative-arm64-branch rel-word-pic
282     16 stack-reg stack-reg LDRpost ;
283
284 M: arm.64 %epilogue
285     cell + 16 align [ stack-reg stack-reg ADDr ] unless-zero ;
286
287 M: arm.64 %jump
288     4 pic-tail-reg ADR
289     0 Br rc-relative-arm64-branch rel-word-pic-tail ;
290
291 M: arm.64 %jump-label
292     0 Br rc-relative-arm64-branch label-fixup ;
293
294 M: arm.64 %prologue
295     cell - 16 align [ stack-reg stack-reg SUBr ] unless-zero ;
296
297 M: arm.64 %return f RET ;
298
299 M: arm.64 %safepoint
300     3 words temp0 LDRl
301     0 temp0 W0 STRuoff
302     3 words Br
303     NOP NOP rc-absolute-cell rel-safepoint ;
304
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 ;
312
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 ;
320
321 M: arm.64 %dispatch 2drop ;
322
323 M: arm.64 %c-invoke 3drop ;
324
325 M: arm.64 %call-gc drop ;
326 M: arm.64 %check-nursery-branch 5drop ;
327
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 ;
333
334 M: arm.64 machine-registers {
335     {
336         int-regs {
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
340         }
341     } {
342         float-regs {
343             V0 V1 V2 V3 V4 V5 V6 V7
344             V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28
345             V29 V30 V31
346         }
347     }
348 } ;
349
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 } }
353 } ;
354
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 } }
358 } ;
359
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 ;
364
365 M: arm.64 %spill 3drop ;
366 M: arm.64 %reload 3drop ;
367 M: arm.64 gc-root-offset ;
368
369 M: arm.64 immediate-arithmetic?
370     -2147483648 2147483647 between? ;
371
372 M: arm.64 immediate-bitwise?
373     [ encode-bitmask drop t ] [ 2drop f ] recover ;
374
375 M: arm.64 immediate-comparand? drop eh? ;
376 M: arm.64 immediate-store? drop eh? ;
377
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 ;
384
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
392     enable-min/max
393     enable-log2
394     enable-bit-test
395     enable-alien-4-intrinsics
396     enable-float-min/max
397     enable-bit-count
398     enable-float-intrinsics
399     enable-fsqrt ;