about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-18 15:08:26 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-18 15:08:26 +0100
commitcb25e077f99e608ecce1f8358ea9f33421a1e810 (patch)
tree3da1e920bae17c9ae840bb1ec7e40004deaf5abc /src
parent0551f13f0ee258d6325285e20833328950e18bbc (diff)
downloadbox64-cb25e077f99e608ecce1f8358ea9f33421a1e810.tar.gz
box64-cb25e077f99e608ecce1f8358ea9f33421a1e810.zip
[DYNAREC] Added CC 'Native call' and 0F 1F NOP opcodes
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64_epilog.S60
-rwxr-xr-xsrc/dynarec/arm64_printer.c2
-rwxr-xr-xsrc/dynarec/arm64_prolog.S29
-rwxr-xr-xsrc/dynarec/dynarec_arm64_00.c57
-rwxr-xr-xsrc/dynarec/dynarec_arm64_0f.c98
-rwxr-xr-xsrc/dynarec/dynarec_arm64_helper.h14
-rwxr-xr-xsrc/emu/x64emu_private.h4
-rwxr-xr-xsrc/main.c3
8 files changed, 199 insertions, 68 deletions
diff --git a/src/dynarec/arm64_epilog.S b/src/dynarec/arm64_epilog.S
index 99723873..1a3b3ddc 100755
--- a/src/dynarec/arm64_epilog.S
+++ b/src/dynarec/arm64_epilog.S
@@ -29,25 +29,16 @@ arm64_epilog:
     str     x27, [x0, (8 * 17)] // put back reg value in emu, including EIP (so x27 must be EIP now)
     //restore all used register
     //vpop     {d8-d15}
-    ldr     x10, [sp, (8 *  0)]
-    ldr     x11, [sp, (8 *  1)]
-    ldr     x12, [sp, (8 *  2)]
-    ldr     x13, [sp, (8 *  3)]
-    ldr     x14, [sp, (8 *  4)]
-    ldr     x15, [sp, (8 *  5)]
-    ldr     x16, [sp, (8 *  6)]
-    ldr     x17, [sp, (8 *  7)]
-    ldr     x18, [sp, (8 *  8)]
-    ldr     x19, [sp, (8 *  9)]
-    ldr     x20, [sp, (8 * 10)]
-    ldr     x21, [sp, (8 * 11)]
-    ldr     x22, [sp, (8 * 12)]
-    ldr     x23, [sp, (8 * 13)]
-    ldr     x24, [sp, (8 * 14)]
-    ldr     x25, [sp, (8 * 15)]
-    ldr     x26, [sp, (8 * 16)]
-    ldr     x27, [sp, (8 * 17)]
-    add     sp,  sp, (8 * 18)
+    ldr     x19, [sp, (8 * 0)]
+    ldr     x20, [sp, (8 * 1)]
+    ldr     x21, [sp, (8 * 2)]
+    ldr     x22, [sp, (8 * 3)]
+    ldr     x23, [sp, (8 * 4)]
+    ldr     x24, [sp, (8 * 5)]
+    ldr     x25, [sp, (8 * 6)]
+    ldr     x26, [sp, (8 * 7)]
+    ldr     x27, [sp, (8 * 8)]
+    add     sp,  sp, (8 * 10)
     ldp     lr, fp, [sp], 16  // saved lr
     //end, return...
     ret
@@ -57,25 +48,16 @@ arm64_epilog:
 arm64_epilog_fast:
     //restore all used register
     //vpop     {d8-d15}
