about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-02-02 16:14:33 +0100
committerptitSeb <sebastien.chev@gmail.com>2025-02-02 16:14:33 +0100
commit9beb6b4f63af3cf03f18a3095f012c97eb1966cb (patch)
tree2bdf0bd4834321b2c2698484437b4156e39c8140 /src
parent0861a88d6e3009b3e70604da089d54672d5942ef (diff)
downloadbox64-9beb6b4f63af3cf03f18a3095f012c97eb1966cb.tar.gz
box64-9beb6b4f63af3cf03f18a3095f012c97eb1966cb.zip
[ARM64_DYNAREC] Small improvment on 64 prefixed opcodes
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/arm64_emitter.h10
-rw-r--r--src/dynarec/arm64/dynarec_arm64_64.c80
-rw-r--r--src/dynarec/arm64/dynarec_arm64_6664.c58
-rw-r--r--src/dynarec/arm64/dynarec_arm64_6764_32.c20
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h22
5 files changed, 70 insertions, 120 deletions
diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h
index 8d604f20..3b336b57 100644
--- a/src/dynarec/arm64/arm64_emitter.h
+++ b/src/dynarec/arm64/arm64_emitter.h
@@ -299,18 +299,24 @@ int convert_bitmask(uint64_t bitmask);
 #define LDRx_REG_LSL3(Rt, Rn, Rm)       EMIT(LDR_REG_gen(0b11, Rm, 0b011, 1, Rn, Rt))
 #define LDRx_REG_UXTW3(Rt, Rn, Rm)      EMIT(LDR_REG_gen(0b11, Rm, 0b010, 1, Rn, Rt))
 #define LDRx_REG_SXTW(Rt, Rn, Rm)       EMIT(LDR_REG_gen(0b11, Rm, 0b110, 0, Rn, Rt))
+#define LDRx_REGz(Rt, Rn, Rm)           EMIT(LDR_REG_gen(0b11, Rm, rex.is32bits?0b110:0b011, 0, Rn, Rt))
 #define LDRw_REG(Rt, Rn, Rm)            EMIT(LDR_REG_gen(0b10, Rm, 0b011, 0, Rn, Rt))
 #define LDRw_REG_LSL2(Rt, Rn, Rm)       EMIT(LDR_REG_gen(0b10, Rm, 0b011, 1, Rn, Rt))
 #define LDRw_REG_SXTW(Rt, Rn, Rm)       EMIT(LDR_REG_gen(0b10, Rm, 0b110, 0, Rn, Rt))
+#define LDRw_REGz(Rt, Rn, Rm)           EMIT(LDR_REG_gen(0b10, Rm, rex.is32bits?0b110:0b011, 0, Rn, Rt))
 #define LDRxw_REG(Rt, Rn, Rm)           EMIT(LDR_REG_gen(0b10+rex.w, Rm, 0b011, 0, Rn, Rt))
 #define LDRz_REG(Rt, Rn, Rm)            EMIT(LDR_REG_gen(rex.is32bits?0b10:0b11, Rm, 0b011, 0, Rn, Rt))
 #define LDRxw_REG_SXTW(Rt, Rn, Rm)      EMIT(LDR_REG_gen(0b10+rex.w, Rm, 0b110, 0, Rn, Rt))
+#define LDRxw_REGz(Rt, Rn, Rm)          EMIT(LDR_REG_gen(0b10+rex.w, Rm, rex.is32bits?0b110:0b011, 0, Rn, Rt))
 #define LDRz_REG_SXTW(Rt, Rn, Rm)       EMIT(LDR_REG_gen(rex.is32bits?0b10:0b11, Rm, 0b110, 0, Rn, Rt))
+#define LDRz_REGz(Rt, Rn, Rm)           EMIT(LDR_REG_gen(rex.is32bits?0b10:0b11, Rm, rex.is32bits?0b110:0b011, 0, Rn, Rt))
 #define LDRB_REG(Rt, Rn, Rm)            EMIT(LDR_REG_gen(0b00, Rm, 0b011, 0, Rn, Rt))
 #define LDRB_REG_UXTW(Rt, Rn, Rm)       EMIT(LDR_REG_gen(0b00, Rm, 0b010, 0, Rn, Rt))
 #define LDRB_REG_SXTW(Rt, Rn, Rm)       EMIT(LDR_REG_gen(0b00, Rm, 0b110, 0, Rn, Rt))
