about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_f0.c19
-rw-r--r--src/dynarec/la64/dynarec_la64_helper.h8
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)