diff --git a/src/singeli/src/avx.singeli b/src/singeli/src/avx.singeli index 1dbf82e0..0bb51ceb 100644 --- a/src/singeli/src/avx.singeli +++ b/src/singeli/src/avx.singeli @@ -41,9 +41,11 @@ def topBlend{f:T, t:T, m:M if w256{T,64} and w256i{M,64}} = T ~~ emit{[4]f64, '_ def homBlend{f:T, t:T, m:M if w256{T}} = topBlend{f, t, m} # shuffles -def shufInd{a:T, b:T=[8]E, {...is} if width{E}==32 and length{is}==8 and ({l,h} => tree_fold{&, l==h-4} and x86_shufps_range{l, 8}){slice{is,0,4}, slice{is,4,8}}} = { +# TODO rename to shuf, move shuf to shuf_imm or something +def shufInd{a:T, b:T=[8]E, {...is} if width{E}==32 and length{is}==8 and ({l,h} => same{l,h-4} and x86_shufps_range{l, 8}){slice{is,0,4}, slice{is,4,8}}} = { T~~emit{[8]f32, '_mm256_shuffle_ps', v2f{a}, v2f{b}, base{4, slice{is,0,4} & 3}} } +def shufInd{a:T, b:T=[4]E, {...is} if width{E}==64 and length{is}==4} = T~~shufInd{re_el{u32,a}, re_el{u32,b}, merge{...each{{i} => tup{i*2, i*2+1}, is}}} # mask stuff def andAllZero{x:T, y:T if w256i{T}} = emit{u1, '_mm256_testz_si256', x, y} diff --git a/src/singeli/src/avx2.singeli b/src/singeli/src/avx2.singeli index 8f33d4d1..8291b355 100644 --- a/src/singeli/src/avx2.singeli +++ b/src/singeli/src/avx2.singeli @@ -93,3 +93,20 @@ def narrow{T, x:X if w256u{X,64} and T== u8} = re_el{T, sel{[16]i8, narrow{u32,x def cvt2{(i32), x:X==[4]f64} = emit{[4]i32, '_mm256_cvtpd_epi32', x} def cvt2{(f64), x:X==[4]i32} = emit{[4]f64, '_mm256_cvtepi32_pd', x} + + +def unzip128{a:[k]E, b:[k]E, 0 if hasarch{'X86_64'} and isunsigned{E}} = { + def ED = w_d{E} + def c = make{[k]E, maxvalue{E} * (1-(1 & range{k}))} + packQ{re_el{ED,a&c}, re_el{ED,b&c}} +} +def unzip128{a:[k]E, b:[k]E, 1 if hasarch{'X86_64'} and isunsigned{E}} = { + def ED = w_d{E} + def ew = width{E} + packQ{re_el{ED,a} >> ew, re_el{ED,b} >> ew} +} +def unzip128{a:T, b:T==[8](u32), k} = shufInd{a, b, tup{0,2,8,10, 4,6,12,14}+k} +def unzip128{a:T, b:T==[4](u64), k} = shufInd{a, b, tup{0,4,2,6}+k} + +def unzip{a:T, b:T, k if w128u{T} and hasarch{'SSE2'}} = unzip128{a, b, k} +def unzip{a:T, b:T, k if w256u{T} and hasarch{'AVX2'}} = shuf{[4]u64, unzip128{a, b, k}, 4b3120} \ No newline at end of file diff --git a/src/singeli/src/base.singeli b/src/singeli/src/base.singeli index a827b393..a9cc5687 100644 --- a/src/singeli/src/base.singeli +++ b/src/singeli/src/base.singeli @@ -203,7 +203,7 @@ def pack {a:T, b:T, k} = unzip{el_s{T}~~a, el_s{T}~~b, k} local def extend kpair{op} = { def op{a:T, b:T} = tup{op{a,b,0}, op{a,b,1}} } -extend ({...f}=>each{kpair,f}){pack, zip, zip128, mzip, mzip128} +extend ({...f}=>each{kpair,f}){pack, zip, zip128, mzip, mzip128, unzip, unzip128} def packQ{{a, b}} = packQ{a, b} def pair{{a, b}} = pair{a, b}