From a637adadd9bea6eb260282ece8b85e6c24152d36 Mon Sep 17 00:00:00 2001 From: dzaima Date: Fri, 2 Sep 2022 13:10:04 +0300 Subject: [PATCH] rearrange arithd.c in preparation for separating its cases --- src/builtins/arithd.c | 553 ++++++++++++++++++++---------------------- 1 file changed, 269 insertions(+), 284 deletions(-) diff --git a/src/builtins/arithd.c b/src/builtins/arithd.c index 20d25436..d96caeaf 100644 --- a/src/builtins/arithd.c +++ b/src/builtins/arithd.c @@ -7,6 +7,14 @@ static f64 pfmod(f64 a, f64 b) { if (a<0 != b<0 && r!=0) r+= b; return r; } +B add_c2(B, B, B); B ceil_c2(B, B, B); +B sub_c2(B, B, B); B div_c2(B, B, B); +B not_c2(B, B, B); B pow_c2(B, B, B); +B mul_c2(B, B, B); B root_c2(B, B, B); +B and_c2(B, B, B); B stile_c2(B, B, B); +B or_c2 (B, B, B); B log_c2(B, B, B); +B floor_c2(B, B, B); + #if SINGELI @@ -20,64 +28,10 @@ static f64 pfmod(f64 a, f64 b) { SLOWIF((!isArr(w) || TI(w,elType)!=el_B) && (!isArr(x) || TI(x,elType)!=el_B)) SLOW2("arithd " #N, w, x); \ return arith_recd(N##_c2, w, x); \ }} -#if TYPED_ARITH - #define GC2f(SYMB, NAME, EXPR, EXTRA) B NAME##_c2(B t, B w, B x) { \ - if (isF64(w) & isF64(x)) return m_f64(EXPR); \ - EXTRA \ - if (isArr(w)|isArr(x)) { \ - if (isArr(w)&isArr(x) && RNK(w)==RNK(x)) { \ - if (!eqShPart(SH(w), SH(x), RNK(w))) thrF(SYMB ": Expected equal shape prefix (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", w, x); \ - usz ia = IA(x); \ - u8 we = TI(w,elType); \ - u8 xe = TI(x,elType); \ - if (elNum(we) && elNum(xe)) { \ - if (weCHR_MAX) thrM("+: Invalid character"); // safe to only check this as wv already must be below CHR_MAX, which is less than U32_MAX/2 + } + decG(x); + return r; + } + }) + }, 0, SI_AA, SI_AS, SI_SA) + + GC2i("-", sub, wv-xv, { + IFN_SINGELI(if (isArr(w) && TI(w,elType)==el_c32) { + if (isC32(x)) { + i32 xv = (i32)o2cu(x); + u32* wp = c32any_ptr(w); usz wia = IA(w); + i32* rp; B r = m_i32arrc(&rp, w); + for (usz i = 0; i < wia; i++) rp[i] = (i32)wp[i] - xv; + decG(w); + return r; + } + if (isArr(x) && eqShape(w, x)) { + u32* wp = c32any_ptr(w); usz wia = IA(w); + if (TI(x,elType)==el_i32) { + u32* rp; B r = m_c32arrc(&rp, w); + i32* xp = i32any_ptr(x); + for (usz i = 0; i < wia; i++) { + rp[i] = (u32)((i32)wp[i] - (i32)xp[i]); + if (rp[i]>CHR_MAX) thrM("-: Invalid character"); // safe - see add + } + decG(w); decG(x); + return r; + } + } + }) + }, 0, SI_AA, SI_AS, SI_SA) + + GC2i("¬", not, 1+wv-xv, {}, 0, NO_SI_AA, REG_AS, REG_SA) + GC2i("×", mul, wv*xv, {}, 2, SI_AA, SI_AS, SI_SA) + GC2i("∧", and, wv*xv, {}, 2, SI_AA, REG_AS, REG_SA) + GC2i("∨", or , (wv+xv)-(wv*xv), {}, 1, SI_AA, REG_AS, REG_SA) + GC2i("⌊", floor, wv>xv?xv:wv, {}, 2, SI_AA, REG_AS, REG_SA) // optimizer optimizes out the fallback mess + GC2i("⌈", ceil , wv>xv?wv:xv, {}, 1, SI_AA, REG_AS, REG_SA) + #undef GC2i + #endif // !SINGELI #endif // TYPED_ARITH -#define REG_SA(NAME, EXPR) \ - if (xe==el_bit) return bit_sel1Fn(NAME##_c2,w,x,1); \ - if (xe==el_i8 && q_i8 (w)) { PI8 (x) i8 wc=o2iu(w); DOI8 (EXPR,x,wc,xp[i],sa8B ) } sa8B :; \ - if (xe==el_i16 && q_i16(w)) { PI16(x) i16 wc=o2iu(w); DOI16(EXPR,x,wc,xp[i],sa16B) } sa16B:; \ - if (xe==el_i32 && q_i32(w)) { PI32(x) i32 wc=o2iu(w); DOI32(EXPR,x,wc,xp[i],sa32B) } sa32B:; \ - if (xe==el_f64) { Rf64(x) PF(x) DOF(EXPR,w,w.f,xp[i]) decG(x); return num_squeeze(r); } -#define REG_AS(NAME, EXPR) \ - if (we==el_bit) return bit_sel1Fn(NAME##_c2,w,x,0); \ - if (we==el_i8 && q_i8 (x)) { PI8 (w) i8 xc=o2iu(x); DOI8 (EXPR,w,wp[i],xc,as8B ) } as8B :; \ - if (we==el_i16 && q_i16(x)) { PI16(w) i16 xc=o2iu(x); DOI16(EXPR,w,wp[i],xc,as16B) } as16B:; \ - if (we==el_i32 && q_i32(x)) { PI32(w) i32 xc=o2iu(x); DOI32(EXPR,w,wp[i],xc,as32B) } as32B:; \ - if (we==el_f64) { Rf64(w) PF(w) DOF(EXPR,x,wp[i],x.f) decG(w); return num_squeeze(r); } +#define AR_I_SCALAR(CHR, NAME, EXPR, MORE) B NAME##_c2(B t, B w, B x) { \ + if (isF64(w) & isF64(x)) return m_f64(EXPR); \ + MORE \ + AR_I_TO_ARR(NAME) \ + thrM(CHR ": Unexpected argument types"); \ +} +#define AR_F_SCALAR(CHR, NAME, EXPR) B NAME##_c2(B t, B w, B x) { \ + if (isF64(w) & isF64(x)) return m_f64(EXPR); \ + AR_F_TO_ARR(NAME) \ + thrM(CHR ": Unexpected argument types"); \ +} - -#define NO_SI_AA(N) -#if SINGELI - #define SI_SA_I(N,S,W,BASE) R##S(x); usz rlen=avx2_##N##SA##_##S((W).u, (void*)xp, (void*)rp, ia); if(RARE(rlen!=ia)) { decG(r); goto BASE; } dec (w);decG(x);return r; - #define SI_AS_I(N,S,X,BASE) R##S(w); usz rlen=avx2_##N##AS##_##S((void*)wp, (X).u, (void*)rp, ia); if(RARE(rlen!=ia)) { decG(r); goto BASE; } decG(w);dec (x);return r; - #define SI_SA(NAME, EXPR) \ - void* xp = tyany_ptr(x); \ - switch(xe) { default: UD; \ - case el_bit: return bit_sel1Fn(NAME##_c2,w,x,1); \ - case el_i8 : { SI_SA_I(NAME, i8,w,saBad) } \ - case el_i16: { SI_SA_I(NAME,i16,w,saBad) } \ - case el_i32: { SI_SA_I(NAME,i32,w,saBad) } \ - case el_f64: { SI_SA_I(NAME,f64,w,saBad) } \ - case el_c8: case el_c16: case el_c32: case el_B:; /*fallthrough*/ \ - } saBad:; - #define SI_AS(NAME, EXPR) \ - void* wp = tyany_ptr(w); \ - switch(we) { default: UD; \ - case el_bit: return bit_sel1Fn(NAME##_c2,w,x,0); \ - case el_i8 : { SI_AS_I(NAME, i8,x,asBad) } \ - case el_i16: { SI_AS_I(NAME,i16,x,asBad) } \ - case el_i32: { SI_AS_I(NAME,i32,x,asBad) } \ - case el_f64: { SI_AS_I(NAME,f64,x,asBad) } \ - case el_c8: case el_c16: case el_c32: case el_B:; /*fallthrough*/ \ - } asBad:; - #define SI_AA(N) return dyArith_AA(&N##DyTableAA, w, x); - #define IFN_SINGELI(X) -#else - #define SI_AA NO_SI_AA - #define SI_AS REG_AS - #define SI_SA REG_SA - #define IFN_SINGELI(X) X -#endif - -GC2i("+", add, wv+xv, { +AR_I_SCALAR("+", add, w.f+x.f, { if (isC32(w) & isF64(x)) { u64 r = (u64)(o2cu(w)+o2i64(x)); if(r>CHR_MAX)thrM("+: Invalid character"); return m_c32((u32)r); } if (isF64(w) & isC32(x)) { u64 r = (u64)(o2cu(x)+o2i64(w)); if(r>CHR_MAX)thrM("+: Invalid character"); return m_c32((u32)r); } -},{ - IFN_SINGELI(if (isArr(w)&isC32(x) || isC32(w)&isArr(x)) { if (isArr(w)) { B t=w;w=x;x=t; } - if (TI(x,elType) == el_i32) { - u32 wv = o2cu(w); - i32* xp = i32any_ptr(x); usz xia = IA(x); - u32* rp; B r = m_c32arrc(&rp, x); - for (usz i = 0; i < xia; i++) { - rp[i] = (u32)(xp[i]+(i32)wv); - if (rp[i]>CHR_MAX) thrM("+: Invalid character"); // safe to only check this as wv already must be below CHR_MAX, which is less than U32_MAX/2 - } - decG(x); - return r; - } - }) -}, 0, SI_AA, SI_AS, SI_SA) - -GC2i("-", sub, wv-xv, { +}); +AR_I_SCALAR("-", sub, w.f-x.f, { if (isC32(w) & isF64(x)) { u64 r = (u64)((i32)o2cu(w)-o2i64(x)); if(r>CHR_MAX)thrM("-: Invalid character"); return m_c32((u32)r); } if (isC32(w) & isC32(x)) return m_f64((i32)(u32)w.u - (i32)(u32)x.u); -},{ - IFN_SINGELI(if (isArr(w) && TI(w,elType)==el_c32) { - if (isC32(x)) { - i32 xv = (i32)o2cu(x); - u32* wp = c32any_ptr(w); usz wia = IA(w); - i32* rp; B r = m_i32arrc(&rp, w); - for (usz i = 0; i < wia; i++) rp[i] = (i32)wp[i] - xv; - decG(w); - return r; - } - if (isArr(x) && eqShape(w, x)) { - u32* wp = c32any_ptr(w); usz wia = IA(w); - if (TI(x,elType)==el_i32) { - u32* rp; B r = m_c32arrc(&rp, w); - i32* xp = i32any_ptr(x); - for (usz i = 0; i < wia; i++) { - rp[i] = (u32)((i32)wp[i] - (i32)xp[i]); - if (rp[i]>CHR_MAX) thrM("-: Invalid character"); // safe - see add - } - decG(w); decG(x); - return r; - } - } - }) -}, 0, SI_AA, SI_AS, SI_SA) - -GC2i("¬", not, 1+wv-xv, { +}) +AR_I_SCALAR("¬", not, 1+w.f-x.f, { if (isC32(w) & isF64(x)) { u64 r = (u64)(1+(i32)o2cu(w)-o2i64(x)); if(r>CHR_MAX)thrM("¬: Invalid character"); return m_c32((u32)r); } if (isC32(w) & isC32(x)) return m_f64(1 + (i32)(u32)w.u - (i32)(u32)x.u); -}, {}, 0, NO_SI_AA, REG_AS, REG_SA) -GC2i("×", mul, wv*xv, {}, {}, 2, SI_AA, SI_AS, SI_SA) -GC2i("∧", and, wv*xv, {}, {}, 2, SI_AA, REG_AS, REG_SA) -GC2i("∨", or , (wv+xv)-(wv*xv), {}, {}, 1, SI_AA, REG_AS, REG_SA) -GC2i("⌊", floor, wv>xv?xv:wv, {}, {}, 2, SI_AA, REG_AS, REG_SA) // optimizer optimizes out the fallback mess -GC2i("⌈", ceil , wv>xv?wv:xv, {}, {}, 1, SI_AA, REG_AS, REG_SA) +}) +AR_I_SCALAR("×", mul, w.f*x.f, {}) +AR_I_SCALAR("∧", and, w.f*x.f, {}) +AR_I_SCALAR("∨", or , (w.f+x.f)-(w.f*x.f), {}) +AR_I_SCALAR("⌊", floor, w.f>x.f?x.f:w.f, {}) +AR_I_SCALAR("⌈", ceil , w.f>x.f?w.f:x.f, {}) +#undef AR_I_SCALAR -GC2f("÷", div , w.f/x.f, {}) -GC2f("⋆", pow , pow(w.f, x.f), {}) -GC2f("√", root , pow(x.f, 1.0/w.f), {}) -GC2f("|", stile, pfmod(x.f, w.f), {}) -GC2f("⋆⁼",log , log(x.f)/log(w.f), {}) - -#undef GC2i -#undef GC2f +AR_F_SCALAR("÷", div , w.f/x.f) +AR_F_SCALAR("⋆", pow , pow(w.f, x.f)) +AR_F_SCALAR("√", root , pow(x.f, 1.0/w.f)) +AR_F_SCALAR("|", stile, pfmod(x.f, w.f)) +AR_F_SCALAR("⋆⁼",log , log(x.f)/log(w.f)) +#undef AR_F_SCALAR #undef P2