From d29b4df50c7b8d2498ef3af1d140f2207155eb4a Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Sat, 25 May 2024 07:04:46 -0400 Subject: [PATCH] Boolean and, or, eq folds for row length >64 --- src/builtins/fold.c | 63 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/src/builtins/fold.c b/src/builtins/fold.c index 272772b6..bce40bb7 100644 --- a/src/builtins/fold.c +++ b/src/builtins/fold.c @@ -505,15 +505,12 @@ B sum_rows_bit(B x) { } } -B xor_rows_bit(B x) { - usz *sh = SH(x); usz n = sh[0]; usz m = sh[1]; - if (m <= 64) return bi_N; - u64* xp = bitarr_ptr(x); - u64* rp; B r = m_bitarrv(&rp, n); +void xor_rows_bit(u64* xp, u64* rp, usz n, usz m, bool eq) { u64 rw = 0; // Buffer for result bits + u64 rx = -(u64)(eq &~ m); // ne to eq conversion if needed #define ADDBIT(I, BIT) \ rw = rw>>1 | (u64)(BIT)<<63; \ - if ((I+1)%64==0) *rp++ = rw; + if ((I+1)%64==0) *rp++ = rw ^ rx; #define XOR_LOOP(LEN, MASK) \ u64 o = 0; /* Carry */ \ for (usz i=0, j=0; i= j+l)) } - usz q=(-n)%64; if (q) *rp = rw >> q; + usz q=(-n)%64; if (q) *rp = (rw^rx) >> q; #undef XOR_LOOP #undef ADDBIT - decG(x); return r; +} + +void or_rows_bit(u64* xp, u64* rp, usz n, usz m, u64 and) { + u64 rw = 0; // Buffer for result bits + #define ADDBIT(I, BIT, XOR) \ + rw = rw>>1 | (u64)(BIT)<<63; \ + if ((I+1)%64==0) *rp++ = XOR ^ rw; + if (m < 128) { + usz c = and? m-1 : 0; + u64 o = 0; + for (usz i=0, j=0; i> (in%64)); + ADDBIT(i, s > c+o, 0); + j = jn+1; + } + } else { + u64 rx = -and; u64 id = ~rx; + u64 o = 0; // Saved bits + for (usz i=0, j=0; i> q; + #undef ADDBIT } B fold_rows_bit(Md1D* fd, B x) { @@ -545,6 +582,14 @@ B fold_rows_bit(Md1D* fd, B x) { if (!v(fd->f)->flags) return bi_N; u8 rtid = v(fd->f)->flags-1; if (rtid==n_add) return sum_rows_bit(x); - if (rtid==n_ne ) return xor_rows_bit(x); + if (rtid==n_ne|rtid==n_eq|rtid==n_or|rtid==n_and) { + usz *sh = SH(x); usz n = sh[0]; usz m = sh[1]; + if (m <= 64) return bi_N; + u64* xp = bitarr_ptr(x); + u64* rp; B r = m_bitarrv(&rp, n); + if (rtid==n_ne|rtid==n_eq) xor_rows_bit(xp, rp, n, m, rtid==n_eq); + else or_rows_bit(xp, rp, n, m, rtid==n_and); + decG(x); return r; + } return bi_N; }