typed arith

This commit is contained in:
dzaima 2021-05-19 18:57:12 +03:00
parent 0f001313a7
commit d08cd90998
3 changed files with 71 additions and 6 deletions

View File

@ -27,12 +27,74 @@ static inline B arith_recd(BBB2B f, B w, B x) {
#define P1(N) { if( isArr(x)) return arith_recm(N##_c1, x); }
#define P2(N) { if(isArr(w)|isArr(x)) return arith_recd(N##_c2, w, x); }
#define ffnx(name, expr, extra) B name##_c2(B t, B w, B x) { \
if (isF64(w) & isF64(x)) return m_f64(expr); \
extra \
P2(name) \
thrM(#name ": invalid arithmetic"); \
}
#if TYPED_ARITH
static B f64_maybe_i32(B x) {
f64* xp = f64arr_ptr(x);
usz ia = a(x)->ia;
if (ia==0) { dec(x); return inc(bi_emptyIVec); }
if (xp[0] != (i32)xp[0]) return x;
i32* rp; B r = m_i32arrc(&rp, x);
for (usz i = 0; i < ia; i++) {
f64 cf = xp[i];
i32 c = (i32)cf;
if (cf!=c) { dec(r); return x; }
rp[i] = c;
}
dec(x);
return r;
}
#define ffnx(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)) { B ow=w; B ox=x; \
if (isArr(w)&isArr(x) && rnk(w)==rnk(x)) { \
usz ia = a(x)->ia; \
u8 we = TI(w).elType; \
u8 xe = TI(x).elType; \
if (isNumEl(we)&isNumEl(xe)) { \
f64* rp; B r = m_f64arrc(&rp, x); \
if (we==el_i32) { B w,x/*shadow*/; i32* wp = i32any_ptr(ow); \
if (xe==el_i32) { i32* xp = i32any_ptr(ox); for (usz i = 0; i < ia; i++) {w.f=wp[i];x.f=xp[i];rp[i]=EXPR;} } \
else { f64* xp = f64any_ptr(ox); for (usz i = 0; i < ia; i++) {w.f=wp[i];x.f=xp[i];rp[i]=EXPR;} } \
} else { B w,x/*shadow*/; f64* wp = f64any_ptr(ow); \
if (xe==el_i32) { i32* xp = i32any_ptr(ox); for (usz i = 0; i < ia; i++) {w.f=wp[i];x.f=xp[i];rp[i]=EXPR;} } \
else { f64* xp = f64any_ptr(ox); for (usz i = 0; i < ia; i++) {w.f=wp[i];x.f=xp[i];rp[i]=EXPR;} } \
} \
dec(w); dec(x); return f64_maybe_i32(r); \
} \
} else if (isF64(w)&isArr(x)) { usz ia = a(x)->ia; \
u8 xe = TI(x).elType; f64*rp; \
if (xe==el_i32) { B r=m_f64arrc(&rp, x); i32*xp=i32any_ptr(x); \
for (usz i = 0; i < ia; i++) {B x/*shadow*/;x.f=xp[i];rp[i]=EXPR;} \
dec(x); return f64_maybe_i32(r); \
} \
if (xe==el_f64) { B r=m_f64arrc(&rp, x); f64*xp=f64any_ptr(x); \
for (usz i = 0; i < ia; i++) {B x/*shadow*/;x.f=xp[i];rp[i]=EXPR;} \
dec(x); return f64_maybe_i32(r); \
} \
} else if (isF64(x)&isArr(w)) { usz ia = a(w)->ia; \
u8 we = TI(w).elType; f64*rp; \
if (we==el_i32) { B r=m_f64arrc(&rp, w); i32*wp=i32any_ptr(w); \
for (usz i = 0; i < ia; i++) {B w/*shadow*/;w.f=wp[i];rp[i]=EXPR;} \
dec(w); return f64_maybe_i32(r); \
} \
if (we==el_f64) { B r=m_f64arrc(&rp, w); f64*wp=f64any_ptr(w); \
for (usz i = 0; i < ia; i++) {B w/*shadow*/;w.f=wp[i];rp[i]=EXPR;} \
dec(w); return f64_maybe_i32(r); \
} \
} \
P2(NAME) \
} \
thrM(#NAME ": invalid arithmetic"); \
}
#else // !TYPED_ARITH
#define ffnx(name, expr, extra) B name##_c2(B t, B w, B x) { \
if (isF64(w) & isF64(x)) return m_f64(expr); \
extra \
P2(name) \
thrM(#name ": invalid arithmetic"); \
}
#endif // TYPED_ARITH
#define ffn(name, op, extra) ffnx(name, w.f op x.f, extra)
f64 pfmod(f64 a, f64 b) {

View File

@ -14,6 +14,7 @@
// #define ALL_R0 // use all of r0.bqn for runtime_0
// #define ALL_R1 // use all of r1.bqn for runtime
// #define RT_SRC // whether ./genRuntimeSrc was used to generate precompiled sources
#define TYPED_ARITH true // whether to use typed arith
#define VM_POS true // whether to store detailed execution position information for stacktraces
#define CHECK_VALID true // whether to check for valid arguments in places where that would be detrimental to performance (e.g. left argument sortedness of ⍋/⍒, incompatible changes in ⌾, etc)
#define EACH_FILLS false // whether to try to squeeze out fills for ¨ and ⌜

View File

@ -353,6 +353,8 @@ u8 selfElType(B x) {
return el_B;
}
bool isNumEl(u8 elt) { return elt==el_i32 | elt==el_f64; }
#ifdef DEBUG