diff --git a/build/src/build.bqn b/build/src/build.bqn index 731e4d81..052abf32 100755 --- a/build/src/build.bqn +++ b/build/src/build.bqn @@ -651,7 +651,7 @@ cachedBin‿linkerCache ← { "xag"‿"src/builtins/sort.c"‿"bins" "2.."‿"src/builtins/select.c"‿"select", "xag"‿"src/builtins/scan.c"‿"scan", - "2a."‿"src/builtins/slash.c"‿"constrep", "2.."‿"src/builtins/scan.c"‿"neq", + "2a."‿"src/builtins/slash.c"‿"constrep", "xag"‿"src/builtins/slash.c"‿"slash", "2.."‿"src/builtins/slash.c"‿"count" ⟩ objs ← ⟨⟩ diff --git a/src/builtins/scan.c b/src/builtins/scan.c index 50312557..d650295d 100644 --- a/src/builtins/scan.c +++ b/src/builtins/scan.c @@ -12,18 +12,14 @@ static u64 vg_rand(u64 x) { return x; } #if SINGELI #define SINGELI_FILE scan #include "../utils/includeSingeli.h" - #if __PCLMUL__ - #define SINGELI_FILE neq - #include "../utils/includeSingeli.h" - #endif #endif B scan_ne(B x, u64 p, u64 ia) { // consumes x u64* xp = bitarr_ptr(x); u64* rp; B r=m_bitarrv(&rp,ia); -#if SINGELI_AVX2 && __PCLMUL__ - clmul_scan_ne(p, xp, rp, BIT_N(ia)); +#if SINGELI + si_scan_ne(p, xp, rp, BIT_N(ia)); #if USE_VALGRIND if (ia&63) rp[ia>>6] = vg_def_u64(rp[ia>>6]); #endif diff --git a/src/singeli/src/neq.singeli b/src/singeli/src/neq.singeli deleted file mode 100644 index 11aef7d6..00000000 --- a/src/singeli/src/neq.singeli +++ /dev/null @@ -1,29 +0,0 @@ -include './base' -include './sse' -include './clmul' - -fn clmul_scan_ne_any(x:*void, r:*void, init:u64, words:u64, mark:u64) : void = { - def V = [2]u64 - m := V**mark - def xor64{a, i, carry} = { # carry is 64-bit broadcasted current total - p := clmul{a, m, i} - t := shr{[16]u8, p, 8} - s := p ^ carry - carry = s ^ t - s - } - xv := *V ~~ x - rv := *V ~~ r - e := words/2 - c := V**init - @for (rv, xv over e) { - rv = apply{zipLo, (@collect (j to 2) xor64{xv, j, c})} - } - if (words & 1) { - storeLow{rv+e, 64, clmul{loadLow{xv+e, 64}, m, 0} ^ c} - } -} -fn clmul_scan_ne_bit(init:u64, x:*u64, r:*u64, ia:u64) : void = { - clmul_scan_ne_any(*void~~x, *void~~r, init, ia, -(u64~~1)) -} -export{'clmul_scan_ne', clmul_scan_ne_bit} diff --git a/src/singeli/src/scan.singeli b/src/singeli/src/scan.singeli index bf53b91f..0d7fc7fd 100644 --- a/src/singeli/src/scan.singeli +++ b/src/singeli/src/scan.singeli @@ -1,5 +1,6 @@ include './base' include './sse' +include './clmul' include './avx' include './avx2' include './mask' @@ -118,6 +119,40 @@ export{'si_scan_pluswrap_u8', scan_assoc_0{u8 , +}} export{'si_scan_pluswrap_u16', scan_assoc_0{u16, +}} export{'si_scan_pluswrap_u32', scan_assoc_0{u32, +}} +# xor scan +fn scan_neq{}(p:u64, x:*u64, r:*u64, nw:u64) : void = { + @for (x, r over nw) { + def sc{v, k} = if (k==64) v else sc{v ^ (v<>63) # repeat sign bit + } +} +fn clmul_scan_ne_any{..._ & hasarch{'PCLMUL'}}(x:*void, r:*void, init:u64, words:u64, mark:u64) : void = { + def V = [2]u64 + m := V**mark + def xor64{a, i, carry} = { # carry is 64-bit broadcasted current total + p := clmul{a, m, i} + t := shr{[16]u8, p, 8} + s := p ^ carry + carry = s ^ t + s + } + xv := *V ~~ x + rv := *V ~~ r + e := words/2 + c := V**init + @for (rv, xv over e) { + rv = apply{zipLo, (@collect (j to 2) xor64{xv, j, c})} + } + if (words & 1) { + storeLow{rv+e, 64, clmul{loadLow{xv+e, 64}, m, 0} ^ c} + } +} +fn scan_neq{..._ & hasarch{'PCLMUL'}}(init:u64, x:*u64, r:*u64, nw:u64) : void = { + clmul_scan_ne_any{}(*void~~x, *void~~r, init, nw, -(u64~~1)) +} +export{'si_scan_ne', scan_neq{}} + # Boolean cumulative sum fn bcs{T}(x:*u64, r:*T, l:u64) : void = { def bitp_get{arr, n} = (load{arr, n>>6} >> (n&63)) & 1