about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-21 13:52:46 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-21 13:52:46 +0100
commit90bd5b0cb19c42f3f0de74dda3a3c6d560ab0a0e (patch)
tree282bf2f04038e0b679d4400dbd61e5f6beee5825 /src
parentfd729da8f1146966ba63c14402aaae9f38b00ebc (diff)
downloadbox64-90bd5b0cb19c42f3f0de74dda3a3c6d560ab0a0e.tar.gz
box64-90bd5b0cb19c42f3f0de74dda3a3c6d560ab0a0e.zip
[DYNAREC] Added F2 0F 10/11 opcodes
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/dynarec_arm64_f20f.c43
-rwxr-xr-xsrc/dynarec/dynarec_arm64_functions.c7
-rwxr-xr-xsrc/dynarec/dynarec_arm64_functions.h2
3 files changed, 44 insertions, 8 deletions
diff --git a/src/dynarec/dynarec_arm64_f20f.c b/src/dynarec/dynarec_arm64_f20f.c
index 1caa91b7..1ca91b65 100755
--- a/src/dynarec/dynarec_arm64_f20f.c
+++ b/src/dynarec/dynarec_arm64_f20f.c
@@ -27,18 +27,20 @@
     if(MODREG) {                                                                                    \

         a = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3));                                     \

     } else {                                                                                        \

-        parity = getedparity(dyn, ninst, addr, nextop, 3);                                          \

+        parity = getedparity(dyn, ninst, addr, nextop, 7, D);                                       \

         a = fpu_get_scratch(dyn);                                                                   \

         if(parity) {                                                                                \

-            addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 3, rex, 0, D); \

+            addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 7, rex, 0, D); \

             VLDR64_U12(a, ed, fixedaddress);                                                        \

         } else {                                                                                    \

-            addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 0, rex, 0, D); \

+            addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 7, rex, 0, D); \

             LDRx_U12(x2, ed, fixedaddress+0);                                                       \

             VMOVQDfrom(a, 0, x2);                                                                   \

         }                                                                                           \

     }

 

+#define GETGX   gd = ((nextop&0x38)>>3)+(rex.r<<3)

+

 uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)

 {

     uint8_t opcode = F8;

@@ -62,10 +64,43 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
 

     switch(opcode) {

 

+        case 0x10:

+            INST_NAME("MOVSD Gx, Ex");

+            nextop = F8;

+            GETGX;

+            if(MODREG) {

+                ed = (nextop&7)+ (rex.b<<3);

+                v0 = sse_get_reg(dyn, ninst, x1, gd);

+                d0 = sse_get_reg(dyn, ninst, x1, ed);

+                VMOV(v0, d0);

+            } else {

+                v0 = sse_get_reg_empty(dyn, ninst, x1, gd);

+                addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 7, rex, 0, 0);

+                LDRx_U12(x2, ed, fixedaddress);

+                VEORQ(v0, v0, v0);

+                VMOVQDfrom(v0, 0, x2);

+            }

+            break;

+        case 0x11:

+            INST_NAME("MOVSD Ex, Gx");

+            nextop = F8;

+            GETGX;

+            v0 = sse_get_reg(dyn, ninst, x1, gd);

+            if(MODREG) {

+                ed = (nextop&7)+ (rex.b<<3);

+                d0 = sse_get_reg(dyn, ninst, x1, ed);

+                VMOV(d0, v0);

+            } else {

+                VMOVQDto(x2, v0, 0);

+                addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 7, rex, 0, 0);

+                STRx_U12(x2, ed, fixedaddress);

+            }

+            break;

+

         case 0x58:

             INST_NAME("ADDSD Gx, Ex");

             nextop = F8;

-            gd = ((nextop&0x38)>>3)+(rex.r<<3);

+            GETGX;

             v0 = sse_get_reg(dyn, ninst, x1, gd);

             GETEX(d0, 0);

             FADDD(v0, v0, d0);

diff --git a/src/dynarec/dynarec_arm64_functions.c b/src/dynarec/dynarec_arm64_functions.c
index 24b1b55b..d2ba4f6f 100755
--- a/src/dynarec/dynarec_arm64_functions.c
+++ b/src/dynarec/dynarec_arm64_functions.c
@@ -240,8 +240,9 @@ void fpu_reset_reg(dynarec_arm_t* dyn)
 
 #define F8      *(uint8_t*)(addr++)
 #define F32     *(uint32_t*)(addr+=4, addr-4)
+#define F32S64  (uint64_t)(int64_t)*(int32_t*)(addr+=4, addr-4)
 // Get if ED will have the correct parity. Not emiting anything. Parity is 2 for DWORD or 3 for QWORD
-int getedparity(dynarec_arm_t* dyn, int ninst, uintptr_t addr, uint8_t nextop, int parity)
+int getedparity(dynarec_arm_t* dyn, int ninst, uintptr_t addr, uint8_t nextop, int parity, int delta)
 {
 
     uint32_t tested = (1<<parity)-1;
@@ -252,7 +253,7 @@ int getedparity(dynarec_arm_t* dyn, int ninst, uintptr_t addr, uint8_t nextop, i
             uint8_t sib = F8;
             int sib_reg = (sib>>3)&7;
             if((sib&0x7)==5) {
-                uint32_t tmp = F32;
+                uint64_t tmp = F32S64;
                 if (sib_reg!=4) {
                     // if XXXXXX+reg<<N then check parity of XXXXX and N should be enough
                     return ((tmp&tested)==0 && (sib>>6)>=parity)?1:0;
@@ -267,7 +268,7 @@ int getedparity(dynarec_arm_t* dyn, int ninst, uintptr_t addr, uint8_t nextop, i
                 return ((sib&0x7)==4 && (sib>>6)>=parity)?1:0;
             }
         } else if((nextop&7)==5) {
-            uint32_t tmp = F32;
+            uint64_t tmp = F32S64+addr+delta;
             return (tmp&tested)?0:1;
         } else {
             return 0;
diff --git a/src/dynarec/dynarec_arm64_functions.h b/src/dynarec/dynarec_arm64_functions.h
index 0d6a02a5..085e4c1f 100755
--- a/src/dynarec/dynarec_arm64_functions.h
+++ b/src/dynarec/dynarec_arm64_functions.h
@@ -47,7 +47,7 @@ void fpu_free_reg(dynarec_arm_t* dyn, int reg);
 void fpu_reset_reg(dynarec_arm_t* dyn);
 
 // Get if ED will have the correct parity. Not emiting anything. Parity is 2 for DWORD or 3 for QWORD
-int getedparity(dynarec_arm_t* dyn, int ninst, uintptr_t addr, uint8_t nextop, int parity);
+int getedparity(dynarec_arm_t* dyn, int ninst, uintptr_t addr, uint8_t nextop, int parity, int delta);
 // Do the GETED, but don't emit anything...
 uintptr_t fakeed(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop);