diff --git a/src/singeli/src/slash.singeli b/src/singeli/src/slash.singeli index d568a1a9..480f73e2 100644 --- a/src/singeli/src/slash.singeli +++ b/src/singeli/src/slash.singeli @@ -35,23 +35,24 @@ def loadu{p:T & *u64==T} = emit{eltype{T}, 'loadu_u64', p} def popcRand{x:T & isint{T} & width{T}==64} = emit{u8, 'rand_popc64', x} # under valgrind, return a random result in the range of possible ones def popcRand{x:T & isint{T} & width{T}<=32} = emit{u8, 'rand_popc64', x} -# Table from l bits to w-bit indices -def maketab{l,w} = { +# Table from l bits to w-bit indices, shifted left by s +def maketab{l,w,s} = { def bot = fold{ {t,k} => join{each{tup, t, k + t<>(64-w) + 1) & (1<>(width{I}-w) + 1) & (1<>2} + trail := make{V, tail{2,iota{16}}} + def step{w,i} = { + ind := load{i32tab, w} + pc := popc_alt{w, ind, 6} + s := sel{[16]i8, V~~make{[4]u32, ind, ... 3**0}, expander} | trail + res := sel{V, load{*V~~(x+4*i)}, s} + store{*V~~r, 0, res} + r+= pc + } + @for_special_buffered{r,8} (w in *u8~~wp over i to sum) { + def rn = if (has_popc) r+popc{w} else 0 + step{w&0xf, 2*i} + step{w>>4, 2*i+1} + if (has_popc) r = rn + } +} + +i64tab:*u32 = maketab{4,8,1} def thresh{c, T==i32 & hasarch{'AVX2'}} = 32 def thresh{c, T==i64 & hasarch{'AVX2'}} = 8 fn slash{c, T & hasarch{'AVX2'} & T>=i32}(wp:*u64, x:arg{c,T}, r:*T, l:u64, sum:u64) : void = {