diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_f0.c | 19 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.h | 8 |
2 files changed, 24 insertions, 3 deletions
diff --git a/src/dynarec/la64/dynarec_la64_f0.c b/src/dynarec/la64/dynarec_la64_f0.c index bfad81df..f95aef81 100644 --- a/src/dynarec/la64/dynarec_la64_f0.c +++ b/src/dynarec/la64/dynarec_la64_f0.c @@ -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); @@ -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); @@ -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); diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h index 484c1324..14ad25d2 100644 --- a/src/dynarec/la64/dynarec_la64_helper.h +++ b/src/dynarec/la64/dynarec_la64_helper.h @@ -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) @@ -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) |