use generic squeeze for arith

This commit is contained in:
dzaima 2021-09-09 17:30:40 +03:00
parent 0913d3b8f2
commit f8962c1eb9
3 changed files with 30 additions and 34 deletions

View File

@ -4,24 +4,6 @@
#define P2(N) { if(isArr(w)|isArr(x)) return arith_recd(N##_c2, w, x); }
#if TYPED_ARITH
static B f64_maybe_i32(B x) {
f64* xp = f64arr_ptr(x);
usz ia = a(x)->ia;
if (ia==0) {
if (rnk(x)>1) return x;
dec(x); return 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 GC2f(SYMB, NAME, EXPR, EXTRA) B NAME##_c2(B t, B w, B x) { \
if (isF64(w) & isF64(x)) return m_f64(EXPR); \
EXTRA \
@ -40,27 +22,27 @@
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); \
dec(w); dec(x); return num_squeeze(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); \
dec(x); return num_squeeze(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); \
dec(x); return num_squeeze(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); \
dec(w); return num_squeeze(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); \
dec(w); return num_squeeze(r); \
} \
} \
P2(NAME) \
@ -127,7 +109,7 @@
if (xei) { PI(x) DOF(EXPR,w,wp[i],xp[i]) } \
else { PF(x) DOF(EXPR,w,wp[i],xp[i]) } \
} \
dec(w); dec(x); return f64_maybe_i32(r); \
dec(w); dec(x); return num_squeeze(r); \
} \
if(we==el_i8 & xe==el_i8 ) { PI8 (w) PI8 (x) DOI8 (EXPR,w,wp[i],xp[i],base); } \
if(we==el_i16 & xe==el_i16) { PI16(w) PI16(x) DOI16(EXPR,w,wp[i],xp[i],base); } \
@ -135,14 +117,14 @@
if (xe==el_i8 && q_i8 (w)) { PI8 (x) i8 wc=o2iu(w); DOI8 (EXPR,x,wc,xp[i],na8B ) } na8B :; \
if (xe==el_i16 && q_i16(w)) { PI16(x) i16 wc=o2iu(w); DOI16(EXPR,x,wc,xp[i],na16B) } na16B:; \
if (xe==el_i32 && q_i32(w)) { PI (x) i32 wc=o2iu(w); DOI32(EXPR,x,wc,xp[i],na32B) } na32B:; \
if (xe==el_i32) { RF(x) PI(x) DOF(EXPR,w,w.f,xp[i]) dec(x); return f64_maybe_i32(r); } \
if (xe==el_f64) { RF(x) PF(x) DOF(EXPR,w,w.f,xp[i]) dec(x); return f64_maybe_i32(r); } \
if (xe==el_i32) { RF(x) PI(x) DOF(EXPR,w,w.f,xp[i]) dec(x); return num_squeeze(r); } \
if (xe==el_f64) { RF(x) PF(x) DOF(EXPR,w,w.f,xp[i]) dec(x); return num_squeeze(r); } \
} else if (isF64(x)&isArr(w)) { usz ia = a(w)->ia; u8 we = TI(w,elType); \
if (we==el_i8 && q_i8 (x)) { PI8 (w) i8 xc=o2iu(x); DOI8 (EXPR,w,wp[i],xc,an8B ) } an8B :; \
if (we==el_i16 && q_i16(x)) { PI16(w) i16 xc=o2iu(x); DOI16(EXPR,w,wp[i],xc,an16B) } an16B:; \
if (we==el_i32 && q_i32(x)) { PI (w) i32 xc=o2iu(x); DOI32(EXPR,w,wp[i],xc,an32B) } an32B:; \
if (we==el_i32) { RF(w) PI(w) DOF(EXPR,x,wp[i],x.f) dec(w); return f64_maybe_i32(r); } \
if (we==el_f64) { RF(w) PF(w) DOF(EXPR,x,wp[i],x.f) dec(w); return f64_maybe_i32(r); } \
if (we==el_i32) { RF(w) PI(w) DOF(EXPR,x,wp[i],x.f) dec(w); return num_squeeze(r); } \
if (we==el_f64) { RF(w) PF(w) DOF(EXPR,x,wp[i],x.f) dec(w); return num_squeeze(r); } \
} \
base: P2(NAME) \
} \

