about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-22 12:40:07 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-22 12:40:07 +0100
commit04aa1af72e68a93d42afd90439744574f3668cda (patch)
treef3555dc0fc0e97cfabaa8516e431c5f8ac9bb31b /src
parent466a8cb1079785b7275e78cd30b1a9d2d4247a6d (diff)
downloadbox64-04aa1af72e68a93d42afd90439744574f3668cda.tar.gz
box64-04aa1af72e68a93d42afd90439744574f3668cda.zip
[DYNAREC] Added 64 8B opcodes, plus some fixes to FS access
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64_printer.c8
-rw-r--r--src/dynarec/dynarec_arm64_64.c13
-rwxr-xr-xsrc/dynarec/dynarec_arm64_helper.c11
-rwxr-xr-xsrc/dynarec/dynarec_arm64_helper.h8
-rwxr-xr-xsrc/emu/x64emu_private.h2
5 files changed, 31 insertions, 11 deletions
diff --git a/src/dynarec/arm64_printer.c b/src/dynarec/arm64_printer.c
index fbd1740e..79f2d6ec 100755
--- a/src/dynarec/arm64_printer.c
+++ b/src/dynarec/arm64_printer.c
@@ -647,22 +647,22 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
     }

     if(isMask(opcode, "01010100iiiiiiiiiiiiiiiiiii0cccc", &a)) {

         int offset = signExtend(imm, 19)<<2;

-        snprintf(buff, sizeof(buff), "B.%s #+%d\t; %p", conds[cond], offset, (void*)(addr + offset));

+        snprintf(buff, sizeof(buff), "B.%s #+%di\t; %p", conds[cond], offset>>2, (void*)(addr + offset));

         return buff;

     }

     if(isMask(opcode, "000101iiiiiiiiiiiiiiiiiiiiiiiiii", &a)) {

         int offset = signExtend(imm, 26)<<2;

-        snprintf(buff, sizeof(buff), "B #+%d\t; %p", offset, (void*)(addr + offset));

+        snprintf(buff, sizeof(buff), "B #+%di\t; %p", offset>>2, (void*)(addr + offset));

         return buff;

     }

     if(isMask(opcode, "f0110100iiiiiiiiiiiiiiiiiiittttt", &a)) {

         int offset = signExtend(imm, 19)<<2;

-        snprintf(buff, sizeof(buff), "CBZ %s, #%+d\t; %p", Xt[Rt], offset, (void*)(addr + offset));

+        snprintf(buff, sizeof(buff), "CBZ %s, #%+di\t; %p", Xt[Rt], offset>>2, (void*)(addr + offset));

         return buff;

     }

     if(isMask(opcode, "f0110101iiiiiiiiiiiiiiiiiiittttt", &a)) {

         int offset = signExtend(imm, 19)<<2;

-        snprintf(buff, sizeof(buff), "CBNZ %s, #%+d\t; %p", Xt[Rt], offset, (void*)(addr + offset));

+        snprintf(buff, sizeof(buff), "CBNZ %s, #%+di\t; %p", Xt[Rt], offset>>2, (void*)(addr + offset));

         return buff;

     }

     if(isMask(opcode, "f0011010100mmmmmcccc00nnnnnddddd", &a)) {

diff --git a/src/dynarec/dynarec_arm64_64.c b/src/dynarec/dynarec_arm64_64.c
index 18517106..8854ca3f 100644
--- a/src/dynarec/dynarec_arm64_64.c
+++ b/src/dynarec/dynarec_arm64_64.c
@@ -61,6 +61,19 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             emit_xor32(dyn, ninst, rex, gd, ed, x3, x4);
             break;
                     
+        case 0x8B:
+            INST_NAME("MOV Gd, FS:Ed");
+            grab_segdata(dyn, addr, ninst, x4, _FS);
+            nextop=F8;
+            GETGD;
+            if(MODREG) {   // reg <= reg
+                MOVxw_REG(gd, xRAX+(nextop&7)+(rex.b<<3));
+            } else {                    // mem <= reg
+                addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0, rex, 0, 0);
+                LDRxw_REG(gd, ed, x4);
+            }
+            break;
+
         default:
             DEFAULT;
     }
diff --git a/src/dynarec/dynarec_arm64_helper.c b/src/dynarec/dynarec_arm64_helper.c
index 27447f7c..6be6efc4 100755
--- a/src/dynarec/dynarec_arm64_helper.c
+++ b/src/dynarec/dynarec_arm64_helper.c
@@ -379,9 +379,16 @@ void grab_segdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg, int se
     int t1 = x1, t2 = x4;
     if(reg==t1) ++t1;
     if(reg==t2) ++t2;
-    LDRx_U12(t2, xEmu, offsetof(x64emu_t, segs_serial[segment]));// fast check here
+    LDRw_U12(t2, xEmu, offsetof(x64emu_t, segs_serial[segment]));
     LDRx_U12(reg, xEmu, offsetof(x64emu_t, segs_offs[segment]));
-    CBZx_MARKSEG(t2);
+    if(segment==_GS) {
+        CBNZw_MARKSEG(t2);   // fast check
+    } else {
+        LDRx_U12(t1, xEmu, offsetof(x64emu_t, context));
+        LDRw_U12(t1, t1, offsetof(box64context_t, sel_serial));
+        SUBw_REG(t1, t1, t2);
+        CBZw_MARKSEG(t1);
+    }
     MOVZw(x1, segment);
     call_c(dyn, ninst, GetSegmentBaseEmu, t2, reg, 1, 0);
     MARKSEG;
diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h
index 785c966c..516c9364 100755
--- a/src/dynarec/dynarec_arm64_helper.h
+++ b/src/dynarec/dynarec_arm64_helper.h
@@ -298,13 +298,13 @@
     j32 = GETMARKSEG-(dyn->arm_size);   \
     Bcond(cond, j32)
 // Branch to MARKSEG if reg is 0 (use j32)
-#define CBZx_MARKSEG(reg)    \
-    j32 = GETMARKSEG-(dyn->arm_size);   \
-    CBZx(reg, j32)
-// Branch to MARKSEG if reg is 0 (use j32)
 #define CBZw_MARKSEG(reg)    \
     j32 = GETMARKSEG-(dyn->arm_size);   \
     CBZw(reg, j32)
+// Branch to MARKSEG if reg is not 0 (use j32)
+#define CBNZw_MARKSEG(reg)              \
+    j32 = GETMARKSEG-(dyn->arm_size);   \
+    CBNZw(reg, j32)
 // Branch to MARKLOCK if cond (use j32)
 #define B_MARKLOCK(cond)    \
     j32 = GETMARKLOCK-(dyn->arm_size);   \
diff --git a/src/emu/x64emu_private.h b/src/emu/x64emu_private.h
index ed7ae653..cf7d459b 100755
--- a/src/emu/x64emu_private.h
+++ b/src/emu/x64emu_private.h
@@ -57,7 +57,7 @@ typedef struct x64emu_s {
     // segments
     uint32_t    segs[6];        // only 32bits value?
     uintptr_t   segs_offs[6];   // computed offset associate with segment
-    uint64_t    segs_serial[6];  // are seg offset clean (not 0) or does they need to be re-computed (0)? For GS, serial need to be the same as context->sel_serial
+    uint32_t    segs_serial[6];  // are seg offset clean (not 0) or does they need to be re-computed (0)? For GS, serial need to be the same as context->sel_serial
     // parent context
     box64context_t *context;
     // cpu helpers