about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-03-10 14:33:40 +0100
committerptitSeb <sebastien.chev@gmail.com>2025-03-10 14:33:40 +0100
commit216cf51d4a3aaa9dacc58cdbc569d40ea64ac50e (patch)
tree7ede107e7a486f9e8e288c5b08b0a85aff07cc94 /src
parent1476b502a27226395535fd67123d72b10c8796cc (diff)
downloadbox64-216cf51d4a3aaa9dacc58cdbc569d40ea64ac50e.tar.gz
box64-216cf51d4a3aaa9dacc58cdbc569d40ea64ac50e.zip
[RV64_DYNAREC] Added 66 F0 81/83 /1 opcode
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_66f0.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_66f0.c b/src/dynarec/rv64/dynarec_rv64_66f0.c
index 22263a42..831f1606 100644
--- a/src/dynarec/rv64/dynarec_rv64_66f0.c
+++ b/src/dynarec/rv64/dynarec_rv64_66f0.c
@@ -125,6 +125,72 @@ uintptr_t dynarec64_66F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                         }
                     }
                     break;
+                case 1: // OR
+                    if (opcode == 0x81) {
+                        INST_NAME("LOCK OR Ew, Iw");
+                    } else {
+                        INST_NAME("LOCK OR Ew, Ib");
+                    }
+                    SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION);
+                    if (MODREG) {
+                        if (opcode == 0x81)
+                            u64 = F16;
+                        else
+                            u64 = (uint16_t)(int16_t)F8S;
+                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
+                        MOV64x(x5, u64);
+                        ZEXTH(x6, ed);
+                        emit_or16(dyn, ninst, x6, x5, x3, x4);
+                        SRLI(ed, ed, 16);
+                        SLLI(ed, ed, 16);
+                        OR(ed, ed, x6);
+                    } else {
+                        addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, (opcode == 0x81) ? 2 : 1);
+                        if (opcode == 0x81)
+                            u64 = F16;
+                        else
+                            u64 = (uint16_t)(int16_t)F8S;
+                        MOV64x(x5, u64);
+
+                        ANDI(x3, wback, 0b10);
+                        BNEZ_MARK(x3);
+
+                        // lower 16 bits
+                        MARKLOCK;
+                        LR_W(x1, wback, 1, 1);
+                        SRLIW(x3, x1, 16);
+                        SLLIW(x3, x3, 16);
+                        OR(x4, x1, x5);
+                        OR(x4, x4, x3);
+                        SC_W(x3, x4, wback, 1, 1);
+                        BNEZ_MARKLOCK(x3);
+                        IFXORNAT (X_ALL | X_PEND) {
+                            SLLIW(x1, x1, 16);
+                            SRLIW(x1, x1, 16);
+                        }
+                        B_MARK3_nocond;
+
+                        MARK;
+                        // upper 16 bits
+                        XORI(wback, wback, 0b10);
+                        MARK2;
+                        LR_W(x1, wback, 1, 1);
+                        SLLIW(x3, x1, 16);
+                        SRLIW(x3, x3, 16);
+                        SRLIW(x1, x1, 16);
+                        OR(x4, x1, x5);
+                        SLLIW(x4, x4, 16);
+                        OR(x4, x4, x3);
+                        SC_W(x3, x4, wback, 1, 1);
+                        BNEZ_MARK2(x3);
+
+                        MARK3;
+                        // final
+                        IFXORNAT (X_ALL | X_PEND) {
+                            emit_or16(dyn, ninst, x1, x5, x3, x4);
+                        }
+                    }
+                    break;
                 default:
                     DEFAULT;
             }