Move fold{} from squeeze.singeli to vecfold.singeli

This commit is contained in:
Marshall Lochbaum 2023-03-17 12:07:29 -04:00
parent 2ddcc14852
commit 06b4f06e64
3 changed files with 33 additions and 44 deletions

View File

@ -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}

View File

@ -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}}
export{'avx2_squeeze_chrB', squeeze{arch_defvw, u64, 1, 1}}

View File

@ -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}}}