special-case JIT ARRO for 1 and 2 items
This commit is contained in:
parent
4246aa5694
commit
7cc37e2723
@ -18,33 +18,51 @@ static Arr* take_impl(usz ria, B x) { // consumes x; returns v↑⥊𝕩 without
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static B unitV1(B x) {
|
B m_vec1(B a) {
|
||||||
if (isF64(x)) {
|
if (isF64(a)) {
|
||||||
i32 i = (i32)x.f;
|
i32 i = (i32)a.f;
|
||||||
if (RARE(x.f != i)) { f64* rp; B r = m_f64arrv(&rp, 1); rp[0] = x.f; return r; }
|
if (RARE(a.f != i)) { f64* rp; B r = m_f64arrv(&rp, 1); rp[0] = a.f; return r; }
|
||||||
if (x.f == (i8 )i) { i8* rp; B r = m_i8arrv (&rp, 1); rp[0] = i; return r; }
|
if (a.f == (i8 )i) { i8* rp; B r = m_i8arrv (&rp, 1); rp[0] = i; return r; }
|
||||||
else if (x.f == (i16)i) { i16* rp; B r = m_i16arrv(&rp, 1); rp[0] = i; return r; }
|
else if (a.f == (i16)i) { i16* rp; B r = m_i16arrv(&rp, 1); rp[0] = i; return r; }
|
||||||
else { i32* rp; B r = m_i32arrv(&rp, 1); rp[0] = i; return r; }
|
else { i32* rp; B r = m_i32arrv(&rp, 1); rp[0] = i; return r; }
|
||||||
}
|
}
|
||||||
if (isC32(x)) {
|
if (isC32(a)) {
|
||||||
u32 c = o2cu(x);
|
u32 c = o2cu(a);
|
||||||
if (LIKELY(c<U8_MAX )) { u8* rp; B r = m_c8arrv (&rp, 1); rp[0] = c; return r; }
|
if (LIKELY(c<U8_MAX )) { u8* rp; B r = m_c8arrv (&rp, 1); rp[0] = c; return r; }
|
||||||
else if (LIKELY(c<U16_MAX)) { u16* rp; B r = m_c16arrv(&rp, 1); rp[0] = c; return r; }
|
else if (LIKELY(c<U16_MAX)) { u16* rp; B r = m_c16arrv(&rp, 1); rp[0] = c; return r; }
|
||||||
else { u32* rp; B r = m_c32arrv(&rp, 1); rp[0] = c; return r; }
|
else { u32* rp; B r = m_c32arrv(&rp, 1); rp[0] = c; return r; }
|
||||||
}
|
}
|
||||||
Arr* ra = m_fillarrp(1); arr_shVec(ra);
|
Arr* ra = m_fillarrp(1); arr_shVec(ra);
|
||||||
fillarr_setFill(ra, asFill(inc(x)));
|
fillarr_setFill(ra, asFill(inc(a)));
|
||||||
fillarr_ptr(ra)[0] = x;
|
fillarr_ptr(ra)[0] = a;
|
||||||
return taga(ra);
|
return taga(ra);
|
||||||
}
|
}
|
||||||
|
B m_vec2(B a, B b) {
|
||||||
|
if (isAtm(a)&isAtm(b)) {
|
||||||
|
if (LIKELY(isNum(a)&isNum(b))) {
|
||||||
|
i32 ai=a.f; i32 bi=b.f;
|
||||||
|
if (RARE(ai!=a.f | bi!=b.f)) { f64* rp; B r = m_f64arrv(&rp, 2); rp[0]=o2fu(a); rp[1]=o2fu(b); return r; }
|
||||||
|
else if (ai==(i8 )ai & bi==(i8 )bi) { i8* rp; B r = m_i8arrv (&rp, 2); rp[0]=ai; rp[1]=bi; return r; }
|
||||||
|
else if (ai==(i16)ai & bi==(i16)bi) { i16* rp; B r = m_i16arrv(&rp, 2); rp[0]=ai; rp[1]=bi; return r; }
|
||||||
|
else { i32* rp; B r = m_i32arrv(&rp, 2); rp[0]=ai; rp[1]=bi; return r; }
|
||||||
|
}
|
||||||
|
if (isC32(b)&isC32(a)) {
|
||||||
|
u32 ac=o2cu(a); u32 bc=o2cu(b);
|
||||||
|
if (ac==(u8 )ac & bc==(u8 )bc) { u8* rp; B r = m_c8arrv (&rp, 2); rp[0]=ac; rp[1]=bc; return r; }
|
||||||
|
else if (ac==(u16)ac & bc==(u16)bc) { u16* rp; B r = m_c16arrv(&rp, 2); rp[0]=ac; rp[1]=bc; return r; }
|
||||||
|
else { u32* rp; B r = m_c32arrv(&rp, 2); rp[0]=ac; rp[1]=bc; return r; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m_v2(a,b);
|
||||||
|
}
|
||||||
|
|
||||||
B shape_c1(B t, B x) {
|
B shape_c1(B t, B x) {
|
||||||
if (isAtm(x)) return unitV1(x);
|
if (isAtm(x)) return m_vec1(x);
|
||||||
usz ia = a(x)->ia;
|
usz ia = a(x)->ia;
|
||||||
if (ia==1 && TI(x,elType)<el_B) {
|
if (ia==1 && TI(x,elType)<el_B) {
|
||||||
B n = IGet(x,0);
|
B n = IGet(x,0);
|
||||||
dec(x);
|
dec(x);
|
||||||
return unitV1(n);
|
return m_vec1(n);
|
||||||
}
|
}
|
||||||
if (reusable(x)) { FL_KEEP(x, fl_squoze);
|
if (reusable(x)) { FL_KEEP(x, fl_squoze);
|
||||||
decSh(v(x)); arr_shVec(a(x));
|
decSh(v(x)); arr_shVec(a(x));
|
||||||
@ -635,7 +653,7 @@ B join_c2(B t, B w, B x) {
|
|||||||
|
|
||||||
|
|
||||||
B couple_c1(B t, B x) {
|
B couple_c1(B t, B x) {
|
||||||
if (isAtm(x)) return unitV1(x);
|
if (isAtm(x)) return m_vec1(x);
|
||||||
usz rr = rnk(x);
|
usz rr = rnk(x);
|
||||||
usz ia = a(x)->ia;
|
usz ia = a(x)->ia;
|
||||||
Arr* r = TI(x,slice)(incG(x),0, ia);
|
Arr* r = TI(x,slice)(incG(x),0, ia);
|
||||||
@ -645,16 +663,7 @@ B couple_c1(B t, B x) {
|
|||||||
return taga(r);
|
return taga(r);
|
||||||
}
|
}
|
||||||
B couple_c2(B t, B w, B x) {
|
B couple_c2(B t, B w, B x) {
|
||||||
if (isAtm(w)&isAtm(x)) {
|
if (isAtm(w)&isAtm(x)) return m_vec2(w, x);
|
||||||
if (LIKELY(isNum(w)&isNum(x))) {
|
|
||||||
i32 wi=w.f; i32 xi=x.f;
|
|
||||||
if (RARE(wi!=w.f | xi!=x.f)) { f64* rp; B r = m_f64arrv(&rp, 2); rp[0]=o2fu(w); rp[1]=o2fu(x); return r; }
|
|
||||||
else if (wi==(i8 )wi & xi==(i8 )xi) { i8* rp; B r = m_i8arrv (&rp, 2); rp[0]=o2iu(w); rp[1]=o2iu(x); return r; }
|
|
||||||
else if (wi==(i16)wi & xi==(i16)xi) { i16* rp; B r = m_i16arrv(&rp, 2); rp[0]=o2iu(w); rp[1]=o2iu(x); return r; }
|
|
||||||
else { i32* rp; B r = m_i32arrv(&rp, 2); rp[0]=o2iu(w); rp[1]=o2iu(x); return r; }
|
|
||||||
}
|
|
||||||
if (isC32(x)&isC32(w)) { u32* rp; B r = m_c32arrv(&rp, 2); rp[0]=o2cu(w); rp[1]=o2cu(x); return r; }
|
|
||||||
}
|
|
||||||
if (isAtm(w)) w = m_atomUnit(w);
|
if (isAtm(w)) w = m_atomUnit(w);
|
||||||
if (isAtm(x)) x = m_atomUnit(x);
|
if (isAtm(x)) x = m_atomUnit(x);
|
||||||
if (!eqShape(w, x)) thrF("≍: 𝕨 and 𝕩 must have equal shapes (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", w, x);
|
if (!eqShape(w, x)) thrF("≍: 𝕨 and 𝕩 must have equal shapes (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", w, x);
|
||||||
|
|||||||
@ -91,6 +91,8 @@ static B m_v1(B a ); // consumes all
|
|||||||
static B m_v2(B a, B b ); // consumes all
|
static B m_v2(B a, B b ); // consumes all
|
||||||
static B m_v3(B a, B b, B c ); // consumes all
|
static B m_v3(B a, B b, B c ); // consumes all
|
||||||
static B m_v4(B a, B b, B c, B d); // consumes all
|
static B m_v4(B a, B b, B c, B d); // consumes all
|
||||||
|
B m_vec1(B a);
|
||||||
|
B m_vec2(B a, B b);
|
||||||
|
|
||||||
// random stuff
|
// random stuff
|
||||||
|
|
||||||
|
|||||||
@ -78,13 +78,16 @@ INS B i_FN2Oi(B w, B x, BB2B fm, BBB2B fd, u32* bc) { POS_UPD;
|
|||||||
INS B i_ARR_0() { // TODO combine with ADDI
|
INS B i_ARR_0() { // TODO combine with ADDI
|
||||||
return emptyHVec();
|
return emptyHVec();
|
||||||
}
|
}
|
||||||
|
INS B i_ARR_2(B e1, B e0) {
|
||||||
|
return m_vec2(e0,e1);
|
||||||
|
}
|
||||||
INS B i_ARR_p(B el0, i64 sz, B* cStack) { assert(sz>0);
|
INS B i_ARR_p(B el0, i64 sz, B* cStack) { assert(sz>0);
|
||||||
HArr_p r = m_harrUv(sz); // can't use harrs as gStack isn't updated
|
HArr_p r = m_harrUv(sz); // can't use harrs as gStack isn't updated
|
||||||
bool allNum = isNum(el0);
|
bool allNum = isNum(el0);
|
||||||
r.a[sz-1] = el0;
|
r.a[sz-1] = el0;
|
||||||
for (i64 i = 1; i < sz; i++) if (!isNum(r.a[sz-i-1] = GSP)) allNum = false;
|
for (i64 i = 1; i < sz; i++) if (!isNum(r.a[sz-i-1] = GSP)) allNum = false;
|
||||||
GS_UPD;
|
GS_UPD;
|
||||||
if (allNum) return withFill(r.b, m_f64(0));
|
if (allNum) return num_squeeze(r.b);
|
||||||
return r.b;
|
return r.b;
|
||||||
}
|
}
|
||||||
INS B i_DFND_0(u32* bc, Scope* sc, Block* bl) { POS_UPD; return m_funBlock(bl, sc); }
|
INS B i_DFND_0(u32* bc, Scope* sc, Block* bl) { POS_UPD; return m_funBlock(bl, sc); }
|
||||||
@ -536,6 +539,7 @@ Nvm_res m_nvm(Body* body) {
|
|||||||
#define POS_UPD(R1,R2) MOV4moi(r_ENV, offsetof(Env,pos), body->bl->map[bcpos]<<1 | 1);
|
#define POS_UPD(R1,R2) MOV4moi(r_ENV, offsetof(Env,pos), body->bl->map[bcpos]<<1 | 1);
|
||||||
#define GS_SET(R) MOV8pr(&gStack, R)
|
#define GS_SET(R) MOV8pr(&gStack, R)
|
||||||
#define GET(R,P,U) { i32 p = SPOSq(-(P)); if (U && lGPos!=p) { Reg t=LEA0(R,r_CS,p,0); GS_SET(t); lGPos=p; if(U!=2) MOV8rm(R,t); } else { MOV8rmo(R, r_CS, p); } }
|
#define GET(R,P,U) { i32 p = SPOSq(-(P)); if (U && lGPos!=p) { Reg t=LEA0(R,r_CS,p,0); GS_SET(t); lGPos=p; if(U!=2) MOV8rm(R,t); } else { MOV8rmo(R, r_CS, p); } }
|
||||||
|
// use GET(R_A1,0,2); as GS_UPD when there's only one argument, and GET(R_A3,-1,2); when there are zero arguments (i think?)
|
||||||
#define NORES(D) if (depth>D) MOV8rm(R_RES, SPOS(R_A3, -D, 0)); // call at end if rax is unset; arg is removed stack item count
|
#define NORES(D) if (depth>D) MOV8rm(R_RES, SPOS(R_A3, -D, 0)); // call at end if rax is unset; arg is removed stack item count
|
||||||
switch (*bc++) {
|
switch (*bc++) {
|
||||||
case POPS: TOPp;
|
case POPS: TOPp;
|
||||||
@ -551,12 +555,14 @@ Nvm_res m_nvm(Body* body) {
|
|||||||
case FN2O: TOPp; GET(R_A1,1,0); GET(R_A2,2,1); IMM(R_A3,off); CCALL(i_FN2O); break; // (B w, B f, B x, u32* bc)
|
case FN2O: TOPp; GET(R_A1,1,0); GET(R_A2,2,1); IMM(R_A3,off); CCALL(i_FN2O); break; // (B w, B f, B x, u32* bc)
|
||||||
case FN1Ci: { u64 fn = L64; POS_UPD(R_A0,R_A3); MOV(R_A1, R_RES); GET(R_A2,0,2); CCALL(fn); } break;
|
case FN1Ci: { u64 fn = L64; POS_UPD(R_A0,R_A3); MOV(R_A1, R_RES); GET(R_A2,0,2); CCALL(fn); } break;
|
||||||
case FN2Ci: { u64 fn = L64; POS_UPD(R_A0,R_A3); MOV(R_A1, R_RES); GET(R_A2,1,1); CCALL(fn); } break;
|
case FN2Ci: { u64 fn = L64; POS_UPD(R_A0,R_A3); MOV(R_A1, R_RES); GET(R_A2,1,1); CCALL(fn); } break;
|
||||||
case FN1Oi:TOPp; GET(R_A1,0,2); IMM(R_A1,L64); IMM(R_A2,off); CCALL(i_FN1Oi); break; // ( B x, BB2B fm, u32* bc)
|
case FN1Oi:TOPp; GET(R_A1,0,2); IMM(R_A1,L64); IMM(R_A2,off); CCALL(i_FN1Oi); break; // ( B x, BB2B fm, u32* bc)
|
||||||
case FN2Oi:TOPp; GET(R_A1,1,1); IMM(R_A2,L64); IMM(R_A3, L64); IMM(R_A4,off); CCALL(i_FN2Oi); break; // (B w, B x, BB2B fm, BBB2B fd, u32* bc)
|
case FN2Oi:TOPp; GET(R_A1,1,1); IMM(R_A2,L64); IMM(R_A3, L64); IMM(R_A4,off); CCALL(i_FN2Oi); break; // (B w, B x, BB2B fm, BBB2B fd, u32* bc)
|
||||||
case ARRM: case ARRO:;
|
case ARRM: case ARRO:; bool o = *(bc-1) == ARRO;
|
||||||
u32 sz = *bc++;
|
u32 sz = *bc++;
|
||||||
if (sz) { TOPp; IMM(R_A1, sz); lGPos=SPOSq(1-sz); INV(2,0,i_ARR_p); } // (B, i64 sz, S)
|
if (sz==0 ) { TOPs; CCALL(i_ARR_0); } // unused with optimizations
|
||||||
else { TOPs; CCALL(i_ARR_0); } // unused with optimizations
|
else if (sz==1 && o) { TOPp; GET(R_A3,0,2); CCALL(m_vec1); } // (B a)
|
||||||
|
else if (sz==2 && o) { TOPp; GET(R_A1,1,1); CCALL(i_ARR_2); } // (B a, B b)
|
||||||
|
else { TOPp; IMM(R_A1, sz); lGPos=SPOSq(1-sz); INV(2,0,i_ARR_p); } // (B a, i64 sz, S)
|
||||||
break;
|
break;
|
||||||
case DFND0: case DFND1: case DFND2: TOPs; // (u32* bc, Scope* sc, Block* bl)
|
case DFND0: case DFND1: case DFND2: TOPs; // (u32* bc, Scope* sc, Block* bl)
|
||||||
Block* bl = (Block*)L64;
|
Block* bl = (Block*)L64;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user