about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-17 10:11:11 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-17 10:11:11 +0100
commita552e5a48f92004a1a76778bece8bf12a1a62ef2 (patch)
tree86937dda75b5fd8ce22fb031770aab64bf18a2ab /src
parentb553c3f3ac7fe752dca6c27be72bec5969a1c955 (diff)
downloadbox64-a552e5a48f92004a1a76778bece8bf12a1a62ef2.tar.gz
box64-a552e5a48f92004a1a76778bece8bf12a1a62ef2.zip
[DYNAREC] Various fixes, around GETED and other stuff (vvvvvv.x86_64 works again)
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64_printer.c14
-rwxr-xr-xsrc/dynarec/dynarec_arm64_00.c2
-rwxr-xr-xsrc/dynarec/dynarec_arm64_emit_math.c13
-rwxr-xr-xsrc/dynarec/dynarec_arm64_emit_tests.c2
-rwxr-xr-xsrc/dynarec/dynarec_arm64_helper.c20
-rwxr-xr-xsrc/dynarec/dynarec_arm64_helper.h12
-rwxr-xr-xsrc/dynarec/dynarec_arm64_pass2.h2
-rwxr-xr-xsrc/dynarec/dynarec_arm64_pass3.h2
8 files changed, 42 insertions, 25 deletions
diff --git a/src/dynarec/arm64_printer.c b/src/dynarec/arm64_printer.c
index 2e0c62c1..9530b039 100755
--- a/src/dynarec/arm64_printer.c
+++ b/src/dynarec/arm64_printer.c
@@ -13,6 +13,8 @@ static const char* WtSp[] = {"w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8
 

 static const char* conds[] = {"cEQ", "cNE", "cCS", "cCC", "cMI", "cPL", "cVS", "cVC", "cHI", "cLS", "cGE", "cLT", "cGT", "cLE", "c__", "inv"};

 

+#define abs(A) (((A)<0)?(-(A)):(A))

+

 typedef struct arm64_print_s {

     int N, S;

     int t, n, m, d;

@@ -108,20 +110,20 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
     if(isMask(opcode, "1x111000010iiiiiiiii01nnnnnttttt", &a)) {

         int size = (opcode>>30)&3;

         int offset = signExtend(imm, 9);

-        snprintf(buff, sizeof(buff), "LDR %s, [%s], %d", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], offset);

+        snprintf(buff, sizeof(buff), "LDR %s, [%s], %s0x%x", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));

         return buff;

     }

     if(isMask(opcode, "1x111000010iiiiiiiii11nnnnnttttt", &a)) {

         int size = (opcode>>30)&3;

         int offset = signExtend(imm, 9);

-        snprintf(buff, sizeof(buff), "LDR %s, [%s, %d]!", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], offset);

+        snprintf(buff, sizeof(buff), "LDR %s, [%s, %s0x%x]!", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));

         return buff;

     }

     if(isMask(opcode, "1x11100101iiiiiiiiiiiinnnnnttttt", &a)) {

         int size = (opcode>>30)&3;

         int offset = (imm)<<size;

         if(offset)

-            snprintf(buff, sizeof(buff), "LDR %s, [%s, %d]", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], offset);

+            snprintf(buff, sizeof(buff), "LDR %s, [%s, 0x%x]", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], offset);

         else

             snprintf(buff, sizeof(buff), "LDR %s, [%s]", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn]);

         return buff;

@@ -148,20 +150,20 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
     if(isMask(opcode, "1x111000000iiiiiiiii01nnnnnttttt", &a)) {

         int size = (opcode>>30)&3;

         int offset = signExtend(imm, 9);

-        snprintf(buff, sizeof(buff), "STR %s, [%s], %d", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], offset);

+        snprintf(buff, sizeof(buff), "STR %s, [%s], %s0x%x", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));

         return buff;

     }

     if(isMask(opcode, "1x111000000iiiiiiiii11nnnnnttttt", &a)) {

         int size = (opcode>>30)&3;

         int offset = signExtend(imm, 9);

-        snprintf(buff, sizeof(buff), "STR %s, [%s, %d]!", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], offset);

+        snprintf(buff, sizeof(buff), "STR %s, [%s, %s0x%x]!", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));

         return buff;

     }

     if(isMask(opcode, "1x11100100iiiiiiiiiiiinnnnnttttt", &a)) {

         int size = (opcode>>30)&3;

         int offset = (imm)<<size;

         if(offset)

-            snprintf(buff, sizeof(buff), "STR %s, [%s, %d]", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], offset);

+            snprintf(buff, sizeof(buff), "STR %s, [%s, 0x%x]", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], offset);

         else

             snprintf(buff, sizeof(buff), "STR %s, [%s]", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn]);

         return buff;

diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c
index b3a4f6f5..c9802203 100755
--- a/src/dynarec/dynarec_arm64_00.c
+++ b/src/dynarec/dynarec_arm64_00.c
@@ -324,7 +324,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     // calling a native function
                     x87_forget(dyn, ninst, x3, x4, 0);
                     sse_purge07cache(dyn, ninst, x3);
-                    GETIP(dyn->insts[ninst].natcall); // read the 0xCC already
+                    GETIP_(dyn->insts[ninst].natcall); // read the 0xCC already
                     STORE_XEMU_MINIMUM(xRIP);
                     CALL_S(x64Int3, -1);
                     LOAD_XEMU_MINIMUM(xRIP);
diff --git a/src/dynarec/dynarec_arm64_emit_math.c b/src/dynarec/dynarec_arm64_emit_math.c
index 0d867ecc..d83187f2 100755
--- a/src/dynarec/dynarec_arm64_emit_math.c
+++ b/src/dynarec/dynarec_arm64_emit_math.c
@@ -161,7 +161,7 @@ void emit_sub32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
     IFX(X_PEND) {
         STRxw_U12(s1, xEmu, offsetof(x64emu_t, op1));
         STRxw_U12(s2, xEmu, offsetof(x64emu_t, op2));
-        SET_DF(s3, d_sub32);
+        SET_DF(s3, rex.w?d_sub64:d_sub32);
     } else IFX(X_ALL) {
         SET_DFNONE(s3);
     }
@@ -225,10 +225,15 @@ void emit_sub32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int64_t c, in
         return;
     }
     IFX(X_PEND) {
+        if(rex.w) {
+            STRx_U12(s1, xEmu, offsetof(x64emu_t, op1));
+        } else {
+            MOVw(s3, s1);
+            STRx_U12(s3, xEmu, offsetof(x64emu_t, op1));
+        }
         MOV64x(s3, c);
-        STRx_U12(s1, xEmu, offsetof(x64emu_t, op1));
         STRx_U12(s3, xEmu, offsetof(x64emu_t, op2));
-        SET_DF(s4, d_sub32);
+        SET_DF(s4, rex.w?d_sub64:d_sub32);
     } else IFX(X_ALL) {
         SET_DFNONE(s4);
     }
@@ -262,7 +267,7 @@ void emit_sub32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int64_t c, in
         BFIw(xFlags, s4, F_AF, 1);    // AF: bc & 0x08
     }
     IFX(X_ZF|X_CF|X_OF) {
-        MOVw(s5, (1<<F_ZF)|(1<<F_CF)|(1<<F_OF));
+        MOV32w(s5, (1<<F_ZF)|(1<<F_CF)|(1<<F_OF));
         BICx(xFlags, xFlags, s5);
     }
     IFX(X_ZF) {
diff --git a/src/dynarec/dynarec_arm64_emit_tests.c b/src/dynarec/dynarec_arm64_emit_tests.c
index 986334e2..1c014b9f 100755
--- a/src/dynarec/dynarec_arm64_emit_tests.c
+++ b/src/dynarec/dynarec_arm64_emit_tests.c
@@ -300,7 +300,7 @@
 void emit_test32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5)
 {
     IFX(X_PEND) {
-        SET_DF(s3, d_tst32);
+        SET_DF(s3, rex.w?d_tst64:d_tst32);
     } else {
         SET_DFNONE(s4);
     }
diff --git a/src/dynarec/dynarec_arm64_helper.c b/src/dynarec/dynarec_arm64_helper.c
index 1bf37ab3..2b5fd809 100755
--- a/src/dynarec/dynarec_arm64_helper.c
+++ b/src/dynarec/dynarec_arm64_helper.c
@@ -39,15 +39,15 @@ uintptr_t geted(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, u
     if(!(nextop&0xC0)) {
         if((nextop&7)==4) {
             uint8_t sib = F8;
-            int sib_reg = (sib>>3)&7;
+            int sib_reg = ((sib>>3)&7)+(rex.x<<3);
             if((sib&0x7)==5) {
                 uint64_t tmp = F32S64;
                 if (sib_reg!=4) {
                     if(tmp && ((tmp<absmin) || (tmp>absmax) || (tmp&mask))) {
                         MOV64x(scratch, tmp);
-                        ADDx_REG_LSL(ret, scratch, xRAX+sib_reg+(rex.x<<3), (sib>>6));
+                        ADDx_REG_LSL(ret, scratch, xRAX+sib_reg, (sib>>6));
                     } else {
-                        LSLx(ret, xRAX+sib_reg+(rex.x<<3), (sib>>6));
+                        LSLx(ret, xRAX+sib_reg, (sib>>6));
                         *fixaddress = tmp;
                     }
                 } else {
@@ -55,7 +55,7 @@ uintptr_t geted(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, u
                 }
             } else {
                 if (sib_reg!=4) {
-                    ADDx_REG_LSL(ret, xRAX+(sib&0x7)+(rex.b<<3), xRAX+sib_reg+(rex.x<<3), (sib>>6));
+                    ADDx_REG_LSL(ret, xRAX+(sib&0x7)+(rex.b<<3), xRAX+sib_reg, (sib>>6));
                 } else {
                     ret = xRAX+(sib&0x7)+(rex.b<<3);
                 }
@@ -74,7 +74,7 @@ uintptr_t geted(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, u
         int sib_reg = 0;
         if((nextop&7)==4) {
             sib = F8;
-            sib_reg = (sib>>3)&7;
+            sib_reg = ((sib>>3)&7)+(rex.x<<3);
         }
         if(nextop&0x80)
             i64 = F32S;
@@ -84,7 +84,7 @@ uintptr_t geted(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, u
             *fixaddress = i64;
             if((nextop&7)==4) {
                 if (sib_reg!=4) {
-                    ADDx_REG_LSL(ret, xRAX+(sib&0x07)+(rex.b<<3), xRAX+sib_reg+(rex.x<<3), (sib>>6));
+                    ADDx_REG_LSL(ret, xRAX+(sib&0x07)+(rex.b<<3), xRAX+sib_reg, (sib>>6));
                 } else {
                     ret = xRAX+(sib&0x07)+(rex.b<<3);
                 }
@@ -96,7 +96,7 @@ uintptr_t geted(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, u
             if(i64<0x1000) {
                 if((nextop&7)==4) {
                     if (sib_reg!=4) {
-                        ADDx_REG_LSL(scratch, xRAX+(sib&0x07)+(rex.b<<3), xRAX+sib_reg+(rex.x<<3), (sib>>6));
+                        ADDx_REG_LSL(scratch, xRAX+(sib&0x07)+(rex.b<<3), xRAX+sib_reg, (sib>>6));
                     } else {
                         scratch = xRAX+(sib&0x07)+(rex.b<<3);
                     }
@@ -116,7 +116,7 @@ uintptr_t geted(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, u
                         } else {
                             ADDx_REG(scratch, scratch, xRAX+(sib&0x07)+(rex.b<<3));
                         }
-                        ADDx_REG_LSL(ret, scratch, xRAX+sib_reg+(rex.x<<3), (sib>>6));
+                        ADDx_REG_LSL(ret, scratch, xRAX+sib_reg, (sib>>6));
                     } else {
                         PASS3(int tmp = xRAX+(sib&0x07)+(rex.b<<3));
                         if(sub) {
@@ -225,7 +225,7 @@ void jump_to_epilog(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst)
             MOVx(xRIP, reg);
         }
     } else {
-        GETIP(ip);
+        GETIP_(ip);
     }
     TABLE64(x2, (uintptr_t)arm64_epilog);
     BR(x2);
@@ -251,7 +251,7 @@ void jump_to_next(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst)
     } else {
         uintptr_t p = getJumpTableAddress64(ip); 
         TABLE64(x2, p);
-        GETIP(ip);
+        GETIP_(ip);
         LDRx_U12(x3, x2, 0);
     }
     MOVx(x1, xRIP);
diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h
index 4fef2acb..5f1b8e20 100755
--- a/src/dynarec/dynarec_arm64_helper.h
+++ b/src/dynarec/dynarec_arm64_helper.h
@@ -427,16 +427,26 @@
 
 #if STEP < 2
 #define GETIP(A)
+#define GETIP_(A)
 #else
 #define GETIP(A)                                    \
     if(dyn->last_ip && (A-dyn->last_ip)<0x1000) {   \
         uint64_t delta = A-dyn->last_ip;            \
         dyn->last_ip += delta;                      \
-        ADDx_U12(xRIP, xRIP, delta);                \
+        if(delta) {                                 \
+            ADDx_U12(xRIP, xRIP, delta);            \
+        }                                           \
     } else {                                        \
         dyn->last_ip = A;                           \
         TABLE64(xRIP, dyn->last_ip);                \
     }
+#define GETIP_(A)                                   \
+    if(dyn->last_ip && (A-dyn->last_ip)<0x1000) {   \
+        uint64_t delta = A-dyn->last_ip;            \
+        ADDx_U12(xRIP, xRIP, delta);                \
+    } else {                                        \
+        TABLE64(xRIP, A);                           \
+    }
 #endif
 
 #if STEP < 2
diff --git a/src/dynarec/dynarec_arm64_pass2.h b/src/dynarec/dynarec_arm64_pass2.h
index f0bf7fbd..838ed665 100755
--- a/src/dynarec/dynarec_arm64_pass2.h
+++ b/src/dynarec/dynarec_arm64_pass2.h
@@ -7,4 +7,4 @@
 #define INST_EPILOG dyn->insts[ninst].epilog = dyn->arm_size; 
 #define INST_NAME(name) 
 #define NEW_BARRIER_INST    if(ninst) ++dyn->sons_size
-#define TABLE64(A, V)   {Table64(dyn, (V)); EMIT(0);}
\ No newline at end of file
+#define TABLE64(A, V)   if((V)>0xffffffffL) {Table64(dyn, (V)); EMIT(0);} else {MOV64x(A, V);}
\ No newline at end of file
diff --git a/src/dynarec/dynarec_arm64_pass3.h b/src/dynarec/dynarec_arm64_pass3.h
index a94c61c7..f58e9364 100755
--- a/src/dynarec/dynarec_arm64_pass3.h
+++ b/src/dynarec/dynarec_arm64_pass3.h
@@ -32,4 +32,4 @@
     ++dyn->sons_size;                               \
     }
 
-#define TABLE64(A, V)   {int val64offset = Table64(dyn, (V)); MESSAGE(LOG_DUMP, "  Table64: 0x%lx\n", (V)); LDRx_literal(A, val64offset);}
\ No newline at end of file
+#define TABLE64(A, V)   if((V)>0xffffffffL) {int val64offset = Table64(dyn, (V)); MESSAGE(LOG_DUMP, "  Table64: 0x%lx\n", (V)); LDRx_literal(A, val64offset);} else {MOV64x(A, V);}
\ No newline at end of file