diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-02-07 13:56:45 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-02-07 13:56:45 +0100 |
| commit | 4047d1ba3c536c66a7baedf474fdc2c17cdefa84 (patch) | |
| tree | c382e68136487bee53c05b5fe8cf70b1771ee23c | |
| parent | d74bee35960219465b4809a84590ca3108ba3665 (diff) | |
| download | box64-4047d1ba3c536c66a7baedf474fdc2c17cdefa84.tar.gz box64-4047d1ba3c536c66a7baedf474fdc2c17cdefa84.zip | |
[ARM64_DYNAREC] More fixes to F0 0F C7 opcode
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_f0.c | 142 | ||||
| -rw-r--r-- | src/dynarec/dynarec_native_pass.c | 2 |
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; |