about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorSophon <wuxilin123@gmail.com>2023-10-05 14:09:17 +0800
committerptitSeb <sebastien.chev@gmail.com>2023-10-07 10:25:24 +0200
commit83738a606d0a32469d58dda99b422a48b729e098 (patch)
tree100fc4a28c16b9fa7d0225a501fad9be2e34cfa0 /src
parentc904a9af1ca653443988ee698dec4670d4b32f88 (diff)
downloadbox64-83738a606d0a32469d58dda99b422a48b729e098.tar.gz
box64-83738a606d0a32469d58dda99b422a48b729e098.zip
Added Snapdragon 8 Gen 2 profile (#1009)
Compilation works with GCC 12.1.0

Tested on AYN Odin 2 with mainline Linux 6.6.0-rc3-next-20230929

Signed-off-by: Xilin Wu <wuxilin123@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_da.c232
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h2
2 files changed, 233 insertions, 1 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_da.c b/src/dynarec/arm64/dynarec_arm64_da.c
new file mode 100644
index 00000000..14b43345
--- /dev/null
+++ b/src/dynarec/arm64/dynarec_arm64_da.c
@@ -0,0 +1,232 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.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 "emu/x87emu_private.h"
+#include "dynarec_native.h"
+
+#include "arm64_printer.h"
+#include "dynarec_arm64_private.h"
+#include "dynarec_arm64_helper.h"
+#include "dynarec_arm64_functions.h"
+
+
+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)
+{
+    uint8_t nextop = F8;
+    int64_t j64;
+    uint8_t ed;
+    uint8_t wback;
+    int v1, v2;
+    int d0;
+    int s0;
+    int64_t fixedaddress;
+    int unscaled;
+
+    MAYUSE(s0);
+    MAYUSE(d0);
+    MAYUSE(v2);
+    MAYUSE(v1);
+    MAYUSE(ed);
+    MAYUSE(j64);
+
+    switch(nextop) {
+        case 0xC0:
+        case 0xC1:
+        case 0xC2:
+        case 0xC3:
+        case 0xC4:
+        case 0xC5:
+        case 0xC6:
+        case 0xC7:
+            INST_NAME("FCMOVB ST0, STx");
+            READFLAGS(X_CF);
+            v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
+            v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
+            TSTw_mask(xFlags, 0, 0);    //mask=1<<F_CF
+            if(ST_IS_F(0)) {
+                FCSELS(v1, v2, v1, cNE);   // F_CF==1
+            } else {
+                FCSELD(v1, v2, v1, cNE);   // F_CF==1
+            }
+            break;
+        case 0xC8:
+        case 0xC9:
+        case 0xCA:
+        case 0xCB:
+        case 0xCC:
+        case 0xCD:
+        case 0xCE:
+        case 0xCF:
+            INST_NAME("FCMOVE ST0, STx");
+            READFLAGS(X_ZF);
+            v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
+            v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
+            TSTw_mask(xFlags, 0b011010, 0); //mask=1<<F_ZF
+            if(ST_IS_F(0)) {
+                FCSELS(v1, v2, v1, cNE);
+            } else {
+                FCSELD(v1, v2, v1, cNE);        // F_ZF==0
+            }
+            break;
+        case 0xD0:
+        case 0xD1:
+        case 0xD2:
+        case 0xD3:
+        case 0xD4:
+        case 0xD5:
+        case 0xD6:
+        case 0xD7:
+            INST_NAME("FCMOVBE ST0, STx");
+            READFLAGS(X_CF|X_ZF);
+            v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
+            v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
+            MOV32w(x1, (1<<F_CF)|(1<<F_ZF));
+            TSTw_REG(xFlags, x1);
+            if(ST_IS_F(0)) {
+                FCSELS(v1, v2, v1, cNE);
+            } else {
+                FCSELD(v1, v2, v1, cNE);   // F_CF==0 & F_ZF==0
+            }
+            break;
+        case 0xD8:
+        case 0xD9:
+        case 0xDA:
+        case 0xDB:
+        case 0xDC:
+        case 0xDD:
+        case 0xDE:
+        case 0xDF:
+            INST_NAME("FCMOVU ST0, STx");
+            READFLAGS(X_PF);
+            v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
+            v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
+            TSTw_mask(xFlags, 0b011110, 0); //mask=1<<F_PF
+            if(ST_IS_F(0)) {
+                FCSELS(v1, v2, v1, cNE);
+            } else {
+                FCSELD(v1, v2, v1, cNE);        // F_PF==0
+            }
+            break;       
+        case 0xE9:
+            INST_NAME("FUCOMPP ST0, ST1");
+            v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
+            v2 = x87_get_st(dyn, ninst, x1, x2, 1, X87_COMBINE(0, nextop&7));
+            if(ST_IS_F(0)) {
+                FCMPS(v1, v2);
+            } else {
+                FCMPD(v1, v2);
+            }
+            FCOM(x1, x2, x3);
+            x87_do_pop(dyn, ninst, x3);
+            x87_do_pop(dyn, ninst, x3);
+            break;
+
+        case 0xE4:
+        case 0xF0:
+        case 0xF1:
+        case 0xF4:
+        case 0xF5:
+        case 0xF6:
+        case 0xF7:
+        case 0xF8:
+        case 0xF9:
+        case 0xFD:
+            DEFAULT;
+            break;
+
+        default:
+            switch((nextop>>3)&7) {
+                case 0:
+                    INST_NAME("FIADD ST0, Ed");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
+                    v2 = fpu_get_scratch(dyn);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
+                    VLD32(v2, ed, fixedaddress);
+                    SXTL_32(v2, v2);    // i32 -> i64
+                    SCVTFDD(v2, v2);    // i64 -> double
+                    FADDD(v1, v1, v2);
+                    break;
+                case 1:
+                    INST_NAME("FIMUL ST0, Ed");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
+                    VLD32(v2, ed, fixedaddress);
+                    SXTL_32(v2, v2);    // i32 -> i64
+                    SCVTFDD(v2, v2);    // i64 -> double
+                    FMULD(v1, v1, v2);
+                    break;
+                case 2:
+                    INST_NAME("FICOM ST0, Ed");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
+                    VLD32(v2, ed, fixedaddress);
+                    SXTL_32(v2, v2);    // i32 -> i64
+                    SCVTFDD(v2, v2);    // i64 -> double
+                    FCMPD(v1, v2);
+                    FCOM(x1, x2, x3);
+                    break;
+                case 3:
+                    INST_NAME("FICOMP ST0, Ed");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
+                    VLD32(v2, ed, fixedaddress);
+                    SXTL_32(v2, v2);    // i32 -> i64
+                    SCVTFDD(v2, v2);    // i64 -> double
+                    FCMPD(v1, v2);
+                    FCOM(x1, x2, x3);
+                    x87_do_pop(dyn, ninst, x3);
+                    break;
+                case 4:
+                    INST_NAME("FISUB ST0, Ed");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
+                    VLD32(v2, ed, fixedaddress);
+                    SXTL_32(v2, v2);    // i32 -> i64
+                    SCVTFDD(v2, v2);    // i64 -> double
+                    FSUBD(v1, v1, v2);
+                    break;
+                case 5:
+                    INST_NAME("FISUBR ST0, Ed");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
+                    VLD32(v2, ed, fixedaddress);
+                    SXTL_32(v2, v2);    // i32 -> i64
+                    SCVTFDD(v2, v2);    // i64 -> double
+                    FSUBD(v1, v2, v1);
+                    break;
+                case 6:
+                    INST_NAME("FIDIV ST0, Ed");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
+                    VLD32(v2, ed, fixedaddress);
+                    SXTL_32(v2, v2);    // i32 -> i64
+                    SCVTFDD(v2, v2);    // i64 -> double
+                    FDIVD(v1, v1, v2);
+                    break;
+                case 7:
+                    INST_NAME("FIDIVR ST0, Ed");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
+                    VLD32(v2, ed, fixedaddress);
+                    SXTL_32(v2, v2);    // i32 -> i64
+                    SCVTFDD(v2, v2);    // i64 -> double
+                    FDIVD(v1, v2, v1);
+                    break;
+            }
+    }
+    return addr;
+}
+
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index 5c7c21f3..792e7e9f 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -1210,7 +1210,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
 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);
 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_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);