about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xCMakeLists.txt2
-rwxr-xr-xsrc/dynarec/dynarec_arm64_00.c4
-rw-r--r--src/dynarec/dynarec_arm64_dd.c198
-rwxr-xr-xsrc/dynarec/dynarec_arm64_helper.h2
4 files changed, 204 insertions, 2 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f5e6bb8c..7f00bbb3 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -291,7 +291,7 @@ if(ARM_DYNAREC)
     #"${BOX64_ROOT}/src/dynarec/dynarec_arm64_da.c"
     "${BOX64_ROOT}/src/dynarec/dynarec_arm64_db.c"
     #"${BOX64_ROOT}/src/dynarec/dynarec_arm64_dc.c"
-    #"${BOX64_ROOT}/src/dynarec/dynarec_arm64_dd.c"
+    "${BOX64_ROOT}/src/dynarec/dynarec_arm64_dd.c"
     #"${BOX64_ROOT}/src/dynarec/dynarec_arm64_de.c"
     #"${BOX64_ROOT}/src/dynarec/dynarec_arm64_df.c"
     "${BOX64_ROOT}/src/dynarec/dynarec_arm64_f0.c"
diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c
index 79b61a91..1b0c573e 100755
--- a/src/dynarec/dynarec_arm64_00.c
+++ b/src/dynarec/dynarec_arm64_00.c
@@ -1840,6 +1840,10 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             addr = dynarec64_DB(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
             break;
 
+        case 0xDD:
+            addr = dynarec64_DD(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
+            break;
+
         case 0xE8:
             INST_NAME("CALL Id");
             i32 = F32S;
diff --git a/src/dynarec/dynarec_arm64_dd.c b/src/dynarec/dynarec_arm64_dd.c
new file mode 100644
index 00000000..0324cba1
--- /dev/null
+++ b/src/dynarec/dynarec_arm64_dd.c
@@ -0,0 +1,198 @@
+#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 "emu/x87emu_private.h"
+
+#include "dynarec_arm64_helper.h"
+#include "dynarec_arm64_functions.h"
+
+
+uintptr_t dynarec64_DD(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 = F8;
+    uint8_t ed;
+    int fixedaddress;
+    int v1, v2;
+    int s0;
+
+    MAYUSE(s0);
+    MAYUSE(v2);
+    MAYUSE(v1);
+
+    switch(nextop) {
+        case 0xC0:
+        case 0xC1:
+        case 0xC2:
+        case 0xC3:
+        case 0xC4:
+        case 0xC5:
+        case 0xC6:
+        case 0xC7:
+            INST_NAME("FFREE STx");
+            break;  // not handling Tag...
+        case 0xD0:
+        case 0xD1:
+        case 0xD2:
+        case 0xD3:
+        case 0xD4:
+        case 0xD5:
+        case 0xD6:
+        case 0xD7:
+            INST_NAME("FST ST0, STx");
+            v1 = x87_get_st(dyn, ninst, x1, x2, 0);
+            v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7);
+            FMOVD(v2, v1);
+            break;
+        case 0xD8:
+            INST_NAME("FSTP ST0, ST0");
+            x87_do_pop(dyn, ninst);
+            break;
+        case 0xD9:
+        case 0xDA:
+        case 0xDB:
+        case 0xDC:
+        case 0xDD:
+        case 0xDE:
+        case 0xDF:
+            INST_NAME("FSTP ST0, STx");
+            v1 = x87_get_st(dyn, ninst, x1, x2, 0);
+            v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7);
+            FMOVD(v2, v1);
+            x87_do_pop(dyn, ninst);
+            break;
+
+        case 0xE0:
+        case 0xE1:
+        case 0xE2:
+        case 0xE3:
+        case 0xE4:
+        case 0xE5:
+        case 0xE6:
+        case 0xE7:
+            INST_NAME("FUCOM ST0, STx");
+            v1 = x87_get_st(dyn, ninst, x1, x2, 0);
+            v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7);
+            FCMPD(v1, v2);
+            FCOM(x1, x2, x3);
+            break;
+        case 0xE8:
+        case 0xE9:
+        case 0xEA:
+        case 0xEB:
+        case 0xEC:
+        case 0xED:
+        case 0xEE:
+        case 0xEF:
+            INST_NAME("FUCOMP ST0, STx");
+            v1 = x87_get_st(dyn, ninst, x1, x2, 0);
+            v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7);
+            FCMPD(v1, v2);
+            FCOM(x1, x2, x3);
+            x87_do_pop(dyn, ninst);
+            break;
+
+        case 0xC8:
+        case 0xC9:
+        case 0xCA:
+        case 0xCB:
+        case 0xCC:
+        case 0xCD:
+        case 0xCE:
+        case 0xCF:
+        case 0xF0:
+        case 0xF1:
+        case 0xF2:
+        case 0xF3:
+        case 0xF4:
+        case 0xF5:
+        case 0xF6:
+        case 0xF7:
+        case 0xF8:
+        case 0xF9:
+        case 0xFA:
+        case 0xFB:
+        case 0xFC:
+        case 0xFD:
+        case 0xFE:
+        case 0xFF:
+            DEFAULT;
+            break;
+
+        default:
+            switch((nextop>>3)&7) {
+                case 0:
+                    INST_NAME("FLD double");
+                    v1 = x87_do_push(dyn, ninst);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 7, rex, 0, 0);
+                    VLDR64_U12(v1, ed, fixedaddress);
+                    break;
+                case 1:
+                    INST_NAME("FISTTP i64, ST0");
+                    v1 = x87_do_push(dyn, ninst);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 7, rex, 0, 0);
+                    s0 = fpu_get_scratch(dyn);
+                    FRINT64ZD(s0, v1);
+                    FCVTZSxD(x2, s0);
+                    STRx_U12(x2, ed, fixedaddress);
+                    x87_do_pop(dyn, ninst);
+                    break;
+                case 2:
+                    INST_NAME("FST double");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 7, rex, 0, 0);
+                    VSTR64_U12(v1, ed, fixedaddress);
+                    break;
+                case 3:
+                    INST_NAME("FSTP double");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 7, rex, 0, 0);
+                    VSTR64_U12(v1, ed, fixedaddress);
+                    x87_do_pop(dyn, ninst);
+                    break;
+                case 4: 
+                    INST_NAME("FRSTOR m108byte");
+                    fpu_purgecache(dyn, ninst, x1, x2, x3);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, rex, 0, 0);
+                    if(ed!=x1) {MOVx_REG(x1, ed);}
+                    CALL(arm_frstor, -1);
+                    break;
+                case 6: 
+                    INST_NAME("FSAVE m108byte");
+                    fpu_purgecache(dyn, ninst, x1, x2, x3);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, rex, 0, 0);
+                    if(ed!=x1) {MOVx_REG(x1, ed);}
+                    CALL(arm_fsave, -1);
+                    break;
+                case 7:
+                    INST_NAME("FNSTSW m2byte");
+                    fpu_purgecache(dyn, ninst, x1, x2, x3);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x4, &fixedaddress, 0xfff<<1, 1, rex, 0, 0);
+                    LDRw_U12(x1, xEmu, offsetof(x64emu_t, top));
+                    LDRH_U12(x3, xEmu, offsetof(x64emu_t, sw));
+                    BFIw(x3, x1, 11, 3); // inject TOP at bit 11 (3 bits)
+                    STRH_U12(x3, ed, fixedaddress);   // store whole sw flags
+                    break;
+                default:
+                    DEFAULT;
+            }
+    }
+    return addr;
+}
+
diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h
index 57576ed1..62539654 100755
--- a/src/dynarec/dynarec_arm64_helper.h
+++ b/src/dynarec/dynarec_arm64_helper.h
@@ -843,7 +843,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
 //uintptr_t dynarec64_DA(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_DB(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_DC(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_DD(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_DD(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_DE(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_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);