From 774db7a9561746d0219d1740e77c93e3c5129d54 Mon Sep 17 00:00:00 2001 From: dzaima Date: Sun, 4 Jul 2021 02:13:52 +0300 Subject: [PATCH] tagged bytecode position --- src/jit/nvm_x86_64.c | 11 +++++++---- src/jit/x86_64.h | 2 ++ src/vm.c | 8 ++++---- src/vm.h | 4 ++-- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/jit/nvm_x86_64.c b/src/jit/nvm_x86_64.c index 2be64f79..ea0c2076 100644 --- a/src/jit/nvm_x86_64.c +++ b/src/jit/nvm_x86_64.c @@ -38,7 +38,7 @@ static void* mmX_allocN(usz sz, u8 type) { assert(sz>=16); return mmX_allocL(BSZ #define GS_UPD { gStack=cStack; } #define P(N) B N=GSP; #if VM_POS - #define POS_UPD envCurr->bcL = bc; + #define POS_UPD envCurr->pos = (u64)bc; #else #define POS_UPD #endif @@ -402,7 +402,8 @@ static u32 readBytes4(u8* d) { static void write_asm(u8* p, u64 sz); static void asm_test() { ALLOC_ASM(64); - for (int i = 0; i < 16; i++) CALLi(123); + for (int i = 0; i < 16; i++) MOV4moi(i, 0, 0xaaaaaaaa); + for (int i = 0; i < 16; i++) MOV4moi(i, 400, 0xaaaaaaaa); GET_ASM(); write_asm(bin, ASM_SIZE); exit(0); @@ -492,7 +493,8 @@ Nvm_res m_nvm(Body* body) { while (true) { u32* s = bc; u32* n = nextBC(bc); - u32* off = origBC + optRes.offset[s-optRes.bc]; + u32 bcpos = optRes.offset[s-optRes.bc]; + u32* off = origBC + bcpos; bool ret = false; #define L64 ({ u64 r = bc[0] | ((u64)bc[1])<<32; bc+= 2; r; }) // #define LEA0(O,I,OFF) { MOV(O,I); ADDI(O,OFF); } @@ -509,7 +511,8 @@ Nvm_res m_nvm(Body* body) { #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);} #endif - #define POS_UPD(R1,R2) IMM(R1, off); MOV8mro(r_ENV, R1, offsetof(Env,bcL)); + // #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->map[bcpos]<<1 | 1); #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 diff --git a/src/jit/x86_64.h b/src/jit/x86_64.h index a0ffe4a9..aa820e72 100644 --- a/src/jit/x86_64.h +++ b/src/jit/x86_64.h @@ -391,6 +391,7 @@ static inline void asm_a(TStack* o, u64 len, u8 v[]) { #define SHRi(O,IMM) AC2(SHRi,O,IMM) #define MOVi(O,IMM) AC2(MOVi,O,IMM) #define MOVi1l(O,IMM) AC2(MOVi1l,O,IMM) +#define MOV4moi(I,OFF,IMM) AC3(MOV4moi,I,OFF,IMM) #define ADD4mi(O,IMM) AC2(ADD4mi,O,IMM) // ADD4mi(o,1) is an alternative for INC4mo(o,0) #define MOV8rm(O,I) AC2(MOV8rm,O,I) // O ← *(u64*)(nullptr + I) @@ -458,6 +459,7 @@ ASMI(MOVi, Reg o, i64 i) { else { nREX8(o,0); ASM1(0xB8+(o&7)); ASM8(i); } } ASMI(MOVi1l, Reg o, i8 imm) { if (o>=4) ASM1(o>=8?0x41:0x40); ASM1(0xb0+(o&7)); ASM1(imm); } +ASMI(MOV4moi, Reg o, i32 off, i32 imm) { nREX4(o,0); ASM1(0xc7); MRMo(o,0,off); ASM4(imm); } ASMI(MOV8mr, Reg o, Reg i) { nREX8(o,i); ASM1(0x89); MRM(o,i); } ASMI(MOV8mro, Reg o, Reg i, i32 off) { nREX8(o,i); ASM1(0x89); MRMo(o,i, off); } ASMI(MOV8rm, Reg i, Reg o) { nREX8(o,i); ASM1(0x8B); MRM(o,i); } ASMI(MOV8rmo, Reg i, Reg o, i32 off) { nREX8(o,i); ASM1(0x8B); MRMo(o,i, off); } ASMI(MOV4mr, Reg o, Reg i) { nREX4(o,i); ASM1(0x89); MRM(o,i); } ASMI(MOV4mro, Reg o, Reg i, i32 off) { nREX4(o,i); ASM1(0x89); MRMo(o,i, off); } diff --git a/src/vm.c b/src/vm.c index f4cc8fa3..c60873c0 100644 --- a/src/vm.c +++ b/src/vm.c @@ -370,7 +370,7 @@ i32 bcDepth=-2; i32* vmStack; i32 bcCtr = 0; #endif -#define BCPOS(B,P) (B->map[P-B->bc]) +#define BCPOS(B,P) (B->map[(P)-B->bc]) B evalBC(Body* b, Scope* sc) { // doesn't consume #ifdef DEBUG_VM bcDepth+= 2; @@ -405,7 +405,7 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume #endif #define L64 ({ u64 r = bc[0] | ((u64)bc[1])<<32; bc+= 2; r; }) #if VM_POS - #define POS_UPD envCurr->bcL = bc-1; + #define POS_UPD envCurr->pos = (u64)(bc-1); #else #define POS_UPD #endif @@ -900,7 +900,7 @@ NOINLINE void vm_pst(Env* s, Env* e) { // e not included i = 10; } Comp* comp = c->sc->body->comp; - i32 bcPos = c>=envStart && c<=envCurr? BCPOS(c->sc->body, c->bcL) : c->bcV; + i32 bcPos = c->pos&1? ((u32)c->pos)>>1 : BCPOS(c->sc->body, (u32*)c->pos); vm_printPos(comp, bcPos, i); i--; } @@ -912,7 +912,7 @@ NOINLINE void vm_pstLive() { void unwindEnv(Env* envNew) { assert(envNew<=envCurr); while (envCurr!=envNew) { - envCurr->bcV = BCPOS(envCurr->sc->body, envCurr->bcL); + if ((envCurr->pos&1) == 0) envCurr->pos = (BCPOS(envCurr->sc->body, (u32*)envCurr->pos)<<1) | 1; envCurr--; } } diff --git a/src/vm.h b/src/vm.h index 27ccf9de..c4885303 100644 --- a/src/vm.h +++ b/src/vm.h @@ -149,7 +149,7 @@ B m_md2Block(Block* bl, Scope* psc); typedef struct Env { - union { u32* bcL; i32 bcV; }; + u64 pos; // if top bit set, ((u32)pos)>>1 is an offset into bytecode; otherwise, it's a pointer in the bytecode Scope* sc; } Env; extern Env* envCurr; @@ -160,7 +160,7 @@ static inline void pushEnv(Scope* sc, u32* bc) { if (envCurr+1==envEnd) thrM("Stack overflow"); envCurr++; envCurr->sc = sc; - envCurr->bcL = bc; + envCurr->pos = (u64)bc; } static inline void popEnv() { assert(envCurr>=envStart);