less bad way of doing JIT jumps
This commit is contained in:
parent
ef230f8dc0
commit
044431bb7d
@ -580,9 +580,9 @@ Nvm_res m_nvm(Body* body) {
|
||||
#define LSC(R,D) { if(D) MOV8rmo(R,R_SP,VAR8(pscs,D)); else MOV(R,r_SC); } // TODO return r_SC directly without a pointless mov
|
||||
#define INCV(R) INC4mo(R, offsetof(Value,refc)); // ADD4mi(R_A3, 1); CCALL(i_INC);
|
||||
#ifdef __BMI2__ // TODO move to runtime detection maybe
|
||||
#define INCB(R,T,U) IMM(T,0xfffffffffffffull);ADD(T,R);IMM(U,0x7fffffffffffeull);CMP(T,U);{JA(lI);MOVi1l(U,0x30);BZHI(U,R,U);INCV(U);LBL1(lI);}
|
||||
#define INCB(R,T,U) IMM(T,0xfffffffffffffull);ADD(T,R);IMM(U,0x7fffffffffffeull);CMP(T,U);{J1(cA,lI);MOVi1l(U,0x30);BZHI(U,R,U);INCV(U);LBL1(lI);}
|
||||
#else
|
||||
#define INCB(R,T,U) IMM(T,0xfffffffffffffull);ADD(T,R);IMM(U,0x7fffffffffffeull);CMP(T,U);{JA(lI);IMM(U,0xffffffffffffull);AND(U,R);INCV(U);LBL1(lI);}
|
||||
#define INCB(R,T,U) IMM(T,0xfffffffffffffull);ADD(T,R);IMM(U,0x7fffffffffffeull);CMP(T,U);{J1(cA,lI);IMM(U,0xffffffffffffull);AND(U,R);INCV(U);LBL1(lI);}
|
||||
#endif
|
||||
// #define POS_UPD(R1,R2) IMM(R1, off); MOV8mro(r_ENV, R1, offsetof(Env,pos));
|
||||
#define POS_UPD(R1,R2) MOV4moi(r_ENV, offsetof(Env,pos), body->bl->map[bcpos + bodyOff]<<1 | 1);
|
||||
@ -631,7 +631,7 @@ Nvm_res m_nvm(Body* body) {
|
||||
case VARO: TOPs; { u64 d=*bc++; u64 p=*bc++; LSC(R_A1,d);
|
||||
MOV8rmo(R_RES,R_A1,p*8+offsetof(Scope,vars)); // read variable
|
||||
INCB(R_RES,R_A2,R_A3); // increment refcount if one's needed
|
||||
if (d) { IMM(R_A2, bi_noVar.u); CMP(R_A2,R_RES); JNE(lN); IMM(R_A0,off); INV(1,1,i_NOVAR); LBL1(lN); } // check for error
|
||||
if (d) { IMM(R_A2, bi_noVar.u); CMP(R_A2,R_RES); J1(cNE,lN); IMM(R_A0,off); INV(1,1,i_NOVAR); LBL1(lN); } // check for error
|
||||
} break;
|
||||
case VARU: TOPs; { u64 d=*bc++; u64 p=*bc++;
|
||||
LSC(R_A1,d); MOV8rmo(R_RES,R_A1,p*8+offsetof(Scope,vars)); // read variable
|
||||
@ -642,17 +642,17 @@ Nvm_res m_nvm(Body* body) {
|
||||
case EXTU: TOPs; { u64 d=*bc++; IMM(R_A0,*bc++); LSC(R_A1,d); CCALL(i_EXTU); } break; // (u32 p, Scope* sc)
|
||||
case SETHi:TOPp; { u64 v1=L64; u64 v2=L64; if (lGPos!=0) GS_SET(r_CS); lGPos=0;
|
||||
GET(R_A1,1,1); LEAi(R_A2,R_SP,VAR(pscs,0)); IMM(R_A3,off); IMM(R_A4,v1); IMM(R_A5,v2); CCALL(i_SETH); // (B s, B x, Scope** pscs, u32* bc, Body* v1, Body* v2)
|
||||
IMM(R_A0, bi_okHdr.u); CMP(R_A0,R_RES); JNE4(l); TSADD(retLbls, l);
|
||||
IMM(R_A0, bi_okHdr.u); CMP(R_A0,R_RES); J4(cNE,l); TSADD(retLbls, l);
|
||||
break;
|
||||
}
|
||||
case PRED1:TOPp; { u64 v1=L64;
|
||||
GET(R_A1,0,2); MOV(R_A1,r_SC); IMM(R_A2,off); IMM(R_A3,v1); CCALL(i_PRED1); // (B x, Scope** pscs, u32* bc, Body* v)
|
||||
IMM(R_A0, bi_okHdr.u); CMP(R_A0,R_RES); JNE4(l); TSADD(retLbls, l); NORES(1);
|
||||
IMM(R_A0, bi_okHdr.u); CMP(R_A0,R_RES); J4(cNE,l); TSADD(retLbls, l); NORES(1);
|
||||
break;
|
||||
}
|
||||
case PRED2:TOPp; { u64 v1=L64; u64 v2=L64;
|
||||
GET(R_A1,0,2); MOV(R_A1,r_SC); IMM(R_A2,off); IMM(R_A3,v1); IMM(R_A4,v2); CCALL(i_PRED2); // (B x, Scope** pscs, u32* bc, Body* v1, Body* v2)
|
||||
IMM(R_A0, bi_okHdr.u); CMP(R_A0,R_RES); JNE4(l); TSADD(retLbls, l); NORES(1);
|
||||
IMM(R_A0, bi_okHdr.u); CMP(R_A0,R_RES); J4(cNE,l); TSADD(retLbls, l); NORES(1);
|
||||
break;
|
||||
}
|
||||
case SETN: TOPp; GET(R_A1,1,1); LEAi(R_A2,R_SP,VAR(pscs,0)); IMM(R_A3,off); CCALL(i_SETN); break; // (B s, B x, Scope** pscs, u32* bc)
|
||||
|
||||
@ -423,39 +423,17 @@ static inline void asm_a(TStack* o, u64 len, u8 v[]) {
|
||||
#define CALLi(POS) {AC1(CALLi,(u64)(POS)); TSADD(b_r, ASM_SIZE-4);} // POS must be 32-bit
|
||||
#define RET() {b_o=asm_r(b_o); ASM1(0xC3);}
|
||||
|
||||
#define JO(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x70);ASM1(-2);} // -2 comes from the instruction being 2 bytes long and L being defined at the start
|
||||
#define JNO(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x71);ASM1(-2);}
|
||||
#define JB(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x72);ASM1(-2);}
|
||||
#define JAE(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x73);ASM1(-2);}
|
||||
#define JE(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x74);ASM1(-2);}
|
||||
#define JNE(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x75);ASM1(-2);}
|
||||
#define JBE(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x76);ASM1(-2);}
|
||||
#define JA(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x77);ASM1(-2);}
|
||||
#define JS(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x78);ASM1(-2);}
|
||||
#define JNS(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x79);ASM1(-2);}
|
||||
#define JP(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x7A);ASM1(-2);}
|
||||
#define JNP(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x7B);ASM1(-2);}
|
||||
#define JL(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x7C);ASM1(-2);}
|
||||
#define JGE(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x7D);ASM1(-2);}
|
||||
#define JLE(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x7E);ASM1(-2);}
|
||||
#define JG(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x7F);ASM1(-2);}
|
||||
#define LBL1(L) { i64 t=(i8)b_o->data[L+1] + ASM_SIZE-(i64)L; if(t!=(i8)t) err("x86-64 codegen: jump too long!"); b_o->data[L+1] = t; }
|
||||
#define JO4(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x0f);ASM1(0x80);ASM4(-6);}
|
||||
#define JNO4(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x0f);ASM1(0x81);ASM4(-6);}
|
||||
#define JB4(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x0f);ASM1(0x82);ASM4(-6);}
|
||||
#define JAE4(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x0f);ASM1(0x83);ASM4(-6);}
|
||||
#define JE4(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x0f);ASM1(0x84);ASM4(-6);}
|
||||
#define JNE4(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x0f);ASM1(0x85);ASM4(-6);}
|
||||
#define JBE4(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x0f);ASM1(0x86);ASM4(-6);}
|
||||
#define JA4(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x0f);ASM1(0x87);ASM4(-6);}
|
||||
#define JS4(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x0f);ASM1(0x88);ASM4(-6);}
|
||||
#define JNS4(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x0f);ASM1(0x89);ASM4(-6);}
|
||||
#define JP4(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x0f);ASM1(0x8A);ASM4(-6);}
|
||||
#define JNP4(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x0f);ASM1(0x8B);ASM4(-6);}
|
||||
#define JL4(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x0f);ASM1(0x8C);ASM4(-6);}
|
||||
#define JGE4(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x0f);ASM1(0x8D);ASM4(-6);}
|
||||
#define JLE4(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x0f);ASM1(0x8E);ASM4(-6);}
|
||||
#define JG4(L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x0f);ASM1(0x8F);ASM4(-6);}
|
||||
static const u8 cO = 0x0; static const u8 cNO = 0x1;
|
||||
static const u8 cB = 0x2; static const u8 cAE = 0x3;
|
||||
static const u8 cE = 0x4; static const u8 cNE = 0x5;
|
||||
static const u8 cBE = 0x6; static const u8 cA = 0x7;
|
||||
static const u8 cS = 0x8; static const u8 cNS = 0x9;
|
||||
static const u8 cP = 0xA; static const u8 cNP = 0xB;
|
||||
static const u8 cL = 0xC; static const u8 cGE = 0xD;
|
||||
static const u8 cLE = 0xE; static const u8 cG = 0xF;
|
||||
#define J1(T, L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1((i8)(0x70+(T)));ASM1(-2);} // -2 comes from the instruction being 2 bytes long and L being defined at the start
|
||||
#define J4(T, L) u64 L=ASM_SIZE; {b_o=asm_r(b_o); ASM1(0x0f);ASM1((i8)(0x80+(T)));ASM4(-6);}
|
||||
#define LBL1(L) { i64 t= (i8)b_o->data[L+1] + ASM_SIZE-(i64)L; if(t!=(i8 )t) err("x86-64 codegen: jump too long!"); b_o->data[L+1] = t; }
|
||||
#define LBL4(L) { i64 t=asm_r4(b_o->data+(L+2)) + ASM_SIZE-(i64)L; if(t!=(i32)t) err("x86-64 codegen: jump too long!"); asm_w4(b_o->data+(L+2), t); }
|
||||
|
||||
ASMI(ADD, Reg o, Reg i) { nREX8(o,i); ASM1(0x01); nA_REG(o,i); }
|
||||
|
||||
Loading…
Reference in New Issue
Block a user