diff --git a/src/singeli/src/fold.singeli b/src/singeli/src/fold.singeli index 517f95c1..7942beaa 100644 --- a/src/singeli/src/fold.singeli +++ b/src/singeli/src/fold.singeli @@ -76,35 +76,41 @@ export{'si_sum_f64', fold_assoc_0{f64,+}} fn select_rows_byte(x0:*void, r0:*void, n:usz, l:usz, e:u8) : usz = { n <<= e - if (hasarch{'AVX2'} and n>=32 and l < usz~~20>>e and (l&1)!=0) { - def V = [32]u8 - def swap_by{x, m} = homBlend{x, shuf{[4]u64, x, 2,3,0,1}, m} + def vl = arch_defvw / 8 + def vh = vl / 2 + def thr = min{vl+2, 20} + def has_blend = hasarch{'SSE4.1'} or hasarch{'AARCH64'} + if (has_blend and n>=vl and l < usz~~thr>>e and (l&1)!=0) { + def V = [vl]u8; def H = [vh]u16 l8 := cast_i{u8, l} - li := cast_i{u8, l + 2 * ((l-1) + (l&2))} # Inverse mod 32 + li := cast_i{u8, l + 2 * ((l-1) + (l&2))} # Inverse mod vl elo:= V**(u8~~1<x) else { + ms := (V**16 & sii) == (V**16 &~ iota{V}) + {x} => homBlend{x, shuf{[4]u64, x, 2,3,0,1}, ms} + } # Blend masks def mg = { # Iteration i should select where mg == V**i ss := (si < V**(l8<>e) * nv} + return{(usz~~vl>>e) * nv} } 0 }