about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xsrc/dynarec/arm64_emitter.h3
-rwxr-xr-xsrc/dynarec/dynarec_arm64_66.c27
2 files changed, 30 insertions, 0 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h
index f6eef0c8..5c58e387 100755
--- a/src/dynarec/arm64_emitter.h
+++ b/src/dynarec/arm64_emitter.h
@@ -198,6 +198,8 @@
 #define LDRw_S9_preindex(Rt, Rn, imm9)    EMIT(LDR_gen(0b10, 0b00, (imm9)&0x1ff, 0b11, Rn, Rt))
 #define LDRB_S9_postindex(Rt, Rn, imm9)   EMIT(LDR_gen(0b00, 0b00, (imm9)&0x1ff, 0b01, Rn, Rt))
 #define LDRB_S9_preindex(Rt, Rn, imm9)    EMIT(LDR_gen(0b00, 0b00, (imm9)&0x1ff, 0b11, Rn, Rt))
+#define LDRH_S9_postindex(Rt, Rn, imm9)   EMIT(LDR_gen(0b01, 0b00, (imm9)&0x1ff, 0b01, Rn, Rt))
+#define LDRH_S9_preindex(Rt, Rn, imm9)    EMIT(LDR_gen(0b01, 0b00, (imm9)&0x1ff, 0b11, Rn, Rt))
 #define LDRxw_S9_postindex(Rt, Rn, imm9)  EMIT(LDR_gen(rex.w?0b11:0b10, 0b00, (imm9)&0x1ff, 0b01, Rn, Rt))
 
 #define LDRS_gen(size, op1, imm9, op2, Rn, Rt)   ((size)<<30 | 0b111<<27 | (op1)<<24 | 0b10<<22 | (imm9)<<12 | (op2)<<10 | (Rn)<<5 | (Rt))
@@ -243,6 +245,7 @@
 #define STRw_S9_preindex(Rt, Rn, imm9)    EMIT(STR_gen(0b10, 0b00, (imm9)&0x1ff, 0b11, Rn, Rt))
 #define STRxw_S9_postindex(Rt, Rn, imm9)  EMIT(STR_gen(rex.w?0b11:0b10, 0b00, (imm9)&0x1ff, 0b01, Rn, Rt))
 #define STRB_S9_postindex(Rt, Rn, imm9)   EMIT(STR_gen(0b00, 0b00, (imm9)&0x1ff, 0b01, Rn, Rt))
+#define STRH_S9_postindex(Rt, Rn, imm9)   EMIT(STR_gen(0b01, 0b00, (imm9)&0x1ff, 0b01, Rn, Rt))
 
 #define ST_gen(size, op1, imm12, Rn, Rt)        ((size)<<30 | 0b111<<27 | (op1)<<24 | 0b00<<22 | (imm12)<<10 | (Rn)<<5 | (Rt))
 #define STRx_U12(Rt, Rn, imm12)           EMIT(ST_gen(0b11, 0b01, ((uint32_t)(imm12>>3))&0xfff, Rn, Rt))
diff --git a/src/dynarec/dynarec_arm64_66.c b/src/dynarec/dynarec_arm64_66.c
index 91f8d618..0c7f7b88 100755
--- a/src/dynarec/dynarec_arm64_66.c
+++ b/src/dynarec/dynarec_arm64_66.c
@@ -444,6 +444,33 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             INST_NAME("NOP");

             break;

 

+        case 0xA5:

+            if(rep) {

+                INST_NAME("REP MOVSW");

+                CBZx_NEXT(xRCX);

+                TBNZ_MARK2(xFlags, F_DF);

+                MARK;   // Part with DF==0

+                LDRH_S9_postindex(x1, xRSI, 2);

+                STRH_S9_postindex(x1, xRDI, 2);

+                SUBx_U12(xRCX, xRCX, 1);

+                CBNZx_MARK(xRCX);

+                B_NEXT_nocond;

+                MARK2;  // Part with DF==1

+                LDRH_S9_postindex(x1, xRSI, -1);

+                STRH_S9_postindex(x1, xRDI, -1);

+                SUBx_U12(xRCX, xRCX, 1);

+                CBNZx_MARK2(xRCX);

+                // done

+            } else {

+                INST_NAME("MOVSW");

+                GETDIR(x3, 2);

+                LDRH_U12(x1, xRSI, 0);

+                STRH_U12(x1, xRDI, 0);

+                ADDx_REG(xRSI, xRSI, x3);

+                ADDx_REG(xRDI, xRDI, x3);

+            }

+            break;

+

         case 0xB8:

         case 0xB9:

         case 0xBA: