about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-25 13:53:48 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-25 13:53:48 +0100
commit11cfae2a984359483b88971fbde3a4e454979ce5 (patch)
tree8b5fb03a10fb695da6800fedcad116255fb51305 /src
parent348bd64449843f70e08dd591c867973d83ea87eb (diff)
downloadbox64-11cfae2a984359483b88971fbde3a4e454979ce5.tar.gz
box64-11cfae2a984359483b88971fbde3a4e454979ce5.zip
[DYNAREC] Added some mecanism to handle weird 66 REX mixing
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/dynarec_arm64_00.c15
-rwxr-xr-xsrc/dynarec/dynarec_arm64_66.c7
-rwxr-xr-xsrc/dynarec/dynarec_arm64_helper.h2
-rwxr-xr-xsrc/dynarec/dynarec_arm64_pass.c18
4 files changed, 26 insertions, 16 deletions
diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c
index 38c6a447..6c690a54 100755
--- a/src/dynarec/dynarec_arm64_00.c
+++ b/src/dynarec/dynarec_arm64_00.c
@@ -24,7 +24,7 @@
 #include "dynarec_arm64_functions.h"
 #include "dynarec_arm64_helper.h"
 
-uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog)
+uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
 {
     uint8_t nextop, opcode;
     uint8_t gd, ed;
@@ -37,8 +37,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
     uint64_t u64;
     uint8_t wback, wb1, wb2;
     int fixedaddress;
-    rex_t rex;
-    int rep;    // 0 none, 1=F2 prefix, 2=F3 prefix
 
     opcode = F8;
     MAYUSE(eb1);
@@ -47,17 +45,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
     MAYUSE(tmp);
     MAYUSE(j32);
 
-    rep = 0;
-    while((opcode==0xF2) || (opcode==0xF3)) {
-        rep = opcode-0xF1;
-        opcode = F8;
-    }
-    rex.rex = 0;
-    while(opcode>=0x40 && opcode<=0x4f) {
-        rex.rex = opcode;
-        opcode = F8;
-    }
-
     switch(opcode) {
         case 0x00:
             INST_NAME("ADD Eb, Gb");
diff --git a/src/dynarec/dynarec_arm64_66.c b/src/dynarec/dynarec_arm64_66.c
index 5a230a65..d1c16122 100755
--- a/src/dynarec/dynarec_arm64_66.c
+++ b/src/dynarec/dynarec_arm64_66.c
@@ -51,6 +51,9 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
         opcode = F8;

     }

 

+    if(rex.w)

+        return dynarec64_00(dyn, addr-1, ip, ninst, rex, rep, ok, need_epilog);

+

     switch(opcode) {

         case 0x01:

             INST_NAME("ADD Ew, Gw");

@@ -286,6 +289,10 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             }

             break;

 

+        case 0x66:

+            addr = dynarec64_66(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);

+            break;

+

         case 0x69:

             INST_NAME("IMUL Gw,Ew,Iw");

             SETFLAGS(X_ALL, SF_PENDING);

diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h
index d51260bf..a06d54ea 100755
--- a/src/dynarec/dynarec_arm64_helper.h
+++ b/src/dynarec/dynarec_arm64_helper.h
@@ -814,7 +814,7 @@ void fpu_reflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3);
 void fpu_pushcache(dynarec_arm_t* dyn, int ninst, int s1);
 void fpu_popcache(dynarec_arm_t* dyn, int ninst, int s1);
 
-uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog);
+uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
 uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
 uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep,int* ok, int* need_epilog);
 //uintptr_t dynarec64_65(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep,int* ok, int* need_epilog);
diff --git a/src/dynarec/dynarec_arm64_pass.c b/src/dynarec/dynarec_arm64_pass.c
index 8f7af07c..97404224 100755
--- a/src/dynarec/dynarec_arm64_pass.c
+++ b/src/dynarec/dynarec_arm64_pass.c
@@ -30,6 +30,8 @@ void arm_pass(dynarec_arm_t* dyn, uintptr_t addr)
     int ok = 1;
     int ninst = 0;
     uintptr_t ip = addr;
+    rex_t rex;
+    int rep;    // 0 none, 1=F2 prefix, 2=F3 prefix
     int need_epilog = 1;
     dyn->sons_size = 0;
     // Clean up (because there are multiple passes)
@@ -65,7 +67,21 @@ void arm_pass(dynarec_arm_t* dyn, uintptr_t addr)
         }
 #endif
 
-        addr = dynarec64_00(dyn, addr, ip, ninst, &ok, &need_epilog);
+        rep = 0;
+        uint8_t pk = PK(0);
+        while((pk==0xF2) || (pk==0xF3)) {
+            rep = pk-0xF1;
+            ++addr;
+            pk = PK(0);
+        }
+        rex.rex = 0;
+        while(pk>=0x40 && pk<=0x4f) {
+            rex.rex = pk;
+            ++addr;
+            pk = PK(0);
+        }
+
+        addr = dynarec64_00(dyn, addr, ip, ninst, rex, rep, &ok, &need_epilog);
 
         INST_EPILOG;