mirror of
https://github.com/ptitSeb/box64.git
synced 2026-11-08 10:10:25 -10:00
[LA64_DYNAREC] Add macros help unaligned lock opcodes. (#3107)
This patch add Macro for 32/64 bits lock opcodes. Added lock add ed, gd/lock add ed, ib/id.
This commit is contained in:
1 parent
75ea309ca1
commit
44822bb07b
2 files changed
+129
-26
No files matched your search
@@ -62,11 +62,35 @@ uintptr_t dynarec64_F0(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
emit_add32(dyn, ninst, rex, ed, gd, x3, x4, x5);
|
||||
} else {
|
||||
addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
|
||||
MARKLOCK;
|
||||
LLxw(x1, wback, 0);
|
||||
ADDxw(x4, x1, gd);
|
||||
SCxw(x4, wback, 0);
|
||||
BEQZ_MARKLOCK(x4);
|
||||
if (rex.w) {
|
||||
if (!ALIGNED_ATOMICxw) {
|
||||
ANDI(x3, wback, 0b111);
|
||||
BNEZ_MARK2(x3);
|
||||
}
|
||||
AMADD_DB_D(x1, gd, wback);
|
||||
B_MARK3_nocond;
|
||||
} else {
|
||||
if (!ALIGNED_ATOMICxw) {
|
||||
ANDI(x3, wback, 0b11);
|
||||
BNEZ_MARK(x3);
|
||||
}
|
||||
// aligned 4byte
|
||||
AMADD_DB_W(x1, gd, wback);
|
||||
if (!ALIGNED_ATOMICxw) {
|
||||
B_MARK3_nocond;
|
||||
MARK;
|
||||
ANDI(x3, wback, 0b111);
|
||||
SLTI(x4, x3, 4);
|
||||
BEQZ_MARK2(x4); // addr %8 >4 , cross 8bytes or cross cacheline
|
||||
LOCK_32_IN_8BYTE(ADD_W(x4, x1, gd), x1, wback, x3, x4, x5, x6, x7);
|
||||
B_MARK3_nocond;
|
||||
}
|
||||
}
|
||||
if (!ALIGNED_ATOMICxw) {
|
||||
MARK2;
|
||||
LOCK_3264_CROSS_8BYTE(ADDxw(x4, x1, gd), x1, wback, x4, x5, x6);
|
||||
MARK3;
|
||||
}
|
||||
IFXORNAT (X_ALL | X_PEND) {
|
||||
emit_add32(dyn, ninst, rex, x1, gd, x3, x4, x5);
|
||||
}
|
||||
@@ -662,27 +686,35 @@ uintptr_t dynarec64_F0(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
else
|
||||
i64 = F8S;
|
||||
MOV64xw(x7, i64);
|
||||
ANDI(x1, wback, (1 << (rex.w + 2)) - 1);
|
||||
BNEZ_MARK3(x1);
|
||||
// Aligned
|
||||
MARKLOCK;
|
||||
LLxw(x1, wback, 0);
|
||||
ADDxw(x4, x1, x7);
|
||||
SCxw(x4, wback, 0);
|
||||
BEQZ_MARKLOCK(x4);
|
||||
B_MARK_nocond;
|
||||
MARK3;
|
||||
// Unaligned
|
||||
ADDI_D(x5, xZR, -(1 << (rex.w + 2)));
|
||||
AND(x5, wback, x5);
|
||||
MARKLOCK2;
|
||||
LDxw(x1, wback, 0);
|
||||
LLxw(x6, x5, 0);
|
||||
ADDxw(x4, x1, x7);
|
||||
SCxw(x6, x5, 0);
|
||||
BEQZ_MARKLOCK2(x6);
|
||||
SDxw(x4, wback, 0);
|
||||
MARK;
|
||||
if (rex.w) {
|
||||
if (!ALIGNED_ATOMICxw) {
|
||||
ANDI(x3, wback, 0b111);
|
||||
BNEZ_MARK2(x3);
|
||||
}
|
||||
AMADD_DB_D(x1, x7, wback);
|
||||
B_MARK3_nocond;
|
||||
} else {
|
||||
if (!ALIGNED_ATOMICxw) {
|
||||
ANDI(x3, wback, 0b11);
|
||||
BNEZ_MARK(x3);
|
||||
}
|
||||
// aligned 4byte
|
||||
AMADD_DB_W(x1, x7, wback);
|
||||
if (!ALIGNED_ATOMICxw) {
|
||||
B_MARK3_nocond;
|
||||
MARK;
|
||||
ANDI(x3, wback, 0b111);
|
||||
SLTI(x4, x3, 4);
|
||||
BEQZ_MARK2(x4); // addr %8 >4 , cross 8bytes or cross cacheline
|
||||
LOCK_32_IN_8BYTE(ADD_W(x4, x1, x7), x1, wback, x3, x4, x5, x6, x7);
|
||||
B_MARK3_nocond;
|
||||
}
|
||||
}
|
||||
if (!ALIGNED_ATOMICxw) {
|
||||
MARK2;
|
||||
LOCK_3264_CROSS_8BYTE(ADDxw(x4, x1, x7), x1, wback, x4, x5, x6);
|
||||
MARK3;
|
||||
}
|
||||
IFXORNAT (X_ALL | X_PEND) {
|
||||
emit_add32c(dyn, ninst, rex, x1, i64, x3, x4, x5, x6);
|
||||
}
|
||||
|
||||
@@ -1810,4 +1810,75 @@ uintptr_t dynarec64_DF(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
|
||||
|
||||
#define PURGE_YMM()
|
||||
|
||||
#define ALIGNED_ATOMICxw ((fixedaddress && !(fixedaddress & (((1 << (2 + rex.w)) - 1)))) || BOX64ENV(dynarec_aligned_atomics))
|
||||
#define ALIGNED_ATOMICH ((fixedaddress && !(fixedaddress & 1)) || BOX64ENV(dynarec_aligned_atomics))
|
||||
|
||||
|
||||
// lock op related macros
|
||||
/*
|
||||
LOCK_3264_CROSS_8BYTE cross 8byte, lock lower part 8byte.
|
||||
use ll.d lock lower 8byte. ld.d load ed to likely emulate atomic 4byte/8byte operation
|
||||
op = atomic function
|
||||
x1 = original ed
|
||||
x2 = wback ed addr
|
||||
x4 = result
|
||||
x5 = 8 byte lower block for sc
|
||||
x6 = aligned addr
|
||||
*/
|
||||
#define LOCK_3264_CROSS_8BYTE(op, x1, wback, x4, x5, x6) \
|
||||
MV(x6, wback); \
|
||||
BSTRINS_D(x6, xZR, 2, 0); \
|
||||
MARKLOCK2; \
|
||||
LL_D(x5, x6, 0); \
|
||||
DBAR(0b00101); \
|
||||
LDxw(x1, wback, 0); \
|
||||
op; \
|
||||
SC_D(x5, x6, 0); \
|
||||
BEQZ_MARKLOCK2(x5); \
|
||||
SDxw(x4, wback, 0);
|
||||
|
||||
/*
|
||||
LOCK_3264_IN_8BYTE unaligned but in 8 bytes.
|
||||
use ll.d/sc.d to atomic operation. use amcas.db.d when possible
|
||||
x1 = original ed
|
||||
x2 = wback ed addr / aligned ed addr
|
||||
x3 = offset
|
||||
x4 = result
|
||||
x5 = 8 byte block
|
||||
x6 = mask, amcas orignal val
|
||||
x7 = imm if inst use imm op
|
||||
*/
|
||||
#define LOCK_32_IN_8BYTE(op, x1, wback, x3, x4, x5, x6, x7) \
|
||||
BSTRINS_D(wback, xZR, 2, 0); \
|
||||
if(wback != x2) { \
|
||||
MV(x2, wback); \
|
||||
wback = x2; \
|
||||
} \
|
||||
SLLI_W(x3, x3, 3); \
|
||||
if (cpuext.lamcas) { \
|
||||
LD_D(x5, wback, 0); \
|
||||
MARKLOCK; \
|
||||
} else { \
|
||||
MARKLOCK; \
|
||||
LL_D(x5, wback, 0); \
|
||||
} \
|
||||
SRL_D(x1, x5, x3); \
|
||||
BSTRPICK_D(x1, x1, 31, 0); \
|
||||
op; \
|
||||
BSTRPICK_D(x4, x4, 31, 0); \
|
||||
SLL_D(x4, x4, x3); \
|
||||
ADDI_D(x6, xZR, -1); \
|
||||
BSTRINS_D(x6, xZR, 63, 32); \
|
||||
SLL_D(x6, x6, x3); \
|
||||
ANDN(x6, x5, x6); \
|
||||
OR(x4, x6, x4); \
|
||||
if (cpuext.lamcas) { \
|
||||
MV(x6, x5); \
|
||||
AMCAS_DB_D(x5, x4, wback); \
|
||||
BNE_MARKLOCK(x5, x6); \
|
||||
} else { \
|
||||
SC_D(x4, wback, 0); \
|
||||
BEQZ_MARKLOCK(x4); \
|
||||
}
|
||||
|
||||
#endif //__DYNAREC_LA64_HELPER_H__
|
||||
Reference in new issue
Block a user