View File

@ -478,21 +478,33 @@ B num_squeeze(B x) {
assert(xe!=el_bit);
if (xe==el_i8) return x;
// TODO fast paths for xe<=el_f64
// TODO fast paths for xe<el_f64
usz i = 0;
i32 or = 0;
i32 or = 0; // using bitwise or as a heuristical ⌈´|𝕩
if (xe==el_f64) {
f64* xp = f64any_ptr(x);
for (; i < ia; i++) {
f64 cf = xp[i];
i32 c = (i32)cf;
if (c!=cf) return x; // already f64
or|= c<0?-c:c;
}
if (or<=I8_MAX ) { i8* rp; B r = m_i8arrc (&rp, x); for (usz i=0;i<ia;i++) rp[i]=(i8 )xp[i]; dec(x); return r; }
else if (or<=I16_MAX) { i16* rp; B r = m_i16arrc(&rp, x); for (usz i=0;i<ia;i++) rp[i]=(i16)xp[i]; dec(x); return r; }
else { i32* rp; B r = m_i32arrc(&rp, x); for (usz i=0;i<ia;i++) rp[i]=(i32)xp[i]; dec(x); return r; }
}
B* xp = arr_bptr(x);
if (xp!=NULL) {
for (; i < ia; i++) {
if (!q_i32(xp[i])) goto n_i32;
if (!q_i32(xp[i])) goto n_i32_1;
i32 c = o2iu(xp[i]);
or|= c<0?-c:c; // using or as a heuristical max
or|= c<0?-c:c;
}
if (or<=I8_MAX ) { i8* rp; B r = m_i8arrc (&rp, x); for (usz i=0;i<ia;i++) rp[i]=o2iu(xp[i]); dec(x); return r; }
else if (or<=I16_MAX) { i16* rp; B r = m_i16arrc(&rp, x); for (usz i=0;i<ia;i++) rp[i]=o2iu(xp[i]); dec(x); return r; }
else { i32* rp; B r = m_i32arrc(&rp, x); for (usz i=0;i<ia;i++) rp[i]=o2iu(xp[i]); dec(x); return r; }
n_i32: while (i<ia) if (!isF64(xp[i++])) return x;
n_i32_1: while (i<ia) if (!isF64(xp[i++])) return x;
f64* rp; B r = m_f64arrc(&rp, x); for (usz i=0;i<ia;i++) rp[i]=o2fu(xp[i]); dec(x); return r;
}
@ -537,6 +549,7 @@ B chr_squeeze(B x) {
else if (or<=U16_MAX) { u16* rp; B r = m_c16arrc(&rp, x); for (usz i=0;i<ia;i++) rp[i]=o2cu(xgetU(x,i)); dec(x); return r; }
else { u32* rp; B r = m_c32arrc(&rp, x); for (usz i=0;i<ia;i++) rp[i]=o2cu(xgetU(x,i)); dec(x); return r; }
}
B any_squeeze(B x) {
assert(isArr(x));
u8 xe = TI(x,elType);
@ -548,6 +561,7 @@ B any_squeeze(B x) {
else if (isC32(x0)) return chr_squeeze(x);
return x;
}
B bqn_merge(B x) {
assert(isArr(x));
usz xia = a(x)->ia;

View File

@ -104,7 +104,7 @@ static usz uszMulT(usz a, usz b) {
static u8 selfElType(B x) { // guaranteed to fit fill
if (isF64(x)) return q_i16(x)? (q_i8(x)? el_i8 : el_i16) : (q_i32(x)? el_i32 : el_f64);
if (isC32(x)) return el_c32;
if (isC32(x)) return LIKELY(q_c8(x))? el_c8 : q_c16(x)? el_c16 : el_c32;
return el_B;
}
static bool elChr(u8 x) {