merged SET_i+POPS
This commit is contained in:
parent
9ee36dae94
commit
72896feb8f
@ -127,12 +127,10 @@ INS B i_SETM(B s, B f, B x, Scope** pscs, u32* bc) { POS_UPD;
|
||||
}
|
||||
INS B i_SETNi( B x, Scope* sc, u32 p, u32* bc) { POS_UPD; v_setI(sc, p, inc(x), false); return x; }
|
||||
INS B i_SETUi( B x, Scope* sc, u32 p, u32* bc) { POS_UPD; v_setI(sc, p, inc(x), true ); return x; }
|
||||
INS B i_SETMi(B f, B x, Scope* sc, u32 p, u32* bc) { POS_UPD;
|
||||
B w = v_getI(sc, p);
|
||||
B r = c2(f,w,x); dec(f);
|
||||
v_setI(sc, p, inc(r), true);
|
||||
return r;
|
||||
}
|
||||
INS B i_SETMi(B f, B x, Scope* sc, u32 p, u32* bc) { POS_UPD; B r = c2(f,v_getI(sc, p),x); dec(f); v_setI(sc, p, inc(r), true); return r; }
|
||||
INS void i_SETNv(B x, Scope* sc, u32 p, u32* bc) { POS_UPD; v_setI(sc, p, x, false); }
|
||||
INS void i_SETUv(B x, Scope* sc, u32 p, u32* bc) { POS_UPD; v_setI(sc, p, x, true ); }
|
||||
INS void i_SETMv(B f, B x, Scope* sc, u32 p, u32* bc) { POS_UPD; B r = c2(f,v_getI(sc, p),x); dec(f); v_setI(sc, p, r, true); }
|
||||
INS B i_FLDO(B ns, u32 p, Scope* sc) {
|
||||
if (!isNsp(ns)) thrM("Trying to read a field from non-namespace");
|
||||
B r = inc(ns_getU(ns, sc->body->nsDesc->nameList, p));
|
||||
@ -194,19 +192,27 @@ typedef struct SRef { B v; i32 p; } SRef;
|
||||
typedef struct OptRes { u32* bc; u32* offset; B refs; } OptRes;
|
||||
static OptRes opt(u32* bc0) {
|
||||
TSALLOC(SRef, stk, 8);
|
||||
TSALLOC(u8, actions, 64); // 1 per instruction; 0: nothing; 1: indicates return; 2: immediate SET; 3: immediate FN1_/FN2C; 4: FN2O; 5: replace with PUSH; 6: decrement 1 data; 10+N: ignore N data
|
||||
TSALLOC(u8, actions, 64); // 1 per instruction; 0: nothing; 1: indicates return; 2: immediate SET; 3: immediate FN1_/FN2C; 4: FN2O; 5: replace with PUSH; 6: decrement 1 data; 7: SET_i+POPS merge; 10+N: ignore N data
|
||||
TSALLOC(u64, data, 64); // variable length; whatever things are needed for the specific action
|
||||
u8 rm_map[] = {10,10,10,11,12,6,6,99,99,99,11,12,13,14,15,16,17,18,19};
|
||||
u8 rm_map[] = {10,10,10,11,12,6,6,11,99,99,11,12,13,14,15,16,17,18,19};
|
||||
#define RM(N) actions[N] = rm_map[actions[N]]
|
||||
u32* bc = bc0; usz pos = 0;
|
||||
while (true) {
|
||||
u32* sbc = bc;
|
||||
#define L64 ({ u64 r = bc[0] | ((u64)bc[1])<<32; bc+= 2; r; })
|
||||
bool ret = false;
|
||||
u8 cact = 0;
|
||||
#define L64 ({ u64 r = bc[0] | ((u64)bc[1])<<32; bc+= 2; r; })
|
||||
#define S(N,I) SRef N = stk[TSSIZE(stk)-1-(I)];
|
||||
switch (*bc++) { case FN1Ci: case FN1Oi: case FN2Ci: case FN2Oi: thrM("JIT optimization: didn't already expect immediate FN__");
|
||||
switch (*bc++) { case FN1Ci: case FN1Oi: case FN2Ci: case FN2Oi: thrM("optimization: didn't expect already immediate FN__");
|
||||
case ADDU: case ADDI: cact = 0; TSADD(stk,SREF(b(L64), pos)); break;
|
||||
case POPS: { assert(TSSIZE(actions) > 0);
|
||||
u64 asz = TSSIZE(actions);
|
||||
if (actions[asz-1]!=2) goto defIns;
|
||||
actions[asz-1] = 7;
|
||||
cact = 10;
|
||||
TSSIZE(stk)--;
|
||||
break;
|
||||
}
|
||||
case LOCM: { u32 d = *bc++; u32 p = *bc++;
|
||||
TSADD(stk,SREF(tag((u64)d<<32 | (u32)p, VAR_TAG), pos));
|
||||
break;
|
||||
@ -303,13 +309,13 @@ static OptRes opt(u32* bc0) {
|
||||
for (i32 i = 0; i < added; i++) TSADD(stk, SREF(bi_optOut, -1))
|
||||
}
|
||||
#undef S
|
||||
TSADD(actions, cact);
|
||||
#undef L64
|
||||
#undef RM
|
||||
TSADD(actions, cact);
|
||||
if (ret) break;
|
||||
bc = nextBC(sbc);
|
||||
pos++;
|
||||
}
|
||||
#undef RM
|
||||
TSFREE(stk);
|
||||
|
||||
TSALLOC(u32, rbc, TSSIZE(actions));
|
||||
@ -327,12 +333,20 @@ static OptRes opt(u32* bc0) {
|
||||
u64 psz = TSSIZE(rbc);
|
||||
#define A64(X) { u64 a64=(X); TSADD(rbc, (u32)a64); TSADD(rbc, a64>>32); }
|
||||
switch (ctype) { default: UD;
|
||||
case 2: assert(v==SETN|v==SETU|v==SETM);
|
||||
case 2: { assert(v==SETN|v==SETU|v==SETM);
|
||||
TSADD(rbc, v==SETN? SETNi : v==SETU? SETUi : SETMi);
|
||||
u64 d = data[dpos++];
|
||||
TSADD(rbc, (u16)(d>>32));
|
||||
TSADD(rbc, (u32)d);
|
||||
break;
|
||||
}
|
||||
case 7: { assert(v==SETN|v==SETU|v==SETM);
|
||||
TSADD(rbc, v==SETN? SETNv : v==SETU? SETUv : SETMv);
|
||||
u64 d = data[dpos++];
|
||||
TSADD(rbc, (u16)(d>>32));
|
||||
TSADD(rbc, (u32)d);
|
||||
break;
|
||||
}
|
||||
case 3: assert(v==FN1C|v==FN1O|v==FN2C);
|
||||
TSADD(rbc, v==FN1C? FN1Ci : v==FN1O? FN1Oi : FN2Ci);
|
||||
A64(data[dpos++]);
|
||||
@ -479,10 +493,12 @@ Nvm_res m_nvm(Body* body) {
|
||||
#define POS_UPD(R1,R2) IMM(R1, off); MOV8mro(r_ENV, R1, offsetof(Env,bcL));
|
||||
#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 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++) {
|
||||
case POPS: TOPp;
|
||||
CCALL(i_POPS);
|
||||
if (depth>1) { u8 t = SPOS(R_A3, -1, 0); MOV8rm(R_RES, t); }
|
||||
// if (depth>1) MOV8rm(R_RES, SPOS(R_A3, -1, 0));
|
||||
NORES(1);
|
||||
break;
|
||||
case ADDI: TOPs; { u64 x = L64; IMM(R_RES, x); IMM(R_A3, v(b(x))); INCV(R_A3); break; } // (u64 v, S)
|
||||
case ADDU: TOPs; IMM(R_RES, L64);
|
||||
@ -527,15 +543,18 @@ Nvm_res m_nvm(Body* body) {
|
||||
case SETU: TOPp; GET(R_A1,1,1); LEAi(R_A2,R_SP,VAR(pscs,0)); IMM(R_A3,off); CCALL(i_SETU); break; // (B s, B x, Scope** pscs, u32* bc)
|
||||
case SETM: TOPp; GET(R_A1,1,1) GET(R_A2,2,1); LEAi(R_A3,R_SP,VAR(pscs,0)); IMM(R_A4,off); CCALL(i_SETM); break; // (B s, B f, B x, Scope** pscs, u32* bc)
|
||||
// TODO SETNi doesn't really need to update gStack
|
||||
case SETNi:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,0,2); LSC(R_A1,d); IMM(R_A2,p); IMM(R_A3,off); CCALL(i_SETNi); break; } // ( B x, Scope* sc, u32 p, u32* bc)
|
||||
case SETUi:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,0,2); LSC(R_A1,d); IMM(R_A2,p); IMM(R_A3,off); CCALL(i_SETUi); break; } // ( B x, Scope* sc, u32 p, u32* bc)
|
||||
case SETMi:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,1,1); LSC(R_A2,d); IMM(R_A3,p); IMM(R_A4,off); CCALL(i_SETMi); break; } // (B f, B x, Scope* sc, u32 p, u32* bc)
|
||||
case SETNi:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,0,2); LSC(R_A1,d); IMM(R_A2,p); IMM(R_A3,off); CCALL(i_SETNi); break; } // ( B x, Scope* sc, u32 p, u32* bc)
|
||||
case SETUi:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,0,2); LSC(R_A1,d); IMM(R_A2,p); IMM(R_A3,off); CCALL(i_SETUi); break; } // ( B x, Scope* sc, u32 p, u32* bc)
|
||||
case SETMi:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,1,1); LSC(R_A2,d); IMM(R_A3,p); IMM(R_A4,off); CCALL(i_SETMi); break; } // (B f, B x, Scope* sc, u32 p, u32* bc)
|
||||
case SETNv:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,0,2); LSC(R_A1,d); IMM(R_A2,p); IMM(R_A3,off); CCALL(i_SETNv); NORES(1); break; } // ( B x, Scope* sc, u32 p, u32* bc)
|
||||
case SETUv:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,0,2); LSC(R_A1,d); IMM(R_A2,p); IMM(R_A3,off); CCALL(i_SETUv); NORES(1); break; } // ( B x, Scope* sc, u32 p, u32* bc)
|
||||
case SETMv:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,1,1); LSC(R_A2,d); IMM(R_A3,p); IMM(R_A4,off); CCALL(i_SETMv); NORES(2); break; } // (B f, B x, Scope* sc, u32 p, u32* bc)
|
||||
case FLDO: TOPp; GET(R_A1,0,2); IMM(R_A1,*bc++); MOV(R_A2,r_SC); CCALL(i_FLDO); break; // (B, u32 p, Scope* sc)
|
||||
case NSPM: TOPp; IMM(R_A1,*bc++); CCALL(i_NSPM); break; // (B, u32 l)
|
||||
case CHKV: TOPp; IMM(R_A1,off); INV(2,0,i_CHKV); break; // (B, u32* bc, S)
|
||||
case RETD: GS_SET(r_CS); MOV(R_A0,r_SC); CCALL(i_RETD); ret=true; break; // (Scope* sc)
|
||||
case RETN: GS_SET(r_CS); ret=true; break;
|
||||
default: thrF("JIT: Unsupported bytecode %i", *s);
|
||||
default: thrF("JIT: Unsupported bytecode %i/%S", *s, nameBC(s));
|
||||
}
|
||||
#undef GET
|
||||
#undef GS_SET
|
||||
|
||||
25
src/vm.c
25
src/vm.c
@ -14,7 +14,8 @@
|
||||
#define FOR_BC(F) F(PUSH) F(VARO) F(VARM) F(ARRO) F(ARRM) F(FN1C) F(FN2C) F(OP1D) F(OP2D) F(TR2D) \
|
||||
F(TR3D) F(SETN) F(SETU) F(SETM) F(POPS) F(DFND) F(FN1O) F(FN2O) F(CHKV) F(TR3O) \
|
||||
F(OP2H) F(LOCO) F(LOCM) F(VFYM) F(SETH) F(RETN) F(FLDO) F(FLDM) F(NSPM) F(RETD) F(SYSV) F(LOCU) \
|
||||
F(EXTO) F(EXTM) F(EXTU) F(ADDI) F(ADDU) F(FN1Ci)F(FN1Oi)F(FN2Ci)F(FN2Oi)
|
||||
F(EXTO) F(EXTM) F(EXTU) F(ADDI) F(ADDU) F(FN1Ci)F(FN1Oi)F(FN2Ci)F(FN2Oi) \
|
||||
F(SETNi)F(SETUi)F(SETMi)F(SETNv)F(SETUv)F(SETMv)
|
||||
|
||||
u32* nextBC(u32* p) {
|
||||
switch(*p) {
|
||||
@ -31,7 +32,7 @@ u32* nextBC(u32* p) {
|
||||
case LOCO: case LOCM: case LOCU:
|
||||
case EXTO: case EXTM: case EXTU:
|
||||
case ADDI: case ADDU:
|
||||
case FN1Ci: case FN1Oi: case FN2Ci: case SETNi: case SETUi: case SETMi:
|
||||
case FN1Ci: case FN1Oi: case FN2Ci: case SETNi: case SETUi: case SETMi: case SETNv: case SETUv: case SETMv:
|
||||
return p+3;
|
||||
case FN2Oi:
|
||||
return p+5;
|
||||
@ -42,9 +43,13 @@ i32 stackDiff(u32* p) {
|
||||
if (*p==ARRO|*p==ARRM) return 1-p[1];
|
||||
switch(*p) { default: UD; // case ARRO: case ARRM: return 1-p[1];
|
||||
case PUSH: case VARO: case VARM: case DFND: case LOCO: case LOCM: case LOCU: case EXTO: case EXTM: case EXTU: case SYSV: case ADDI: case ADDU: return 1;
|
||||
case FN1Ci:case FN1Oi:case CHKV: case VFYM: case FLDO: case FLDM: case SETNi:case SETUi:case RETD: case NSPM: return 0;
|
||||
case FN2Ci:case FN2Oi:case FN1C: case FN1O: case OP1D: case TR2D: case SETN: case SETU: case SETMi:case POPS: case OP2H: case SETH: case RETN: return -1;
|
||||
case OP2D: case TR3D: case FN2C: case FN2O: case SETM: case TR3O: return -2;
|
||||
case FN1Ci:case FN1Oi:case CHKV: case VFYM: case FLDO: case FLDM: case RETD: case NSPM: return 0;
|
||||
case FN2Ci:case FN2Oi:case FN1C: case FN1O: case OP1D: case TR2D: case POPS: case OP2H: case SETH: case RETN: return -1;
|
||||
case OP2D: case TR3D: case FN2C: case FN2O: case TR3O: return -2;
|
||||
|
||||
case SETN: return -1; case SETNi:return 0; case SETNv:return -1;
|
||||
case SETU: return -1; case SETUi:return 0; case SETUv:return -1;
|
||||
case SETM: return -2; case SETMi:return -1; case SETMv:return -2;
|
||||
}
|
||||
}
|
||||
i32 stackConsumed(u32* p) {
|
||||
@ -52,9 +57,13 @@ i32 stackConsumed(u32* p) {
|
||||
switch(*p) { default: UD; // case ARRO: case ARRM: return -p[1];
|
||||
case PUSH: case VARO: case VARM: case DFND: case LOCO: case LOCM: case LOCU: case EXTO: case EXTM: case EXTU: case SYSV: case ADDI: case ADDU: return 0;
|
||||
case CHKV: case VFYM: case RETD: return 0;
|
||||
case FN1Ci:case FN1Oi:case FLDO: case FLDM: case NSPM: case RETN: case POPS: case SETNi:case SETUi:return 1;
|
||||
case FN2Ci:case FN2Oi:case FN1C: case FN1O: case SETMi:case OP1D: case TR2D: case SETN: case SETU: case OP2H: case SETH: return 2;
|
||||
case OP2D: case TR3D: case FN2C: case FN2O: case SETM: case TR3O: return 3;
|
||||
case FN1Ci:case FN1Oi:case FLDO: case FLDM: case NSPM: case RETN: case POPS: return 1;
|
||||
case FN2Ci:case FN2Oi:case FN1C: case FN1O: case OP1D: case TR2D: case OP2H: case SETH: return 2;
|
||||
case OP2D: case TR3D: case FN2C: case FN2O: case TR3O: return 3;
|
||||
|
||||
case SETN: return 2; case SETNi: case SETNv: return 1;
|
||||
case SETU: return 2; case SETUi: case SETUv: return 1;
|
||||
case SETM: return 3; case SETMi: case SETMv: return 2;
|
||||
}
|
||||
}
|
||||
i32 stackAdded(u32* p) {
|
||||
|
||||
1
src/vm.h
1
src/vm.h
@ -47,6 +47,7 @@ enum {
|
||||
ADDI, ADDU, // separate PUSH for refcounting needed/not needed (stores the object inline as 2 u32s, instead of reading from `objs`)
|
||||
FN1Ci, FN1Oi, FN2Ci, FN2Oi, // FN__ alternatives that don't take the function from the stack, but instead as an 2×u32 immediate in the bytecode
|
||||
SETNi, SETUi, SETMi, // SET_ alternatives that expect the set variable as a depth-position pair like LOC_
|
||||
SETNv, SETUv, SETMv, // SET_i alternatives that also don't return the result
|
||||
BC_SIZE
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user