#include "../core.h" #include "../utils/mut.h" #include "../builtins.h" #include #define F64_MIN -INFINITY #define F64_MAX INFINITY #if !USE_VALGRIND static u64 vg_rand(u64 x) { return x; } #endif #if SINGELI #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-variable" #include "../singeli/gen/scan.c" #pragma GCC diagnostic pop #endif #if SINGELI && __PCLMUL__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-variable" #include "../singeli/gen/neq.c" #pragma GCC diagnostic pop #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 && __PCLMUL__ clmul_scan_ne(p, xp, rp, BIT_N(ia)); #else for (usz i = 0; i < BIT_N(ia); i++) { u64 c = xp[i]; u64 r = c ^ (c<<1); r^= r<< 2; r^= r<< 4; r^= r<<8; r^= r<<16; r^= r<<32; r^= p; rp[i] = r; p = -(r>>63); // repeat sign bit } #endif decG(x); return r; } static B scan_or(B x, u64 ia) { // consumes x u64* xp = bitarr_ptr(x); u64* rp; B r=m_bitarrv(&rp,ia); usz n=BIT_N(ia); u64 xi; usz i=0; while (i,MIN,or ,asc) } #undef MM_CASE #undef MINMAX #undef MINMAX_SCAN B scan_c1(Md1D* d, B x) { B f = d->f; if (isAtm(x) || RNK(x)==0) thrM("`: Argument cannot have rank 0"); ur xr = RNK(x); usz ia = IA(x); if (ia==0) return x; B xf = getFillQ(x); u8 xe = TI(x,elType); if (xr==1 && xe<=el_f64 && isFun(f) && v(f)->flags) { u8 rtid = v(f)->flags-1; if (xe==el_bit) { u64* xp=bitarr_ptr(x); if (rtid==n_add ) return scan_add_bool(x, ia); if (rtid==n_or | rtid==n_ceil ) return scan_or(x, ia); if (rtid==n_and | rtid==n_mul | rtid==n_floor) return scan_and(x, ia); if (rtid==n_ne ) return scan_ne(x, 0, ia); if (rtid==n_lt) { u64* rp; B r=m_bitarrv(&rp,ia); usz n=BIT_N(ia); u64 m10 = 0x5555555555555555; u64 p = 0; for (usz i=0; i>63); rp[i] = p = x & (m10 ^ (x + c)); } decG(x); return r; } goto base; } if (rtid==n_add) { // + if (xe==el_i8 ) { i8* xp=i8any_ptr (x); i32* rp; B r=m_i32arrv(&rp, ia); i32 c=0; for (usz i=0; if; if (isAtm(x) || RNK(x)==0) thrM("`: 𝕩 cannot have rank 0"); ur xr = RNK(x); usz* xsh = SH(x); usz ia = IA(x); B wf = getFillQ(w); u8 xe = TI(x,elType); if (xr==1 && q_i32(w) && elInt(xe) && isFun(f) && v(f)->flags) { u8 rtid = v(f)->flags-1; i32 wv = o2iG(w); if (xe==el_bit) { u64* xp=bitarr_ptr(x); if (rtid==n_add) { i32* rp; B r=m_i32arrv(&rp, ia); i64 c=wv; for (usz i=0; ic)c=xp[i]; rp[i]=c; } decG(x); return r; } if (xe==el_i16 && wv==(i16)wv) { i16* xp=i16any_ptr(x); i16* rp; B r=m_i16arrv(&rp, ia); i16 c=wv; for (usz i=0; ic)c=xp[i]; rp[i]=c; } decG(x); return r; } if (xe==el_i32 && wv==(i32)wv) { i32* xp=i32any_ptr(x); i32* rp; B r=m_i32arrv(&rp, ia); i32 c=wv; for (usz i=0; ic)c=xp[i]; rp[i]=c; } decG(x); return r; } } if (rtid==n_ne) { // ≠ if (!q_ibit(wv)) { goto base; } bool c=wv; if (xe==el_i8 ) { i8* xp=i8any_ptr (x); u64* rp; B r=m_bitarrv(&rp, ia); for (usz i=0; i