Enable (non-boolean) constrep on SSSE3

This commit is contained in:
Marshall Lochbaum 2024-08-13 20:12:19 -04:00
parent 048529740b
commit fc1265b3f2

View File

@ -59,7 +59,7 @@ exportT{'si_replicate_scan', flat_table{rep_by_scan, ind_types, dat_types}}
# Constant replicate
if_inline (not (hasarch{'AVX2'} or hasarch{'AARCH64'})) {
if_inline (not (hasarch{'SSSE3'} or hasarch{'AARCH64'})) {
fn rep_const{T}(wv:u64, x:*void, r:*void, n:u64) : void = {
rep_by_scan{T, cast_i{usz,wv}, x, r, cast_i{usz, wv*n}}
@ -67,6 +67,8 @@ fn rep_const{T}(wv:u64, x:*void, r:*void, n:u64) : void = {
} else {
def has_bytesel_128 = not hasarch{'AVX2'}
def incl{a,b} = slice{iota{b+1},a}
# 1+˝∨`⌾⌽0=div|⌜range
@ -80,8 +82,6 @@ def fact_inds = slice{iota{fact_size},8}
def fact_tab = makefact{basic_rep, fact_inds}
factors:*u8 = fact_tab
def sdtype = [arch_defvw/8]i8 # shuf data type
def get_shufs{step, wv, len} = {
def i = iota{len*step}
@ -91,7 +91,7 @@ def get_shuf_data{wv, len} = get_shufs{vcount{sdtype}, wv, len} # [len] byte-sel
def get_shuf_data{wv} = get_shuf_data{wv, wv}
# all shuffle vectors for 𝕨≤7
def special_2 = ~hasarch{'AARCH64'} # handle 2 specially on x86-64
def special_2 = not has_bytesel_128 # handle 2 specially on AVX2
def rcsh_vals = slice{basic_rep, special_2}
rcsh_offs:*u8 = shiftright{0, scan{+,rcsh_vals}}
rcsh_data:*i8 = join{join{each{get_shuf_data, rcsh_vals}}}
@ -107,7 +107,7 @@ def read_shuf_vecs{l, ellw:(u64), shp:*V} = { # tuple of byte selectors in 1<<el
r:=each{bind{~~,[32]i8},mzip128{s, s + X**1}}
r
}
def double{x:X if hasarch{'AARCH64'}} = {
def double{x:X if has_bytesel_128} = {
s:= x+x
zip{s, s + X**1}
}
@ -168,7 +168,7 @@ if_inline (hasarch{'AVX2'}) {
def rep_const_shuffle{wv, xv:*V, rv:*V, n:(u64)} = rep_const_shuffle{wv, get_rep_iter{V, wv}, xv, rv, n}
} else if_inline (hasarch{'AARCH64'}) {
} else { # has_bytesel_128
def rep_iter_from_sh{sh}{x, gen} = {
each{{s} => gen{sel{[16]u8, x, s}}, sh}
@ -192,7 +192,7 @@ fn rep_const_shuffle_partial4(wv:u64, ellw:u64, x:*i8, r:*i8, n:u64) : void = {
def wvb = wv << ellw
def hs = (h*step) / wvb # Actual step size in argument elements
def shufbase{i if hasarch{'AVX2'}} = shuf{[4]u64, load{*V~~(x+i)}, 4b1010}
def shufbase{i if hasarch{'AARCH64'}} = load{*V~~(x+i)}
def shufbase{i if has_bytesel_128} = load{*V~~(x+i)}
def shufrun{a, s} = sel{[16]i8, a, s} # happens to be the same across AVX2 & NEON
i:u64 = 0