diff options
Diffstat (limited to 'src/dynarec/arm64/dynarec_arm64_helper.h')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.h | 78 |
1 files changed, 57 insertions, 21 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index 84346f84..bcb9c8b3 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -80,6 +80,15 @@ LDx(x1, wback, fixedaddress); \ ed = x1; \ } +#define GETEDz(D) if(MODREG) { \ + ed = xRAX+(nextop&7)+(rex.b<<3); \ + wback = 0; \ + } else { \ + SMREAD(); \ + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, D); \ + LDz(x1, wback, fixedaddress); \ + ed = x1; \ + } #define GETEDw(D) if((nextop&0xC0)==0xC0) { \ ed = xEAX+(nextop&7)+(rex.b<<3); \ wback = 0; \ @@ -187,6 +196,16 @@ LDRx_REG(x1, wback, O); \ ed = x1; \ } +//GETEDOz can use r1 for ed, and r2 for wback. wback is 0 if ed is xEAX..xEDI +#define GETEDOz(O, D) if(MODREG) { \ + ed = xRAX+(nextop&7)+(rex.b<<3); \ + wback = 0; \ + } else { \ + SMREAD(); \ + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, D); \ + LDRz_REG(x1, wback, O); \ + ed = x1; \ + } #define GETSEDOw(O, D) if((nextop&0xC0)==0xC0) { \ ed = xRAX+(nextop&7)+(rex.b<<3); \ SXTWx(x1, ed); \ @@ -341,18 +360,18 @@ gb2 = 0; \ } else { \ gd = (nextop&0x38)>>3; \ - gb2 = ((gd&4)>>2); \ + gb2 = ((gd&4)<<1); \ gb1 = xRAX+(gd&3); \ } \ gd = i; \ - UBFXx(gd, gb1, gb2*8, 8); + UBFXx(gd, gb1, gb2, 8); //GETSGB signe extend GB, will use i for gd #define GETSGB(i) if(rex.rex) { \ gb1 = xRAX+((nextop&0x38)>>3)+(rex.r<<3); \ gb2 = 0; \ } else { \ gd = (nextop&0x38)>>3; \ - gb2 = ((gd&4)>>2); \ + gb2 = ((gd&4)<<1); \ gb1 = xRAX+(gd&3); \ } \ gd = i; \ @@ -455,17 +474,19 @@ // R0 will not be pushed/popd if ret is -2. Flags are not save/restored #define CALL_S(F, ret) call_c(dyn, ninst, F, x7, ret, 0, 0) -#define MARK dyn->insts[ninst].mark = dyn->native_size -#define GETMARK dyn->insts[ninst].mark -#define MARK2 dyn->insts[ninst].mark2 = dyn->native_size -#define GETMARK2 dyn->insts[ninst].mark2 -#define MARK3 dyn->insts[ninst].mark3 = dyn->native_size -#define GETMARK3 dyn->insts[ninst].mark3 -#define MARKF dyn->insts[ninst].markf = dyn->native_size -#define GETMARKF dyn->insts[ninst].markf -#define MARKSEG dyn->insts[ninst].markseg = dyn->native_size -#define GETMARKSEG dyn->insts[ninst].markseg -#define MARKLOCK dyn->insts[ninst].marklock = dyn->native_size +#define MARK dyn->insts[ninst].mark = dyn->native_size +#define GETMARK dyn->insts[ninst].mark +#define MARK2 dyn->insts[ninst].mark2 = dyn->native_size +#define GETMARK2 dyn->insts[ninst].mark2 +#define MARK3 dyn->insts[ninst].mark3 = dyn->native_size +#define GETMARK3 dyn->insts[ninst].mark3 +#define MARKF dyn->insts[ninst].markf = dyn->native_size +#define GETMARKF dyn->insts[ninst].markf +#define MARKF2 dyn->insts[ninst].markf2 = dyn->native_size +#define GETMARKF2 dyn->insts[ninst].markf2 +#define MARKSEG dyn->insts[ninst].markseg = dyn->native_size +#define GETMARKSEG dyn->insts[ninst].markseg +#define MARKLOCK dyn->insts[ninst].marklock = dyn->native_size #define GETMARKLOCK dyn->insts[ninst].marklock // Branch to MARK if cond (use j64) @@ -504,6 +525,10 @@ #define B_MARK2_nocond \ j64 = GETMARK2-(dyn->native_size); \ B(j64) +// Branch to MARK2 if reg is 0 (use j64) +#define CBZx_MARK2(reg) \ + j64 = GETMARK2-(dyn->native_size); \ + CBZx(reg, j64) // Branch to MARK2 if reg is not 0 (use j64) #define CBNZx_MARK2(reg) \ j64 = GETMARK2-(dyn->native_size); \ @@ -717,7 +742,7 @@ LDP_REGS(R12, R13); \ LDP_REGS(R14, R15) -#define SET_DFNONE(S) if(!dyn->f.dfnone) {MOVZw(S, d_none); STRw_U12(S, xEmu, offsetof(x64emu_t, df)); dyn->f.dfnone=1;} +#define SET_DFNONE(S) if(!dyn->f.dfnone) {STRw_U12(wZR, xEmu, offsetof(x64emu_t, df)); dyn->f.dfnone=1;} #define SET_DF(S, N) if((N)!=d_none) {MOVZw(S, (N)); STRw_U12(S, xEmu, offsetof(x64emu_t, df)); dyn->f.dfnone=0;} else SET_DFNONE(S) #define SET_NODF() dyn->f.dfnone = 0 #define SET_DFOK() dyn->f.dfnone = 1 @@ -759,10 +784,10 @@ } else dyn->f.pending = SF_SET #endif #ifndef JUMP -#define JUMP(A, C) +#define JUMP(A, C) #endif #ifndef BARRIER -#define BARRIER(A) +#define BARRIER(A) #endif #ifndef BARRIER_NEXT #define BARRIER_NEXT(A) @@ -832,7 +857,7 @@ #define MODREG ((nextop&0xC0)==0xC0) -void arm64_epilog(); +void arm64_epilog(void); void* arm64_next(x64emu_t* emu, uintptr_t addr); #ifndef STEPNAME @@ -996,8 +1021,8 @@ uintptr_t geted16(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, // generic x64 helper void jump_to_epilog(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst); void jump_to_next(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst); -void ret_to_epilog(dynarec_arm_t* dyn, int ninst); -void retn_to_epilog(dynarec_arm_t* dyn, int ninst, int n); +void ret_to_epilog(dynarec_arm_t* dyn, int ninst, rex_t rex); +void retn_to_epilog(dynarec_arm_t* dyn, int ninst, rex_t rex, int n); void iret_to_epilog(dynarec_arm_t* dyn, int ninst, int is64bits); void call_c(dynarec_arm_t* dyn, int ninst, void* fnc, int reg, int ret, int saveflags, int save_reg); void call_n(dynarec_arm_t* dyn, int ninst, void* fnc, int w); @@ -1121,16 +1146,19 @@ int neoncache_st_coherency(dynarec_arm_t* dyn, int ninst, int a, int b); #if STEP == 0 #define ST_IS_F(A) 0 +#define ST_IS_I64(A) 0 #define X87_COMBINE(A, B) NEON_CACHE_ST_D #define X87_ST0 NEON_CACHE_ST_D #define X87_ST(A) NEON_CACHE_ST_D #elif STEP == 1 #define ST_IS_F(A) (neoncache_get_current_st(dyn, ninst, A)==NEON_CACHE_ST_F) +#define ST_IS_I64(A) (neoncache_get_current_st(dyn, ninst, A)==NEON_CACHE_ST_I64) #define X87_COMBINE(A, B) neoncache_combine_st(dyn, ninst, A, B) #define X87_ST0 neoncache_get_current_st(dyn, ninst, 0) #define X87_ST(A) neoncache_get_current_st(dyn, ninst, A) #else #define ST_IS_F(A) (neoncache_get_st(dyn, ninst, A)==NEON_CACHE_ST_F) +#define ST_IS_I64(A) (neoncache_get_st(dyn, ninst, A)==NEON_CACHE_ST_I64) #if STEP == 3 #define X87_COMBINE(A, B) neoncache_st_coherency(dyn, ninst, A, B) #else @@ -1210,7 +1238,7 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n #if STEP < 3 #define MAYUSE(A) (void)A #else -#define MAYUSE(A) +#define MAYUSE(A) #endif #define GOCOND(B, T1, T2) \ @@ -1318,4 +1346,12 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n STRw_U12(s2, xEmu, offsetof(x64emu_t, test.test)); \ } +#define GETREX() \ + rex.rex = 0; \ + if(!rex.is32bits) \ + while(opcode>=0x40 && opcode<=0x4f) { \ + rex.rex = opcode; \ + opcode = F8; \ + } + #endif //__DYNAREC_ARM64_HELPER_H__ |