about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-07-05 17:13:30 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-07-05 17:13:30 +0200
commitd0dee6cb506a800727ce25b0afc35914c8708d32 (patch)
treef58f4097bc82b6257717878d950d4d5595c48c60 /src
parente3bbfe30524edf2d3a5b0dc2e701b5aff95b5e6a (diff)
downloadbox64-d0dee6cb506a800727ce25b0afc35914c8708d32.tar.gz
box64-d0dee6cb506a800727ce25b0afc35914c8708d32.zip
[DYNAREC] Added DC opcodes (for CB15)
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/dynarec_arm64_00.c4
-rw-r--r--src/dynarec/dynarec_arm64_dc.c219
-rwxr-xr-xsrc/dynarec/dynarec_arm64_helper.h2
3 files changed, 223 insertions, 2 deletions
diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c
index 4d189ec3..d31beef9 100755
--- a/src/dynarec/dynarec_arm64_00.c
+++ b/src/dynarec/dynarec_arm64_00.c
@@ -1914,7 +1914,9 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
         case 0xDB:
             addr = dynarec64_DB(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
             break;
-
+        case 0xDC:
+            addr = dynarec64_DC(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;
diff --git a/src/dynarec/dynarec_arm64_dc.c b/src/dynarec/dynarec_arm64_dc.c
new file mode 100644
index 00000000..0fa8ddb2
--- /dev/null
+++ b/src/dynarec/dynarec_arm64_dc.c
@@ -0,0 +1,219 @@
+#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_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
+{
+    (void)ip; (void)rep; (void)need_epilog;
+
+    uint8_t nextop = F8;
+    uint8_t wback;
+    int64_t fixedaddress;
+    int v1, v2;
+
+    MAYUSE(v2);
+    MAYUSE(v1);
+
+    switch(nextop) {
+        case 0xC0:
+        case 0xC1:
+        case 0xC2:
+        case 0xC3:
+        case 0xC4:
+        case 0xC5:
+        case 0xC6:
+        case 0xC7:
+            INST_NAME("FADD STx, ST0");
+            v2 = x87_get_st(dyn, ninst, x1, x2, 0);
+            v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7);
+            FADDD(v1, v1, v2);
+            break;
+        case 0xC8:
+        case 0xC9:
+        case 0xCA:
+        case 0xCB:
+        case 0xCC:
+        case 0xCD:
+        case 0xCE:
+        case 0xCF:
+            INST_NAME("FMUL STx, ST0");
+            v2 = x87_get_st(dyn, ninst, x1, x2, 0);
+            v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7);
+            FMULD(v1, v1, v2);
+            break;
+        case 0xD0:
+        case 0xD1:
+        case 0xD2:
+        case 0xD3:
+        case 0xD4:
+        case 0xD5:
+        case 0xD6:
+        case 0xD7:
+            INST_NAME("FCOM ST0, STx"); //yep
+            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 0xD8:
+        case 0xD9:
+        case 0xDA:
+        case 0xDB:
+        case 0xDC:
+        case 0xDD:
+        case 0xDE:
+        case 0xDF:
+            INST_NAME("FCOMP 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 0xE0:
+        case 0xE1:
+        case 0xE2:
+        case 0xE3:
+        case 0xE4:
+        case 0xE5:
+        case 0xE6:
+        case 0xE7:
+            INST_NAME("FSUBR STx, ST0");
+            v2 = x87_get_st(dyn, ninst, x1, x2, 0);
+            v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7);
+            FSUBD(v1, v2, v1);
+            break;
+        case 0xE8:
+        case 0xE9:
+        case 0xEA:
+        case 0xEB:
+        case 0xEC:
+        case 0xED:
+        case 0xEE:
+        case 0xEF:
+            INST_NAME("FSUB STx, ST0");
+            v2 = x87_get_st(dyn, ninst, x1, x2, 0);
+            v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7);
+            FSUBD(v1, v1, v2);
+            break;
+        case 0xF0:
+        case 0xF1:
+        case 0xF2:
+        case 0xF3:
+        case 0xF4:
+        case 0xF5:
+        case 0xF6:
+        case 0xF7:
+            INST_NAME("FDIVR STx, ST0");
+            v2 = x87_get_st(dyn, ninst, x1, x2, 0);
+            v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7);
+            FDIVD(v1, v2, v1);
+            break;       
+        case 0xF8:
+        case 0xF9:
+        case 0xFA:
+        case 0xFB:
+        case 0xFC:
+        case 0xFD:
+        case 0xFE:
+        case 0xFF:
+            INST_NAME("FDIV STx, ST0");
+            v2 = x87_get_st(dyn, ninst, x1, x2, 0);
+            v1 = x87_get_st(dyn, ninst, x1, x2, nextop&7);
+            FDIVD(v1, v1, v2);
+            break;
+        default:
+            switch((nextop>>3)&7) {
+                case 0:
+                    INST_NAME("FADD ST0, double[ED]");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0);
+                    v2 = fpu_get_scratch(dyn);
+                    addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<3, 3, rex, 0, 0);
+                    VLDR64_U12(v2, wback, fixedaddress);
+                    FADDD(v1, v1, v2);
+                    break;
+                case 1:
+                    INST_NAME("FMUL ST0, double[ED]");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0);
+                    v2 = fpu_get_scratch(dyn);
+                    addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<3, 3, rex, 0, 0);
+                    VLDR64_U12(v2, wback, fixedaddress);
+                    FMULD(v1, v1, v2);
+                    break;
+                case 2:
+                    INST_NAME("FCOM ST0, double[ED]");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0);
+                    v2 = fpu_get_scratch(dyn);
+                    addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<3, 3, rex, 0, 0);
+                    VLDR64_U12(v2, wback, fixedaddress);
+                    FCMPD(v1, v2);
+                    FCOM(x1, x2, x3);
+                    break;
+                case 3:
+                    INST_NAME("FCOMP ST0, double[ED]");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0);
+                    v2 = fpu_get_scratch(dyn);
+                    addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<3, 3, rex, 0, 0);
+                    VLDR64_U12(v2, wback, fixedaddress);
+                    FCMPD(v1, v2);
+                    FCOM(x1, x2, x3);
+                    x87_do_pop(dyn, ninst);
+                    break;
+                case 4:
+                    INST_NAME("FSUB ST0, double[ED]");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0);
+                    v2 = fpu_get_scratch(dyn);
+                    addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<3, 3, rex, 0, 0);
+                    VLDR64_U12(v2, wback, fixedaddress);
+                    FSUBD(v1, v1, v2);
+                    break;
+                case 5:
+                    INST_NAME("FSUBR ST0, double[ED]");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0);
+                    v2 = fpu_get_scratch(dyn);
+                    addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<3, 3, rex, 0, 0);
+                    VLDR64_U12(v2, wback, fixedaddress);
+                    FSUBD(v1, v2, v1);
+                    break;
+                case 6:
+                    INST_NAME("FDIV ST0, double[ED]");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0);
+                    v2 = fpu_get_scratch(dyn);
+                    addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<3, 3, rex, 0, 0);
+                    VLDR64_U12(v2, wback, fixedaddress);
+                    FDIVD(v1, v1, v2);
+                    break;
+                case 7:
+                    INST_NAME("FDIVR ST0, double[ED]");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0);
+                    v2 = fpu_get_scratch(dyn);
+                    addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<3, 3, rex, 0, 0);
+                    VLDR64_U12(v2, wback, fixedaddress);
+                    FDIVD(v1, v2, v1);
+                    break;
+            }
+    }
+    return addr;
+}
diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h
index 63986f61..800f5b1e 100755
--- a/src/dynarec/dynarec_arm64_helper.h
+++ b/src/dynarec/dynarec_arm64_helper.h
@@ -893,7 +893,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
 uintptr_t dynarec64_D9(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_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_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_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);