a rep >rep-array :> a'
rep <rep-array> :> c'
elts [| from to |
- from a' nth-unsafe
- rep rep-length 1 - bitand
+ from rep rep-length 1 - bitand
+ a' nth-unsafe
to c' set-nth-unsafe
] each-index
c' underlying>> ; inline
n 1 + c' set-nth-unsafe
] each
c' underlying>> ;
-: (simd-vs+) ( a b rep -- c ) dup '[ + _ c-type-clamp ] components-2map ;
-: (simd-vs-) ( a b rep -- c ) dup '[ - _ c-type-clamp ] components-2map ;
-: (simd-vs*) ( a b rep -- c ) dup '[ - _ c-type-clamp ] components-2map ;
+: (simd-vs+) ( a b rep -- c )
+ dup rep-component-type '[ + _ c-type-clamp ] components-2map ;
+: (simd-vs-) ( a b rep -- c )
+ dup rep-component-type '[ - _ c-type-clamp ] components-2map ;
+: (simd-vs*) ( a b rep -- c )
+ dup rep-component-type '[ * _ c-type-clamp ] components-2map ;
: (simd-v*) ( a b rep -- c ) [ * ] components-2map ;
: (simd-v/) ( a b rep -- c ) [ / ] components-2map ;
: (simd-vmin) ( a b rep -- c ) [ min ] components-2map ;
: (simd-vlshift) ( a n rep -- c ) swap '[ _ shift ] bitwise-components-map ;
: (simd-vrshift) ( a n rep -- c ) swap '[ _ neg shift ] bitwise-components-map ;
: (simd-hlshift) ( a n rep -- c )
- drop tail-slice 16 0 pad-tail ;
+ drop head-slice* 16 0 pad-head ;
: (simd-hrshift) ( a n rep -- c )
- drop head-slice 16 0 pad-head ;
+ drop tail-slice 16 0 pad-tail ;
: (simd-vshuffle-elements) ( a n rep -- c ) [ rep-length 0 pad-tail ] keep (vshuffle) ;
: (simd-vshuffle-bytes) ( a b rep -- c ) drop uchar-16-rep (vshuffle) ;
:: (simd-vmerge-head) ( a b rep -- c )
: (simd-vall?) ( a rep -- ? ) [ bitand ] bitwise-components-reduce zero? not ;
: (simd-vnone?) ( a rep -- ? ) [ bitor ] bitwise-components-reduce zero? ;
: (simd-v>float) ( a rep -- c )
- [ >rep-array ] [ >float-vector-rep [>rep-array] ] bi call( i -- f ) ;
+ [ >rep-array ] [ >float-vector-rep [>rep-array] ] bi call( i -- f ) underlying>> ;
: (simd-v>integer) ( a rep -- c )
- [ >rep-array ] [ >int-vector-rep [>rep-array] ] bi call( i -- f ) ;
+ [ >rep-array ] [ >int-vector-rep [>rep-array] ] bi call( i -- f ) underlying>> ;
: (simd-vpack-signed) ( a b rep -- c )
[ 2>rep-array cord-append ]
[ narrow-vector-rep [ [<rep-array>] ] [ rep-component-type ] bi ] bi
- '[ _ c-type-clamp ] swap map-as ;
+ '[ _ c-type-clamp ] swap map-as underlying>> ;
: (simd-vpack-unsigned) ( a b rep -- c )
[ 2>rep-array cord-append ]
[ narrow-vector-rep >uint-vector-rep [ [<rep-array>] ] [ rep-component-type ] bi ] bi
- '[ _ c-type-clamp ] swap map-as ;
+ '[ _ c-type-clamp ] swap map-as underlying>> ;
: (simd-vunpack-head) ( a rep -- c )
[ >rep-array ] [ widen-vector-rep [ rep-length ] [ [>rep-array] ] bi ] bi
[ head-slice ] dip call( a' -- c' ) underlying>> ;
[ >rep-array ] [ widen-vector-rep [ rep-length ] [ [>rep-array] ] bi ] bi
[ tail-slice ] dip call( a' -- c' ) underlying>> ;
: (simd-with) ( n rep -- v )
- [ rep-length iota swap '[ _ ] ] [ <rep-array> ] bi replicate-as ;
+ [ rep-length iota swap '[ _ ] ] [ <rep-array> ] bi replicate-as
+ underlying>> ;
: (simd-gather-2) ( m n rep -- v ) <rep-array> [ 2 set-firstn ] keep underlying>> ;
: (simd-gather-4) ( m n o p rep -- v ) <rep-array> [ 4 set-firstn ] keep underlying>> ;
: (simd-select) ( a n rep -- x ) [ swap ] dip >rep-array nth-unsafe ;
GENERIC: simd-element-type ( obj -- c-type )
GENERIC: simd-rep ( simd -- rep )
+M: object simd-element-type drop f ;
+M: object simd-rep drop f ;
+
<<
<PRIVATE
[ 3dup [ drop [ simd-128? ] both? ] [ '[ simd-rep _ eq? ] both? ] 3bi and ]
2dip if ; inline
-: simd-construct-op ( exemplar quot: ( rep -- v ) -- v )
- [ dup simd-rep ] dip curry make-underlying ; inline
-
: simd-unbox ( a -- a (a) )
[ ] [ underlying>> ] bi ; inline
: vn->v-op ( a n rep quot: ( (a) n rep -- (c) ) fallback-quot -- c )
drop [ simd-unbox ] 3dip 3curry make-underlying ; inline
+: vn->n-op ( a n rep quot: ( (a) n rep -- n ) fallback-quot -- n )
+ drop [ underlying>> ] 3dip call ; inline
+
: v->n-op ( a rep quot: ( (a) rep -- n ) fallback-quot -- n )
drop [ underlying>> ] 2dip call ; inline
PRIVATE>
>>
-DEFER: simd-with
-DEFER: simd-cast
-
<<
<PRIVATE
A-cast DEFINES ${T}-cast
A{ DEFINES ${T}{
-ELT [ A-rep rep-component-type ]
-N [ A-rep rep-length ]
+ELT [ A-rep rep-component-type ]
+N [ A-rep rep-length ]
+COERCER [ ELT c-type-class "coercer" word-prop [ ] or ]
SET-NTH [ ELT dup c:c-setter c:array-accessor ]
M: A like drop dup \ A instance? [ >A ] unless ; inline
-: A-with ( n -- v ) \ A new simd-with ; inline
-: A-cast ( v -- v' ) \ A new simd-cast ; inline
+: A-with ( n -- v ) COERCER call \ A-rep (simd-with) \ A boa ; inline
+: A-cast ( v -- v' ) underlying>> \ A boa ; inline
! SIMD vectors as sequences
M: A clone [ clone ] change-underlying ; inline
M: A length drop N ; inline
M: A nth-unsafe
- swap {
- { 0 [ 0 \ A-rep (simd-select) ] }
- { 1 [ 1 \ A-rep (simd-select) ] }
- { 2 [ 2 \ A-rep (simd-select) ] }
- { 3 [ 3 \ A-rep (simd-select) ] }
- { 4 [ 4 \ A-rep (simd-select) ] }
- { 5 [ 5 \ A-rep (simd-select) ] }
- { 6 [ 6 \ A-rep (simd-select) ] }
- { 7 [ 7 \ A-rep (simd-select) ] }
- { 8 [ 8 \ A-rep (simd-select) ] }
- { 9 [ 9 \ A-rep (simd-select) ] }
- { 10 [ 10 \ A-rep (simd-select) ] }
- { 11 [ 11 \ A-rep (simd-select) ] }
- { 12 [ 12 \ A-rep (simd-select) ] }
- { 13 [ 13 \ A-rep (simd-select) ] }
- { 14 [ 14 \ A-rep (simd-select) ] }
- { 15 [ 15 \ A-rep (simd-select) ] }
- } case ; inline
+ swap \ A-rep [ (simd-select) ] [ call-next-method ] vn->n-op ; inline
M: A c:byte-length drop 16 ; inline
M: A new-sequence
[ length bad-simd-length ] if ; inline
M: A equal?
- \ A [ drop v= vall? ] [ 3drop f ] if-both-vectors-match ; inline
+ \ A-rep [ drop v= vall? ] [ 3drop f ] if-both-vectors-match ; inline
! SIMD primitive operations
M: A hlshift \ A-rep [ (simd-hlshift) ] [ call-next-method ] vn->v-op ; inline
M: A hrshift \ A-rep [ (simd-hrshift) ] [ call-next-method ] vn->v-op ; inline
M: A vshuffle-elements \ A-rep [ (simd-vshuffle-elements) ] [ call-next-method ] vn->v-op ; inline
-M: A vshuffle-bytes \ A-rep [ (simd-vshuffle-bytes) ] [ call-next-method ] vv->v-op ; inline
+M: A vshuffle-bytes \ A-rep [ (simd-vshuffle-bytes) ] [ call-next-method ] vv'->v-op ; inline
M: A (vmerge-head) \ A-rep [ (simd-vmerge-head) ] [ call-next-method ] vv->v-op ; inline
M: A (vmerge-tail) \ A-rep [ (simd-vmerge-tail) ] [ call-next-method ] vv->v-op ; inline
M: A v<= \ A-rep [ (simd-v<=) ] [ call-next-method ] vv->v-op ; inline
! SIMD high-level specializations
-M: A vbroadcast [ swap nth ] keep simd-with ; inline
-M: A n+v [ simd-with ] keep v+ ; inline
-M: A n-v [ simd-with ] keep v- ; inline
-M: A n*v [ simd-with ] keep v* ; inline
-M: A n/v [ simd-with ] keep v/ ; inline
-M: A v+n over simd-with v+ ; inline
-M: A v-n over simd-with v- ; inline
-M: A v*n over simd-with v* ; inline
-M: A v/n over simd-with v/ ; inline
+M: A vbroadcast swap nth A-with ; inline
+M: A n+v [ A-with ] dip v+ ; inline
+M: A n-v [ A-with ] dip v- ; inline
+M: A n*v [ A-with ] dip v* ; inline
+M: A n/v [ A-with ] dip v/ ; inline
+M: A v+n A-with v+ ; inline
+M: A v-n A-with v- ; inline
+M: A v*n A-with v* ; inline
+M: A v/n A-with v/ ; inline
M: A norm-sq dup v. assert-positive ; inline
M: A norm norm-sq sqrt ; inline
M: A distance v- norm ; inline
! M: simd-128 >pprint-sequence ;
! M: simd-128 pprint* pprint-object ;
-\ A-boa \ A new N {
- { 2 [ '[ _ [ (simd-gather-2) ] simd-construct-op ] ] }
- { 4 [ '[ _ [ (simd-gather-4) ] simd-construct-op ] ] }
- [ swap '[ _ _ nsequence ] ]
-} case BOA-EFFECT define-inline
+\ A-boa
+[ COERCER N napply ] N {
+ { 2 [ [ A-rep (simd-gather-2) A boa ] ] }
+ { 4 [ [ A-rep (simd-gather-4) A boa ] ] }
+ [ \ A new '[ _ _ nsequence ] ]
+} case compose
+BOA-EFFECT define-inline
M: A pprint-delims drop \ A{ \ } ;
SYNTAX: A{ \ } [ >A ] parse-literal ;
c:<c-type>
byte-array >>class
A >>boxed-class
- [ A-rep alien-vector \ A boa ] >>getter
+ [ A-rep alien-vector A boa ] >>getter
[ [ underlying>> ] 2dip A-rep set-alien-vector ] >>setter
16 >>size
16 >>align
INSTANCE: simd-128 sequence
-! SIMD constructors
-
-: simd-with ( n seq -- v )
- [ (simd-with) ] simd-construct-op ; inline
-
-MACRO: simd-boa ( class -- )
- new dup length {
- { 2 [ '[ _ [ (simd-gather-2) ] simd-construct-op ] ] }
- { 4 [ '[ _ [ (simd-gather-4) ] simd-construct-op ] ] }
- [ swap '[ _ _ nsequence ] ]
- } case ;
-
-: simd-cast ( v seq -- v' )
- [ underlying>> ] dip new-underlying ; inline
-
! SIMD instances
SIMD-128: char-16