typed arith
This commit is contained in:
parent
0f001313a7
commit
d08cd90998
74
src/arith.c
74
src/arith.c
@ -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) {
|
||||
|
||||
@ -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 ⌜
|
||||
|
||||
@ -353,6 +353,8 @@ u8 selfElType(B x) {
|
||||
return el_B;
|
||||
}
|
||||
|
||||
bool isNumEl(u8 elt) { return elt==el_i32 | elt==el_f64; }
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
Loading…
Reference in New Issue
Block a user