about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64_printer.c17
-rwxr-xr-xsrc/dynarec/dynarec_arm64_00.c11
-rwxr-xr-xsrc/dynarec/dynarec_arm64_0f.c36
-rwxr-xr-xsrc/dynarec/dynarec_arm64_660f.c4
-rwxr-xr-xsrc/dynarec/dynarec_arm64_f20f.c72
-rwxr-xr-xsrc/dynarec/dynarec_arm64_f30f.c72
-rwxr-xr-xsrc/dynarec/dynarec_arm64_helper.h8
7 files changed, 212 insertions, 8 deletions
diff --git a/src/dynarec/arm64_printer.c b/src/dynarec/arm64_printer.c
index ed179df0..b0b1849a 100755
--- a/src/dynarec/arm64_printer.c
+++ b/src/dynarec/arm64_printer.c
@@ -717,7 +717,22 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
             snprintf(buff, sizeof(buff), "VORR %c%d, %c%d, %c%d", q, Rd, q, Rn, q, Rm);

         return buff;

     }

-

+    // UMOV

+    if(isMask(opcode, "0Q001110000rrrrr001111nnnnnddddd", &a)) {

+        char q = a.Q?'Q':'D';

+        char s = '?';

+        int sz=0;

+        if(a.Q==0 && immr&1) {s='B'; sz=0; }

+        else if(a.Q==0 && (immr&3)==2) {s='H'; sz=1; }

+        else if(a.Q==0 && (immr&7)==4) {s='S'; sz=2; }

+        else if(a.Q==1 && (immr&15)==8) {s='D'; sz=3; }

+        int index = (immr)>>(sz+1);

+        if(sz>2)

+            snprintf(buff, sizeof(buff), "MOV %s, %c%d.%c[%d]", a.Q?Xt[Rd]:Wt[Rd], q, Rn, s, index);

+        else

+            snprintf(buff, sizeof(buff), "UMOV %s, %c%d.%c[%d]", a.Q?Xt[Rd]:Wt[Rd], q, Rn, s, index);

+        return buff;

+    }

     // VEOR

     if(isMask(opcode, "0Q101110001mmmmm000111nnnnnddddd", &a)) {

         char q = a.Q?'Q':'D';

diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c
index dcf74f1c..fbd258b4 100755
--- a/src/dynarec/dynarec_arm64_00.c
+++ b/src/dynarec/dynarec_arm64_00.c
@@ -159,7 +159,16 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;
 
         case 0x0F:
-            addr = dynarec64_0F(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
+            switch(rep) {
+            case 1:
+                addr = dynarec64_F20F(dyn, addr, ip, ninst, rex, ok, need_epilog);
+                break;
+            case 2:
+                addr = dynarec64_F30F(dyn, addr, ip, ninst, rex, ok, need_epilog);
+                break;
+            default:
+                addr = dynarec64_0F(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
+            }
             break;
         case 0x10:
             INST_NAME("ADC Eb, Gb");
diff --git a/src/dynarec/dynarec_arm64_0f.c b/src/dynarec/dynarec_arm64_0f.c
index bc7da54d..3f869b9d 100755
--- a/src/dynarec/dynarec_arm64_0f.c
+++ b/src/dynarec/dynarec_arm64_0f.c
@@ -83,6 +83,42 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
 

 

 

+        case 0x10:

+            INST_NAME("MOVUPS Gx,Ex");

+            nextop = F8;

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

+            if(MODREG) {

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

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

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

+                VMOVQ(v0, v1);

+            } else {

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

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

+                LDRx_U12(x2, ed, fixedaddress);

+                VMOVQDfrom(v0, 0, x2);

+                LDRx_U12(x2, ed, fixedaddress+8);

+                VMOVQDfrom(v0, 1, x2);

+            }

+            break;

+        case 0x11:

+            INST_NAME("MOVUPS Ex,Gx");

+            nextop = F8;

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

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

+            if(MODREG) {

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

+                v1 = sse_get_reg_empty(dyn, ninst, x1, ed);

+                VMOVQ(v1, v0);

+            } else {

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

+                VMOVQDto(x2, v0, 0);

+                STRx_U12(x2, ed, fixedaddress);

+                VMOVQDto(x2, v0, 1);

+                LDRx_U12(x2, ed, fixedaddress+8);

+            }

+            break;

+

         case 0x1F:

             INST_NAME("NOP (multibyte)");

             nextop = F8;

diff --git a/src/dynarec/dynarec_arm64_660f.c b/src/dynarec/dynarec_arm64_660f.c
index 7dafc606..6069c3ef 100755
--- a/src/dynarec/dynarec_arm64_660f.c
+++ b/src/dynarec/dynarec_arm64_660f.c
@@ -106,7 +106,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             gd = ((nextop&0x38)>>3)+(rex.r<<3);

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

             if(rex.w) {

-                if((nextop&0xC0)==0xC0) {

+                if(MODREG) {

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

                     VMOVQDto(ed, v0, 0);

                 } else {

@@ -115,7 +115,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     STRx_U12(x2, ed, fixedaddress);

                 }

             } else {

-                if((nextop&0xC0)==0xC0) {

+                if(MODREG) {

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

                     VMOVSto(ed, v0, 0);

                 } else {

diff --git a/src/dynarec/dynarec_arm64_f20f.c b/src/dynarec/dynarec_arm64_f20f.c
new file mode 100755
index 00000000..e8708a12
--- /dev/null
+++ b/src/dynarec/dynarec_arm64_f20f.c
@@ -0,0 +1,72 @@
+#include <stdio.h>

+#include <stdlib.h>

+#include <stddef.h>

+#include <pthread.h>

+#include <errno.h>

+

+#include "debug.h"

+#include "box64context.h"

+#include "dynarec.h"

+#include "emu/x64emu_private.h"

+#include "emu/x64run_private.h"

+#include "x64run.h"

+#include "x64emu.h"

+#include "box64stack.h"

+#include "callback.h"

+#include "emu/x64run_private.h"

+#include "x64trace.h"

+#include "dynarec_arm64.h"

+#include "dynarec_arm64_private.h"

+#include "arm64_printer.h"

+

+#include "dynarec_arm64_functions.h"

+#include "dynarec_arm64_helper.h"

+

+// Get Ex as a double, not a quad (warning, x2 and x3 may get used)

+#define GETEX(a) \

+    if((nextop&0xC0)==0xC0) { \

+        a = sse_get_reg(dyn, ninst, x1, nextop&7); \

+    } else {    \

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

+        a = fpu_get_scratch_double(dyn);            \

+        if(parity) {                                \

+            addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 1023, 3); \

+            VLDR_64(a, ed, fixedaddress);           \

+        } else {                                    \

+            addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095-4, 0);\

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

+            LDR_IMM9(x3, ed, fixedaddress+4);       \

+            VMOVtoV_D(a, x2, x3);                   \

+        }                                           \

+    }

+

+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;

+    uint8_t nextop, u8;

+    int32_t i32, j32;

+    uint8_t gd, ed;

+    uint8_t wback, wb1;

+    uint8_t eb1, eb2;

+    int v0, v1;

+    int q0, q1;

+    int d0;

+    int s0;

+    int fixedaddress;

+    int parity;

+

+    MAYUSE(d0);

+    MAYUSE(q1);

+    MAYUSE(eb1);

+    MAYUSE(eb2);

+    MAYUSE(j32);

+

+    switch(opcode) {

+

+

+        default:

+            DEFAULT;

+    }

+    return addr;

+}

+

diff --git a/src/dynarec/dynarec_arm64_f30f.c b/src/dynarec/dynarec_arm64_f30f.c
new file mode 100755
index 00000000..68b22031
--- /dev/null
+++ b/src/dynarec/dynarec_arm64_f30f.c
@@ -0,0 +1,72 @@
+#include <stdio.h>

+#include <stdlib.h>

+#include <stddef.h>

+#include <pthread.h>

+#include <errno.h>

+

+#include "debug.h"

+#include "box64context.h"

+#include "dynarec.h"

+#include "emu/x64emu_private.h"

+#include "emu/x64run_private.h"

+#include "x64run.h"

+#include "x64emu.h"

+#include "box64stack.h"

+#include "callback.h"

+#include "emu/x64run_private.h"

+#include "x64trace.h"

+#include "dynarec_arm64.h"

+#include "dynarec_arm64_private.h"

+#include "arm64_printer.h"

+

+#include "dynarec_arm64_functions.h"

+#include "dynarec_arm64_helper.h"

+

+// Get Ex as a double, not a quad (warning, x2 and x3 may get used)

+#define GETEX(a) \

+    if((nextop&0xC0)==0xC0) { \

+        a = sse_get_reg(dyn, ninst, x1, nextop&7); \

+    } else {    \

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

+        a = fpu_get_scratch_double(dyn);            \

+        if(parity) {                                \

+            addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 1023, 3); \

+            VLDR_64(a, ed, fixedaddress);           \

+        } else {                                    \

+            addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095-4, 0);\

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

+            LDR_IMM9(x3, ed, fixedaddress+4);       \

+            VMOVtoV_D(a, x2, x3);                   \

+        }                                           \

+    }

+

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

+{

+    uint8_t opcode = F8;

+    uint8_t nextop, u8;

+    int32_t i32, j32;

+    uint8_t gd, ed;

+    uint8_t wback, wb1;

+    uint8_t eb1, eb2;

+    int v0, v1;

+    int q0, q1;

+    int d0;

+    int s0;

+    int fixedaddress;

+    int parity;

+

+    MAYUSE(d0);

+    MAYUSE(q1);

+    MAYUSE(eb1);

+    MAYUSE(eb2);

+    MAYUSE(j32);

+

+    switch(opcode) {

+

+

+        default:

+            DEFAULT;

+    }

+    return addr;

+}

+

diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h
index 46febe3a..c814d89f 100755
--- a/src/dynarec/dynarec_arm64_helper.h
+++ b/src/dynarec/dynarec_arm64_helper.h
@@ -758,8 +758,8 @@ 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_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_FS(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_GS(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_FS(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_GS(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_66(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_67(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_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep int* ok, int* need_epilog);
@@ -772,8 +772,8 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
 //uintptr_t dynarec64_DF(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_F0(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_660F(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_F20F(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_F30F(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_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
+uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
 
 #if STEP < 2
 #define PASS2(A)