diff --git a/makefile b/makefile index d6e02c49..c110a1b4 100644 --- a/makefile +++ b/makefile @@ -224,7 +224,7 @@ preSingeliBin: @${MAKE} i_singeli=0 singeli=0 force_build_dir=obj/presingeli f= lf= postmsg="singeli sources:" i_t=presingeli i_f='-O1 -DPRE_SINGELI' FFI=0 OUTPUT=obj/presingeli/BQN c -build_singeli: ${addprefix src/singeli/gen/, cmp.c dyarith.c copy.c equal.c squeeze.c scan.c slash.c} +build_singeli: ${addprefix src/singeli/gen/, cmp.c dyarith.c copy.c equal.c squeeze.c scan.c slash.c bits.c} @echo $(postmsg) src/singeli/gen/%.c: src/singeli/src/%.singeli preSingeliBin @echo $< | cut -c 17- | sed 's/^/ /' diff --git a/src/singeli/src/bitops.singeli b/src/singeli/src/bitops.singeli index 1824dd4a..320394a0 100644 --- a/src/singeli/src/bitops.singeli +++ b/src/singeli/src/bitops.singeli @@ -60,3 +60,7 @@ def spreadBits{T, a & vcount{T} <= width{eltype{T}} & w256u{T}} = { b:= make{T, 1< { + cb:= loadBatchBit{VT, bits, i} + storeBatch{r, i, blendF{e0v, e1v, cb}, M} + }} +} + +bitsel_i{VL,T}(r:*u8, bits:*u64, e0:u64, e1:u64, len:u64) : void = { + bitsel{VL, T, *T~~r, bits, trunc{T,e0}, trunc{T,e1}, len} +} + +'avx2_bitsel_8' =bitsel_i{256, u8} +'avx2_bitsel_16'=bitsel_i{256, u16} +'avx2_bitsel_32'=bitsel_i{256, u32} +'avx2_bitsel_64'=bitsel_i{256, u64} \ No newline at end of file diff --git a/src/singeli/src/copy.singeli b/src/singeli/src/copy.singeli index 69d9ab7d..922000f2 100644 --- a/src/singeli/src/copy.singeli +++ b/src/singeli/src/copy.singeli @@ -11,9 +11,8 @@ def copyFromBits{T, xp: *u64, rp: *eltype{T}, l:u64} = { def TU = ty_u{T} maskedLoop{bulk, l, {i, M} => { - x:= b_getBatch{bulk, xp, i} # TODO unroll f64 by two to make b_getBatch not sad - y:= spreadBits{TU, x} - r:= y & TU~~broadcast{T, 1} + x:= loadBatchBit{TU, xp, i} + r:= x & TU~~broadcast{T, 1} storeBatch{rp, i, T~~r, M} }} } diff --git a/src/singeli/src/dyarith.singeli b/src/singeli/src/dyarith.singeli index 70676663..24e4e5a7 100644 --- a/src/singeli/src/dyarith.singeli +++ b/src/singeli/src/dyarith.singeli @@ -25,10 +25,6 @@ def rootty{T & isvec{T}} = eltype{T} def is_s{X} = issigned{rootty{X}} def is_u{X} = isunsigned{rootty{X}} -def loadBatchBit{T, x:*u64, n:(Size)} = { - spreadBits{T, b_getBatch{vcount{T}, x, n}} -} - def ty_sc{O, R} = R # keep floats as-is def ty_sc{O, R & is_s{O} & is_u{R}} = ty_s{R} def ty_sc{O, R & is_u{O} & is_s{R}} = ty_u{R} diff --git a/src/utils/bits.c b/src/utils/bits.c index c198f457..47466a00 100644 --- a/src/utils/bits.c +++ b/src/utils/bits.c @@ -1,5 +1,20 @@ #include "../core.h" + +#if SINGELI + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-variable" + #include "../singeli/gen/bits.c" + #pragma GCC diagnostic pop + typedef void (*BitselFn)(u8*, u64*, u64, u64, u64); + static BitselFn bitselFns[] = { + [0]=avx2_bitsel_8, + [1]=avx2_bitsel_16, + [2]=avx2_bitsel_32, + [3]=avx2_bitsel_64, + }; +#endif + NOINLINE Arr* allZeroes(usz ia) { u64* rp; Arr* r = m_bitarrp(&rp, ia); for (usz i = 0; i < BIT_N(ia); i++) rp[i] = 0; return r; } NOINLINE Arr* allOnes (usz ia) { u64* rp; Arr* r = m_bitarrp(&rp, ia); for (usz i = 0; i < BIT_N(ia); i++) rp[i] = ~0ULL; return r; } @@ -45,12 +60,16 @@ NOINLINE B bit_sel(B b, B e0, B e1) { sel: void* rp = m_tyarrlc(&r, width, b, type); - switch(width) { - case 0: for (usz i=0; i