clean up arithd.c & slightly improve non-Singeli impls
This commit is contained in:
parent
32142a45d6
commit
f76836aedd
@ -37,9 +37,8 @@ typedef void (*AndBytesFn)(u8*, u8*, u64, u64);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ARITH_SLOW(N) SLOWIF((!isArr(w) || TI(w,elType)!=el_B) && (!isArr(x) || TI(x,elType)!=el_B)) SLOW2("arithd " #N, w, x)
|
#define ARITH_SLOW(N) SLOWIF((!isArr(w) || TI(w,elType)!=el_B) && (!isArr(x) || TI(x,elType)!=el_B)) SLOW2("arithd " #N, w, x)
|
||||||
#define P2(N) { if(isArr(w)|isArr(x)) { ARITH_SLOW(N); \
|
#define P2(N) { if(isArr(w)|isArr(x)) { ARITH_SLOW(N); return arith_recd(N##_c2, w, x); }}
|
||||||
return arith_recd(N##_c2, w, x); \
|
|
||||||
}}
|
|
||||||
#if !TYPED_ARITH
|
#if !TYPED_ARITH
|
||||||
#define AR_I_TO_ARR(NAME) P2(NAME)
|
#define AR_I_TO_ARR(NAME) P2(NAME)
|
||||||
#define AR_F_TO_ARR AR_I_TO_ARR
|
#define AR_F_TO_ARR AR_I_TO_ARR
|
||||||
@ -84,11 +83,11 @@ typedef void (*AndBytesFn)(u8*, u8*, u64, u64);
|
|||||||
if (xe<el_i32) { x=taga(cpyI32Arr(x)); xe=el_i32; } void* xp = tyany_ptr(x); \
|
if (xe<el_i32) { x=taga(cpyI32Arr(x)); xe=el_i32; } void* xp = tyany_ptr(x); \
|
||||||
Rf64(x); \
|
Rf64(x); \
|
||||||
if (we==el_i32) { B w,x /*shadow*/; \
|
if (we==el_i32) { B w,x /*shadow*/; \
|
||||||
if (xe==el_i32) { DECOR for (usz i = 0; i < ia; i++) {w.f=((i32*)wp)[i]; x.f=((i32*)xp)[i]; rp[i]=EXPR;} } \
|
if (xe==el_i32) { DECOR for (usz i = 0; i < ia; i++) { w.f=((i32*)wp)[i]; x.f=((i32*)xp)[i]; rp[i]=EXPR; } } \
|
||||||
else { DECOR for (usz i = 0; i < ia; i++) {w.f=((i32*)wp)[i]; x.f=((f64*)xp)[i]; rp[i]=EXPR;} } \
|
else { DECOR for (usz i = 0; i < ia; i++) { w.f=((i32*)wp)[i]; x.f=((f64*)xp)[i]; rp[i]=EXPR; } } \
|
||||||
} else { B w,x /*shadow*/; \
|
} else { B w,x /*shadow*/; \
|
||||||
if (xe==el_i32) { DECOR for (usz i = 0; i < ia; i++) {w.f=((f64*)wp)[i]; x.f=((i32*)xp)[i]; rp[i]=EXPR;} } \
|
if (xe==el_i32) { DECOR for (usz i = 0; i < ia; i++) { w.f=((f64*)wp)[i]; x.f=((i32*)xp)[i]; rp[i]=EXPR; } } \
|
||||||
else { DECOR for (usz i = 0; i < ia; i++) {w.f=((f64*)wp)[i]; x.f=((f64*)xp)[i]; rp[i]=EXPR;} } \
|
else { DECOR for (usz i = 0; i < ia; i++) { w.f=((f64*)wp)[i]; x.f=((f64*)xp)[i]; rp[i]=EXPR; } } \
|
||||||
} \
|
} \
|
||||||
decG(w); decG(x); return num_squeeze(r); \
|
decG(w); decG(x); return num_squeeze(r); \
|
||||||
} \
|
} \
|
||||||
@ -153,11 +152,24 @@ typedef void (*AndBytesFn)(u8*, u8*, u64, u64);
|
|||||||
SA_DISPATCH(mul) SA_DISPATCH(and)
|
SA_DISPATCH(mul) SA_DISPATCH(and)
|
||||||
SA_DISPATCH(ceil) SA_DISPATCH(floor)
|
SA_DISPATCH(ceil) SA_DISPATCH(floor)
|
||||||
#undef SA_DISPATCH
|
#undef SA_DISPATCH
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define NO_SI_AA(N)
|
static NOINLINE B bit_sel1Fn(BBB2B f, B w, B x, bool bitX) { // consumes both
|
||||||
#define SI_AA NO_SI_AA
|
B b = bitX? x : w;
|
||||||
#define SI_AS REG_AS
|
u64* bp = bitarr_ptr(b);
|
||||||
#define SI_SA REG_SA
|
usz ia = IA(b);
|
||||||
|
|
||||||
|
bool b0 = ia? bp[0]&1 : 0;
|
||||||
|
bool both = bit_has(bp, ia, !b0);
|
||||||
|
|
||||||
|
B e0=m_f64(0), e1=m_f64(0); // initialized to have something to decrement later
|
||||||
|
bool h0=both || b0==0; if (h0) e0 = bitX? f(bi_N, inc(w), m_f64(0)) : f(bi_N, m_f64(0), inc(x));
|
||||||
|
bool h1=both || b0==1; if (h1) e1 = bitX? f(bi_N, w, m_f64(1)) : f(bi_N, m_f64(1), x);
|
||||||
|
// non-bitarr arg has been consumed
|
||||||
|
B r = bit_sel(b, e0, e1); // and now the bitarr arg is consumed too
|
||||||
|
dec(e0); dec(e1);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
#define REG_SA(NAME, EXPR) \
|
#define REG_SA(NAME, EXPR) \
|
||||||
if (xe==el_bit) return bit_sel1Fn(NAME##_c2,w,x,1); \
|
if (xe==el_bit) return bit_sel1Fn(NAME##_c2,w,x,1); \
|
||||||
@ -240,6 +252,7 @@ typedef void (*AndBytesFn)(u8*, u8*, u64, u64);
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
#undef AR_I_AA
|
#undef AR_I_AA
|
||||||
|
|
||||||
#define AR_I_AS(CHR, NAME, EXPR, DO_AS, EXTRA) NOINLINE B NAME##_AS(B t, B w, B x) { \
|
#define AR_I_AS(CHR, NAME, EXPR, DO_AS, EXTRA) NOINLINE B NAME##_AS(B t, B w, B x) { \
|
||||||
B r; u8 we=TI(w,elType); EXTRA \
|
B r; u8 we=TI(w,elType); EXTRA \
|
||||||
if (isF64(x)) { usz ia=IA(w); DO_AS(NAME,EXPR) } \
|
if (isF64(x)) { usz ia=IA(w); DO_AS(NAME,EXPR) } \
|
||||||
@ -254,33 +267,16 @@ typedef void (*AndBytesFn)(u8*, u8*, u64, u64);
|
|||||||
dec_ret: decG(x); return r; \
|
dec_ret: decG(x); return r; \
|
||||||
}
|
}
|
||||||
|
|
||||||
static NOINLINE B bit_sel1Fn(BBB2B f, B w, B x, bool bitX) { // consumes both
|
AR_I_SA("-", sub, wv-xv, REG_SA, {})
|
||||||
B b = bitX? x : w;
|
AR_I_SA("×", mul, wv*xv, REG_SA, {})
|
||||||
u64* bp = bitarr_ptr(b);
|
|
||||||
usz ia = IA(b);
|
|
||||||
|
|
||||||
bool b0 = ia? bp[0]&1 : 0;
|
|
||||||
bool both = false;
|
|
||||||
for (usz i = 0; i < ia; i++) if (bitp_get(bp,i) != b0) { both=true; break; }
|
|
||||||
|
|
||||||
B e0=m_f64(0), e1=m_f64(0); // initialized to have something to decrement later
|
|
||||||
bool h0=both || b0==0; if (h0) e0 = bitX? f(bi_N, inc(w), m_f64(0)) : f(bi_N, m_f64(0), inc(x));
|
|
||||||
bool h1=both || b0==1; if (h1) e1 = bitX? f(bi_N, w, m_f64(1)) : f(bi_N, m_f64(1), x);
|
|
||||||
// non-bitarr arg has been consumed
|
|
||||||
B r = bit_sel(b, e0, e1); // and now the bitarr arg is consumed too
|
|
||||||
dec(e0); dec(e1);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
AR_I_SA("-", sub, wv-xv, SI_SA, {})
|
|
||||||
AR_I_SA("×", mul, wv*xv, SI_SA, {})
|
|
||||||
AR_I_SA("∧", and, wv*xv, REG_SA, {})
|
AR_I_SA("∧", and, wv*xv, REG_SA, {})
|
||||||
AR_I_SA("∨", or , (wv+xv)-(wv*xv), REG_SA, {})
|
AR_I_SA("∨", or , (wv+xv)-(wv*xv), REG_SA, {})
|
||||||
AR_I_SA("⌊", floor, wv>xv?xv:wv, REG_SA, {})
|
AR_I_SA("⌊", floor, wv>xv?xv:wv, REG_SA, {})
|
||||||
AR_I_SA("⌈", ceil , wv>xv?wv:xv, REG_SA, {})
|
AR_I_SA("⌈", ceil , wv>xv?wv:xv, REG_SA, {})
|
||||||
AR_I_SA("+", add, wv+xv, SI_SA, {
|
AR_I_SA("+", add, wv+xv, REG_SA, {
|
||||||
if (isC32(w) && xe==el_i32) {
|
if (isC32(w) && elInt(xe)) {
|
||||||
u32 wv = o2cG(w);
|
u32 wv = o2cG(w);
|
||||||
|
if (xe!=el_i32) x = taga(cpyI32Arr(x));
|
||||||
i32* xp = i32any_ptr(x); usz xia = IA(x);
|
i32* xp = i32any_ptr(x); usz xia = IA(x);
|
||||||
u32* rp; r = m_c32arrc(&rp, x);
|
u32* rp; r = m_c32arrc(&rp, x);
|
||||||
for (usz i = 0; i < xia; i++) {
|
for (usz i = 0; i < xia; i++) {
|
||||||
@ -293,9 +289,10 @@ typedef void (*AndBytesFn)(u8*, u8*, u64, u64);
|
|||||||
#undef AR_I_SA
|
#undef AR_I_SA
|
||||||
|
|
||||||
|
|
||||||
AR_I_AS("-", sub, wv-xv, SI_AS, {
|
AR_I_AS("-", sub, wv-xv, REG_AS, {
|
||||||
if (we==el_c32 && isC32(x)) {
|
if (elChr(we) && isC32(x)) {
|
||||||
i32 xv = (i32)o2cG(x);
|
i32 xv = (i32)o2cG(x);
|
||||||
|
if (we!=el_c32) w = taga(cpyC32Arr(w));
|
||||||
u32* wp = c32any_ptr(w); usz wia = IA(w);
|
u32* wp = c32any_ptr(w); usz wia = IA(w);
|
||||||
i32* rp; r = m_i32arrc(&rp, w);
|
i32* rp; r = m_i32arrc(&rp, w);
|
||||||
for (usz i = 0; i < wia; i++) rp[i] = (i32)wp[i] - xv;
|
for (usz i = 0; i < wia; i++) rp[i] = (i32)wp[i] - xv;
|
||||||
@ -314,17 +311,14 @@ typedef void (*AndBytesFn)(u8*, u8*, u64, u64);
|
|||||||
|
|
||||||
#define AR_F_TO_ARR(NAME) return NAME##_c2_arr(t, w, x);
|
#define AR_F_TO_ARR(NAME) return NAME##_c2_arr(t, w, x);
|
||||||
#define AR_I_TO_ARR(NAME) \
|
#define AR_I_TO_ARR(NAME) \
|
||||||
if (isArr(x)) { \
|
if (isArr(x)) return isArr(w)? NAME##_AA(t, w, x) : NAME##_SA(t, w, x); \
|
||||||
if (isArr(w)) return NAME##_AA(t, w, x); \
|
else if (isArr(w)) return NAME##_AS(t, w, x);
|
||||||
else return NAME##_SA(t, w, x); \
|
|
||||||
} else if (isArr(w)) return NAME##_AS(t, w, x);
|
|
||||||
|
|
||||||
#endif // TYPED_ARITH
|
#endif // TYPED_ARITH
|
||||||
|
|
||||||
#define AR_I_SCALAR(CHR, NAME, EXPR, MORE) B NAME##_c2(B t, B w, B x) { \
|
#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); \
|
if (isF64(w) & isF64(x)) return m_f64(EXPR); \
|
||||||
MORE \
|
MORE; AR_I_TO_ARR(NAME) \
|
||||||
AR_I_TO_ARR(NAME) \
|
|
||||||
thrM(CHR ": Unexpected argument types"); \
|
thrM(CHR ": Unexpected argument types"); \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,12 +384,11 @@ static f64 comb(f64 k, f64 n) { // n choose k
|
|||||||
return exp(lgamma(n+1) - lgamma(k+1) - lgamma(j+1));
|
return exp(lgamma(n+1) - lgamma(k+1) - lgamma(j+1));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MATH(n,N) \
|
#define MATH(n,N) B n##_c2(B t, B w, B x) { \
|
||||||
B n##_c2(B t, B w, B x) { \
|
|
||||||
if (isNum(w) && isNum(x)) return m_f64(n(x.f, w.f)); \
|
if (isNum(w) && isNum(x)) return m_f64(n(x.f, w.f)); \
|
||||||
P2(n) \
|
P2(n) \
|
||||||
thrM("•math." #N ": Unexpected argument types"); \
|
thrM("•math." #N ": Unexpected argument types"); \
|
||||||
}
|
}
|
||||||
MATH(atan2,Atan2) MATH(hypot,Hypot) MATH(comb,Comb)
|
MATH(atan2,Atan2) MATH(hypot,Hypot) MATH(comb,Comb)
|
||||||
#undef MATH
|
#undef MATH
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user