about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-01-29 09:58:44 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-01-29 09:58:44 +0100
commit6d5c3489c9584dce29bbe90b50f2ce5db0786592 (patch)
treec01e0d219b9ad4ba7a402d14e8f5a10da41d8924 /src
parentd48ab494374c47f2fb41d4e2427bd80761df0de2 (diff)
downloadbox64-6d5c3489c9584dce29bbe90b50f2ce5db0786592.tar.gz
box64-6d5c3489c9584dce29bbe90b50f2ce5db0786592.zip
[ARM64_DYNAREC] Added F0 0F C0 opcode
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_f0.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_f0.c b/src/dynarec/arm64/dynarec_arm64_f0.c
index 09d053cb..3748b561 100644
--- a/src/dynarec/arm64/dynarec_arm64_f0.c
+++ b/src/dynarec/arm64/dynarec_arm64_f0.c
@@ -528,6 +528,52 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 }
                 break;
 
+                case 0xC0:
+                    switch(rep) {
+                        case 0:
+                            INST_NAME("LOCK XADD Eb, Gb");
+                            SETFLAGS(X_ALL, SF_SET_PENDING);
+                            nextop = F8;
+                            GETGB(x1);
+                            if(MODREG) {
+                                ed = xRAX+(nextop&7)+(rex.b<<3);
+                                GETEB(x2, 0);
+                                gd = x2; ed = x1;    // swap gd/ed
+                                emit_add8(dyn, ninst, x1, x2, x4, x5);
+                                GBBACK; // gb gets x2 (old ed)
+                                EBBACK; // eb gets x1 (sum)
+                            } else {
+                                addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
+                                if(arm64_atomics) {
+                                    UFLAG_IF {
+                                        MOVxw_REG(x3, gd);
+                                        LDADDALB(x3, gd, wback);
+                                        SMDMB();
+                                        emit_add8(dyn, ninst, x3, gd, x4, x5);
+                                    } else {
+                                        LDADDALB(gd, gd, wback);
+                                        SMDMB();
+                                    }
+                                    GBBACK;
+                                } else {
+                                    MARKLOCK;
+                                    LDAXRB(x1, wback);
+                                    ADDw_REG(x4, x1, gd);
+                                    STLXRB(x3, x4, wback);
+                                    CBNZx_MARKLOCK(x3);
+                                    SMDMB();
+                                    IFX(X_ALL|X_PEND) {
+                                        MOVxw_REG(x2, x1);
+                                        emit_add8(dyn, ninst, x2, gd, x3, x4);
+                                    }
+                                    BFIz(gb1, x1, gb2, 8);
+                                }
+                            }
+                            break;
+                        default:
+                            DEFAULT;
+                    }
+                    break;
                 case 0xC1:
                     switch(rep) {
                         case 0: