about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-12-26 16:30:10 +0800
committerGitHub <noreply@github.com>2024-12-26 09:30:10 +0100
commit205ef4ddeb69fbc0a1b105b23b6d65959479bee5 (patch)
tree286e317e3fd26118c3e95d27160a3a3c79687ded
parent145689783f91eae5248ade24edde61362a0a6ba0 (diff)
downloadbox64-205ef4ddeb69fbc0a1b105b23b6d65959479bee5.tar.gz
box64-205ef4ddeb69fbc0a1b105b23b6d65959479bee5.zip
[LA64_DYNAREC] Added more opcodes (#2213)
-rw-r--r--src/dynarec/la64/dynarec_la64_f0.c36
-rw-r--r--src/dynarec/la64/dynarec_la64_f20f.c10
2 files changed, 43 insertions, 3 deletions
diff --git a/src/dynarec/la64/dynarec_la64_f0.c b/src/dynarec/la64/dynarec_la64_f0.c
index 89d85998..d19e9f70 100644
--- a/src/dynarec/la64/dynarec_la64_f0.c
+++ b/src/dynarec/la64/dynarec_la64_f0.c
@@ -450,7 +450,7 @@ uintptr_t dynarec64_F0(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             nextop = F8;
             SMDMB();
             switch ((nextop >> 3) & 7) {
-                case 0: // ADD
+                case 0:
                     if (opcode == 0x81) {
                         INST_NAME("LOCK ADD Ed, Id");
                     } else {
@@ -488,7 +488,7 @@ uintptr_t dynarec64_F0(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         SMDMB();
                     }
                     break;
-                case 1: // OR
+                case 1:
                     if (opcode == 0x81) {
                         INST_NAME("LOCK OR Ed, Id");
                     } else {
@@ -526,7 +526,37 @@ uintptr_t dynarec64_F0(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                             emit_or32c(dyn, ninst, rex, x1, i64, x3, x4);
                     }
                     break;
-                case 5: // SUB
+                case 4:
+                    if (opcode == 0x81) {
+                        INST_NAME("LOCK AND Ed, Id");
+                    } else {
+                        INST_NAME("LOCK AND Ed, Ib");
+                    }
+                    SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION);
+                    if (MODREG) {
+                        if (opcode == 0x81)
+                            i64 = F32S;
+                        else
+                            i64 = F8S;
+                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
+                        emit_and32c(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;
+                        MOV64xw(x7, i64);
+                        if (rex.w) {
+                            AMAND_DB_D(x1, x7, wback);
+                        } else {
+                            AMAND_DB_W(x1, x7, wback);
+                        }
+                        IFXORNAT (X_ALL | X_PEND)
+                            emit_and32c(dyn, ninst, rex, x1, i64, x3, x4);
+                    }
+                    break;
+                case 5:
                     if (opcode == 0x81) {
                         INST_NAME("LOCK SUB Ed, Id");
                     } else {
diff --git a/src/dynarec/la64/dynarec_la64_f20f.c b/src/dynarec/la64/dynarec_la64_f20f.c
index fec9879f..774dcbf4 100644
--- a/src/dynarec/la64/dynarec_la64_f20f.c
+++ b/src/dynarec/la64/dynarec_la64_f20f.c
@@ -326,6 +326,16 @@ uintptr_t dynarec64_F20F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
             MOVGR2FR_D(q1, x2);
             VEXTRINS_D(v0, q1, 0);
             break;
+        case 0xE6: // TODO: !fastround
+            INST_NAME("CVTPD2DQ Gx, Ex");
+            nextop = F8;
+            GETEX(v1, 0, 0);
+            GETGX_empty(v0);
+            u8 = sse_setround(dyn, ninst, x1, x2);
+            VFTINT_W_D(v0, v1, v1);
+            x87_restoreround(dyn, ninst, u8);
+            VINSGR2VR_D(v0, xZR, 1);
+            break;
         default:
             DEFAULT;
     }