-    ldr     x10, [sp, (8 *  0)]
-    ldr     x11, [sp, (8 *  1)]
-    ldr     x12, [sp, (8 *  2)]
-    ldr     x13, [sp, (8 *  3)]
-    ldr     x14, [sp, (8 *  4)]
-    ldr     x15, [sp, (8 *  5)]
-    ldr     x16, [sp, (8 *  6)]
-    ldr     x17, [sp, (8 *  7)]
-    ldr     x18, [sp, (8 *  8)]
-    ldr     x19, [sp, (8 *  9)]
-    ldr     x20, [sp, (8 * 10)]
-    ldr     x21, [sp, (8 * 11)]
-    ldr     x22, [sp, (8 * 12)]
-    ldr     x23, [sp, (8 * 13)]
-    ldr     x24, [sp, (8 * 14)]
-    ldr     x25, [sp, (8 * 15)]
-    ldr     x26, [sp, (8 * 16)]
-    ldr     x27, [sp, (8 * 17)]
-    add     sp,  sp, (8 * 18)
-    ldp     lr, fp, [sp, 16]!  // saved lr
+    ldr     x19, [sp, (8 * 0)]
+    ldr     x20, [sp, (8 * 1)]
+    ldr     x21, [sp, (8 * 2)]
+    ldr     x22, [sp, (8 * 3)]
+    ldr     x23, [sp, (8 * 4)]
+    ldr     x24, [sp, (8 * 5)]
+    ldr     x25, [sp, (8 * 6)]
+    ldr     x26, [sp, (8 * 7)]
+    ldr     x27, [sp, (8 * 8)]
+    add     sp,  sp, (8 * 10)
+    ldp     lr, fp, [sp], 16  // saved lr
     //end, return...
     ret
diff --git a/src/dynarec/arm64_printer.c b/src/dynarec/arm64_printer.c
index 082260b9..0f9abb55 100755
--- a/src/dynarec/arm64_printer.c
+++ b/src/dynarec/arm64_printer.c
@@ -423,6 +423,8 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
             snprintf(buff, sizeof(buff), "UXTB %s, %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn]);

         else if(immr==0 && imms==0b001111)

             snprintf(buff, sizeof(buff), "UXTH %s, %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn]);

+        else if(imms>=immr)

+            snprintf(buff, sizeof(buff), "UBFX %s, %s, %d, %d", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], immr, imms-immr+1);

         else

             snprintf(buff, sizeof(buff), "UBFM %s, %s, %d, %d", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], immr, imms);

 

diff --git a/src/dynarec/arm64_prolog.S b/src/dynarec/arm64_prolog.S
index c1dc3b48..679af0ce 100755
--- a/src/dynarec/arm64_prolog.S
+++ b/src/dynarec/arm64_prolog.S
@@ -10,25 +10,16 @@
 arm64_prolog:
     //save all 18 used register
     stp     lr, fp, [sp, -16]!  // save lr
-    sub     sp,  sp, (8 * 18)
-    str     x10, [sp, (8 *  0)]
-    str     x11, [sp, (8 *  1)]
-    str     x12, [sp, (8 *  2)]
-    str     x13, [sp, (8 *  3)]
-    str     x14, [sp, (8 *  4)]
-    str     x15, [sp, (8 *  5)]
-    str     x16, [sp, (8 *  6)]
-    str     x17, [sp, (8 *  7)]
-    str     x18, [sp, (8 *  8)]
-    str     x19, [sp, (8 *  9)]
-    str     x20, [sp, (8 * 10)]
-    str     x21, [sp, (8 * 11)]
-    str     x22, [sp, (8 * 12)]
-    str     x23, [sp, (8 * 13)]
-    str     x24, [sp, (8 * 14)]
-    str     x25, [sp, (8 * 15)]
-    str     x26, [sp, (8 * 16)]
-    str     x27, [sp, (8 * 17)]
+    sub     sp,  sp, (8 * 10)
+    str     x19, [sp, (8 * 0)]
+    str     x20, [sp, (8 * 1)]
+    str     x21, [sp, (8 * 2)]
+    str     x22, [sp, (8 * 3)]
+    str     x23, [sp, (8 * 4)]
+    str     x24, [sp, (8 * 5)]
+    str     x25, [sp, (8 * 6)]
+    str     x26, [sp, (8 * 7)]
+    str     x27, [sp, (8 * 8)]
     //vpush     {d8-d15}    // save NEON regs?
     //setup emu -> register
     ldr     x10, [x0, (8 *  0)]
diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c
index bfc53bfc..a70fba00 100755
--- a/src/dynarec/dynarec_arm64_00.c
+++ b/src/dynarec/dynarec_arm64_00.c
@@ -109,6 +109,10 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             emit_or32c(dyn, ninst, rex, xRAX, i32, x3, x4);
             break;
 
+        case 0x0F:
+            addr = dynarec64_0F(dyn, addr, ip, ninst, rex, ok, need_epilog);
+            break;
+
         case 0x21:
             INST_NAME("AND Ed, Gd");
             SETFLAGS(X_ALL, SF_SET);
@@ -487,7 +491,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
         case 0xC3:
             INST_NAME("RET");
             // SETFLAGS(X_ALL, SF_SET);    // Hack, set all flags (to an unknown state...)
-            // ^^^ that hack break PlantsVsZombies and GOG Setup under wine....
             READFLAGS(X_PEND);  // so instead, force the defered flags, so it's not too slow, and flags are not lost
             BARRIER(2);
             ret_to_epilog(dyn, ninst);
@@ -495,6 +498,58 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             *ok = 0;
             break;
 
+        case 0xCC:
+            SETFLAGS(X_ALL, SF_SET);    // Hack, set all flags (to an unknown state...)
+            if(PK(0)=='S' && PK(1)=='C') {
+                addr+=2;
+                BARRIER(2);
+                INST_NAME("Special Box64 instruction");
+                if((PK64(0)==0))
+                {
+                    addr+=8;
+                    MESSAGE(LOG_DEBUG, "Exit x64 Emu\n");
+                    //GETIP(ip+1+2);    // no use
+                    //STORE_XEMU_REGS(xRIP);    // no need, done in epilog
+                    MOV32w(x1, 1);
+                    STRw_U12(x1, xEmu, offsetof(x64emu_t, quit));
+                    *ok = 0;
+                    *need_epilog = 1;
+                } else {
+                    MESSAGE(LOG_DUMP, "Native Call to %s\n", GetNativeName(GetNativeFnc(ip)));
+                    x87_forget(dyn, ninst, x3, x4, 0);
+                    sse_purge07cache(dyn, ninst, x3);
+                    GETIP(ip+1); // read the 0xCC
+                    STORE_XEMU_MINIMUM(xRIP);
+                    CALL_S(x64Int3, -1);
+                    LOAD_XEMU_MINIMUM(xRIP);
+                    addr+=8+8;
+                    TABLE64(x3, addr); // expected return address
+                    CMPSx_REG(xRIP, x3);
+                    B_MARK(cNE);
+                    LDRw_U12(x1, xEmu, offsetof(x64emu_t, quit));
+                    CMPSw_U12(x1, 1);
+                    B_NEXT(cNE);
+                    MARK;
+                    jump_to_epilog(dyn, 0, xRIP, ninst);
+                }
+            } else {
+                #if 0
+                INST_NAME("INT 3");
+                // check if TRAP signal is handled
+                LDRx_U12(x1, xEmu, offsetof(x64emu_t, context));
+                MOV32w(x2, offsetof(box64context_t, signals[SIGTRAP]));
+                LDRx_REG_LSL3(x3, x1, x2);
+                CMPSx_U12(x3, 0);
+                B_NEXT(cNE);
+                MOV32w(x1, SIGTRAP);
+                CALL_(raise, -1, 0);
+                break;
+                #else
+                DEFAULT;
+                #endif
+            }
+            break;
+
         case 0xE8:
             INST_NAME("CALL Id");
             i32 = F32S;
diff --git a/src/dynarec/dynarec_arm64_0f.c b/src/dynarec/dynarec_arm64_0f.c
new file mode 100755
index 00000000..bc2bdd86
--- /dev/null
+++ b/src/dynarec/dynarec_arm64_0f.c
@@ -0,0 +1,98 @@
+#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 "my_cpuid.h"

+#include "emu/x87emu_private.h"

+

+#include "dynarec_arm64_functions.h"

+#include "dynarec_arm64_helper.h"

+

+#define GETGX(a)    \

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

+    a = sse_get_reg(dyn, ninst, x1, gd)

+#define GETEX(a)    \

+    if(MODREG) { \

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

+    } else {    \

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

+        a = fpu_get_scratch_quad(dyn); \

+        VLD1Q_64(a, ed);    \

+    }

+#define GETGM(a)    \

+    gd = (nextop&0x38)>>3;  \

+    a = mmx_get_reg(dyn, ninst, x1, gd)

+#define GETEM(a)    \

+    if(MODREG) { \

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

+    } else {    \

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

+        a = fpu_get_scratch_double(dyn); \

+        VLD1_64(a, ed);    \

+    }

+#define PUTEM(a)    \

+    if(!MODREG) { \

+        VST1_64(a, ed);    \

+    }

+

+uintptr_t dynarec64_0F(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, i32_, j32;

+    uint8_t gd, ed;

+    uint8_t wback, wb1, wb2;

+    uint8_t eb1, eb2;

+    uint8_t gb1, gb2;

+    int v0, v1, v2;

+    int q0, q1;

+    int d0, d1;

+    int s0;

+    int fixedaddress;

+    int parity;

+    MAYUSE(s0);

+    MAYUSE(q1);

+    MAYUSE(v2);

+    MAYUSE(gb2);

+    MAYUSE(gb1);

+    MAYUSE(eb2);

+    MAYUSE(eb1);

+    MAYUSE(wb2);

+    MAYUSE(j32);

+    #if STEP == 3

+    //static const int8_t mask_shift8[] = { -7, -6, -5, -4, -3, -2, -1, 0 };

+    #endif

+

+    switch(opcode) {

+

+

+

+        case 0x1F:

+            INST_NAME("NOP (multibyte)");

+            nextop = F8;

+            FAKEED;

+            break;

+

+

+        default:

+            DEFAULT;

+    }

+    return addr;

+}

+

diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h
index 68042470..28dfc97e 100755
--- a/src/dynarec/dynarec_arm64_helper.h
+++ b/src/dynarec/dynarec_arm64_helper.h
@@ -93,11 +93,11 @@
                 }
 #define WBACKO(O)   if(wback) {STR_REG_LSL_IMM5(ed, wback, O, 0);}
 //FAKEELike GETED, but doesn't get anything
-#define FAKEED  if((nextop&0xC0)!=0xC0) {   \
+#define FAKEED  if(!MODREG) {   \
                     addr = fakeed(dyn, addr, ninst, nextop); \
                 }
 // GETGW extract x64 register in gd, that is i
-#define GETGW(i) gd = xEAX+((nextop&0x38)>>3); UXTH(i, gd, 0); gd = i;
+#define GETGW(i) gd = xEAX+((nextop&0x38)>>3)+(rex.r<<3); UXTH(i, gd, 0); gd = i;
 //GETEWW will use i for ed, and can use w for wback.
 #define GETEWW(w, i) if((nextop&0xC0)==0xC0) {  \
                     wback = xEAX+(nextop&7);\
@@ -139,7 +139,7 @@
 // Write w back to original register / memory
 #define EWBACKW(w)   if(wb1) {STRH_IMM8(w, wback, fixedaddress);} else {BFI(wback, w, 0, 16);}
 // Write back gd in correct register
-#define GWBACK       BFI((xEAX+((nextop&0x38)>>3)), gd, 0, 16);
+#define GWBACK       BFI((xEAX+((nextop&0x38)>>3)+(rex.r<<3)), gd, 0, 16);
 //GETEB will use i for ed, and can use r3 for wback.
 #define GETEB(i) if((nextop&0xC0)==0xC0) {  \
                     wback = (nextop&7);     \
@@ -190,12 +190,14 @@
                     gb2 = ((gd&4)>>2);      \
                     gb1 = xEAX+(gd&3);      \
                     gd = i;                 \
+                    nopenope!               \
                     UXTB(gd, gb1, gb2);
 //GETSGB signe extend GB, will use i for gd
 #define GETSGB(i)    gd = (nextop&0x38)>>3; \
                     gb2 = ((gd&4)>>2);      \
                     gb1 = xEAX+(gd&3);      \
                     gd = i;                 \
+                    nopenope!               \
                     SXTB(gd, gb1, gb2);
 // Write gb (gd) back to original register / memory
 #define GBBACK   BFI(gb1, gd, gb2*8, 8);
@@ -373,7 +375,7 @@
     LOAD_REG(R8);          \
     LOAD_REG(R9);          \
     LDRx_U12(xFlags, xEmu, offsetof(x64emu_t, eflags)); \
-    if(A) {LDRx_U12(A, xEmu, offsetof(x64emu_t, ip));}
+    if(A) {LDRx_U12(A, xEmu, offsetof(x64emu_t, ip)); if(A==xRIP) dyn->last_ip = 0;}
 
 #define SET_DFNONE(S)    if(!dyn->dfnone) {MOVZw(S, d_none); STRw_U12(S, xEmu, offsetof(x64emu_t, df)); dyn->dfnone=1;}
 #define SET_DF(S, N)     if(N) {MOVZw(S, N); STRw_U12(S, xEmu, offsetof(x64emu_t, df)); dyn->dfnone=0;} else SET_DFNONE(S)
@@ -443,7 +445,7 @@
 #define GETIP_(A)                                   \
     if(dyn->last_ip && (A-dyn->last_ip)<0x1000) {   \
         uint64_t delta = A-dyn->last_ip;            \
-        ADDx_U12(xRIP, xRIP, delta);                \
+        if(delta) {ADDx_U12(xRIP, xRIP, delta);}    \
     } else {                                        \
         TABLE64(xRIP, A);                           \
     }
@@ -737,7 +739,7 @@ void fpu_pushcache(dynarec_arm_t* dyn, int ninst, int s1);
 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, 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* ok, int* need_epilog);
 //uintptr_t dynarec64_FS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog);
 //uintptr_t dynarec64_GS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog);
 //uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog);
diff --git a/src/emu/x64emu_private.h b/src/emu/x64emu_private.h
index 27bb60f1..ed7ae653 100755
--- a/src/emu/x64emu_private.h
+++ b/src/emu/x64emu_private.h
@@ -63,8 +63,6 @@ typedef struct x64emu_s {
     // cpu helpers
     reg64_t     zero;
     reg64_t     *sbiidx[16];
-    // scratch stack, used for alignement of double and 64bits ints on arm. 200 elements should be enough
-    uint64_t    scratch[200];
     // emu control
     int         quit;
     int         error;
@@ -73,6 +71,8 @@ typedef struct x64emu_s {
     int         exit;
     int         quitonlongjmp;  // quit if longjmp is called
     int         longjmp;        // if quit because of longjmp
+    // scratch stack, used for alignement of double and 64bits ints on arm. 200 elements should be enough
+    uint64_t    scratch[200];
     // local stack, do be deleted when emu is freed
     void*       stack2free; // this is the stack to free (can be NULL)
     void*       init_stack; // initial stack (owned or not)
diff --git a/src/main.c b/src/main.c
index 0811136c..c14591b0 100755
--- a/src/main.c
+++ b/src/main.c
@@ -933,7 +933,8 @@ int main(int argc, const char **argv, const char **env) {
     if(ld_preload.size) {
         for (int i=0; i<ld_preload.size; ++i) {
             if(AddNeededLib(NULL, NULL, 0, ld_preload.paths[i], my_context, emu)) {
-                printf_log(LOG_INFO, "Warning, cannot pre-load lib: \"%s\"\n", ld_preload.paths[i]);
+                if(!strstr(ld_preload.paths[i], "vgpreload_"))
+                    printf_log(LOG_INFO, "Warning, cannot pre-load lib: \"%s\"\n", ld_preload.paths[i]);
             }            
         }
     }