about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorxctan <xctan@cirno.icu>2023-07-28 17:31:46 +0000
committerGitHub <noreply@github.com>2023-07-28 19:31:46 +0200
commitf5fadea30e6d71046293f382d98f9f570bd31321 (patch)
tree096a4f129e648a6b3ab522b9995be0d18508553e /src
parentbedfb82066a283e370b1cae60d0f860665dcb904 (diff)
downloadbox64-f5fadea30e6d71046293f382d98f9f570bd31321.tar.gz
box64-f5fadea30e6d71046293f382d98f9f570bd31321.zip
[RV64_DYNAREC] Added more opcodes for Yuzu (#911)
* [RV64_DYNAREC] Fixed PTEST opcode

* [RV64_DYNAREC] Added 64 66 89 MOV opcode

* [RV64_DYNAREC] Added 66 87 XCHG opcode
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_66.c61
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f.c2
-rw-r--r--src/dynarec/rv64/dynarec_rv64_6664.c30
3 files changed, 91 insertions, 2 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c
index 49a7ef65..66a9f1c1 100644
--- a/src/dynarec/rv64/dynarec_rv64_66.c
+++ b/src/dynarec/rv64/dynarec_rv64_66.c
@@ -427,6 +427,67 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             GETGW(x2);
             emit_test16(dyn, ninst, x1, x2, x3, x4, x5);
             break;
+        case 0x87:
+            INST_NAME("(LOCK)XCHG Ew, Gw");
+            nextop = F8;
+            if(MODREG) {
+                GETGD;
+                GETED(0);
+                ADDI(x1, gd, 0);
+                LUI(x3, 0xffff0);
+                AND(gd, gd, x3);
+                ZEXTH(x4, ed);
+                OR(gd, gd, x4);
+                AND(ed, ed, x3);
+                ZEXTH(x4, x1);
+                OR(ed, ed, x4);
+            } else {
+                GETGD;
+                addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
+                SMDMB();
+
+                ANDI(x3, ed, 1);
+                BNEZ_MARK(x3);
+
+                ANDI(x3, ed, 0b10);
+                LUI(x5, 0xffff0);
+                ZEXTH(x6, gd);
+                BNEZ_MARK3(x3);
+
+                MARKLOCK;
+                LR_W(x1, ed, 1, 0);
+                AND(x3, x1, x5);
+                OR(x3, x3, x6);
+                SC_W(x3, x3, ed, 0, 1);
+                BNEZ_MARKLOCK(x3);
+                ZEXTH(x1, x1);
+                B_MARK2_nocond;
+
+                MARK3;
+                NOT(x5, x5);
+                SLLI(x5, x5, 16);
+                SLLI(x6, x6, 16);
+                NOT(x5, x5);
+                LR_W(x1, ed, 1, 0);
+                AND(x3, x1, x5);
+                OR(x3, x3, x6);
+                SC_W(x3, x3, ed, 0, 1);
+                BNEZ(x3, -4 * 4);
+                SRLI(x1, x1, 16);
+                ZEXTH(x1, x1);
+                B_MARK2_nocond;
+
+                MARK;
+                LHU(x1, ed, 0);
+                SH(gd, ed, 0);
+
+                MARK2;
+                SMDMB();
+                LUI(x5, 0xffff0);
+                AND(gd, gd, x5);
+                OR(gd, gd, x1);
+            }
+            break;
         case 0x89:
             INST_NAME("MOV Ew, Gw");
             nextop = F8;
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c
index 3f51289e..86bf0dbe 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f.c
@@ -411,7 +411,7 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                             AND(x4, x4, x6);
                             OR(x3, x3, x4);
                             BNEZ(x3, 8);
-                            ORI(xFlags, xFlags, 1<<F_ZF);
+                            ORI(xFlags, xFlags, 1<<F_CF);
                         }
                     }
                     break;
diff --git a/src/dynarec/rv64/dynarec_rv64_6664.c b/src/dynarec/rv64/dynarec_rv64_6664.c
index a139e3ae..3acac902 100644
--- a/src/dynarec/rv64/dynarec_rv64_6664.c
+++ b/src/dynarec/rv64/dynarec_rv64_6664.c
@@ -37,6 +37,35 @@ uintptr_t dynarec64_6664(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
     GETREX();
 
     switch(opcode) {
+        case 0x89:
+            INST_NAME("MOV FS:Ew, Gw");
+            nextop = F8;
+            GETGD;  // don't need GETGW here
+            if(MODREG) {
+                ed = xRAX+(nextop&7)+(rex.b<<3);
+                if(rex.w) {
+                    ADDI(ed, gd, 0);
+                } else {
+                    if(ed!=gd) {
+                        LUI(x1, 0xffff0);
+                        AND(gd, gd, x1);
+                        ZEXTH(x1, ed);
+                        OR(gd, gd, x1);
+                    }
+                }
+            } else {
+                grab_segdata(dyn, addr, ninst, x4, seg);
+                addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+                ADD(x4, ed, x4);
+                if(rex.w) {
+                    SD(gd, x4, fixedaddress);
+                } else {
+                    SH(gd, x4, fixedaddress);
+                }
+                SMWRITE();
+            }
+            break;
+
         case 0x8B:
             INST_NAME("MOV Gd, FS:Ed");
             nextop=F8;
@@ -69,7 +98,6 @@ uintptr_t dynarec64_6664(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             }
             break;
 
-
         default:
             DEFAULT;
     }