about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2023-12-23 17:26:34 +0800
committerGitHub <noreply@github.com>2023-12-23 10:26:34 +0100
commit446fb9c99fd7d966c6f4bf9fe28bd203729b0352 (patch)
treedd8ed038fd9ab0f21ab1d0d64f7a687c5fc44de3 /src
parentc774cb0c27b4d0dc35b53aba774bf8a332b96aea (diff)
downloadbox64-446fb9c99fd7d966c6f4bf9fe28bd203729b0352.tar.gz
box64-446fb9c99fd7d966c6f4bf9fe28bd203729b0352.zip
[DYNAREC_RV64] Added more opcodes for ets2 (#1158)
* [DYNAREC_RV64] Added F3 0F 52 RSQRTSS opcode

* [DYNAREC_RV64] Added F0 81 /6 LOCK XOR opcode (aligned only)

* [DYNAREC_RV64] Added F3 0F 16 MOVSHDUP opcode

* Format
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f0.c39
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f30f.c38
2 files changed, 68 insertions, 9 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_f0.c b/src/dynarec/rv64/dynarec_rv64_f0.c
index d90aa34e..a9f842f6 100644
--- a/src/dynarec/rv64/dynarec_rv64_f0.c
+++ b/src/dynarec/rv64/dynarec_rv64_f0.c
@@ -654,7 +654,7 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     if(MODREG) {
                         if(opcode==0x81) i64 = F32S; else i64 = F8S;
                         ed = xRAX+(nextop&7)+(rex.b<<3);
-                        emit_sub32(dyn, ninst, rex, ed, i64, x3, x4, x5);
+                        emit_sub32c(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;
@@ -672,8 +672,41 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                             emit_sub32c(dyn, ninst, rex, x1, i64, x3, x4, x5, x6);
                     }
                     break;
-                default:
-                    DEFAULT;
+                case 6: // XOR
+                    if (opcode == 0x81) {
+                        INST_NAME("LOCK XOR Ed, Id");
+                    } else {
+                        INST_NAME("LOCK XOR 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_xor32c(dyn, ninst, rex, ed, i64, x3, x4);
+                    } 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);
+                        if (i64 >= -2048 && i64 <= 2047) {
+                            XORI(x4, x1, i64);
+                        } else {
+                            MOV64xw(x4, i64);
+                            XOR(x4, x1, x4);
+                        }
+                        SCxw(x3, x4, wback, 1, 1);
+                        BNEZ_MARKLOCK(x3);
+                        IFX(X_ALL | X_PEND)
+                            emit_xor32c(dyn, ninst, rex, x1, i64, x3, x4);
+                    }
+                    break;
+                default: DEFAULT;
             }
             SMDMB();
             break;
diff --git a/src/dynarec/rv64/dynarec_rv64_f30f.c b/src/dynarec/rv64/dynarec_rv64_f30f.c
index 1b57e9ed..45a6a2cf 100644
--- a/src/dynarec/rv64/dynarec_rv64_f30f.c
+++ b/src/dynarec/rv64/dynarec_rv64_f30f.c
@@ -89,12 +89,27 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
 
             // GX->ud[1] = GX->ud[0] = EX->ud[0];
             // GX->ud[3] = GX->ud[2] = EX->ud[2];
-            LD(x3, wback, fixedaddress + 0);
-            SD(x3, gback, gdoffset + 0);
-            SD(x3, gback, gdoffset + 4);
-            LD(x3, wback, fixedaddress + 8);
-            SD(x3, gback, gdoffset + 8);
-            SD(x3, gback, gdoffset + 12);
+            LW(x3, wback, fixedaddress + 0);
+            SW(x3, gback, gdoffset + 0);
+            SW(x3, gback, gdoffset + 4);
+            LW(x3, wback, fixedaddress + 8);
+            SW(x3, gback, gdoffset + 8);
+            SW(x3, gback, gdoffset + 12);
+            break;
+        case 0x16:
+            INST_NAME("MOVSHDUP Gx, Ex");
+            nextop = F8;
+            GETGX();
+            GETEX(x2, 0);
+
+            // GX->ud[1] = GX->ud[0] = EX->ud[1];
+            // GX->ud[3] = GX->ud[2] = EX->ud[3];
+            LW(x3, wback, fixedaddress + 4);
+            SW(x3, gback, gdoffset + 0);
+            SW(x3, gback, gdoffset + 4);
+            LW(x3, wback, fixedaddress + 12);
+            SW(x3, gback, gdoffset + 8);
+            SW(x3, gback, gdoffset + 12);
             break;
         case 0x1E:
             INST_NAME("NOP / ENDBR32 / ENDBR64");
@@ -168,6 +183,17 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             GETGXSS_empty(v1);
             FSQRTS(v1, v0);
             break;
+        case 0x52:
+            INST_NAME("RSQRTSS Gx, Ex");
+            nextop = F8;
+            GETEXSS(v0, 0);
+            GETGXSS_empty(v1);
+            q0 = fpu_get_scratch(dyn);
+            LUI(x3, 0x3F800); // 1.0f
+            FMVWX(q0, x3);
+            FSQRTS(v1, v0);
+            FDIVS(v1, q0, v1);
+            break;
         case 0x53:
             INST_NAME("RCPSS Gx, Ex");
             nextop = F8;