Skip to content

Commit

Permalink
[LA64_DYNAREC] Added LOCK CMPXCHG unaligned version (ptitSeb#1545)
Browse files Browse the repository at this point in the history
  • Loading branch information
ksco authored and Javier97sm committed Aug 16, 2024
1 parent 79acc46 commit 5e6c015
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
19 changes: 18 additions & 1 deletion src/dynarec/la64/dynarec_la64_f0.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ uintptr_t dynarec64_F0(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
} else {
SMDMB();
addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
ANDI(x1, wback, (1 << (rex.w + 2)) - 1);
BNEZ_MARK3(x1);
// Aligned
MARKLOCK;
MV(x4, gd);
LLxw(x1, wback, 0);
Expand All @@ -106,6 +109,20 @@ uintptr_t dynarec64_F0(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
// EAX == Ed
SCxw(x4, wback, 0);
BEQZ_MARKLOCK(x4);
B_MARK_nocond;
MARK3;
// Unaligned
ADDI_D(x5, xZR, -(1 << (rex.w + 2)));
AND(x5, x5, wback);
MARK2;
LDxw(x1, wback, 0);
LLxw(x6, x5, 0);
SUBxw(x3, x1, xRAX);
BNEZ_MARK(x3);
// EAX == Ed
SCxw(x6, x5, 0);
BEQZ_MARK2(x6);
SDxw(gd, wback, 0);
MARK;
UFLAG_IF { emit_cmp32(dyn, ninst, rex, xRAX, x1, x3, x4, x5, x6); }
MVxw(xRAX, x1);
Expand Down Expand Up @@ -409,7 +426,7 @@ uintptr_t dynarec64_F0(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
SETFLAGS(X_ALL & ~X_CF, SF_SUBSET_PENDING);
SMDMB();
if (MODREG) {
ed = xRAX + (nextop & 7) + (rex.b << 3);
ed = TO_LA64((nextop & 7) + (rex.b << 3));
emit_dec32(dyn, ninst, rex, ed, x3, x4, x5, x6);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
Expand Down
8 changes: 6 additions & 2 deletions src/dynarec/la64/dynarec_la64_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,10 @@
#define BEQ_MARK3(reg1, reg2) Bxx_gen(EQ, MARK3, reg1, reg2)
// Branch to MARKLOCK if reg1==reg2 (use j64)
#define BEQ_MARKLOCK(reg1, reg2) Bxx_gen(EQ, MARKLOCK, reg1, reg2)
// Branch to MARK if reg1==0 (use j64)
#define BEQZ_MARK(reg) BxxZ_gen(EQ, MARK, reg)
// Branch to MARK2 if reg1==0 (use j64)
#define BEQZ_MARK2(reg) BxxZ_gen(EQ, MARK2, reg)
// Branch to MARKLOCK if reg1==0 (use j64)
#define BEQZ_MARKLOCK(reg) BxxZ_gen(EQ, MARKLOCK, reg)

Expand Down Expand Up @@ -450,8 +454,8 @@
// Branch to MARK if reg1>=reg2 (use j64)
#define BGE_MARK(reg1, reg2) Bxx_gen(GE, MARK, reg1, reg2)

// Branch to MARK1 instruction unconditionnal (use j64)
#define B_MARK1_nocond Bxx_gen(__, MARK1, 0, 0)
// Branch to MARK instruction unconditionnal (use j64)
#define B_MARK_nocond Bxx_gen(__, MARK, 0, 0)
// Branch to MARK2 instruction unconditionnal (use j64)
#define B_MARK2_nocond Bxx_gen(__, MARK2, 0, 0)
// Branch to MARK3 instruction unconditionnal (use j64)
Expand Down

0 comments on commit 5e6c015

Please sign in to comment.