From 5cfa89ad5aac14d70ce9bea864446e23bf485f6b Mon Sep 17 00:00:00 2001 From: dzaima Date: Thu, 1 Sep 2022 15:05:38 +0300 Subject: [PATCH] separate functions for comparison scalar & array cases --- src/builtins/cmp.c | 194 ++++++++++++++++++++++++-------------------- src/singeli/c/cmp.c | 74 ++++++++++------- 2 files changed, 148 insertions(+), 120 deletions(-) diff --git a/src/builtins/cmp.c b/src/builtins/cmp.c index e3ee9172..99efac5b 100644 --- a/src/builtins/cmp.c +++ b/src/builtins/cmp.c @@ -1,73 +1,6 @@ #include "../core.h" #include "../utils/each.h" -#define P2(N) { if (isArr(w)|isArr(x)) { \ - SLOWIF((!isArr(w) || TI(w,elType)!=el_B) && (!isArr(x) || TI(x,elType)!=el_B)) SLOW2("cmp " #N, w, x); \ - return arith_recd(N##_c2, w, x); \ -}} - -#if SINGELI -#include "../singeli/c/cmp.c" -#else -#define AL(X) u64* rp; B r = m_bitarrc(&rp, X); usz ria=IA(r); usz bia = BIT_N(ria); -#define CMP_IMPL(CHR, NAME, RNAME, PNAME, L, R, OP, FC, CF, BX) \ - if (isF64(w)&isF64(x)) return m_i32(w.f OP x.f); \ - if (isC32(w)&isC32(x)) return m_i32(w.u OP x.u); \ - if (isF64(w)&isC32(x)) return m_i32(FC); \ - if (isC32(w)&isF64(x)) return m_i32(CF); \ - if (isArr(w)) { u8 we = TI(w,elType); \ - if (we==el_B) goto end; \ - if (isArr(x)) { u8 xe = TI(x,elType); \ - if (xe==el_B) goto end; \ - if (RNK(w)==RNK(x)) { if (!eqShape(w, x)) thrF(CHR": Expected equal shape prefix (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", w, x); \ - if (we!=xe) { B tw=w,tx=x; \ - we = aMakeEq(&tw, &tx, we, xe); \ - if (we==el_MAX) goto end; \ - w=tw; x=tx; \ - } \ - AL(x) \ - switch(we) { default: UD; \ - case el_bit: { u64* wp=bitarr_ptr(w); u64* xp=bitarr_ptr(x); for(usz i=0;i=, 0, 1, wv | ~xv) -CMP("<", lt,gt, gt, x,w, < , 1, 0, ~wv & xv) -CMP(">", gt,lt, gt, w,x, > , 0, 1, wv & ~xv) -#undef CMP +B le_c2(B, B, B); B ge_c2(B, B, B); +B lt_c2(B, B, B); B gt_c2(B, B, B); +B eq_c2(B, B, B); B ne_c2(B, B, B); -B eq_c2(B t, B w, B x) { - CMP_IMPL("=", eq, eq, eq, w,x, ==, 0, 0, ~wv^xv); - P2(eq); - B r = m_i32(atomEqual(w, x)); - dec(w); dec(x); - return r; +#define CMP_REC(NAME, RNAME, PRE) NOINLINE B NAME##_rec(i32 swapped, B w, B x) { PRE \ + SLOWIF((!isArr(w) || TI(w,elType)!=el_B) && (!isArr(x) || TI(x,elType)!=el_B)) SLOW2("recursive cmp " #NAME, w, x); \ + return swapped? arith_recd(RNAME##_c2, x, w) : arith_recd(NAME##_c2, w, x); \ } -B ne_c2(B t, B w, B x) { - CMP_IMPL("≠", ne, ne, ne, w,x, !=, 1, 1, wv^xv); - P2(ne); - B r = m_i32(!atomEqual(w, x)); - dec(w); dec(x); - return r; +CMP_REC(le, ge, ) +CMP_REC(lt, gt, ) +CMP_REC(eq, eq, swapped=0;) +CMP_REC(ne, ne, swapped=0;) +#define ge_rec(S, W, X) le_rec(!S, X, W) +#define gt_rec(S, W, X) lt_rec(!S, X, W) +#undef CMP_REC + +#if SINGELI +#include "../singeli/c/cmp.c" +#else + +#define AL(X) u64* rp; B r = m_bitarrc(&rp, X); usz ria=IA(r); usz bia = BIT_N(ria); +#define CMP_AA(CN, CR, NAME, OP, BX, PRE) NOINLINE B NAME##_AA(i32 swapped, B w, B x) { PRE \ + u8 xe = TI(x, elType); if (xe==el_B) goto bad; \ + u8 we = TI(w, elType); if (we==el_B) goto bad; \ + if (RNK(w)==RNK(x)) { if (!eqShape(w, x)) thrF("%U: Expected equal shape prefix (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", swapped?CR:CN, swapped?x:w, swapped?w:x); \ + if (we!=xe) { B tw=w,tx=x; \ + we = aMakeEq(&tw, &tx, we, xe); \ + if (we==el_MAX) goto bad; \ + w=tw; x=tx; \ + } \ + AL(x) \ + switch(we) { default: UD; \ + case el_bit: { u64* wp=bitarr_ptr(w); u64* xp=bitarr_ptr(x); for(usz i=0;i", lt, < , ~wv & xv, ) +CMP_AA("=", "?", eq, ==, ~wv^xv, swapped=0;) +CMP_AA("≠", "?", ne, !=, wv^xv, swapped=0;) +#define ge_AA(T, W, X) le_AA(!T, X, W) +#define gt_AA(T, W, X) lt_AA(!T, X, W) +#undef CMP_AA + + +#define CMP_SA(NAME, OP, BX, PRE) NOINLINE B NAME##_SA(i32 swapped, B w, B x) { PRE \ + u8 xe = TI(x, elType); if (xe==el_B) goto bad; AL(x) \ + switch(xe) { default: UD; \ + case el_bit: { if (!q_bit(w)) break; u64 wv=bitx(w); u64* xp=bitarr_ptr(x); for(usz i=0;i=, wv | ~xv, ) +CMP_SA(lt, < , ~wv & xv, ) +CMP_SA(gt, > , wv & ~xv, ) +#undef CMP_SA + +#endif + + + +#define CMP_TO_ARR(NAME, RNAME) \ + if (isArr(x)) { \ + if (isArr(w)) return NAME##_AA(0, w, x); \ + else return NAME##_SA(0, w, x); \ + } else if (isArr(w)) return RNAME##_SA(1, x, w); + +#define CMP_SCALAR(NAME, RNAME, OP, FC, CF) B NAME##_c2(B t, B w, B x) { \ + if (isF64(w)&isF64(x)) return m_i32(w.f OP x.f); \ + if (isC32(w)&isC32(x)) return m_i32(w.u OP x.u); \ + CMP_TO_ARR(NAME, RNAME); \ + if (isF64(w)&isC32(x)) return m_i32(FC); \ + if (isC32(w)&isF64(x)) return m_i32(CF); \ + return m_i32(compare(w, x) OP 0); \ } +CMP_SCALAR(le, ge, <=, 1, 0) +CMP_SCALAR(ge, le, >=, 0, 1) +CMP_SCALAR(lt, gt, < , 1, 0) +CMP_SCALAR(gt, lt, > , 0, 1) + +NOINLINE B eq_atom(B t, B w, B x) { B r = m_i32( atomEqual(w, x)); dec(w); dec(x); return r; } +NOINLINE B ne_atom(B t, B w, B x) { B r = m_i32(!atomEqual(w, x)); dec(w); dec(x); return r; } +B eq_c2(B t, B w, B x) { if(isF64(w)&isF64(x)) return m_i32(w.f==x.f); if(isC32(w)&isC32(x)) return m_i32(w.u==x.u); CMP_TO_ARR(eq, eq); return eq_atom(t, w, x); } +B ne_c2(B t, B w, B x) { if(isF64(w)&isF64(x)) return m_i32(w.f!=x.f); if(isC32(w)&isC32(x)) return m_i32(w.u!=x.u); CMP_TO_ARR(ne, ne); return ne_atom(t, w, x); } + +#undef CMP_SCALAR +#undef CMP_TO_ARR B gt_c1(B t, B x) { if (isAtm(x)) return x; diff --git a/src/singeli/c/cmp.c b/src/singeli/c/cmp.c index 4e144aad..bac3e0d9 100644 --- a/src/singeli/c/cmp.c +++ b/src/singeli/c/cmp.c @@ -35,35 +35,49 @@ FN_LUT(avx2, gt, AS); FN_LUT(avx2, gt, AA); FN_LUT(avx2, ge, AS); FN_LUT(avx2, ge, AA); FN_LUT(avx2, lt, AS); FN_LUT(avx2, le, AS); +#undef FN_LUT + #define AL(X) u64* rp; B r = m_bitarrc(&rp, X); usz ria=IA(r) -#define CMP_IMPL(CHR, NAME, RNAME, PNAME, L, R, OP, FC, CF, BX) \ - if (isF64(w)&isF64(x)) return m_i32(w.f OP x.f); \ - if (isC32(w)&isC32(x)) return m_i32(w.u OP x.u); \ - if (isArr(w)) { u8 we = TI(w,elType); \ - if (we==el_B) goto end; \ - if (isArr(x)) { u8 xe = TI(x,elType); \ - if (xe==el_B) goto end; \ - if (RNK(w)==RNK(x)) { if (!eqShape(w, x)) thrF(CHR": Expected equal shape prefix (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", w, x); \ - if (we!=xe) { B tw=w,tx=x; \ - we = aMakeEq(&tw, &tx, we, xe); \ - if (we==el_MAX) goto end; \ - w=tw; x=tx; \ - } \ - AL(x); \ - if (ria) lut_avx2_##PNAME##AA[we](rp, (u8*)tyany_ptr(L), (u8*)tyany_ptr(R), ria); \ - decG(w);decG(x); return r; \ - } else goto end; \ - } \ - AL(w); \ - if (ria) lut_avx2_##NAME##AS [we](rp, (u8*)tyany_ptr(w), x.u, ria); \ - else dec(x); \ - decG(w); return r; \ - } else if (isArr(x)) { u8 xe = TI(x,elType); if (xe==el_B) goto end; AL(x); \ - if (ria) lut_avx2_##RNAME##AS[xe](rp, (u8*)tyany_ptr(x), w.u, ria); \ - else dec(w); \ - decG(x); return r; \ - } \ - if (isF64(w)&isC32(x)) return m_i32(FC); \ - if (isC32(w)&isF64(x)) return m_i32(CF); \ - end:; +#define CMP_AA(CN, CR, NAME, PRE) NOINLINE B NAME##_AA(i32 swapped, B w, B x) { PRE \ + u8 xe = TI(x, elType); if (xe==el_B) goto bad; \ + u8 we = TI(w, elType); if (we==el_B) goto bad; \ + if (RNK(w)==RNK(x)) { if (!eqShape(w, x)) thrF("%U: Expected equal shape prefix (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", swapped?CR:CN, swapped?x:w, swapped?w:x); \ + if (we!=xe) { B tw=w,tx=x; \ + we = aMakeEq(&tw, &tx, we, xe); \ + if (we==el_MAX) goto bad; \ + w=tw; x=tx; \ + } \ + AL(x); \ + if (ria) lut_avx2_##NAME##AA[we](rp, (u8*)tyany_ptr(w), (u8*)tyany_ptr(x), ria); \ + decG(w);decG(x); return r; \ + } \ + bad: return NAME##_rec(swapped, w, x); \ +} +CMP_AA("≥", "≤", ge, ) +CMP_AA(">", "<", gt, ) +CMP_AA("=", "?", eq, swapped=0;) +CMP_AA("≠", "?", ne, swapped=0;) +#define le_AA(T, W, X) ge_AA(!T, X, W) +#define lt_AA(T, W, X) gt_AA(!T, X, W) +#undef CMP_AA + + + + +#define CMP_SA(NAME, RNAME, PRE) B NAME##_SA(i32 swapped, B w, B x) { PRE \ + u8 xe = TI(x, elType); if (xe==el_B) goto bad; \ + AL(x); \ + if (ria) lut_avx2_##RNAME##AS[xe](rp, (u8*)tyany_ptr(x), w.u, ria); \ + else dec(w); \ + decG(x); return r; \ + bad: return NAME##_rec(swapped, w, x); \ +} +CMP_SA(eq, eq, swapped=0;) +CMP_SA(ne, ne, swapped=0;) +CMP_SA(le, ge, ) +CMP_SA(ge, le, ) +CMP_SA(lt, gt, ) +CMP_SA(gt, lt, ) +#undef CMP_SA +#undef AL \ No newline at end of file