diff --git a/src/singeli/src/count.singeli b/src/singeli/src/count.singeli index b9b9fa15..bc393e69 100644 --- a/src/singeli/src/count.singeli +++ b/src/singeli/src/count.singeli @@ -3,27 +3,12 @@ include './sse' include './avx' include './avx2' include 'util/tup' - -# TODO merge with squeeze -def fold{F, x:T} = { - show{'WARNING: using fallback fold'} - def E = eltype{T} - r:E = 0 - each{{i} => { r = F{r, extract{x, i}} }, iota{vcount{T}}} - r -} -def fold{F, x:T & width{T}==128 & hasarch{'X86_64'}} = { - c:= x - def EW = elwidth{T} - if (EW<=64) c = F{c, shuf{[4]u32, c, 4b1032}} - if (EW<=32) c = F{c, shuf{[4]u32, c, 4b2301}} - if (EW<=16) c = F{c, sel{[16]u8, c, make{[16]i8, iota{16}^2}}} - if (EW<=8) c = F{c, sel{[16]u8, c, make{[16]i8, iota{16}^1}}} - extract{c, 0} -} -def fold{F, x:T & width{T}==256 & hasarch{'X86_64'}} = fold{F, F{half{x, 0}, half{x, 1}}} +include './vecfold' fn sum_vec{T==[32]i8}(v:T) = fold{+, [16]i16~~fold{+, unpackQ{v, T**0}}} +def minmax{c, a, b} = tern{c{cast_i{i8,a},cast_i{i8,b}}, a, b} +def min{a:i16, b:i16} = minmax{<, a, b} +def max{a:i16, b:i16} = minmax{>, a, b} def inc{ptr, ind, v} = store{ptr, ind, v + load{ptr, ind}} def inc{ptr, ind} = inc{ptr, ind, 1} diff --git a/src/singeli/src/squeeze.singeli b/src/singeli/src/squeeze.singeli index a282dfd7..9b01d230 100644 --- a/src/singeli/src/squeeze.singeli +++ b/src/singeli/src/squeeze.singeli @@ -11,6 +11,7 @@ if (hasarch{'AVX2'}) { include './mask' include './cbqnDefs' include 'util/tup' +include './vecfold' def preserve_negative_zero = 0 @@ -42,30 +43,6 @@ def anyNonChar{M, x:T & isvec{T} & hasarch{'X86_64'}} = { -def fold{F, x:T} = { - show{'WARNING: using fallback fold for ', F, T} - def E = eltype{T} - r:E = 0 - each{{i} => { r = F{r, extract{x, i}} }, iota{vcount{T}}} - r -} -def fold{F, x:T & w128{T} & hasarch{'X86_64'}} = { - c:= x - def EW = elwidth{T} - if (EW<=64) c = F{c, shuf{[4]u32, c, 4b1032}} - if (EW<=32) c = F{c, shuf{[4]u32, c, 4b2301}} - if (hasarch{'SSSE3'} and 0) { - if (EW<=16) c = F{c, sel{[16]u8, c, make{[16]i8, iota{16}^2}}} - if (EW==8) c = F{c, sel{[16]u8, c, make{[16]i8, iota{16}^1}}} - extract{c, 0} - } else { - if (EW<=16) c = F{c, shuf16Lo{c, 4b2301}} - if (EW==8) { v:=extract{[8]i16~~c, 0}; cast_i{u8, F{v, v>>8}} } - else extract{c, 0} - } -} -def fold{F, x:T & w256{T} & hasarch{'X86_64'}} = fold{F, F{half{x, 0}, half{x, 1}}} - def makeOptBranch{enable, F} = { if (enable) { def skip = makelabel{}; goto{skip} @@ -209,4 +186,4 @@ export{'avx2_squeeze_numB', squeeze{arch_defvw, f64, 0, 1}} export{'avx2_squeeze_c16', squeeze{arch_defvw, u16, 1, 0}} export{'avx2_squeeze_c32', squeeze{arch_defvw, u32, 1, 0}} -export{'avx2_squeeze_chrB', squeeze{arch_defvw, u64, 1, 1}} \ No newline at end of file +export{'avx2_squeeze_chrB', squeeze{arch_defvw, u64, 1, 1}} diff --git a/src/singeli/src/vecfold.singeli b/src/singeli/src/vecfold.singeli new file mode 100644 index 00000000..b123b596 --- /dev/null +++ b/src/singeli/src/vecfold.singeli @@ -0,0 +1,27 @@ +# Fold associative/commutative operation across a register +# Used by squeeze.singeli, count.singeli +# Has to be included after util/tup because of name conflict + +def fold{F, x:T} = { + show{'WARNING: using fallback fold for ', F, T} + def E = eltype{T} + r:E = 0 + each{{i} => { r = F{r, extract{x, i}} }, iota{vcount{T}}} + r +} +def fold{F, x:T & w128{T} & hasarch{'X86_64'}} = { + c:= x + def EW = elwidth{T} + if (EW<=64) c = F{c, shuf{[4]u32, c, 4b1032}} + if (EW<=32) c = F{c, shuf{[4]u32, c, 4b2301}} + if (hasarch{'SSSE3'} and 0) { + if (EW<=16) c = F{c, sel{[16]u8, c, make{[16]i8, iota{16}^2}}} + if (EW==8) c = F{c, sel{[16]u8, c, make{[16]i8, iota{16}^1}}} + extract{c, 0} + } else { + if (EW<=16) c = F{c, shuf16Lo{c, 4b2301}} + if (EW==8) { v:=extract{[8]i16~~c, 0}; cast_i{eltype{T}, F{v, v>>8}} } + else extract{c, 0} + } +} +def fold{F, x:T & w256{T} & hasarch{'X86_64'}} = fold{F, F{half{x, 0}, half{x, 1}}}