about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2023-04-01 16:21:25 +0800
committerGitHub <noreply@github.com>2023-04-01 10:21:25 +0200
commita1d5cb0e6961c68499113345c02bcff42a0e9fab (patch)
treea446ccb7b6508c3bde59dbfb90185e539992e2b1 /src
parent89ca436e916ba54b41e64a2adc2135ec86e7d85b (diff)
downloadbox64-a1d5cb0e6961c68499113345c02bcff42a0e9fab.tar.gz
box64-a1d5cb0e6961c68499113345c02bcff42a0e9fab.zip
[RV64_DYNAREC] Added more opcodes for Stardew Valley (#660)
* [RV64_DYNAREC] Added F0 0F B1 /0 LOCK CMPXCHG opcode

* [RV64_DYNAREC] Added F0 81,83 /0 opcode

* [RV64_DYNAREC] Added 0F 16 MOVHPS opcode
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c19
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f0.c74
2 files changed, 89 insertions, 4 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index 176e37c2..d373bab1 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -135,8 +135,23 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             if(!MODREG)
                 SMWRITE2();
             break;
-
-
+        case 0x16:
+            nextop = F8;
+            if(MODREG) {
+                INST_NAME("MOVLHPS Gx,Ex");
+                GETGX(x1);
+                GETEX(x2, 0);
+                LD(x4, wback, 0);
+                SD(x4, gback, fixedaddress+8);
+            } else {
+                INST_NAME("MOVHPS Gx,Ex");
+                SMREAD();
+                GETGX(x1);
+                GETEX(x2, 0);
+                LD(x4, wback, 0);
+                SD(x4, gback, fixedaddress+8);
+            }
+            break;
         case 0x18:
             nextop = F8;
             if((nextop&0xC0)==0xC0) {
diff --git a/src/dynarec/rv64/dynarec_rv64_f0.c b/src/dynarec/rv64/dynarec_rv64_f0.c
index 446d830f..77fdc60b 100644
--- a/src/dynarec/rv64/dynarec_rv64_f0.c
+++ b/src/dynarec/rv64/dynarec_rv64_f0.c
@@ -54,15 +54,53 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         opcode = F8;
     }
 
+    // TODO: Take care of unligned memory access for all the LOCK ones.
+    // https://github.com/ptitSeb/box64/pull/604
     switch(opcode) {
         case 0x0F:
             nextop = F8;
             switch(nextop) {
+                case 0xB1:
+                    switch (rep) {
+                        case 0:
+                            INST_NAME("LOCK CMPXCHG Ed, Gd");
+                            SETFLAGS(X_ALL, SF_SET_PENDING);
+                            nextop = F8;
+                            GETGD;
+                            SMDMB();
+                            if (MODREG) {
+                                ed = xRAX+(nextop&7)+(rex.b<<3);
+                                wback = 0;
+                                UFLAG_IF {emit_cmp32(dyn, ninst, rex, xRAX, ed, x3, x4, x5, x6);}
+                                MV(x1, ed); // save value
+                                SUB(x2, x1, xRAX);
+                                BNE_MARK2(x2, xZR);
+                                MV(ed, gd);
+                                MARK2;
+                                MVxw(xRAX, x1);
+                                B_NEXT_nocond;
+                            } else {
+                                addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
+                                MARKLOCK;
+                                LRxw(x1, wback, 1, 1);
+                                SUB(x3, x1, xRAX);
+                                BNE_MARK(x3, xZR);
+                                // EAX == Ed
+                                SCxw(x4, gd, wback, 1, 1);
+                                BNEZ_MARKLOCK(x4);
+                                MARK;
+                                UFLAG_IF {emit_cmp32(dyn, ninst, rex, xRAX, x1, x3, x4, x5, x6);}
+                                MVxw(xRAX, x1);
+                            }
+                            SMDMB();
+                            break;
+                        default:
+                            DEFAULT;
+                    }
+                    break;
                 case 0xC1:
                     switch(rep) {
                         case 0:
-                            // TODO: Take care of unligned memory access.
-                            // https://github.com/ptitSeb/box64/pull/604
                             INST_NAME("LOCK XADD Gd, Ed");
                             SETFLAGS(X_ALL, SF_SET_PENDING);
                             nextop = F8;
@@ -97,6 +135,38 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     DEFAULT;
             }
             break;
+        case 0x81:
+        case 0x83:
+            nextop = F8;
+            SMDMB();
+            switch((nextop>>3)&7) {
+                case 0: // ADD
+                    if(opcode==0x81) {
+                        INST_NAME("LOCK ADD Ed, Id");
+                    } else {
+                        INST_NAME("LOCK ADD Ed, Ib");
+                    }
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    if(MODREG) {
+                        if(opcode==0x81) i64 = F32S; else i64 = F8S;
+                        ed = xRAX+(nextop&7)+(rex.b<<3);
+                        emit_add32c(dyn, ninst, rex, ed, i64, x3, x4, x5, x6);
+                    } else {
+                        addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1);
+                        if(opcode==0x81) i64 = F32S; else i64 = F8S;
+                        MARKLOCK;
+                        LRxw(x1, wback, 1, 1);
+                        emit_add32c(dyn, ninst, rex, x1, i64, x3, x4, x5, x6);
+                        SCxw(x3, x1, wback, 1, 1);
+                        BNEZ_MARKLOCK(x3);
+                    }
+                    SMDMB();
+                    break;
+                default: 
+                    DEFAULT;
+            }
+            SMDMB();
+            break;
         default:
             DEFAULT;
     }