about summary refs log tree commit diff stats
path: root/src/dynarec/arm64/dynarec_arm64_helper.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/dynarec/arm64/dynarec_arm64_helper.h')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h78
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__