new array-atom arith
This commit is contained in:
parent
629076d001
commit
c0b2164dc8
@ -7,6 +7,8 @@ static f64 pfmod(f64 a, f64 b) {
|
||||
if (a<0 != b<0 && r!=0) r+= b;
|
||||
return r;
|
||||
}
|
||||
static f64 bqn_or(f64 w, f64 x) { return (w+x)-(w*x); }
|
||||
|
||||
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);
|
||||
@ -59,52 +61,6 @@ B floor_c2(B, B, B);
|
||||
#define DOI8(EXPR,A,W,X,BASE) { Ri8(A) for (usz i=0; i<ia; i++) { i16 wv=W; i16 xv=X; i16 rv=EXPR; if (RARE(rv!=( i8)rv)) { decG(r); goto BASE; } rp[i]=rv; } goto dec_ret; }
|
||||
#define DOI16(EXPR,A,W,X,BASE) { Ri16(A) for (usz i=0; i<ia; i++) { i32 wv=W; i32 xv=X; i32 rv=EXPR; if (RARE(rv!=(i16)rv)) { decG(r); goto BASE; } rp[i]=rv; } goto dec_ret; }
|
||||
#define DOI32(EXPR,A,W,X,BASE) { Ri32(A) for (usz i=0; i<ia; i++) { i64 wv=W; i64 xv=X; i64 rv=EXPR; if (RARE(rv!=(i32)rv)) { decG(r); goto BASE; } rp[i]=rv; } goto dec_ret; }
|
||||
#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]) goto dec_ret; }
|
||||
#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) goto dec_ret; }
|
||||
|
||||
|
||||
#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; } goto dec_ret;
|
||||
#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; } goto dec_ret;
|
||||
#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
|
||||
|
||||
#define GC2f(SYMB, NAME, EXPR) B NAME##_c2_arr(B t, B w, B x) { \
|
||||
if (isArr(w)|isArr(x)) { B r; \
|
||||
@ -146,13 +102,39 @@ B floor_c2(B, B, B);
|
||||
|
||||
|
||||
#if SINGELI
|
||||
#define AR_DISPATCH(NAME) FORCE_INLINE B NAME##_AA(B t, B w, B x) { return dyArith_AA(&NAME##DyTableAA, w, x); }
|
||||
AR_DISPATCH(add) AR_DISPATCH(floor)
|
||||
AR_DISPATCH(sub) AR_DISPATCH(or)
|
||||
AR_DISPATCH(mul) AR_DISPATCH(ceil)
|
||||
AR_DISPATCH(and)
|
||||
#undef AR_DISPATCH
|
||||
#define AA_DISPATCH(NAME) FORCE_INLINE B NAME##_AA(B t, B w, B x) { return dyArith_AA(&NAME##DyTableAA, w, x); }
|
||||
AA_DISPATCH(add) AA_DISPATCH(or)
|
||||
AA_DISPATCH(sub)
|
||||
AA_DISPATCH(mul) AA_DISPATCH(and)
|
||||
AA_DISPATCH(ceil) AA_DISPATCH(floor)
|
||||
#undef AA_DISPATCH
|
||||
|
||||
#define SA_DISPATCH(NAME) FORCE_INLINE B NAME##_SA(B t, B w, B x) { return dyArith_SA(&NAME##DyTableNA, w, x); }
|
||||
#define AS_DISPATCH(NAME) FORCE_INLINE B NAME##_AS(B t, B w, B x) { return dyArith_SA(&NAME##DyTableAN, x, w); }
|
||||
SA_DISPATCH(add)
|
||||
SA_DISPATCH(sub) AS_DISPATCH(sub)
|
||||
SA_DISPATCH(mul) SA_DISPATCH(and)
|
||||
SA_DISPATCH(ceil) SA_DISPATCH(floor)
|
||||
#undef SA_DISPATCH
|
||||
#else
|
||||
#define NO_SI_AA(N)
|
||||
#define SI_AA NO_SI_AA
|
||||
#define SI_AS REG_AS
|
||||
#define SI_SA REG_SA
|
||||
|
||||
#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]) goto dec_ret; }
|
||||
#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) goto dec_ret; }
|
||||
|
||||
static B bitAA0(B w, B x, usz ia) { UD; }
|
||||
static NOINLINE B bitAA1(B w, B x, usz ia) {
|
||||
u64* rp; B r = m_bitarrc(&rp, x);
|
||||
@ -204,12 +186,12 @@ B floor_c2(B, B, B);
|
||||
}
|
||||
AR_I_AA("×", mul, wv*xv, 2, {})
|
||||
AR_I_AA("∧", and, wv*xv, 2, {})
|
||||
AR_I_AA("∨", or , (wv+xv)-(wv*xv), 1, {})
|
||||
AR_I_AA("∨", or , bqn_or(wv, xv), 1, {})
|
||||
AR_I_AA("⌊", floor, wv>xv?xv:wv, 2, {})
|
||||
AR_I_AA("⌈", ceil , wv>xv?wv:xv, 1, {})
|
||||
AR_I_AA("+", add, wv+xv, 0, {})
|
||||
AR_I_AA("-", sub, wv-xv, 0, {
|
||||
IFN_SINGELI(if (we==el_c32 && xe==el_i32) {
|
||||
if (we==el_c32 && xe==el_i32) {
|
||||
u32* wp = c32any_ptr(w); usz wia = IA(w);
|
||||
u32* rp; r = m_c32arrc(&rp, w);
|
||||
i32* xp = i32any_ptr(x);
|
||||
@ -218,82 +200,80 @@ B floor_c2(B, B, B);
|
||||
if (rp[i]>CHR_MAX) thrM("-: Invalid character"); // safe - see add
|
||||
}
|
||||
goto dec_ret;
|
||||
})
|
||||
}
|
||||
})
|
||||
#undef AR_I_AA
|
||||
#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 \
|
||||
if (isF64(x)) { usz ia=IA(w); DO_AS(NAME,EXPR) } \
|
||||
ARITH_SLOW; return arith_recd(NAME##_c2, w, x); \
|
||||
dec_ret: decG(w); return r; \
|
||||
}
|
||||
|
||||
#define AR_I_SA(CHR, NAME, EXPR, DO_SA, EXTRA) NOINLINE B NAME##_SA(B t, B w, B x) { \
|
||||
B r; u8 xe=TI(x,elType); EXTRA \
|
||||
if (isF64(w)) { usz ia=IA(x); DO_SA(NAME,EXPR) } \
|
||||
ARITH_SLOW; return arith_recd(NAME##_c2, w, x); \
|
||||
dec_ret: decG(x); return r; \
|
||||
}
|
||||
|
||||
static NOINLINE B bit_sel1Fn(BBB2B f, B w, B x, bool bitX) { // consumes both
|
||||
B b = bitX? x : w;
|
||||
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, h0, e1, h1); // 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("∨", or , (wv+xv)-(wv*xv), 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("+", add, wv+xv, SI_SA, {
|
||||
if (isC32(w) && xe==el_i32) {
|
||||
u32 wv = o2cu(w);
|
||||
i32* xp = i32any_ptr(x); usz xia = IA(x);
|
||||
u32* rp; 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
|
||||
}
|
||||
goto dec_ret;
|
||||
}
|
||||
})
|
||||
#undef AR_I_SA
|
||||
|
||||
|
||||
AR_I_AS("-", sub, wv-xv, SI_AS, {
|
||||
if (we==el_c32 && isC32(x)) {
|
||||
i32 xv = (i32)o2cu(x);
|
||||
u32* wp = c32any_ptr(w); usz wia = IA(w);
|
||||
i32* rp; r = m_i32arrc(&rp, w);
|
||||
for (usz i = 0; i < wia; i++) rp[i] = (i32)wp[i] - xv;
|
||||
goto dec_ret;
|
||||
}
|
||||
})
|
||||
#undef AR_I_AS
|
||||
#endif // !SINGELI
|
||||
|
||||
|
||||
|
||||
#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 \
|
||||
if (isF64(x)) { usz ia=IA(w); DO_AS(NAME,EXPR) } \
|
||||
ARITH_SLOW; return arith_recd(NAME##_c2, w, x); \
|
||||
dec_ret: decG(w); return r; \
|
||||
}
|
||||
|
||||
#define AR_I_SA(CHR, NAME, EXPR, DO_SA, EXTRA) NOINLINE B NAME##_SA(B t, B w, B x) { \
|
||||
B r; u8 xe=TI(x,elType); EXTRA \
|
||||
if (isF64(w)) { usz ia=IA(x); DO_SA(NAME,EXPR) } \
|
||||
ARITH_SLOW; return arith_recd(NAME##_c2, w, x); \
|
||||
dec_ret: decG(x); return r; \
|
||||
}
|
||||
|
||||
static NOINLINE B bit_sel1Fn(BBB2B f, B w, B x, bool bitX) { // consumes both
|
||||
B b = bitX? x : w;
|
||||
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, h0, e1, h1); // 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("∨", or , (wv+xv)-(wv*xv), 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("+", add, wv+xv, SI_SA, {
|
||||
if (isC32(w) && xe==el_i32) {
|
||||
u32 wv = o2cu(w);
|
||||
i32* xp = i32any_ptr(x); usz xia = IA(x);
|
||||
u32* rp; 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
|
||||
}
|
||||
goto dec_ret;
|
||||
}
|
||||
})
|
||||
#undef AR_I_SA
|
||||
|
||||
|
||||
AR_I_AS("-", sub, wv-xv, SI_AS, {
|
||||
if (we==el_c32 && isC32(x)) {
|
||||
i32 xv = (i32)o2cu(x);
|
||||
u32* wp = c32any_ptr(w); usz wia = IA(w);
|
||||
i32* rp; r = m_i32arrc(&rp, w);
|
||||
for (usz i = 0; i < wia; i++) rp[i] = (i32)wp[i] - xv;
|
||||
goto dec_ret;
|
||||
}
|
||||
})
|
||||
#define add_AS(T, W, X) add_SA(T, X, W)
|
||||
#define mul_AS(T, W, X) mul_SA(T, X, W)
|
||||
#define and_AS(T, W, X) and_SA(T, X, W)
|
||||
#define or_AS(T, W, X) or_SA(T, X, W)
|
||||
#define floor_AS(T, W, X) floor_SA(T, X, W)
|
||||
#define ceil_AS(T, W, X) ceil_SA(T, X, W)
|
||||
#undef AR_I_AS
|
||||
|
||||
#define AR_F_TO_ARR(NAME) return NAME##_c2_arr(t, w, x);
|
||||
#define AR_I_TO_ARR(NAME) \
|
||||
@ -326,7 +306,7 @@ AR_I_SCALAR("-", sub, w.f-x.f, {
|
||||
})
|
||||
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("∨", or , bqn_or(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
|
||||
|
||||
@ -52,7 +52,7 @@ typedef struct EntAA {
|
||||
} EntAA;
|
||||
|
||||
typedef struct DyTableAA {
|
||||
EntAA entsAA[8*8]; // one for each instruction
|
||||
EntAA entsAA[el_B*el_B]; // one for each instruction
|
||||
BBB2B mainFn;
|
||||
char* repr;
|
||||
} DyTableAA;
|
||||
@ -130,7 +130,7 @@ NOINLINE B dyArith_AA(DyTableAA* table, B w, B x) {
|
||||
}
|
||||
case e_call_sqx: {
|
||||
assert(TI(x,elType)==el_f64);
|
||||
x = num_squeeze(x);
|
||||
x = num_squeezeChk(x);
|
||||
u8 xe = TI(x,elType);
|
||||
if (xe==el_f64) goto rec;
|
||||
e = &table->entsAA[TI(w,elType)*8 + xe];
|
||||
@ -147,6 +147,135 @@ NOINLINE B dyArith_AA(DyTableAA* table, B w, B x) {
|
||||
}
|
||||
|
||||
|
||||
typedef struct DyTableSA DyTableSA;
|
||||
typedef bool (*ForBitsel)(DyTableSA*, B w, B* r);
|
||||
typedef u64 (*AtomArrFnC)(u8* r, u64 w, u8* x, u64 len);
|
||||
typedef B (*DyArithChrFn)(DyTableSA*, B, B, usz, u8);
|
||||
|
||||
typedef struct {
|
||||
// >=el_i8 el_bit
|
||||
union { AtomArrFnC f1; ForBitsel bitsel; };
|
||||
union { AtomArrFnC f2; };
|
||||
} EntSA;
|
||||
|
||||
|
||||
struct DyTableSA {
|
||||
EntSA ents[el_B];
|
||||
BBB2B mainFn;
|
||||
char* repr;
|
||||
DyTableSA* chrAtom;
|
||||
};
|
||||
|
||||
bool bad_forBitselNN_SA(DyTableSA* table, B w, B* r) { return false; }
|
||||
#define bad_forBitselCN_SA bad_forBitselNN_SA
|
||||
|
||||
B bad_chrAtomSA(DyTableSA* table, B w, B x, usz ia, u8 xe) { return arith_recd(table->mainFn, w, x); }
|
||||
#define bad_chrAtomAS bad_chrAtomSA
|
||||
|
||||
u64 failAtomArr1(u8* r, u64 w, u8* x, u64 len) { return 0; }
|
||||
u64 failAtomArr2(u8* r, u64 w, u8* x, u64 len) { return 1; }
|
||||
|
||||
u8 nextType[] = {
|
||||
[t_i8arr ] = t_i16arr, [t_c8arr ] = t_c16arr,
|
||||
[t_i16arr] = t_i32arr, [t_c16arr] = t_c32arr,
|
||||
[t_i32arr] = t_f64arr, [t_c32arr] = t_empty,
|
||||
[t_f64arr] = t_empty,
|
||||
};
|
||||
|
||||
B dyArith_SA(DyTableSA* table, B w, B x) {
|
||||
usz ia = IA(x);
|
||||
u8 xe = TI(x,elType);
|
||||
|
||||
u8 width, type; // when one argument is a number, both + and - have character array result iif the other argument is a character array; therefore result type doesn't need a lookup
|
||||
u64 wa;
|
||||
|
||||
EntSA* e;
|
||||
|
||||
if (!isF64(w)) {
|
||||
if (!isC32(w)) goto rec;
|
||||
DyTableSA* t2 = table->chrAtom;
|
||||
if (t2==NULL) goto rec;
|
||||
table = t2;
|
||||
|
||||
|
||||
wa = o2cu(w);
|
||||
newXEc:
|
||||
switch(xe) { default: UD;
|
||||
case el_bit: goto bitsel;
|
||||
case el_i8: if (wa==( u8)wa) { e=&table->ents[el_i8 ]; width=0; type=t_c8arr; goto f1; } else goto cwiden_i8;
|
||||
case el_i16: if (wa==(u16)wa) { e=&table->ents[el_i16]; width=1; type=t_c16arr; goto f1; } else goto cwiden_i16;
|
||||
case el_i32: e=&table->ents[el_i32]; width=2; type=t_c32arr; goto f1;
|
||||
case el_f64: x=num_squeezeChk(x); xe=TI(x,elType); if (xe!=el_f64) goto newXEc; else goto rec;
|
||||
case el_c8: if (wa==( u8)wa) { e=&table->ents[el_c8 ]; width=0; type=t_i8arr; goto f1; } goto cwiden_c8; // TODO check for & use unsigned w
|
||||
case el_c16: if (wa==(u16)wa) { e=&table->ents[el_c16]; width=1; type=t_i16arr; goto f1; } goto cwiden_c16;
|
||||
case el_c32: e=&table->ents[el_c32]; width=2; type=t_i32arr; goto f1;
|
||||
case el_B: goto rec;
|
||||
}
|
||||
|
||||
cwiden_i8: if (q_c16(w)) { type=t_c16arr; goto cpy_i16; }
|
||||
cwiden_i16: { type=t_c32arr; goto cpy_i32; }
|
||||
|
||||
cwiden_c8: if (q_c16(w)) { type=t_i16arr; goto cpy_c16; }
|
||||
cwiden_c16: { type=t_i32arr; goto cpy_c32; }
|
||||
goto rec;
|
||||
}
|
||||
|
||||
switch(xe) { default: UD;
|
||||
case el_bit: goto bitsel;
|
||||
case el_i8: if (q_i8 (w)) { e=&table->ents[el_i8 ]; width=0; type=t_i8arr; goto wint; } goto iwiden_i8;
|
||||
case el_i16: if (q_i16(w)) { e=&table->ents[el_i16]; width=1; type=t_i16arr; goto wint; } goto iwiden_i16;
|
||||
case el_i32: if (q_i32(w)) { e=&table->ents[el_i32]; width=2; type=t_i32arr; goto wint; } goto iwiden_i32;
|
||||
case el_f64: e=&table->ents[el_f64]; width=3; type=t_f64arr; goto wf64;
|
||||
case el_c8: if (q_i8 (w)) { e=&table->ents[el_c8 ]; width=0; type=t_c8arr; goto wint; } goto iwiden_c8;
|
||||
case el_c16: if (q_i16(w)) { e=&table->ents[el_c16]; width=1; type=t_c16arr; goto wint; } goto iwiden_c16;
|
||||
case el_c32: if (q_i32(w)) { e=&table->ents[el_c32]; width=2; type=t_c32arr; goto wint; } goto rec;
|
||||
case el_B: goto rec;
|
||||
}
|
||||
|
||||
wint: wa=(u32)o2iu(w); goto f1;
|
||||
wf64: wa=w.u; goto f1;
|
||||
|
||||
iwiden_i8: if (q_i16(w)) { wa=(u32)o2iu(w); type=t_i16arr; goto cpy_i16; }
|
||||
iwiden_i16: if (q_i32(w)) { wa=(u32)o2iu(w); type=t_i32arr; goto cpy_i32; }
|
||||
iwiden_i32: { wa=w.u; type=t_f64arr; goto cpy_f64; }
|
||||
|
||||
iwiden_c8: if (q_i16(w)) { wa=(u32)o2iu(w); type=t_c16arr; goto cpy_c16; }
|
||||
iwiden_c16: if (q_i32(w)) { wa=(u32)o2iu(w); type=t_c32arr; goto cpy_c32; }
|
||||
goto rec;
|
||||
|
||||
// TODO reuse the copied array for the result; maybe even alternate copy & operation to stay in cache
|
||||
cpy_c16: x = taga(cpyC16Arr(x)); width=1; e=&table->ents[el_c16]; goto f1;
|
||||
cpy_c32: x = taga(cpyC32Arr(x)); width=2; e=&table->ents[el_c32]; goto f1;
|
||||
|
||||
cpy_i16: x = taga(cpyI16Arr(x)); width=1; e=&table->ents[el_i16]; goto f1;
|
||||
cpy_i32: x = taga(cpyI32Arr(x)); width=2; e=&table->ents[el_i32]; goto f1;
|
||||
cpy_f64: x = taga(cpyF64Arr(x)); width=3; e=&table->ents[el_f64]; goto f1;
|
||||
|
||||
AtomArrFnC fn; B r;
|
||||
f1: fn = e->f1;
|
||||
u64 got = fn(m_tyarrlc(&r, width, x, type), wa, tyany_ptr(x), ia);
|
||||
if (got==ia) goto decG_ret;
|
||||
decG(r);
|
||||
|
||||
type = nextType[type];
|
||||
if (type==t_empty) goto rec;
|
||||
fn = e->f2;
|
||||
if (fn(m_tyarrlc(&r, width+1, x, type), wa, tyany_ptr(x), ia)==0) goto decG_ret;
|
||||
decG(r);
|
||||
goto rec;
|
||||
|
||||
|
||||
decG_ret: decG(x); return r;
|
||||
|
||||
rec: return arith_recd(table->mainFn, w, x);
|
||||
|
||||
bitsel: {
|
||||
B opts[2];
|
||||
if (!table->ents[el_bit].bitsel(table, w, opts)) goto rec;
|
||||
return bit_sel(x, opts[0], 1, opts[1], 1);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#include "../gen/dyarith.c"
|
||||
@ -157,4 +286,36 @@ static void powAAu_f64_f64_f64(u8* r, u8* w, u8* x, u64 len) { for (u64 i = 0;
|
||||
static void stileAAu_f64_f64_f64(u8* r, u8* w, u8* x, u64 len) { for (u64 i = 0; i < len; i++) ((f64*)r)[i] = pfmod(((f64*)x)[i], ((f64*)w)[i]); }
|
||||
static void logAAu_f64_f64_f64(u8* r, u8* w, u8* x, u64 len) { for (u64 i = 0; i < len; i++) ((f64*)r)[i] = log(((f64*)x)[i])/log(((f64*)w)[i]); }
|
||||
|
||||
#define BI_C2(N, W, X) ({ B w_ = (W); N##_c2(w_, w_, X); })
|
||||
// bool sub_forBitselCN_SA (DyTableSA* table, B w, B* r) { u32 v=o2cu(w); r[0] = m_c32(v-0); r[1] = m_c32(v-1); if (v==0) BI_C2(sub, w, m_f64(1)); return true; }
|
||||
bool add_forBitselNN_SA (DyTableSA* table, B w, B* r) { f64 f=o2fu(w); r[0] = m_f64(f+0); r[1] = m_f64(f+1); return true; }
|
||||
bool sub_forBitselNN_SA (DyTableSA* table, B w, B* r) { f64 f=o2fu(w); r[0] = m_f64(f-0); r[1] = m_f64(f-1); return true; }
|
||||
bool subR_forBitselNN_SA(DyTableSA* table, B w, B* r) { f64 f=o2fu(w); r[0] = m_f64(0-f); r[1] = m_f64(1-f); return true; }
|
||||
bool mul_forBitselNN_SA (DyTableSA* table, B w, B* r) { f64 f=o2fu(w); r[0] = m_f64(f*0); r[1] = m_f64(f*1); return true; }
|
||||
bool min_forBitselNN_SA (DyTableSA* table, B w, B* r) { f64 f=o2fu(w); r[0] = m_f64(f<=0?f:0); r[1] = m_f64(f<=1?f:1); return true; }
|
||||
bool max_forBitselNN_SA (DyTableSA* table, B w, B* r) { f64 f=o2fu(w); r[0] = m_f64(f>=0?f:0); r[1] = m_f64(f>=1?f:1); return true; }
|
||||
|
||||
bool add_forBitselCN_SA(DyTableSA* table, B w, B* r) { u32 wc=o2cu(w); if(wc+1<=CHR_MAX) return false; r[0] = m_c32(wc); r[1] = m_c32(wc+1); return true; }
|
||||
bool sub_forBitselCN_SA(DyTableSA* table, B w, B* r) { u32 wc=o2cu(w); if(wc !=0 ) return false; r[0] = m_c32(wc); r[1] = m_c32(wc-1); return true; }
|
||||
|
||||
B sub_c2R(B t, B w, B x) { return sub_c2(t, x, w); }
|
||||
|
||||
static NOINLINE B or_SA(B t, B w, B x) {
|
||||
if (!isF64(w)) return arith_recd(or_c2, w, x);
|
||||
if (LIKELY(TI(x,elType)==el_bit)) {
|
||||
bitsel:
|
||||
return bit_sel(x, BI_C2(or, w, m_f64(0)), 1, BI_C2(or, w, m_f64(1)), 1);
|
||||
}
|
||||
x = num_squeezeChk(x);
|
||||
if (TI(x,elType)==el_bit) goto bitsel;
|
||||
|
||||
f64* rp;
|
||||
B r = m_f64arrc(&rp, x);
|
||||
usz ia = a(x)->ia;
|
||||
x = toF64Any(x);
|
||||
orSAc_f64_f64_f64((u8*)rp, w.u, tyany_ptr(x), ia);
|
||||
decG(x);
|
||||
return r;
|
||||
}
|
||||
|
||||
#include "../gen/arTables.c"
|
||||
|
||||
@ -21,22 +21,6 @@ def assert{x & x==1} = 1
|
||||
def assert{x:u1} = emit{void, 'si_assert', x}
|
||||
|
||||
|
||||
|
||||
def tern{c, T, F & anyInt{c}} = {
|
||||
if(c) T
|
||||
else F
|
||||
}
|
||||
def tern{c, t:T, f:T & anyInt{c}} = {
|
||||
res:T = f
|
||||
if (c) res = t
|
||||
res
|
||||
}
|
||||
|
||||
def min{a, b & knum{a} & knum{b}} = tern{a<b, a, b}
|
||||
def max{a, b & knum{a} & knum{b}} = tern{a>b, a, b}
|
||||
|
||||
|
||||
|
||||
# various checks
|
||||
def knum{x} = match{kind{x},'number'}
|
||||
def isreg{x} = match{kind{x},'register'}
|
||||
@ -113,6 +97,21 @@ def maxvalue{T & isunsigned{T}} = (1<<width{T})-1
|
||||
def minvalue{T & issigned{T}} = - (1<<(width{T}-1))
|
||||
def maxvalue{T & issigned{T}} = (1<<(width{T}-1))-1
|
||||
|
||||
|
||||
def tern{c, T, F & anyInt{c}} = {
|
||||
if(c) T
|
||||
else F
|
||||
}
|
||||
def tern{c, t:T, f:T & anyInt{c}} = {
|
||||
res:T = f
|
||||
if (c) res = t
|
||||
res
|
||||
}
|
||||
|
||||
def min{a, b & knum{a} & knum{b}} = tern{a<b, a, b}
|
||||
def max{a, b & knum{a} & knum{b}} = tern{a>b, a, b}
|
||||
|
||||
|
||||
# tuple operations
|
||||
def broadcast{T, v & isprim{T}} = v
|
||||
def any{v:T & isprim{T}} = v
|
||||
|
||||
@ -22,9 +22,12 @@ def fmt_op{X== max}= 'max'
|
||||
def rootty{T & isprim{T}} = T
|
||||
def rootty{T & isvec{T}} = eltype{T}
|
||||
|
||||
def is_s{X} = issigned{rootty{X}}
|
||||
def is_u{X} = isunsigned{rootty{X}}
|
||||
|
||||
def ty_sc{O, R} = R # keep floats as-is
|
||||
def ty_sc{O, R & issigned{O} & isunsigned{rootty{R}}} = ty_s{R}
|
||||
def ty_sc{O, R & isunsigned{O} & issigned{rootty{R}}} = ty_u{R}
|
||||
def ty_sc{O, R & is_s{O} & is_u{R}} = ty_s{R}
|
||||
def ty_sc{O, R & is_u{O} & is_s{R}} = ty_u{R}
|
||||
|
||||
def bqn_or{a, b} = (a+b)-(a*b)
|
||||
|
||||
@ -37,7 +40,7 @@ def arithChk1{F==__sub, M, w:T, x:T, r:T & isvec{T} & width{eltype{T}}<=16} = an
|
||||
|
||||
|
||||
|
||||
def arithChk2{F, M, w:T, x:T & issigned{rootty{T}} & (match{F,__add} | match{F,__sub})} = {
|
||||
def arithChk2{F, M, w:T, x:T & is_s{T} & (match{F,__add} | match{F,__sub})} = {
|
||||
r:= F{w,x}
|
||||
tup{r, arithChk1{F, M, w, x, r}}
|
||||
}
|
||||
@ -81,9 +84,9 @@ def arithChk2{F, M, w:T, x:T & match{F,__mul} & isvec{T} & i32==eltype{T}} = {
|
||||
def runner{u, R, F} = {
|
||||
def c = ~u
|
||||
|
||||
def run{F, OO, M, w, x} = { show{'todo', fmt_op{F}, c, w, x}; emit{void,'__builtin_abort'}; w }
|
||||
def run{F, OO, M, w, x} = { show{'todo', c, R, fmt_op{F}, w, x}; emit{void,'__builtin_abort'}; w }
|
||||
|
||||
def run{F, OO, M, w:T, x:T & c} = {
|
||||
def run{F, OO, M, w:T, x:T & c & R!=u32} = {
|
||||
def r2 = arithChk2{F, M, w, x}
|
||||
if (rare{tupsel{1,r2}}) OO{}
|
||||
tupsel{0,r2}
|
||||
@ -92,54 +95,24 @@ def runner{u, R, F} = {
|
||||
def run{F, OO, M, w, x & u} = F{w, x} # trivial base implementation
|
||||
|
||||
def toggleTop{x:X} = x ^ broadcast{X, 1<<(width{eltype{X}}-1)}
|
||||
def run{F==__sub, OO, M, w:VU, x:VU & isunsigned{eltype{VU}}} = { # 'b'-'a'
|
||||
def run{F==__sub, OO, M, w:VU, x:VU & is_u{VU}} = { # 'b'-'a'
|
||||
def VS = ty_s{VU}
|
||||
run{F, OO, M, VS~~toggleTop{w}, VS~~toggleTop{x}}
|
||||
}
|
||||
def run{F, OO, M, w:VU, x:VS & isunsigned{eltype{VU}} & issigned{eltype{VS}}} = { # 'a'+3, 'a'-3
|
||||
def run{F, OO, M, w:VU, x:VS & is_u{VU} & is_s{VS}} = { # 'a'+3, 'a'-3
|
||||
toggleTop{VU~~run{F, OO, M, VS~~toggleTop{w}, x}}
|
||||
}
|
||||
# def run{F==__add, OO, M, w:VS, x:VU & issigned{eltype{VS}} & isunsigned{eltype{VU}}} = run{F, OO, M, x, w} # 3+'a' → 'a'+3
|
||||
def run{F==__add, OO, M, w:VS, x:VU & is_s{VS} & is_u{VU}} = run{F, OO, M, x, w} # 3+'a' → 'a'+3
|
||||
|
||||
def run{F, OO, M, w:VW, x:VX & c & R==u32 & (match{F,__add} | match{F,__sub})} = { # 'a'+1, 'a'-1
|
||||
r:= F{ty_u{w}, ty_u{x}}
|
||||
if (any{M{r > broadcast{type{r}, 1114111}}}) OO{}
|
||||
to_el{R, VW}~~r
|
||||
}
|
||||
run
|
||||
}
|
||||
|
||||
|
||||
# old atom F array & array F atom
|
||||
def arithAny{VT, F, W, X, r, len} = {
|
||||
def bulk = vcount{VT}
|
||||
def run = runner{eltype{VT}==f64, eltype{VT}, F}
|
||||
maskedLoop{bulk, len, {i, M} => storeBatch{r, i, run{F, {} => return{i}, M, W{i}, X{i}}, M}}
|
||||
len
|
||||
}
|
||||
# cast a guaranteed float to a more specific type; return{0} if not possible
|
||||
def cast_fB{T, x:(u64) & f64==T} = from_B{f64, x}
|
||||
def cast_fB{T, x:(u64) & issigned{T} & T<i64} = {
|
||||
f:f64 = from_B{f64, x}
|
||||
r:T = ftrunc{T, f}
|
||||
if (rare{f!=fext{r}}) return{cast{Size,0}}
|
||||
r
|
||||
}
|
||||
def arithAS{VT, F, w, x, r, len} = { xv:= broadcast{VT, x}; arithAny{VT, F, {i}=>load{*VT~~w, i}, {i}=>xv, r, len} }
|
||||
def arithSA{VT, F, w, x, r, len} = { wv:= broadcast{VT, w}; arithAny{VT, F, {i}=>wv, {i}=>load{*VT~~x, i}, r, len} }
|
||||
arithAS{F,VT}(w: *u8, x: u64, r: *u8, len: Size) : Size = { def T=eltype{VT}; arithAS{VT, F, *T ~~ w, cast_fB{T, x}, *T~~r, len} }
|
||||
arithSA{F,VT}(w: u64, x: *u8, r: *u8, len: Size) : Size = { def T=eltype{VT}; arithSA{VT, F, cast_fB{T, w}, *T ~~ x, *T~~r, len} }
|
||||
|
||||
'avx2_addAS_i8' = arithAS{__add,[32]i8 }; 'avx2_addSA_i8' = arithSA{__add,[32]i8 }
|
||||
'avx2_addAS_i16' = arithAS{__add,[16]i16}; 'avx2_addSA_i16' = arithSA{__add,[16]i16}
|
||||
'avx2_addAS_i32' = arithAS{__add,[ 8]i32}; 'avx2_addSA_i32' = arithSA{__add,[ 8]i32}
|
||||
'avx2_addAS_f64' = arithAS{__add,[ 4]f64}; 'avx2_addSA_f64' = arithSA{__add,[ 4]f64}
|
||||
'avx2_subAS_i8' = arithAS{__sub,[32]i8 }; 'avx2_subSA_i8' = arithSA{__sub,[32]i8 }
|
||||
'avx2_subAS_i16' = arithAS{__sub,[16]i16}; 'avx2_subSA_i16' = arithSA{__sub,[16]i16}
|
||||
'avx2_subAS_i32' = arithAS{__sub,[ 8]i32}; 'avx2_subSA_i32' = arithSA{__sub,[ 8]i32}
|
||||
'avx2_subAS_f64' = arithAS{__sub,[ 4]f64}; 'avx2_subSA_f64' = arithSA{__sub,[ 4]f64}
|
||||
'avx2_mulAS_i8' = arithAS{__mul,[32]i8 }; 'avx2_mulSA_i8' = arithSA{__mul,[32]i8 }
|
||||
'avx2_mulAS_i16' = arithAS{__mul,[16]i16}; 'avx2_mulSA_i16' = arithSA{__mul,[16]i16}
|
||||
'avx2_mulAS_i32' = arithAS{__mul,[ 8]i32}; 'avx2_mulSA_i32' = arithSA{__mul,[ 8]i32}
|
||||
'avx2_mulAS_f64' = arithAS{__mul,[ 4]f64}; 'avx2_mulSA_f64' = arithSA{__mul,[ 4]f64}
|
||||
|
||||
|
||||
|
||||
# new array F array
|
||||
def arithAAimpl{vw, mode, F, W, X, R, w, x, r, len} = {
|
||||
# show{fmt_op{F}, mode, W, X, R}
|
||||
if (R==u1) {
|
||||
@ -180,4 +153,28 @@ def arithAA{mode, F, W, X, R} = {
|
||||
else arithAAu{vw, mode, F, W, X, R}
|
||||
}
|
||||
|
||||
# mode: 0:overflow-checked, needed; 1:overflow-erroring; 2: overflow-checked, not needed
|
||||
arithSAf{vw, mode, F, swap, W, X, R}(r:*u8, w:u64, x:*u8, len:u64) : u64 = {
|
||||
# show{fmt_op{F}, swap, mode, W, X, R}
|
||||
def bulk = vw / max{width{W}, width{R}}
|
||||
def TY = [bulk]R
|
||||
def overflow = tern{mode==1, {i}=>return{1}, {i}=>return{i}}
|
||||
|
||||
def run = runner{(R==f64) | (mode==2), R, F}
|
||||
def getW{v} = trunc{W, v}
|
||||
def getW{v & W==f64} = interp_f64{v}
|
||||
cw:= broadcast{ty_sc{W, TY}, getW{w}}
|
||||
|
||||
maskedLoop{bulk, len, {i, M} => {
|
||||
cx:= loadBatch{*X~~x, i, ty_sc{X, TY}}
|
||||
storeBatch{*R~~r, i, TY~~run{F, {} => overflow{i}, M, tern{swap,cx,cw}, tern{swap,cw,cx}}, M}
|
||||
}}
|
||||
|
||||
if (mode==1) 0
|
||||
else len
|
||||
}
|
||||
|
||||
def arithSA{mode, F, swap, W, X, R} = arithSAf{256, mode, F, swap, W, X, R}
|
||||
|
||||
'orSAc_f64_f64_f64'=arithSA{2,bqn_or,0,f64,f64,f64}
|
||||
include './../gen/arDefs'
|
||||
@ -1,6 +1,4 @@
|
||||
debug ← 0=≠•args
|
||||
•term.OutRaw⍟debug ∾⟨@+27 ⋄ "[H" ⋄ @+27 ⋄ "[2J" ⋄ @+27 ⋄ "[3J"⟩
|
||||
•Out⍟(3×debug) 200⥊'-'
|
||||
impls‿tables ← 2↑•args
|
||||
|
||||
T ← =⊸{<⎉𝕨⍉⍟𝕨>𝕩}
|
||||
@ -17,14 +15,7 @@ tmLit ← "uceue"
|
||||
|
||||
tyWidth ← 99‿0‿1‿2‿3‿0‿1‿2 # in log2(bytes)
|
||||
tyName ← "bit"‿"i8"‿"i16"‿"i32"‿"f64"‿"c8"‿"c16"‿"c32"
|
||||
tySiType ← "u1"‿"i8"‿"i16"‿"i32"‿"f64"‿"u8"‿"u16"‿"u32"
|
||||
|
||||
ShowTbl ← {
|
||||
# 𝕩 ↩ {∧´⥊𝕩≡¨@? @; 𝕩/˜𝕩≢¨@}¨ 𝕩
|
||||
𝕩 ≍˘⍟=¨ ↩
|
||||
•Show 𝕩
|
||||
#•Out •Repr 𝕩
|
||||
}⍟debug
|
||||
tySiName ← "u1"‿"i8"‿"i16"‿"i32"‿"f64"‿"u8"‿"u16"‿"u32"
|
||||
|
||||
mdNone ← 0
|
||||
mdExact ← 1
|
||||
@ -33,21 +24,26 @@ mdBit2i8 ← 3
|
||||
mdF64Chr ← 4
|
||||
mdSqF64 ← 5
|
||||
|
||||
singeliFns ← ⟨⟩
|
||||
GetSingeli ← { tm‿w‿x‿r‿id‿si:
|
||||
singeliAAFns ← ⟨⟩
|
||||
GetSingeliAA ← { tm‿w‿x‿r‿id‿si:
|
||||
{
|
||||
r≡@? @;
|
||||
name ← ∾⟨id, "AA", tm⊑tmLit, "_", w⊑tyName, "_", x⊑tyName, "_", r⊑tyName⟩
|
||||
singeliFns∾↩ <name‿w‿x‿r‿tm‿si
|
||||
singeliAAFns∾↩ <name‿w‿x‿r‿tm‿si
|
||||
name
|
||||
}
|
||||
}
|
||||
|
||||
singeliASFns ← ⟨⟩
|
||||
|
||||
nl←@+10
|
||||
cSrc ← ""
|
||||
siSrc ← ""
|
||||
|
||||
Make ← {𝕊ns:
|
||||
cbqn‿repr‿id‿si‿commutative ← ns
|
||||
|
||||
# array-array
|
||||
aaA‿aaB ← {4≡≠𝕩?𝕩∾id‿si; 𝕩}¨¨ ns.aa_a‿ns.aa_b # add ID and singeli fn to entries that don't have it explicit
|
||||
|
||||
currTypes ← ↕8‿8
|
||||
@ -94,16 +90,16 @@ Make ← {𝕊ns:
|
||||
Type ← {𝕊: 3⊑n⊑map}
|
||||
⊢◶⟨
|
||||
@ # mdNone
|
||||
{𝕊: ⟨GetSingeli e, t, Type@, call∾(bit=3⊑n⊑map)⊑"rbyte"‿"bit", s, @⟩} # mdExact
|
||||
{𝕊: ⟨GetSingeli e, t, Type@, call∾(bit=3⊑n⊑map)⊑"rbyte"‿"bit", s, ((s≠m)/"wx")∾tyName⊑˜⊑m/n⟩} # mdCast
|
||||
{𝕊: ⟨GetSingeli e, t, Type@, call∾"wxi8", s, @⟩} # mdBit2i8
|
||||
{𝕊: ⟨GetSingeliAA e, t, Type@, call∾(bit=3⊑n⊑map)⊑"rbyte"‿"bit", s, @⟩} # mdExact
|
||||
{𝕊: ⟨GetSingeliAA e, t, Type@, call∾(bit=3⊑n⊑map)⊑"rbyte"‿"bit", s, ((s≠m)/"wx")∾tyName⊑˜⊑m/n⟩} # mdCast
|
||||
{𝕊: ⟨GetSingeliAA e, t, Type@, call∾"wxi8", s, @⟩} # mdBit2i8
|
||||
{𝕊: ⟨@, t, @, "e_call_sqx", s, @⟩} # mdF64Chr
|
||||
{𝕊: ⟨GetSingeli e, t, Type@, call∾"wxf64sq", s, @⟩} # mdSqF64
|
||||
{𝕊: ⟨GetSingeliAA e, t, Type@, call∾"wxf64sq", s, @⟩} # mdSqF64
|
||||
⟩ 𝕩
|
||||
}¨ res
|
||||
}¨ aaA‿aaB
|
||||
|
||||
# ShowTbl ∾´¨ instrs
|
||||
{•Show ≍˘¨𝕩}⍟debug instrs
|
||||
|
||||
cSrc∾↩ ∾⟨
|
||||
"B ", cbqn, "_c2(B,B,B);", nl
|
||||
@ -132,6 +128,62 @@ Make ← {𝕊ns:
|
||||
" .repr = """, repr, """", nl
|
||||
"};", nl
|
||||
⟩
|
||||
|
||||
# array-scalar / scalar-array
|
||||
ty0 ← tyName
|
||||
ty1 ← ⟨@, "i16","i32","f64",@, "c16","c32",@⟩
|
||||
tyi ← ⟨@, "i8","i16","i32","f64", "i8","i16","i32"⟩
|
||||
tyc ← ⟨@, "c8","c16","c32",@, "c8","c16","c32"⟩
|
||||
isc ← ⟨0, 0, 0, 0, 0, 1, 1, 1⟩
|
||||
{ 𝕊 swap‿get:
|
||||
choices ← ns.sa
|
||||
hadChrArr ← 0
|
||||
{
|
||||
0≡≠𝕩? @;
|
||||
charAtm ← 'c' ≡ ⊑⊑𝕩
|
||||
hasNumArr ← ⊑'i' ∊ 1⊑¨𝕩
|
||||
hasChrArr ← ⊑'c' ∊ 1⊑¨𝕩
|
||||
resChr ← {(2⊑¨𝕩)⌾((2↑¨𝕩)⊸⊑) 2‿2⥊@} 'c'=𝕩
|
||||
argarr ← ⌽⍟swap "SA"
|
||||
canOverflow ← "f64"⊸≢¨ tyName
|
||||
|
||||
cSrc∾↩ ∾⟨
|
||||
"static DyTableSA ", cbqn,"DyTable", ⌽⍟swap (charAtm⊑"NC")∾"A", " = {", nl
|
||||
" .ents = {", nl
|
||||
" {.bitsel=", hasNumArr◶⟨"bad", {𝕊:id∾swap/"R"}⟩ @, "_forBitsel", charAtm⊑"NC", "N_SA},", nl
|
||||
∾{ 𝕊 num:
|
||||
onlyFirst ← ns.overflowEq⊑ ⟨1, ¬num⊑canOverflow⟩
|
||||
f1‿f2 ← 1‿2 {
|
||||
𝕩≢@? @≢𝕩⊑ty1?
|
||||
charArr ← num⊑isc
|
||||
¬ (charAtm∧¬num⊑canOverflow) ∨ (onlyFirst ∧ 𝕨=2) ∨ (¬hasChrArr)∧charArr?
|
||||
currRes ← charAtm‿charArr⊑resChr
|
||||
currRes≢@?
|
||||
tw←num⊑charAtm⊑tyi‿tyc ⋄ tx←num⊑tyName ⋄ tr←num⊑currRes⊑tyi‿tyc
|
||||
tw≢@? tx≢@? tr≢@?
|
||||
siName ← ∾⟨id, argarr, 𝕨⊑"?ce", ∾'_'⊸∾¨ tw‿tx‿tr⟩
|
||||
𝕨 { 𝕊:
|
||||
siSrc∾↩ ∾⟨"'", siName, "'=arithSA{", '0'+ 𝕨⊑⟨@, onlyFirst⊑0‿2, 1⟩, ',', si, ',', '0'+swap, ∾(',' ∾ 'u'⌾⊑⍟('c'≡⊑))¨ tw‿tx‿tr, '}', nl⟩
|
||||
singeliASFns∾↩ <siName
|
||||
}⍟⊢ ¬⊑(<siName)∊singeliASFns
|
||||
siName;
|
||||
"failAtomArr"∾'0'+𝕨
|
||||
}¨ ⟨num⊑@‿1‿2‿3‿4‿5‿6‿7,
|
||||
num⊑@‿2‿3‿4‿@‿6‿7‿@⟩
|
||||
∾⟨" {.f1=",f1,", .f2=",f2,"},", nl⟩
|
||||
}¨ 1+↕7
|
||||
" },", nl
|
||||
" .chrAtom = ", hadChrArr◶"NULL"‿{𝕊: ∾⟨"&",cbqn,"DyTable", ⌽⍟swap "CA"⟩} @, ",", nl
|
||||
" .mainFn = ", cbqn, "_c2", swap/"R", ",", nl
|
||||
" .repr = """, repr, """", nl
|
||||
"};", nl
|
||||
⟩
|
||||
|
||||
hadChrArr∨↩ charAtm
|
||||
}¨ 2↑(("ci"⊐⊑¨)⊔⊢) ⌽⍟swap⌾(2⊸↑)¨ choices
|
||||
}¨ (2-commutative)↑ ⟨0‿{𝕩.sa} ⋄ 1‿{𝕩.as}⟩
|
||||
|
||||
siSrc∾↩ nl
|
||||
}
|
||||
|
||||
|
||||
@ -150,52 +202,57 @@ Make ← {𝕊ns:
|
||||
commutative⇐1 ⋄ repr⇐"+" ⋄ cbqn⇐"add" ⋄ si⇐"__add" ⋄ id⇐"add"
|
||||
aa_a ⇐ c_numDiag∾⟨c‿i8‿c8‿c8, c‿i16‿c16‿c16, e‿i32‿c32‿c32, xsq‿c8‿f64‿@, xsq‿c16‿f64‿@, xsq‿c32‿f64‿@⟩∾⟨c‿i8‿i16‿i16, c‿i8‿i32‿i32, c‿i16‿i32‿i32⟩
|
||||
aa_b ⇐ w_numDiag∾⟨e‿i8‿c8‿c16, e‿i16‿c16‿c32⟩
|
||||
sa⇐"iii"‿"icc"‿"cic" ⋄ overflowEq⇐1
|
||||
}
|
||||
Make {
|
||||
commutative⇐0 ⋄ repr⇐"-" ⋄ cbqn⇐"sub" ⋄ si⇐"__sub" ⋄ id⇐"sub"
|
||||
aa_a ⇐ c_numDiag∾⟨c‿c8‿c8‿i8, c‿c16‿c16‿i16, u‿c32‿c32‿i32⟩∾⟨c‿c8‿i8‿c8, c‿c16‿i16‿c16, e‿c32‿i32‿c32⟩∾⟨xsq‿c8‿f64‿@, xsq‿c16‿f64‿@, xsq‿c32‿f64‿@⟩
|
||||
aa_b ⇐ w_numDiag∾⟨u‿c8‿c8‿i16, u‿c16‿c16‿i32⟩ ∾⟨e‿c8‿i8‿c16, e‿c16‿i16‿c32⟩
|
||||
sa⇐"iii"‿"cic"‿"cci" ⋄ overflowEq⇐1
|
||||
}
|
||||
Make¨ { repr‿cbqn:
|
||||
commutative⇐1 ⋄ repr‿cbqn⇐ ⋄ si⇐"__mul" ⋄ id⇐"mul"
|
||||
aa_a ⇐ bitand∾c_numDiag # ∾⟨u‿bit‿i8‿i8, u‿bit‿i16‿i16, u‿bit‿i32‿i32, u‿bit‿f64‿f64⟩
|
||||
aa_b ⇐ w_numDiag # TODO readd ↑
|
||||
sa⇐⟨"iii"⟩ ⋄ overflowEq⇐1
|
||||
}¨ ⟨"×"‿"mul", "∧"‿"and"⟩
|
||||
Make {
|
||||
commutative⇐1 ⋄ repr⇐"∨" ⋄ cbqn⇐"or" ⋄ si⇐"bqn_or" ⋄ id⇐"or"
|
||||
aa_a ⇐ bitor∾⟨rsq‿f64‿f64‿f64⟩ # TODO maybe new instr to squeeze arguments & try to go bitarr-bitarr
|
||||
aa_b ⇐ ⟨⟩ # and maybe use that for ∧ but not ×
|
||||
sa⇐⟨⟩ ⋄ overflowEq⇐1
|
||||
}
|
||||
Make {
|
||||
commutative⇐1 ⋄ repr⇐"⌊" ⋄ cbqn⇐"floor" ⋄ si⇐"min" ⋄ id⇐"min"
|
||||
aa_a ⇐ bitand∾u_numDiag ⋄ aa_b ⇐ ⟨⟩
|
||||
sa⇐⟨"iii"⟩ ⋄ overflowEq⇐0
|
||||
}
|
||||
Make {
|
||||
commutative⇐1 ⋄ repr⇐"⌈" ⋄ cbqn⇐"ceil" ⋄ si⇐"max" ⋄ id⇐"max"
|
||||
aa_a ⇐ bitor∾u_numDiag ⋄ aa_b ⇐ ⟨⟩
|
||||
sa⇐⟨"iii"⟩ ⋄ overflowEq⇐0
|
||||
}
|
||||
# Make¨ { repr‿cbqn‿si:
|
||||
# commutative⇐0 ⋄ repr‿cbqn‿si⇐ ⋄ id⇐cbqn
|
||||
# aa_a ⇐ ⟨rsq‿f64‿f64‿f64⟩ ⋄ aa_b ⇐ ⟨⟩
|
||||
# sa⇐"i" ⋄ as⇐"i" ⋄ overflowEq⇐1
|
||||
# }¨ ⟨"÷"‿"div"‿"__div", "√"‿"root"‿@, "|"‿"stile"‿@, "⋆"‿"pow"‿@, "⋆⁼"‿"log"‿@⟩
|
||||
}
|
||||
|
||||
siSrc ← ""
|
||||
GenSingeli ← { 𝕊name‿w‿x‿r‿tm‿si:
|
||||
si≢@?
|
||||
siSrc ∾↩ ∾⟨"'", name, "'=arithAA{", '0'+tm, ',', si, ',', w⊑tySiType, ',', x⊑tySiType, ',', r⊑tySiType, '}', nl⟩;
|
||||
siSrc ∾↩ ∾⟨"'", name, "'=arithAA{", '0'+tm, ',', si, ',', w⊑tySiName, ',', x⊑tySiName, ',', r⊑tySiName, '}', nl⟩;
|
||||
# else
|
||||
@
|
||||
}
|
||||
|
||||
GenSingeli¨ ⍷singeliFns
|
||||
GenSingeli¨ ⍷singeliAAFns
|
||||
|
||||
⊢◶{𝕊:
|
||||
impls •FChars siSrc
|
||||
tables •FChars cSrc
|
||||
}‿{𝕊:
|
||||
# •Out cSrc
|
||||
•Out cSrc
|
||||
•Out siSrc
|
||||
1
|
||||
} debug
|
||||
|
||||
} debug
|
||||
Loading…
Reference in New Issue
Block a user