+#define LDRB_REGz(Rt, Rn, Rm)           EMIT(LDR_REG_gen(0b00, Rm, rex.is32bits?0b110:0b011, 0, Rn, Rt))
 #define LDRH_REG(Rt, Rn, Rm)            EMIT(LDR_REG_gen(0b01, Rm, 0b011, 0, Rn, Rt))
 #define LDRH_REG_SXTW(Rt, Rn, Rm)       EMIT(LDR_REG_gen(0b01, Rm, 0b110, 0, Rn, Rt))
+#define LDRH_REGz(Rt, Rn, Rm)           EMIT(LDR_REG_gen(0b01, Rm, rex.is32bits?0b110:0b011, 0, Rn, Rt))
 
 #define LDRS_U12_gen(size, op1, opc, imm12, Rn, Rt)    ((size)<<30 | 0b111<<27 | (op1)<<24 | (opc)<<22 | (imm12)<<10 | (Rn)<<5 | (Rt))
 #define LDRSHx_U12(Rt, Rn, imm12)           EMIT(LDRS_U12_gen(0b01, 0b01, 0b10, ((uint32_t)(imm12>>1))&0xfff, Rn, Rt))
@@ -323,6 +329,7 @@ int convert_bitmask(uint64_t bitmask);
 #define LDRS_REG_gen(size, Rm, option, S, Rn, Rt)    ((size)<<30 | 0b111<<27 | 0b10<<22 | 1<<21 | (Rm)<<16 | (option)<<13 | (S)<<12 | (0b10)<<10 | (Rn)<<5 | (Rt))
 #define LDRSW_REG(Rt, Rn, Rm)           EMIT(LDRS_REG_gen(0b10, Rm, 0b011, 0, Rn, Rt))
 #define LDRSW_REG_SXTW(Rt, Rn, Rm)      EMIT(LDRS_REG_gen(0b10, Rm, 0b110, 0, Rn, Rt))
+#define LDRSW_REGz(Rt, Rn, Rm)          EMIT(LDRS_REG_gen(0b10, Rm, rex.is32bits?0b110:0b011, 0, Rn, Rt))
 
 #define LDR_PC_gen(opc, imm19, Rt)      ((opc)<<30 | 0b011<<27 | (imm19)<<5 | (Rt))
 #define LDRx_literal(Rt, imm19)         EMIT(LDR_PC_gen(0b01, ((imm19)>>2)&0x7FFFF, Rt))
@@ -399,12 +406,15 @@ int convert_bitmask(uint64_t bitmask);
 #define STRw_REG_SXTW(Rt, Rn, Rm)       EMIT(STR_REG_gen(0b10, Rm, 0b110, 0, Rn, Rt))
 #define STRB_REG(Rt, Rn, Rm)            EMIT(STR_REG_gen(0b00, Rm, 0b011, 0, Rn, Rt))
 #define STRB_REG_SXTW(Rt, Rn, Rm)       EMIT(STR_REG_gen(0b00, Rm, 0b110, 0, Rn, Rt))
+#define STRB_REGz(Rt, Rn, Rm)           EMIT(STR_REG_gen(0b00, Rm, rex.is32bits?0b110:0b011, 0, Rn, Rt))
 #define STRH_REG(Rt, Rn, Rm)            EMIT(STR_REG_gen(0b01, Rm, 0b011, 0, Rn, Rt))
 #define STRH_REG_SXTW(Rt, Rn, Rm)       EMIT(STR_REG_gen(0b01, Rm, 0b110, 0, Rn, Rt))
 #define STRxw_REG(Rt, Rn, Rm)           EMIT(STR_REG_gen(rex.w?0b11:0b10, Rm, 0b011, 0, Rn, Rt))
 #define STRxw_REG_SXTW(Rt, Rn, Rm)      EMIT(STR_REG_gen(rex.w?0b11:0b10, Rm, 0b110, 0, Rn, Rt))
+#define STRxw_REGz(Rt, Rn, Rm)          EMIT(STR_REG_gen(rex.w?0b11:0b10, Rm, rex.is32bits?0b110:0b011, 0, Rn, Rt))
 #define STRz_REG(Rt, Rn, Rm)            EMIT(STR_REG_gen(rex.is32bits?0b10:0b11, Rm, 0b011, 0, Rn, Rt))
 #define STRz_REG_SXTW(Rt, Rn, Rm)       EMIT(STR_REG_gen(rex.is32bits?0b10:0b11, Rm, 0b110, 0, Rn, Rt))
+#define STRz_REGz(Rt, Rn, Rm)           EMIT(STR_REG_gen(rex.is32bits?0b10:0b11, Rm, rex.is32bits?0b110:0b011, 0, Rn, Rt))
 
 // LOAD/STORE PAIR
 #define MEMPAIR_gen(size, L, op2, imm7, Rt2, Rn, Rt)    ((size)<<31 | 0b101<<27 | (op2)<<23 | (L)<<22 | (imm7)<<15 | (Rt2)<<10 | (Rn)<<5 | (Rt))
diff --git a/src/dynarec/arm64/dynarec_arm64_64.c b/src/dynarec/arm64/dynarec_arm64_64.c
index 867b9d44..0c16e90d 100644
--- a/src/dynarec/arm64/dynarec_arm64_64.c
+++ b/src/dynarec/arm64/dynarec_arm64_64.c
@@ -351,10 +351,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             } else {
                                 SMREAD();
                                 addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
-                                if(rex.is32bits)
-                                    LDRB_REG_SXTW(gd, x4, ed);
-                                else
-                                    LDRB_REG(gd, ed, x4);
+                                LDRB_REGz(gd, x4, ed);
                             }
                             break;
                         default:
@@ -488,7 +485,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
         case 0x5D:
         case 0x5E:
         case 0x5F:
-            // just use regular conditional jump
+            // just use regular push/pop
             return dynarec64_00(dyn, addr-1, ip, ninst, rex, rep, ok, need_epilog);
 
         case 0x63:
@@ -506,10 +503,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         grab_segdata(dyn, addr, ninst, x4, seg);
                         SMREAD();
                         addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
-                        if(rex.is32bits)
-                            LDRSW_REG_SXTW(gd, x4, ed);
-                        else
-                            LDRSW_REG(gd, ed, x4);
+                        LDRSW_REGz(gd, x4, ed);
                     }
                 } else {
                     if(MODREG) {   // reg <= reg
@@ -518,10 +512,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         grab_segdata(dyn, addr, ninst, x4, seg);
                         SMREAD();
                         addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
-                        if(rex.is32bits)
-                            LDRw_REG_SXTW(gd, x4, ed);
-                        else
-                            LDRw_REG(gd, ed, x4);
+                        LDRw_REGz(gd, x4, ed);
                     }
                 }
             }
@@ -858,10 +849,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             } else {
                 grab_segdata(dyn, addr, ninst, x4, seg);
                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
-                if(rex.is32bits)
-                    STRB_REG_SXTW(gd, x4, wback);
-                else
-                    STRB_REG(gd, wback, x4);
+                STRB_REGz(gd, x4, wback);
             }
             break;
         case 0x89:
@@ -873,10 +861,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 MOVxw_REG(TO_NAT((nextop & 7) + (rex.b << 3)), gd);
             } else {                    // mem <= reg
                 addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
-                if(rex.is32bits)
-                    STRxw_REG_SXTW(gd, x4, ed);
-                else
-                    STRxw_REG(gd, ed, x4);
+                STRxw_REGz(gd, x4, ed);
                 SMWRITE2();
             }
             break;
@@ -910,10 +895,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 grab_segdata(dyn, addr, ninst, x4, seg);
                 SMREAD();
                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
-                if(rex.is32bits)
-                    LDRB_REG_SXTW(x4, x4, wback);
-                else
-                    LDRB_REG(x4, wback, x4);
+                LDRB_REGz(x4, x4, wback);
                 ed = x4;
             }
             BFIx(gb1, ed, gb2, 8);
@@ -928,10 +910,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             } else {                    // mem <= reg
                 SMREAD();
                 addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
-                if(rex.is32bits)
-                    LDRxw_REG_SXTW(gd, x4, ed);
-                else
-                    LDRxw_REG(gd, ed, x4);
+                LDRxw_REGz(gd, x4, ed);
             }
             break;
 
@@ -961,10 +940,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             } else {
                 SMREAD();
                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
-                if(rex.is32bits)
-                    LDRH_REG_SXTW(x1, x4, wback);
-                else
-                    LDRH_REG(x1, wback, x4);
+                LDRH_REGz(x1, x4, wback);
                 ed = x1;
             }
             STRH_U12(ed, xEmu, offsetof(x64emu_t, segs[u8]));
@@ -980,17 +956,11 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 POP1z(x2); // so this can handle POP [ESP] and maybe some variant too
                 addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0, 0, rex, NULL, 0, 0);
                 if(ed==xRSP) {
-                    if(rex.is32bits)
-                        STRz_REG_SXTW(x2, x4, ed);
-                    else
-                        STRz_REG(x2, ed, x4);
+                    STRz_REGz(x2, x4, ed);
                 } else {
                     // complicated to just allow a segfault that can be recovered correctly
                     SUBz_U12(xRSP, xRSP, rex.is32bits?4:8);
-                    if(rex.is32bits)
-                        STRz_REG_SXTW(x2, x4, ed);
-                    else
-                        STRz_REG(x2, ed, x4);
+                    STRz_REGz(x2, x4, ed);
                     ADDz_U12(xRSP, xRSP, rex.is32bits?4:8);
                 }
             }
@@ -1023,10 +993,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             else
                 u64 = F64;
             MOV64z(x1, u64);
-            if(rex.is32bits)
-                LDRxw_REG_SXTW(xRAX, x4, x1);
-            else
-                LDRxw_REG(xRAX, x4, x1);
+            LDRxw_REGz(xRAX, x4, x1);
             break;
         case 0xA2:
             INST_NAME("MOV FS:Od,AL");
@@ -1036,10 +1003,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             else
                 u64 = F64;
             MOV64z(x1, u64);
-            if(rex.is32bits)
-                STRB_REG_SXTW(xRAX, x4, x1);
-            else
-                STRB_REG(xRAX, x4, x1);
+            STRB_REGz(xRAX, x4, x1);
             SMWRITE2();
             break;
         case 0xA3:
@@ -1050,10 +1014,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             else
                 u64 = F64;
             MOV64z(x1, u64);
-            if(rex.is32bits)
-                STRxw_REG_SXTW(xRAX, x4, x1);
-            else
-                STRxw_REG(xRAX, x4, x1);
+            STRxw_REGz(xRAX, x4, x1);
             SMWRITE2();
             break;
 
@@ -1062,8 +1023,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             SETFLAGS(X_ALL, SF_SET_PENDING);
             UXTBx(x1, xRAX);
             u8 = F8;
-            MOV32w(x2, u8);
-            emit_test8(dyn, ninst, x1, x2, x3, x4, x5);
+            emit_test8c(dyn, ninst, x1, u8, x3, x4, x5);
             break;
 
         case 0xC6:
@@ -1086,10 +1046,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 1);
                 u8 = F8;
                 MOV32w(x3, u8);
-                if(rex.is32bits)
-                    STRB_REG_SXTW(x3, x4, ed);
-                else
-                    STRB_REG(x3, ed, x4);
+                STRB_REGz(x3, x4, ed);
                 SMWRITE2();
             }
             break;
@@ -1105,10 +1062,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 4);
                 i64 = F32S;
                 MOV64xw(x3, i64);
-                if(rex.is32bits)
-                    STRxw_REG_SXTW(x3, x4, ed);
-                else
-                    STRxw_REG(x3, ed, x4);
+                STRxw_REGz(x3, x4, ed);
                 SMWRITE2();
             }
             break;
diff --git a/src/dynarec/arm64/dynarec_arm64_6664.c b/src/dynarec/arm64/dynarec_arm64_6664.c
index 4d381392..f2dbee70 100644
--- a/src/dynarec/arm64/dynarec_arm64_6664.c
+++ b/src/dynarec/arm64/dynarec_arm64_6664.c
@@ -60,12 +60,11 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     } else {
                         grab_segdata(dyn, addr, ninst, x4, seg);
                         SMREAD();
-                        addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
+                        addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
+                        ADDz_REG(x4, x4, ed);
+                        ed = x4;
                         v1 = fpu_get_scratch(dyn, ninst);
-                        if(rex.is32bits)
-                            VLDR64_REG_SXTW(v1, x4, ed);
-                        else
-                            VLDR64_REG(v1, ed, x4);
+                        VLD64(v1, ed, fixedaddress);
                     }
                     FCMPD(v0, v1);
                     FCOMI(x1, x2);
@@ -81,12 +80,11 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     } else {
                         GETGX_empty(v0);
                         grab_segdata(dyn, addr, ninst, x4, seg);
-                        addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
+                        addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
                         SMREAD();
-                        if(rex.is32bits)
-                            VLDR128_REG_SXTW(v0, x4, ed);
-                        else
-                            VLDR128_REG(v0, ed, x4);
+                        ADDz_REG(x4, x4, ed);
+                        ed = x4;
+                        VLD128(v0, ed, fixedaddress);
                     }
                     break;
 
@@ -99,11 +97,10 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                         VMOVQ(v1, v0);
                     } else {
                         grab_segdata(dyn, addr, ninst, x4, seg);
-                        addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
-                        if(rex.is32bits)
-                            VSTR128_REG_SXTW(v0, x4, ed);
-                        else
-                            VSTR128_REG(v0, ed, x4);
+                        addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
+                        ADDz_REG(x4, x4, ed);
+                        ed = x4;
+                        VST128(v0, ed, fixedaddress);
                         SMWRITE2();
                     }
                     break;
@@ -118,11 +115,10 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                         FMOVD(v1, v0);
                     } else {
                         grab_segdata(dyn, addr, ninst, x4, seg);
-                        addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
-                        if(rex.is32bits)
-                            VSTR64_REG_SXTW(v0, x4, ed);
-                        else
-                            VSTR64_REG(v0, ed, x4);
+                        addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
+                        ADDz_REG(x4, x4, ed);
+                        ed = x4;
+                        VST64(v0, ed, fixedaddress);
                         SMWRITE();
                     }
                     break;
@@ -234,14 +230,13 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                 }
             } else {
                 grab_segdata(dyn, addr, ninst, x4, seg);
-                addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
+                addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<(rex.w?3:1), rex.w?7:1, rex, NULL, 0, 0);
+                ADDz_REG(x4, x4, ed);
+                ed = x4;
                 if(rex.w) {
-                    STRx_REG(gd, ed, x4);
+                    STx(gd, ed, fixedaddress);
                 } else {
-                    if(rex.is32bits)
-                        STRH_REG_SXTW(gd, x4, ed);
-                    else
-                        STRH_REG(gd, ed, x4);
+                    STH(gd, ed, fixedaddress);
                 }
                 SMWRITE();
             }
@@ -263,14 +258,13 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             } else {                    // mem <= reg
                 grab_segdata(dyn, addr, ninst, x4, seg);
                 SMREAD();
-                addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
+                addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<(rex.w?3:1), rex.w?7:1, rex, NULL, 0, 0);
+                ADDz_REG(x4, x4, ed);
+                ed = x4;
                 if(rex.w) {
-                    LDRx_REG(gd, ed, x4);
+                    LDx(gd, ed, fixedaddress);
                 } else {
-                    if(rex.is32bits)
-                        LDRH_REG_SXTW(x1, x4, ed);
-                    else
-                        LDRH_REG(x1, ed, x4);
+                    LDH(x1, ed, fixedaddress);
                     BFIx(gd, x1, 0, 16);
                 }
             }
diff --git a/src/dynarec/arm64/dynarec_arm64_6764_32.c b/src/dynarec/arm64/dynarec_arm64_6764_32.c
index 71fa7820..4076c7d3 100644
--- a/src/dynarec/arm64/dynarec_arm64_6764_32.c
+++ b/src/dynarec/arm64/dynarec_arm64_6764_32.c
@@ -69,8 +69,9 @@ uintptr_t dynarec64_6764_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, in
                 MOVxw_REG(TO_NAT((nextop & 7) + (rex.b << 3)), gd);
             } else {                    // mem <= reg
                 grab_segdata(dyn, addr, ninst, x4, seg);
-                addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, 0);
-                STRw_REG(gd, ed, x4);
+                addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, 0);
+                ADDz_REG(x4, x4, ed);
+                STz(gd, x4, fixedaddress);
             }
             break;
 
@@ -82,8 +83,9 @@ uintptr_t dynarec64_6764_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, in
                 MOVxw_REG(gd, TO_NAT((nextop & 7) + (rex.b << 3)));
             } else {                    // mem => reg
                 grab_segdata(dyn, addr, ninst, x4, seg);
-                addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, 0);
-                LDRw_REG(gd, ed, x4);
+                addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, 0);
+                ADDz_REG(x4, x4, ed);
+                LDz(gd, x4, fixedaddress);
             }
             break;
 
@@ -96,8 +98,9 @@ uintptr_t dynarec64_6764_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, in
             } else {                    // mem <= reg
                 grab_segdata(dyn, addr, ninst, x4, seg);
                 POP1_32(x1);
-                addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, 0);
-                STRw_REG(x1, ed, x4);
+                addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, 0);
+                ADDz_REG(x4, x4, ed);
+                STz(x1, x4, fixedaddress);
             }
             break;
 
@@ -139,8 +142,9 @@ uintptr_t dynarec64_6764_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, in
                         DEFAULT;
                     } else {
                         SMREAD();
-                        addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0, 0, 0);
-                        LDRw_REG(x3, ed, x4);
+                        addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, 0);
+                        ADDz_REG(x4, x4, ed);
+                        LDW(x3, x4, fixedaddress);
                         PUSH1_32(x3);
                     }
                     break;
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index 3bf240ab..91349ac9 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -176,13 +176,10 @@
     } else {                                                                                            \
         SMREAD();                                                                                       \
         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, D); \
-        if (rex.is32bits)                                                                               \
-            LDRxw_REG_SXTW(x1, O, wback);                                                               \
-        else                                                                                            \
-            LDRxw_REG(x1, wback, O);                                                                    \
+        LDRxw_REGz(x1, O, wback);                                                                       \
         ed = x1;                                                                                        \
     }
-#define WBACKO(O)   if(wback) {if(rex.is32bits) STRxw_REG_SXTW(ed, O, wback); else STRxw_REG(ed, wback, O); SMWRITE2();}
+#define WBACKO(O)   if(wback) {STRxw_REGz(ed, O, wback); SMWRITE2();}
 //GETEDOx can use r1 for ed, and r2 for wback. wback is 0 if ed is xEAX..xEDI
 #define GETEDOx(O, D)                                                                                   \
     if (MODREG) {                                                                                       \
@@ -191,10 +188,7 @@
     } else {                                                                                            \
         SMREAD();                                                                                       \
         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, D); \
-        if (rex.is32bits)                                                                               \
-            LDRx_REG_SXTW(x1, O, wback);                                                                \
-        else                                                                                            \
-            LDRx_REG(x1, wback, O);                                                                     \
+        LDRx_REGz(x1, O, wback);                                                                        \
         ed = x1;                                                                                        \
     }
 //GETEDOz can use r1 for ed, and r2 for wback. wback is 0 if ed is xEAX..xEDI
@@ -205,10 +199,7 @@
     } else {                                                                                            \
         SMREAD();                                                                                       \
         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, D); \
-        if (rex.is32bits)                                                                               \
-            LDRz_REG_SXTW(x1, O, wback);                                                                \
-        else                                                                                            \
-            LDRz_REG(x1, wback, O);                                                                     \
+        LDRz_REGz(x1, O, wback);                                                                        \
         ed = x1;                                                                                        \
     }
 #define GETSEDOw(O, D)                                                                                  \
@@ -220,10 +211,7 @@
     } else {                                                                                            \
         SMREAD();                                                                                       \
         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, D); \
-        if (rex.is32bits)                                                                               \
-            LDRSW_REG_SXTW(x1, O, wback);                                                               \
-        else                                                                                            \
-            LDRSW_REG(x1, wback, O);                                                                    \
+        LDRSW_REGz(x1, O, wback);                                                                       \
         wb = ed = x1;                                                                                   \
     }
 //FAKEELike GETED, but doesn't get anything