]> gitweb.factorcode.org Git - factor.git/blob - basis/compiler/cfg/intrinsics/simd/simd.factor
use radix literals
[factor.git] / basis / compiler / cfg / intrinsics / simd / simd.factor
1 ! Copyright (C) 2009 Slava Pestov, Joe Groff.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors alien alien.c-types byte-arrays fry
4 classes.algebra cpu.architecture kernel layouts math sequences
5 math.vectors math.vectors.simd.intrinsics
6 macros generalizations combinators combinators.short-circuit
7 arrays locals compiler.tree.propagation.info
8 compiler.cfg.builder.blocks
9 compiler.cfg.comparisons
10 compiler.cfg.stacks compiler.cfg.stacks.local compiler.cfg.hats
11 compiler.cfg.instructions compiler.cfg.registers
12 compiler.cfg.intrinsics
13 compiler.cfg.intrinsics.alien
14 compiler.cfg.intrinsics.simd.backend
15 specialized-arrays ;
16 FROM: alien.c-types => heap-size char short int longlong float double ;
17 SPECIALIZED-ARRAYS: char uchar short ushort int uint longlong ulonglong float double ;
18 IN: compiler.cfg.intrinsics.simd
19
20 ! compound vector ops
21
22 : sign-bit-mask ( rep -- byte-array )
23     signed-rep {
24         { char-16-rep [ uchar-array{
25             0x80 0x80 0x80 0x80
26             0x80 0x80 0x80 0x80
27             0x80 0x80 0x80 0x80
28             0x80 0x80 0x80 0x80
29         } underlying>> ] }
30         { short-8-rep [ ushort-array{
31             0x8000 0x8000 0x8000 0x8000
32             0x8000 0x8000 0x8000 0x8000
33         } underlying>> ] }
34         { int-4-rep [ uint-array{
35             0x8000,0000 0x8000,0000
36             0x8000,0000 0x8000,0000
37         } underlying>> ] }
38         { longlong-2-rep [ ulonglong-array{
39             0x8000,0000,0000,0000
40             0x8000,0000,0000,0000
41         } underlying>> ] }
42     } case ;
43
44 : ^load-neg-zero-vector ( rep -- dst )
45     {
46         { float-4-rep [ float-array{ -0.0 -0.0 -0.0 -0.0 } underlying>> ^^load-literal ] }
47         { double-2-rep [ double-array{ -0.0 -0.0 } underlying>> ^^load-literal ] }
48     } case ;
49
50 : ^load-add-sub-vector ( rep -- dst )
51     signed-rep {
52         { float-4-rep    [ float-array{ -0.0  0.0 -0.0  0.0 } underlying>> ^^load-literal ] }
53         { double-2-rep   [ double-array{ -0.0  0.0 } underlying>> ^^load-literal ] }
54         { char-16-rep    [ char-array{ -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 } underlying>> ^^load-literal ] }
55         { short-8-rep    [ short-array{ -1 0 -1 0 -1 0 -1 0 } underlying>> ^^load-literal ] }
56         { int-4-rep      [ int-array{ -1 0 -1 0 } underlying>> ^^load-literal ] }
57         { longlong-2-rep [ longlong-array{ -1 0 } underlying>> ^^load-literal ] }
58     } case ;
59
60 : ^load-half-vector ( rep -- dst )
61     {
62         { float-4-rep  [ float-array{  0.5 0.5 0.5 0.5 } underlying>> ^^load-literal ] }
63         { double-2-rep [ double-array{ 0.5 0.5 }         underlying>> ^^load-literal ] }
64     } case ;
65
66 : >variable-shuffle ( shuffle rep -- shuffle' )
67     rep-component-type heap-size
68     [ dup <repetition> >byte-array ]
69     [ iota >byte-array ] bi
70     '[ _ n*v _ v+ ] map concat ;
71
72 : ^load-immediate-shuffle ( shuffle rep -- dst )
73     >variable-shuffle ^^load-literal ;
74
75 :: ^blend-vector ( mask true false rep -- dst )
76     true mask rep ^^and-vector
77     mask false rep ^^andn-vector
78     rep ^^or-vector ;
79
80 : ^not-vector ( src rep -- dst )
81     {
82         [ ^^not-vector ]
83         [ [ ^^fill-vector ] [ ^^xor-vector ] bi ]
84     } v-vector-op ;
85
86 :: ^((compare-vector)) ( src1 src2 rep {cc,swap} -- dst )
87     {cc,swap} first2 :> ( cc swap? )
88     swap?
89     [ src2 src1 rep cc ^^compare-vector ]
90     [ src1 src2 rep cc ^^compare-vector ] if ;
91
92 :: ^(compare-vector) ( src1 src2 rep orig-cc -- dst )
93     rep orig-cc %compare-vector-ccs :> ( ccs not? )
94
95     ccs empty?
96     [ rep not? [ ^^fill-vector ] [ ^^zero-vector ] if ]
97     [
98         ccs unclip :> ( rest-ccs first-cc )
99         src1 src2 rep first-cc ^((compare-vector)) :> first-dst
100
101         rest-ccs first-dst
102         [ [ src1 src2 rep ] dip ^((compare-vector)) rep ^^or-vector ]
103         reduce
104
105         not? [ rep ^not-vector ] when
106     ] if ;
107
108 :: ^minmax-compare-vector ( src1 src2 rep cc -- dst )
109     cc order-cc {
110         { cc<  [ src1 src2 rep ^^max-vector src1 rep cc/= ^(compare-vector) ] }
111         { cc<= [ src1 src2 rep ^^min-vector src1 rep cc=  ^(compare-vector) ] }
112         { cc>  [ src1 src2 rep ^^min-vector src1 rep cc/= ^(compare-vector) ] }
113         { cc>= [ src1 src2 rep ^^max-vector src1 rep cc=  ^(compare-vector) ] }
114     } case ;
115
116 : ^compare-vector ( src1 src2 rep cc -- dst )
117     {
118         [ ^(compare-vector) ]
119         [ ^minmax-compare-vector ]
120         { unsigned-int-vector-rep [| src1 src2 rep cc |
121             rep sign-bit-mask ^^load-literal :> sign-bits
122             src1 sign-bits rep ^^xor-vector
123             src2 sign-bits rep ^^xor-vector
124             rep signed-rep cc ^(compare-vector)
125         ] }
126     } vv-cc-vector-op ;
127
128 : ^unpack-vector-head ( src rep -- dst )
129     {
130         [ ^^unpack-vector-head ]
131         { unsigned-int-vector-rep [ [ ^^zero-vector ] [ ^^merge-vector-head ] bi ] }
132         { signed-int-vector-rep [| src rep |
133             src src rep ^^merge-vector-head :> merged
134             rep rep-component-type heap-size 8 * :> bits
135             merged bits rep widen-vector-rep ^^shr-vector-imm
136         ] }
137         { signed-int-vector-rep [| src rep |
138             rep ^^zero-vector :> zero
139             zero src rep cc> ^compare-vector :> sign
140             src sign rep ^^merge-vector-head
141         ] }
142     } v-vector-op ;
143
144 : ^unpack-vector-tail ( src rep -- dst )
145     {
146         [ ^^unpack-vector-tail ]
147         [ [ ^^tail>head-vector ] [ ^^unpack-vector-head ] bi ]
148         { unsigned-int-vector-rep [ [ ^^zero-vector ] [ ^^merge-vector-tail ] bi ] }
149         { signed-int-vector-rep [| src rep |
150             src src rep ^^merge-vector-tail :> merged
151             rep rep-component-type heap-size 8 * :> bits
152             merged bits rep widen-vector-rep ^^shr-vector-imm
153         ] }
154         { signed-int-vector-rep [| src rep |
155             rep ^^zero-vector :> zero
156             zero src rep cc> ^compare-vector :> sign
157             src sign rep ^^merge-vector-tail
158         ] }
159     } v-vector-op ;
160
161 PREDICATE: fixnum-vector-rep < int-vector-rep
162     rep-component-type heap-size cell < ;
163
164 : ^(sum-vector-2) ( src rep -- dst )
165     {
166         [ dupd ^^horizontal-add-vector ]
167         [| src rep | 
168             src src rep ^^merge-vector-head :> head
169             src src rep ^^merge-vector-tail :> tail
170             head tail rep ^^add-vector
171         ]
172     } v-vector-op ;
173
174 : ^(sum-vector-4) ( src rep -- dst )
175     {
176         [
177             [ dupd ^^horizontal-add-vector ]
178             [ dupd ^^horizontal-add-vector ] bi
179         ]
180         [| src rep | 
181             src src rep ^^merge-vector-head :> head
182             src src rep ^^merge-vector-tail :> tail
183             head tail rep ^^add-vector :> src'
184
185             rep widen-vector-rep :> rep'
186             src' src' rep' ^^merge-vector-head :> head'
187             src' src' rep' ^^merge-vector-tail :> tail'
188             head' tail' rep ^^add-vector
189         ]
190     } v-vector-op ;
191
192 : ^(sum-vector-8) ( src rep -- dst )
193     {
194         [
195             [ dupd ^^horizontal-add-vector ]
196             [ dupd ^^horizontal-add-vector ]
197             [ dupd ^^horizontal-add-vector ] tri
198         ]
199         [| src rep | 
200             src src rep ^^merge-vector-head :> head
201             src src rep ^^merge-vector-tail :> tail
202             head tail rep ^^add-vector :> src'
203
204             rep widen-vector-rep :> rep'
205             src' src' rep' ^^merge-vector-head :> head'
206             src' src' rep' ^^merge-vector-tail :> tail'
207             head' tail' rep ^^add-vector :> src''
208
209             rep' widen-vector-rep :> rep''
210             src'' src'' rep'' ^^merge-vector-head :> head''
211             src'' src'' rep'' ^^merge-vector-tail :> tail''
212             head'' tail'' rep ^^add-vector
213         ]
214     } v-vector-op ;
215
216 : ^(sum-vector-16) ( src rep -- dst )
217     {
218         [
219             {
220                 [ dupd ^^horizontal-add-vector ]
221                 [ dupd ^^horizontal-add-vector ]
222                 [ dupd ^^horizontal-add-vector ]
223                 [ dupd ^^horizontal-add-vector ]
224             } cleave
225         ]
226         [| src rep | 
227             src src rep ^^merge-vector-head :> head
228             src src rep ^^merge-vector-tail :> tail
229             head tail rep ^^add-vector :> src'
230
231             rep widen-vector-rep :> rep'
232             src' src' rep' ^^merge-vector-head :> head'
233             src' src' rep' ^^merge-vector-tail :> tail'
234             head' tail' rep ^^add-vector :> src''
235
236             rep' widen-vector-rep :> rep''
237             src'' src'' rep'' ^^merge-vector-head :> head''
238             src'' src'' rep'' ^^merge-vector-tail :> tail''
239             head'' tail'' rep ^^add-vector :> src'''
240
241             rep'' widen-vector-rep :> rep'''
242             src''' src''' rep''' ^^merge-vector-head :> head'''
243             src''' src''' rep''' ^^merge-vector-tail :> tail'''
244             head''' tail''' rep ^^add-vector
245         ]
246     } v-vector-op ;
247
248 : ^(sum-vector) ( src rep -- dst )
249     [
250         dup rep-length {
251             {  2 [ ^(sum-vector-2) ] }
252             {  4 [ ^(sum-vector-4) ] }
253             {  8 [ ^(sum-vector-8) ] }
254             { 16 [ ^(sum-vector-16) ] }
255         } case
256     ] [ ^^vector>scalar ] bi ;
257
258 : ^sum-vector ( src rep -- dst )
259     {
260         { float-vector-rep [ ^(sum-vector) ] }
261         { fixnum-vector-rep [| src rep |
262             src rep ^unpack-vector-head :> head
263             src rep ^unpack-vector-tail :> tail
264             rep widen-vector-rep :> wide-rep
265             head tail wide-rep ^^add-vector wide-rep
266             ^(sum-vector)
267         ] }
268     } v-vector-op ;
269
270 : shuffle? ( obj -- ? ) { [ array? ] [ [ integer? ] all? ] } 1&& ;
271
272 : ^shuffle-vector-imm ( src1 shuffle rep -- dst )
273     [ rep-length 0 pad-tail ] keep {
274         [ ^^shuffle-vector-imm ]
275         [ [ ^load-immediate-shuffle ] [ ^^shuffle-vector ] bi ]
276     } vl-vector-op ;
277
278 : ^shuffle-2-vectors-imm ( src1 src2 shuffle rep -- dst )
279     [ rep-length 0 pad-tail ] keep {
280         { double-2-rep [| src1 src2 shuffle rep |
281             shuffle first2 [ 4 mod ] bi@ :> ( i j )
282             {
283                 { [ i j [ 2 < ] both? ] [
284                     src1 shuffle rep ^shuffle-vector-imm
285                 ] }
286                 { [ i j [ 2 >= ] both? ] [
287                     src2 shuffle [ 2 - ] map rep ^shuffle-vector-imm
288                 ] }
289                 { [ i 2 < ] [
290                     src1 src2 i j 2 - 2array rep ^^shuffle-vector-halves-imm
291                 ] }
292                 ! [ j 2 < ]
293                 [ src2 src1 i 2 - j 2array rep ^^shuffle-vector-halves-imm ]
294             } cond
295         ] }
296     } vvl-vector-op ;
297
298 : ^broadcast-vector ( src n rep -- dst )
299     [ rep-length swap <array> ] keep
300     ^shuffle-vector-imm ;
301
302 : ^with-vector ( src rep -- dst )
303     [ ^^scalar>vector ] keep [ 0 ] dip ^broadcast-vector ;
304
305 : ^select-vector ( src n rep -- dst )
306     {
307         [ ^^select-vector ]
308         [ [ ^broadcast-vector ] keep ^^vector>scalar ]
309     } vl-vector-op ;
310
311 ! intrinsic emitters
312
313 : emit-simd-v+ ( node -- )
314     {
315         [ ^^add-vector ]
316     } emit-vv-vector-op ;
317
318 : emit-simd-v- ( node -- )
319     {
320         [ ^^sub-vector ]
321     } emit-vv-vector-op ;
322
323 : emit-simd-vneg ( node -- )
324     {
325         { float-vector-rep [ [ ^load-neg-zero-vector swap ] [ ^^sub-vector ] bi ] }
326         { int-vector-rep   [ [ ^^zero-vector         swap ] [ ^^sub-vector ] bi ] }
327     } emit-v-vector-op ;
328
329 : emit-simd-v+- ( node -- )
330     {
331         [ ^^add-sub-vector ]
332         { float-vector-rep [| src1 src2 rep |
333             rep ^load-add-sub-vector :> signs
334             src2 signs rep ^^xor-vector :> src2'
335             src1 src2' rep ^^add-vector
336         ] }
337         { int-vector-rep   [| src1 src2 rep |
338             rep ^load-add-sub-vector :> signs
339             src2  signs rep ^^xor-vector :> src2'
340             src2' signs rep ^^sub-vector :> src2''
341             src1 src2'' rep ^^add-vector
342         ] }
343     } emit-vv-vector-op ;
344
345 : emit-simd-vs+ ( node -- )
346     {
347         { float-vector-rep [ ^^add-vector ] }
348         { int-vector-rep [ ^^saturated-add-vector ] }
349     } emit-vv-vector-op ;
350
351 : emit-simd-vs- ( node -- )
352     {
353         { float-vector-rep [ ^^sub-vector ] }
354         { int-vector-rep [ ^^saturated-sub-vector ] }
355     } emit-vv-vector-op ;
356
357 : emit-simd-vs* ( node -- )
358     {
359         { float-vector-rep [ ^^mul-vector ] }
360         { int-vector-rep [ ^^saturated-mul-vector ] }
361     } emit-vv-vector-op ;
362
363 : emit-simd-v* ( node -- )
364     {
365         [ ^^mul-vector ]
366     } emit-vv-vector-op ;
367
368 : emit-simd-v*high ( node -- )
369     {
370         [ ^^mul-high-vector ]
371     } emit-vv-vector-op ;
372
373 : emit-simd-v*hs+ ( node -- )
374     {
375         [ ^^mul-horizontal-add-vector ]
376     } emit-vv-vector-op ;
377
378 : emit-simd-v/ ( node -- )
379     {
380         [ ^^div-vector ]
381     } emit-vv-vector-op ;
382
383 : emit-simd-vmin ( node -- )
384     {
385         [ ^^min-vector ]
386         [
387             [ cc< ^compare-vector ]
388             [ ^blend-vector ] 3bi
389         ]
390     } emit-vv-vector-op ;
391
392 : emit-simd-vmax ( node -- )
393     {
394         [ ^^max-vector ]
395         [
396             [ cc> ^compare-vector ]
397             [ ^blend-vector ] 3bi
398         ]
399     } emit-vv-vector-op ;
400
401 : emit-simd-vavg ( node -- )
402     {
403         [ ^^avg-vector ]
404         { float-vector-rep [| src1 src2 rep |
405             src1 src2 rep ^^add-vector
406             rep ^load-half-vector rep ^^mul-vector
407         ] }
408     } emit-vv-vector-op ;
409
410 : emit-simd-v. ( node -- )
411     {
412         [ ^^dot-vector ]
413         { float-vector-rep [ [ ^^mul-vector ] [ ^sum-vector ] bi ] }
414     } emit-vv-vector-op ;
415
416 : emit-simd-vsad ( node -- )
417     {
418         [
419             [ ^^sad-vector dup { 2 3 0 1 } int-4-rep ^^shuffle-vector-imm int-4-rep ^^add-vector ]
420             [ widen-vector-rep ^^vector>scalar ] bi
421         ]
422     } emit-vv-vector-op ;
423
424 : emit-simd-vsqrt ( node -- )
425     {
426         [ ^^sqrt-vector ]
427     } emit-v-vector-op ;
428
429 : emit-simd-sum ( node -- )
430     {
431         [ ^sum-vector ]
432     } emit-v-vector-op ;
433
434 : emit-simd-vabs ( node -- )
435     {
436         { unsigned-int-vector-rep [ drop ] }
437         [ ^^abs-vector ]
438         { float-vector-rep [ [ ^load-neg-zero-vector ] [ swapd ^^andn-vector ] bi ] }
439         { int-vector-rep [| src rep |
440             rep ^^zero-vector :> zero
441             zero src rep ^^sub-vector :> -src
442             zero src rep cc> ^compare-vector :> sign
443             sign -src src rep ^blend-vector
444         ] }
445     } emit-v-vector-op ;
446
447 : emit-simd-vand ( node -- )
448     {
449         [ ^^and-vector ]
450     } emit-vv-vector-op ;
451
452 : emit-simd-vandn ( node -- )
453     {
454         [ ^^andn-vector ]
455     } emit-vv-vector-op ;
456
457 : emit-simd-vor ( node -- )
458     {
459         [ ^^or-vector ]
460     } emit-vv-vector-op ;
461
462 : emit-simd-vxor ( node -- )
463     {
464         [ ^^xor-vector ]
465     } emit-vv-vector-op ;
466
467 : emit-simd-vnot ( node -- )
468     {
469         [ ^not-vector ]
470     } emit-v-vector-op ;
471
472 : emit-simd-vlshift ( node -- )
473     {
474         [ ^^shl-vector ]
475     } {
476         [ ^^shl-vector-imm ]
477     } [ integer? ] emit-vv-or-vl-vector-op ;
478
479 : emit-simd-vrshift ( node -- )
480     {
481         [ ^^shr-vector ]
482     } {
483         [ ^^shr-vector-imm ]
484     } [ integer? ] emit-vv-or-vl-vector-op ;
485
486 : emit-simd-hlshift ( node -- )
487     {
488         [ ^^horizontal-shl-vector-imm ]
489     } [ integer? ] emit-vl-vector-op ;
490
491 : emit-simd-hrshift ( node -- )
492     {
493         [ ^^horizontal-shr-vector-imm ]
494     } [ integer? ] emit-vl-vector-op ;
495
496 : emit-simd-vshuffle-elements ( node -- )
497     {
498         [ ^shuffle-vector-imm ]
499     } [ shuffle? ] emit-vl-vector-op ;
500
501 : emit-simd-vshuffle2-elements ( node -- )
502     {
503         [ ^shuffle-2-vectors-imm ]
504     } [ shuffle? ] emit-vvl-vector-op ;
505
506 : emit-simd-vshuffle-bytes ( node -- )
507     {
508         [ ^^shuffle-vector ]
509     } emit-vv-vector-op ;
510
511 : emit-simd-vmerge-head ( node -- )
512     {
513         [ ^^merge-vector-head ]
514     } emit-vv-vector-op ;
515
516 : emit-simd-vmerge-tail ( node -- )
517     {
518         [ ^^merge-vector-tail ]
519     } emit-vv-vector-op ;
520
521 : emit-simd-v<= ( node -- )
522     {
523         [ cc<= ^compare-vector ]
524     } emit-vv-vector-op ;
525 : emit-simd-v< ( node -- )
526     {
527         [ cc< ^compare-vector ]
528     } emit-vv-vector-op ;
529 : emit-simd-v= ( node -- )
530     {
531         [ cc=  ^compare-vector ]
532     } emit-vv-vector-op ;
533 : emit-simd-v> ( node -- )
534     {
535         [ cc>  ^compare-vector ]
536     } emit-vv-vector-op ;
537 : emit-simd-v>= ( node -- )
538     {
539         [ cc>= ^compare-vector ]
540     } emit-vv-vector-op ;
541 : emit-simd-vunordered? ( node -- )
542     {
543         [ cc/<>= ^compare-vector ]
544     } emit-vv-vector-op ;
545
546 : emit-simd-vany? ( node -- )
547     {
548         [ vcc-any ^^test-vector ]
549     } emit-v-vector-op ;
550 : emit-simd-vall? ( node -- )
551     {
552         [ vcc-all ^^test-vector ]
553     } emit-v-vector-op ;
554 : emit-simd-vnone? ( node -- )
555     {
556         [ vcc-none ^^test-vector ]
557     } emit-v-vector-op ;
558 : emit-simd-vgetmask ( node -- )
559     {
560         [ ^^move-vector-mask ]
561     } emit-v-vector-op ;
562
563 : emit-simd-v>float ( node -- )
564     {
565         { float-vector-rep [ drop ] }
566         { int-vector-rep [ ^^integer>float-vector ] }
567     } emit-v-vector-op ;
568
569 : emit-simd-v>integer ( node -- )
570     {
571         { float-vector-rep [ ^^float>integer-vector ] }
572         { int-vector-rep [ drop ] }
573     } emit-v-vector-op ;
574
575 : emit-simd-vpack-signed ( node -- )
576     {
577         { double-2-rep [| src1 src2 rep |
578             src1 double-2-rep ^^float-pack-vector :> dst-head
579             src2 double-2-rep ^^float-pack-vector :> dst-tail
580             dst-head dst-tail { 0 1 0 1 } float-4-rep ^^shuffle-vector-halves-imm
581         ] }
582         { int-vector-rep [ ^^signed-pack-vector ] }
583     } emit-vv-vector-op ;
584
585 : emit-simd-vpack-unsigned ( node -- )
586     {
587         [ ^^unsigned-pack-vector ]
588     } emit-vv-vector-op ;
589
590 : emit-simd-vunpack-head ( node -- )
591     {
592         [ ^unpack-vector-head ]
593     } emit-v-vector-op ;
594
595 : emit-simd-vunpack-tail ( node -- )
596     {
597         [ ^unpack-vector-tail ]
598     } emit-v-vector-op ;
599
600 : emit-simd-with ( node -- )
601     {
602         { fixnum-vector-rep [ ^with-vector ] }
603         { float-vector-rep  [ ^with-vector ] }
604     } emit-v-vector-op ;
605
606 : emit-simd-gather-2 ( node -- )
607     {
608         { fixnum-vector-rep [ ^^gather-int-vector-2 ] }
609         { fixnum-vector-rep [ ^^gather-vector-2 ] }
610         { float-vector-rep  [ ^^gather-vector-2 ] }
611     } emit-vv-vector-op ;
612
613 : emit-simd-gather-4 ( node -- )
614     {
615         { fixnum-vector-rep [ ^^gather-int-vector-4 ] }
616         { fixnum-vector-rep [ ^^gather-vector-4 ] }
617         { float-vector-rep  [ ^^gather-vector-4 ] }
618     } emit-vvvv-vector-op ;
619
620 : emit-simd-select ( node -- )
621     {
622         { fixnum-vector-rep [ ^select-vector ] }
623         { float-vector-rep  [ ^select-vector ] }
624     } [ integer? ] emit-vl-vector-op ;
625
626 : emit-alien-vector ( node -- )
627     dup [
628         '[
629             ds-drop prepare-load-memory
630             _ f ^^load-memory-imm ds-push
631         ]
632         [ inline-load-memory? ] inline-accessor
633     ] with { [ %alien-vector-reps member? ] } if-literals-match ;
634
635 : emit-set-alien-vector ( node -- )
636     dup [
637         '[
638             ds-drop prepare-store-memory
639             _ f ##store-memory-imm,
640         ]
641         [ byte-array inline-store-memory? ]
642         inline-accessor
643     ] with { [ %alien-vector-reps member? ] } if-literals-match ;
644
645 : enable-simd ( -- )
646     {
647         { (simd-v+)                 [ emit-simd-v+                  ] }
648         { (simd-v-)                 [ emit-simd-v-                  ] }
649         { (simd-vneg)               [ emit-simd-vneg                ] }
650         { (simd-v+-)                [ emit-simd-v+-                 ] }
651         { (simd-vs+)                [ emit-simd-vs+                 ] }
652         { (simd-vs-)                [ emit-simd-vs-                 ] }
653         { (simd-vs*)                [ emit-simd-vs*                 ] }
654         { (simd-v*)                 [ emit-simd-v*                  ] }
655         { (simd-v*high)             [ emit-simd-v*high              ] }
656         { (simd-v*hs+)              [ emit-simd-v*hs+               ] }
657         { (simd-v/)                 [ emit-simd-v/                  ] }
658         { (simd-vmin)               [ emit-simd-vmin                ] }
659         { (simd-vmax)               [ emit-simd-vmax                ] }
660         { (simd-vavg)               [ emit-simd-vavg                ] }
661         { (simd-v.)                 [ emit-simd-v.                  ] }
662         { (simd-vsad)               [ emit-simd-vsad                ] }
663         { (simd-vsqrt)              [ emit-simd-vsqrt               ] }
664         { (simd-sum)                [ emit-simd-sum                 ] }
665         { (simd-vabs)               [ emit-simd-vabs                ] }
666         { (simd-vbitand)            [ emit-simd-vand                ] }
667         { (simd-vbitandn)           [ emit-simd-vandn               ] }
668         { (simd-vbitor)             [ emit-simd-vor                 ] }
669         { (simd-vbitxor)            [ emit-simd-vxor                ] }
670         { (simd-vbitnot)            [ emit-simd-vnot                ] }
671         { (simd-vand)               [ emit-simd-vand                ] }
672         { (simd-vandn)              [ emit-simd-vandn               ] }
673         { (simd-vor)                [ emit-simd-vor                 ] }
674         { (simd-vxor)               [ emit-simd-vxor                ] }
675         { (simd-vnot)               [ emit-simd-vnot                ] }
676         { (simd-vlshift)            [ emit-simd-vlshift             ] }
677         { (simd-vrshift)            [ emit-simd-vrshift             ] }
678         { (simd-hlshift)            [ emit-simd-hlshift             ] }
679         { (simd-hrshift)            [ emit-simd-hrshift             ] }
680         { (simd-vshuffle-elements)  [ emit-simd-vshuffle-elements   ] }
681         { (simd-vshuffle2-elements) [ emit-simd-vshuffle2-elements  ] }
682         { (simd-vshuffle-bytes)     [ emit-simd-vshuffle-bytes      ] }
683         { (simd-vmerge-head)        [ emit-simd-vmerge-head         ] }
684         { (simd-vmerge-tail)        [ emit-simd-vmerge-tail         ] }
685         { (simd-v<=)                [ emit-simd-v<=                 ] }
686         { (simd-v<)                 [ emit-simd-v<                  ] }
687         { (simd-v=)                 [ emit-simd-v=                  ] }
688         { (simd-v>)                 [ emit-simd-v>                  ] }
689         { (simd-v>=)                [ emit-simd-v>=                 ] }
690         { (simd-vunordered?)        [ emit-simd-vunordered?         ] }
691         { (simd-vany?)              [ emit-simd-vany?               ] }
692         { (simd-vall?)              [ emit-simd-vall?               ] }
693         { (simd-vnone?)             [ emit-simd-vnone?              ] }
694         { (simd-v>float)            [ emit-simd-v>float             ] }
695         { (simd-v>integer)          [ emit-simd-v>integer           ] }
696         { (simd-vpack-signed)       [ emit-simd-vpack-signed        ] }
697         { (simd-vpack-unsigned)     [ emit-simd-vpack-unsigned      ] }
698         { (simd-vunpack-head)       [ emit-simd-vunpack-head        ] }
699         { (simd-vunpack-tail)       [ emit-simd-vunpack-tail        ] }
700         { (simd-with)               [ emit-simd-with                ] }
701         { (simd-gather-2)           [ emit-simd-gather-2            ] }
702         { (simd-gather-4)           [ emit-simd-gather-4            ] }
703         { (simd-select)             [ emit-simd-select              ] }
704         { alien-vector              [ emit-alien-vector             ] }
705         { set-alien-vector          [ emit-set-alien-vector         ] }
706         { assert-positive           [ drop                          ] }
707         { (simd-vgetmask)           [ emit-simd-vgetmask            ] }
708     } enable-intrinsics ;
709
710 enable-simd