diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-02-03 18:03:26 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-02-03 18:03:26 +0100 |
| commit | 3fa527b45ba5945b1c8596621c96986e534e4888 (patch) | |
| tree | c88e7917500b0fb1ea6aca5bdba41c16935349ed /src | |
| parent | 121d986b1114990ae69a6834cea6979200e0c39b (diff) | |
| download | box64-3fa527b45ba5945b1c8596621c96986e534e4888.tar.gz box64-3fa527b45ba5945b1c8596621c96986e534e4888.zip | |
[ARM64_DYNAREC] Reworked STRONGMEM 2 & 3
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_00.c | 40 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_66.c | 12 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_67.c | 4 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_functions.c | 4 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.h | 41 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_private.h | 7 |
6 files changed, 89 insertions, 19 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index 78ed6bd3..a269e5cf 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -244,6 +244,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("PUSH SS"); LDRH_U12(x1, xEmu, offsetof(x64emu_t, segs[_SS])); PUSH1_32(x1); + SMWRITE(); } else { DEFAULT; } @@ -251,6 +252,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0x17: if(rex.is32bits) { INST_NAME("POP SS"); + SMREAD(); POP1_32(x1); STRH_U12(x1, xEmu, offsetof(x64emu_t, segs[_SS])); STRw_U12(xZR, xEmu, offsetof(x64emu_t, segs_serial[_SS])); @@ -319,6 +321,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("PUSH DS"); LDRH_U12(x1, xEmu, offsetof(x64emu_t, segs[_DS])); PUSH1_32(x1); + SMWRITE(); } else { DEFAULT; } @@ -326,6 +329,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0x1F: if(rex.is32bits) { INST_NAME("POP DS"); + SMREAD(); POP1_32(x1); STRH_U12(x1, xEmu, offsetof(x64emu_t, segs[_DS])); STRw_U12(xZR, xEmu, offsetof(x64emu_t, segs_serial[_DS])); @@ -632,6 +636,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SKIPTEST(x1); dyn->doublepush = 0; } else { + WILLWRITE(); gd = xRAX+(opcode&0x07)+(rex.b<<3); u32 = PK(0); i32 = 1; @@ -660,6 +665,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin PUSH1z(gd); } } + SMWRITE(); } break; case 0x58: @@ -675,6 +681,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SKIPTEST(x1); dyn->doublepop = 0; } else { + SMREAD(); gd = xRAX+(opcode&0x07)+(rex.b<<3); u32 = PK(0); i32 = 1; @@ -713,11 +720,13 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0x60: if(rex.is32bits) { INST_NAME("PUSHAD"); + WILLWRITE(); MOVw_REG(x1, xRSP); PUSH2_32(xRAX, xRCX); PUSH2_32(xRDX, xRBX); PUSH2_32(x1, xRBP); PUSH2_32(xRSI, xRDI); + SMWRITE(); } else { DEFAULT; } @@ -725,6 +734,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0x61: if(rex.is32bits) { INST_NAME("POPAD"); + SMREAD(); POP2_32(xRDI, xRSI); POP2_32(xRBP, x1); POP2_32(xRBX, xRDX); @@ -794,8 +804,10 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin LDRSW_U12(x1, x3, 0); PUSH1z(x1); } else { + WILLWRITE(); MOV64z(x3, i64); PUSH1z(x3); + SMWRITE(); } break; case 0x69: @@ -835,7 +847,9 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("PUSH Ib"); i64 = F8S; MOV64z(x3, i64); + WILLWRITE(); PUSH1z(x3); + SMWRITE(); break; case 0x6B: INST_NAME("IMUL Gd, Ed, Ib"); @@ -870,7 +884,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } } break; - case 0x6C: case 0x6D: INST_NAME(opcode == 0x6C ? "INSB" : "INSD"); @@ -1212,6 +1225,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin BFIx(eb1, gd, eb2*8, 8); } else { addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff, 0, rex, &lock, 0, 0); + WILLWRITELOCK(lock); STB(gd, ed, fixedaddress); SMWRITELOCK(lock); } @@ -1224,6 +1238,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MOVxw_REG(xRAX+(nextop&7)+(rex.b<<3), gd); } else { // mem <= reg addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, &lock, 0, 0); + WILLWRITELOCK(lock); STxw(gd, ed, fixedaddress); SMWRITELOCK(lock); } @@ -1321,6 +1336,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0x8F: INST_NAME("POP Ed"); nextop = F8; + SMREAD(); if(MODREG) { POP1z(xRAX+(nextop&7)+(rex.b<<3)); } else { @@ -1375,10 +1391,12 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("PUSHF"); READFLAGS(X_ALL); PUSH1z(xFlags); + SMWRITE(); break; case 0x9D: INST_NAME("POPF"); SETFLAGS(X_ALL, SF_SET); + SMREAD(); POP1z(xFlags); MOV32w(x1, 0x3F7FD7); ANDw_REG(xFlags, xFlags, x1); @@ -1436,6 +1454,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin u64 = F64; MOV64z(x1, u64); if(isLockAddress(u64)) lock=1; else lock = 0; + WILLWRITELOCK(lock); STRB_U12(xRAX, x1, 0); SMWRITELOCK(lock); break; @@ -1447,6 +1466,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin u64 = F64; MOV64z(x1, u64); if(isLockAddress(u64)) lock=1; else lock = 0; + WILLWRITELOCK(lock); STRxw_U12(xRAX, x1, 0); SMWRITELOCK(lock); break; @@ -1512,6 +1532,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 2: if(rep==1) {INST_NAME("REPNZ CMPSB");} else {INST_NAME("REPZ CMPSB");} MAYSETFLAGS(); + SMREAD(); SETFLAGS(X_ALL, SF_SET_PENDING); CBZx_NEXT(xRCX); TBNZ_MARK2(xFlags, F_DF); @@ -1537,6 +1558,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("CMPSB"); SETFLAGS(X_ALL, SF_SET_PENDING); GETDIR(x3, 1); + SMREAD(); LDRB_U12(x1, xRSI, 0); LDRB_U12(x2, xRDI, 0); ADDx_REG(xRSI, xRSI, x3); @@ -1552,6 +1574,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin if(rep==1) {INST_NAME("REPNZ CMPSD");} else {INST_NAME("REPZ CMPSD");} MAYSETFLAGS(); SETFLAGS(X_ALL, SF_SET_PENDING); + SMREAD(); CBZx_NEXT(xRCX); TBNZ_MARK2(xFlags, F_DF); MARK; // Part with DF==0 @@ -1576,6 +1599,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("CMPSD"); SETFLAGS(X_ALL, SF_SET_PENDING); GETDIR(x3, rex.w?8:4); + SMREAD(); LDRxw_U12(x1, xRSI, 0); LDRxw_U12(x2, xRDI, 0); ADDx_REG(xRSI, xRSI, x3); @@ -1600,6 +1624,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin emit_test32(dyn, ninst, rex, xRAX, x2, x3, x4, x5); break; case 0xAA: + WILLWRITE(); if(rep) { INST_NAME("REP STOSB"); CBZx_NEXT(xRCX); @@ -1608,11 +1633,12 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin STRB_S9_postindex(xRAX, xRDI, 1); SUBx_U12(xRCX, xRCX, 1); CBNZx_MARK(xRCX); - B_NEXT_nocond; + B_MARK3_nocond; MARK2; // Part with DF==1 STRB_S9_postindex(xRAX, xRDI, -1); SUBx_U12(xRCX, xRCX, 1); CBNZx_MARK2(xRCX); + MARK3; // done } else { INST_NAME("STOSB"); @@ -1623,6 +1649,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SMWRITE(); break; case 0xAB: + WILLWRITE(); if(rep) { INST_NAME("REP STOSD"); CBZx_NEXT(xRCX); @@ -1631,11 +1658,12 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin STRxw_S9_postindex(xRAX, xRDI, rex.w?8:4); SUBx_U12(xRCX, xRCX, 1); CBNZx_MARK(xRCX); - B_NEXT_nocond; + B_MARK3_nocond; MARK2; // Part with DF==1 STRxw_S9_postindex(xRAX, xRDI, rex.w?-8:-4); SUBx_U12(xRCX, xRCX, 1); CBNZx_MARK2(xRCX); + MARK3; // done } else { INST_NAME("STOSD"); @@ -1652,6 +1680,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("LODSB"); } GETDIR(x1, 1); + SMREAD(); if(rep) { CBZx_NEXT(xRCX); MARK; @@ -1688,6 +1717,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 2: if(rep==1) {INST_NAME("REPNZ SCASB");} else {INST_NAME("REPZ SCASB");} MAYSETFLAGS(); + SMREAD(); SETFLAGS(X_ALL, SF_SET_PENDING); CBZx_NEXT(xRCX); UBFXw(x1, xRAX, 0, 8); @@ -1725,6 +1755,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 2: if(rep==1) {INST_NAME("REPNZ SCASD");} else {INST_NAME("REPZ SCASD");} MAYSETFLAGS(); + SMREAD(); SETFLAGS(X_ALL, SF_SET_PENDING); CBZx_NEXT(xRCX); TBNZ_MARK2(xFlags, F_DF); @@ -2065,6 +2096,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin ed = x3; } else ed = xZR; + WILLWRITELOCK(lock); STB(ed, wback, fixedaddress); SMWRITELOCK(lock); } @@ -2084,6 +2116,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin ed = x3; } else ed = xZR; + WILLWRITELOCK(lock); STxw(ed, wback, fixedaddress); SMWRITELOCK(lock); } @@ -3328,6 +3361,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("PUSH Ed"); GETEDz(0); PUSH1z(ed); + SMWRITE(); break; default: diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c index ee261791..aa5384cd 100644 --- a/src/dynarec/arm64/dynarec_arm64_66.c +++ b/src/dynarec/arm64/dynarec_arm64_66.c @@ -705,11 +705,14 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0x9C: INST_NAME("PUSHF"); READFLAGS(X_ALL); + WILLWRITE(); PUSH1_16(xFlags); + SMWRITE(); break; case 0x9D: INST_NAME("POPF"); SETFLAGS(X_ALL, SF_SET); + SMREAD(); POP1_16(x1); // probably not usefull... BFIw(xFlags, x1, 0, 16); MOV32w(x1, 0x3F7FD7); @@ -746,11 +749,13 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin u64 = F64; MOV64z(x1, u64); if(isLockAddress(u64)) lock=1; else lock = 0; + WILLWRITELOCK(lock); STRH_U12(xRAX, x1, 0); SMWRITELOCK(lock); break; case 0xA5: + SMREAD(); if(rep) { INST_NAME("REP MOVSW"); CBZx_NEXT(xRCX); @@ -775,9 +780,11 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin ADDx_REG(xRSI, xRSI, x3); ADDx_REG(xRDI, xRDI, x3); } + SMWRITE(); break; case 0xA7: + SMREAD(); switch(rep) { case 1: case 2: @@ -827,6 +834,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0xAB: + WILLWRITE(); if(rep) { INST_NAME("REP STOSW"); CBZx_NEXT(xRCX); @@ -835,11 +843,12 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin STRH_S9_postindex(xRAX, xRDI, 2); SUBx_U12(xRCX, xRCX, 1); CBNZx_MARK(xRCX); - B_NEXT_nocond; + B_MARK3_nocond; MARK2; // Part with DF==1 STRH_S9_postindex(xRAX, xRDI, -2); SUBx_U12(xRCX, xRCX, 1); CBNZx_MARK2(xRCX); + MARK3; // done } else { INST_NAME("STOSW"); @@ -847,6 +856,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin STRH_U12(xRAX, xRDI, 0); ADDx_REG(xRDI, xRDI, x3); } + SMWRITE(); break; case 0xAD: diff --git a/src/dynarec/arm64/dynarec_arm64_67.c b/src/dynarec/arm64/dynarec_arm64_67.c index 3c379e0c..cde17af2 100644 --- a/src/dynarec/arm64/dynarec_arm64_67.c +++ b/src/dynarec/arm64/dynarec_arm64_67.c @@ -666,6 +666,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } } else { addr = geted32(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, &lock, 0, 0); + WILLWRITELOCK(lock); STH(gd, ed, fixedaddress); SMWRITELOCK(lock); } @@ -832,6 +833,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin BFIx(eb1, gd, eb2*8, 8); } else { addr = geted32(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff, 0, rex, &lock, 0, 0); + WILLWRITELOCK(lock); STB(gd, ed, fixedaddress); SMWRITELOCK(lock); } @@ -844,6 +846,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MOVxw_REG(xRAX+(nextop&7)+(rex.b<<3), gd); } else { // mem <= reg addr = geted32(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, &lock, 0, 0); + WILLWRITELOCK(lock); STxw(gd, ed, fixedaddress); SMWRITELOCK(lock); } @@ -993,6 +996,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin addr = geted32(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, &lock, 0, 4); i64 = F32S; MOV64xw(x3, i64); + WILLWRITELOCK(lock); STxw(x3, ed, fixedaddress); SMWRITELOCK(lock); } diff --git a/src/dynarec/arm64/dynarec_arm64_functions.c b/src/dynarec/arm64/dynarec_arm64_functions.c index 27280dc5..c747fc7e 100644 --- a/src/dynarec/arm64/dynarec_arm64_functions.c +++ b/src/dynarec/arm64/dynarec_arm64_functions.c @@ -537,7 +537,7 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t r { if(box64_dynarec_dump) { printf_x64_instruction(rex.is32bits?my_context->dec32:my_context->dec, &dyn->insts[ninst].x64, name); - dynarec_log(LOG_NONE, "%s%p: %d emitted opcodes, inst=%d, barrier=%d state=%d/%d(%d), %s=%X/%X, use=%X, need=%X/%X, sm=%d/%d", + dynarec_log(LOG_NONE, "%s%p: %d emitted opcodes, inst=%d, barrier=%d state=%d/%d(%d), %s=%X/%X, use=%X, need=%X/%X, sm=%d(%d/%d)", (box64_dynarec_dump>1)?"\e[32m":"", (void*)(dyn->native_start+dyn->insts[ninst].address), dyn->insts[ninst].size/4, @@ -552,7 +552,7 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t r dyn->insts[ninst].x64.use_flags, dyn->insts[ninst].x64.need_before, dyn->insts[ninst].x64.need_after, - dyn->smread, dyn->smwrite); + dyn->smwrite, dyn->insts[ninst].will_write, dyn->insts[ninst].last_write); if(dyn->insts[ninst].pred_sz) { dynarec_log(LOG_NONE, ", pred="); for(int ii=0; ii<dyn->insts[ninst].pred_sz; ++ii) diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index 1bcc968e..f66f4e08 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -34,30 +34,51 @@ // Strong mem emulation helpers #define SMREAD_MIN 2 -#define SMWRITE_MIN 1 -// Sequence of Read will trigger a DMB on "first" read if strongmem is >= SMREAD_MIN +#define SMFIRST_MIN 1 +#if STEP == 0 +// pass 0 will store is opcode write memory +#define SMWRITE() dyn->insts[ninst].will_write = 1; dyn->smwrite = 1 +#define SMREAD() +#define SMREADLOCK(lock) +#define SMMIGHTREAD() +#define SMWRITE2() if(box64_dynarec_strongmem>SMREAD_MIN) {SMWRITE();} +#define SMWRITELOCK(lock) SMWRITE() +#define WILLWRITELOCK(lock) +#define WILLWRITE() +#define SMMIGHTWRITE() if(!MODREG) {SMWRITE();} +#define SMSTART() dyn->smwrite = 0; +#define SMEND() if(dyn->smwrite && (box64_dynarec_strongmem>SMFIRST_MIN)) {int i = ninst; while(i>=0 && !dyn->insts[i].will_write) --i; if(i>=0) {dyn->insts[i].last_write = 1;}} dyn->smwrite = 0 +#define SMDMB() +#else // Sequence of Write will trigger a DMB on "last" write if strongmem is >= 1 -// All Write operation that might use a lock all have a memory barrier if strongmem is >= SMWRITE_MIN +// Block will trigget at 1st and last if strongmem is >= SMFIRST_MIN +// Read will contribute to trigger a DMB on "first" read if strongmem is >= SMREAD_MIN // Opcode will read -#define SMREAD() if((dyn->smread==0) && (box64_dynarec_strongmem>SMREAD_MIN)) {SMDMB();} else dyn->smread=1 +#define SMREAD() if(dyn->insts[ninst].will_write) {WILLWRITE();} else if(box64_dynarec_strongmem>SMREAD_MIN) {SMWRITE();} // Opcode will read with option forced lock -#define SMREADLOCK(lock) if((lock) || ((dyn->smread==0) && (box64_dynarec_strongmem>SMREAD_MIN))) {SMDMB();} +#define SMREADLOCK(lock) if((lock) || (box64_dynarec_strongmem>SMREAD_MIN)) {SMWRITELOCK(lock);} // Opcode might read (depend on nextop) #define SMMIGHTREAD() if(!MODREG) {SMREAD();} // Opcode has wrote -#define SMWRITE() dyn->smwrite=1 +#define SMWRITE() if((box64_dynarec_strongmem>=SMFIRST_MIN) && dyn->smwrite==0) {SMDMB();} dyn->smwrite=1 // Opcode has wrote (strongmem>1 only) -#define SMWRITE2() if(box64_dynarec_strongmem>SMREAD_MIN) dyn->smwrite=1 +#define SMWRITE2() if(box64_dynarec_strongmem>SMREAD_MIN) {SMWRITE();} // Opcode has wrote with option forced lock -#define SMWRITELOCK(lock) if(lock || (box64_dynarec_strongmem>SMWRITE_MIN)) {SMDMB();} else dyn->smwrite=1 +#define SMWRITELOCK(lock) if(lock) {SMDMB();} else {SMWRITE();} +// Opcode has wrote with option forced lock +#define WILLWRITELOCK(lock) if(lock) {DMB_ISH();} else {WILLWRITE();} // Opcode might have wrote (depend on nextop) #define SMMIGHTWRITE() if(!MODREG) {SMWRITE();} +// Opcode will write (without reading) +#define WILLWRITE() if((box64_dynarec_strongmem>=SMFIRST_MIN) && dyn->smwrite==0) {SMDMB();} else if(box64_dynarec_strongmem>=SMFIRST_MIN && dyn->insts[ninst].last_write) {SMDMB();} dyn->smwrite=1 // Start of sequence #define SMSTART() SMEND() // End of sequence -#define SMEND() if(dyn->smwrite && box64_dynarec_strongmem) {if(box64_dynarec_strongmem){DSB_ISH();}else{DMB_ISH();}} dyn->smwrite=0; dyn->smread=0; +#define SMEND() if(dyn->smwrite && box64_dynarec_strongmem) {DMB_ISH();} dyn->smwrite=0; // Force a Data memory barrier (for LOCK: prefix) -#define SMDMB() if(box64_dynarec_strongmem){DSB_ISH();}else{DMB_ISH();} dyn->smwrite=0; dyn->smread=1 +#define SMDMB() if(box64_dynarec_strongmem){DSB_ISH();}else{DMB_ISH();} dyn->smwrite=0; + +#endif //LOCK_* define #define LOCK_LOCK (int*)1 diff --git a/src/dynarec/arm64/dynarec_arm64_private.h b/src/dynarec/arm64/dynarec_arm64_private.h index 0e5c0e9b..1a7b387e 100644 --- a/src/dynarec/arm64/dynarec_arm64_private.h +++ b/src/dynarec/arm64/dynarec_arm64_private.h @@ -76,7 +76,9 @@ typedef struct instruction_arm64_s { int pass2choice;// value for choices that are fixed on pass2 for pass3 uintptr_t natcall; int retn; - int barrier_maybe; + uint8_t barrier_maybe; + uint8_t will_write; + uint8_t last_write; flagcache_t f_exit; // flags status at end of instruction neoncache_t n; // neoncache at end of instruction (but before poping) flagcache_t f_entry; // flags status before the instruction begin @@ -109,12 +111,11 @@ typedef struct dynarec_arm_s { dynablock_t* dynablock; instsize_t* instsize; size_t insts_size; // size of the instruction size array (calculated) - uint8_t smread; // for strongmem model emulation - uint8_t smwrite; // for strongmem model emulation uintptr_t forward; // address of the last end of code while testing forward uintptr_t forward_to; // address of the next jump to (to check if everything is ok) int32_t forward_size; // size at the forward point int forward_ninst; // ninst at the forward point + uint8_t smwrite; // for strongmem model emulation uint8_t doublepush; uint8_t doublepop; uint8_t always_test; |