about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-02-07 13:56:45 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-02-07 13:56:45 +0100
commit4047d1ba3c536c66a7baedf474fdc2c17cdefa84 (patch)
treec382e68136487bee53c05b5fe8cf70b1771ee23c
parentd74bee35960219465b4809a84590ca3108ba3665 (diff)
downloadbox64-4047d1ba3c536c66a7baedf474fdc2c17cdefa84.tar.gz
box64-4047d1ba3c536c66a7baedf474fdc2c17cdefa84.zip
[ARM64_DYNAREC] More fixes to F0 0F C7 opcode
-rw-r--r--src/dynarec/arm64/dynarec_arm64_f0.c142
-rw-r--r--src/dynarec/dynarec_native_pass.c2
2 files changed, 70 insertions, 74 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_f0.c b/src/dynarec/arm64/dynarec_arm64_f0.c
index 0eda1a0a..37940eec 100644
--- a/src/dynarec/arm64/dynarec_arm64_f0.c
+++ b/src/dynarec/arm64/dynarec_arm64_f0.c
@@ -24,7 +24,7 @@
 
 uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
 {
-    (void)ip; (void)rep; (void)need_epilog;
+    (void)ip; (void)need_epilog;
 
     uint8_t opcode = F8;
     uint8_t nextop;
@@ -644,88 +644,84 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;
 
                 case 0xC7:
+                    // rep has no impact here
                     nextop = F8;
-                    switch(rep) {
-                        case 0:
-                        switch((nextop>>3)&7) {
-                            case 1:
-                            INST_NAME("LOCK CMPXCHG8B Gq, Eq");
-                            SETFLAGS(X_ZF, SF_SUBSET);
-                            addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
-                            if(!ALIGNED_ATOMICxw) {
-                                TSTx_mask(wback, 1, 0, 1+rex.w);    // mask=3 or 7
-                                B_MARK2(cNE);    // unaligned
+                    switch((nextop>>3)&7) {
+                        case 1:
+                        INST_NAME("LOCK CMPXCHG8B Gq, Eq");
+                        SETFLAGS(X_ZF, SF_SUBSET);
+                        addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
+                        if(!ALIGNED_ATOMICxw) {
+                            TSTx_mask(wback, 1, 0, 1+rex.w);    // mask=3 or 7
+                            B_MARK2(cNE);    // unaligned
+                        }
+                        if(arm64_atomics) {
+                            MOVx_REG(x2, xRAX);
+                            MOVx_REG(x3, xRDX);
+                            MOVx_REG(x4, xRBX);
+                            MOVx_REG(x5, xRCX);
+                            CASPALxw(x2, x4, wback);
+                            UFLAG_IF {
+                                CMPSxw_REG(x2, xRAX);
+                                CCMPxw(x3, xRDX, 0, cEQ);
+                                CSETw(x1, cEQ);
                             }
-                            if(arm64_atomics) {
-                                MOVx_REG(x2, xRAX);
-                                MOVx_REG(x3, xRDX);
-                                MOVx_REG(x4, xRBX);
-                                MOVx_REG(x5, xRCX);
-                                CASPALxw(x2, x4, wback);
-                                UFLAG_IF {
-                                    CMPSxw_REG(x2, xRAX);
-                                    CCMPxw(x3, xRDX, 0, cEQ);
-                                    CSETw(x1, cEQ);
-                                }
-                                MOVx_REG(xRAX, x2);
-                                MOVx_REG(xRDX, x3);
-                                if(!ALIGNED_ATOMICxw) {
-                                    B_MARK3_nocond;
-                                }
-                            } else {
-                                MARKLOCK;
-                                LDAXPxw(x2, x3, wback);
-                                CMPSxw_REG(xRAX, x2);
-                                CCMPxw(xRDX, x3, 0, cEQ);
-                                B_MARK(cNE);    // EAX!=ED[0] || EDX!=Ed[1]
-                                STLXPxw(x4, xRBX, xRCX, wback);
-                                CBNZx_MARKLOCK(x4);
-                                UFLAG_IF {
-                                    MOV32w(x1, 1);
-                                }
+                            MOVx_REG(xRAX, x2);
+                            MOVx_REG(xRDX, x3);
+                            if(!ALIGNED_ATOMICxw) {
                                 B_MARK3_nocond;
-                                MARK;
-                                MOVxw_REG(xRAX, x2);
-                                MOVxw_REG(xRDX, x3);
-                                UFLAG_IF {
-                                    MOV32w(x1, 0);
-                                }
-                                if(!ALIGNED_ATOMICxw) {
-                                    B_MARK3_nocond;
-                                }
+                            }
+                        } else {
+                            MARKLOCK;
+                            LDAXPxw(x2, x3, wback);
+                            CMPSxw_REG(xRAX, x2);
+                            CCMPxw(xRDX, x3, 0, cEQ);
+                            B_MARK(cNE);    // EAX!=ED[0] || EDX!=Ed[1]
+                            STLXPxw(x4, xRBX, xRCX, wback);
+                            CBNZx_MARKLOCK(x4);
+                            UFLAG_IF {
+                                MOV32w(x1, 1);
+                            }
+                            B_MARK3_nocond;
+                            MARK;
+                            MOVxw_REG(xRAX, x2);
+                            MOVxw_REG(xRDX, x3);
+                            UFLAG_IF {
+                                MOV32w(x1, 0);
                             }
                             if(!ALIGNED_ATOMICxw) {
-                                MARK2;
-                                LDPxw_S7_offset(x2, x3, wback, 0);
-                                LDAXRB(x4, wback);
-                                CMPSxw_REG(xRAX, x2);
-                                CCMPxw(xRDX, x3, 0, cEQ);
-                                B_MARKSEG(cNE);    // EAX!=ED[0] || EDX!=Ed[1]
-                                STLXRB(x4, xRBX, wback);
-                                CBNZx_MARK2(x4);
-                                STPxw_S7_offset(xRBX, xRCX, wback, 0);
-                                UFLAG_IF {
-                                    MOV32w(x1, 1);
-                                }
                                 B_MARK3_nocond;
-                                MARKSEG;
-                                MOVxw_REG(xRAX, x2);
-                                MOVxw_REG(xRDX, x3);
-                                UFLAG_IF {
-                                    MOV32w(x1, 0);
-                                }
                             }
-                            MARK3;
-                            SMDMB();
+                        }
+                        if(!ALIGNED_ATOMICxw) {
+                            MARK2;
+                            LDPxw_S7_offset(x2, x3, wback, 0);
+                            LDAXRB(x4, wback);
+                            CMPSxw_REG(xRAX, x2);
+                            CCMPxw(xRDX, x3, 0, cEQ);
+                            B_MARKSEG(cNE);    // EAX!=ED[0] || EDX!=Ed[1]
+                            STLXRB(x4, xRBX, wback);
+                            CBNZx_MARK2(x4);
+                            STPxw_S7_offset(xRBX, xRCX, wback, 0);
                             UFLAG_IF {
-                                BFIw(xFlags, x1, F_ZF, 1);
+                                MOV32w(x1, 1);
+                            }
+                            B_MARK3_nocond;
+                            MARKSEG;
+                            MOVxw_REG(xRAX, x2);
+                            MOVxw_REG(xRDX, x3);
+                            UFLAG_IF {
+                                MOV32w(x1, 0);
                             }
-                            break;
-                        default:
-                            DEFAULT;
                         }
-                        default:
-                            DEFAULT;
+                        MARK3;
+                        SMDMB();
+                        UFLAG_IF {
+                            BFIw(xFlags, x1, F_ZF, 1);
+                        }
+                        break;
+                    default:
+                        DEFAULT;
                     }
                     break;
 
diff --git a/src/dynarec/dynarec_native_pass.c b/src/dynarec/dynarec_native_pass.c
index acea77e0..3ee9f28b 100644
--- a/src/dynarec/dynarec_native_pass.c
+++ b/src/dynarec/dynarec_native_pass.c
@@ -40,7 +40,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
     uintptr_t ip = addr;
     uintptr_t init_addr = addr;
     rex_t rex;
-    int rep;    // 0 none, 1=F2 prefix, 2=F3 prefix
+    int rep = 0;    // 0 none, 1=F2 prefix, 2=F3 prefix
     int need_epilog = 1;
     // Clean up (because there are multiple passes)
     dyn->f.pending = 0;