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/arm64/dynarec_arm64_66.c29
-rw-r--r--src/dynarec/la64/dynarec_la64_66.c32
-rw-r--r--src/dynarec/rv64/dynarec_rv64_66.c32
-rw-r--r--src/emu/x64run66.c15
4 files changed, 105 insertions, 3 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c
index 15ce091b..3dc765df 100644
--- a/src/dynarec/arm64/dynarec_arm64_66.c
+++ b/src/dynarec/arm64/dynarec_arm64_66.c
@@ -758,7 +758,34 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             STRH_U12(xRAX, x1, 0);

             SMWRITELOCK(lock);

             break;

-

+        case 0xA4:

+            SMREAD();

+            if(rep) {

+                INST_NAME("REP MOVSB");

+                CBZx_NEXT(xRCX);

+                TBNZ_MARK2(xFlags, F_DF);

+                MARK;   // Part with DF==0

+                LDRB_S9_postindex(x1, xRSI, 1);

+                STRB_S9_postindex(x1, xRDI, 1);

+                SUBx_U12(xRCX, xRCX, 1);

+                CBNZx_MARK(xRCX);

+                B_NEXT_nocond;

+                MARK2;  // Part with DF==1

+                LDRB_S9_postindex(x1, xRSI, -1);

+                STRB_S9_postindex(x1, xRDI, -1);

+                SUBx_U12(xRCX, xRCX, 1);

+                CBNZx_MARK2(xRCX);

+                // done

+            } else {

+                INST_NAME("MOVSB");

+                GETDIR(x3, 1);

+                LDRB_U12(x1, xRSI, 0);

+                STRB_U12(x1, xRDI, 0);

+                ADDx_REG(xRSI, xRSI, x3);

+                ADDx_REG(xRDI, xRDI, x3);

+            }

+            SMWRITE();

+            break;

         case 0xA5:

             SMREAD();

             if(rep) {

diff --git a/src/dynarec/la64/dynarec_la64_66.c b/src/dynarec/la64/dynarec_la64_66.c
index 5130a3b0..3c32462d 100644
--- a/src/dynarec/la64/dynarec_la64_66.c
+++ b/src/dynarec/la64/dynarec_la64_66.c
@@ -413,6 +413,38 @@ uintptr_t dynarec64_66(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 BSTRINS_D(gd, x2, 15, 0);
             }
             break;
+
+        case 0xA4:
+            if (rep) {
+                INST_NAME("REP MOVSB");
+                CBZ_NEXT(xRCX);
+                ANDI(x1, xFlags, 1 << F_DF);
+                BNEZ_MARK2(x1);
+                MARK; // Part with DF==0
+                LD_BU(x1, xRSI, 0);
+                ST_B(x1, xRDI, 0);
+                ADDI_D(xRSI, xRSI, 1);
+                ADDI_D(xRDI, xRDI, 1);
+                ADDI_D(xRCX, xRCX, -1);
+                BNEZ_MARK(xRCX);
+                B_NEXT_nocond;
+                MARK2; // Part with DF==1
+                LD_BU(x1, xRSI, 0);
+                ST_B(x1, xRDI, 0);
+                ADDI_D(xRSI, xRSI, -1);
+                ADDI_D(xRDI, xRDI, -1);
+                ADDI_D(xRCX, xRCX, -1);
+                BNEZ_MARK2(xRCX);
+                // done
+            } else {
+                INST_NAME("MOVSB");
+                GETDIR(x3, x1, 1);
+                LD_BU(x1, xRSI, 0);
+                ST_B(x1, xRDI, 0);
+                ADD_D(xRSI, xRSI, x3);
+                ADD_D(xRDI, xRDI, x3);
+            }
+            break;
         case 0xA5:
             if (rep) {
                 INST_NAME("REP MOVSW");
diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c
index ba57b57d..0f0f31d0 100644
--- a/src/dynarec/rv64/dynarec_rv64_66.c
+++ b/src/dynarec/rv64/dynarec_rv64_66.c
@@ -717,7 +717,37 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             SH(xRAX, x1, 0);
             SMWRITELOCK(lock);
             break;
-
+        case 0xA4:
+            if(rep) {
+                INST_NAME("REP MOVSB");
+                CBZ_NEXT(xRCX);
+                ANDI(x1, xFlags, 1<<F_DF);
+                BNEZ_MARK2(x1);
+                MARK;   // Part with DF==0
+                LBU(x1, xRSI, 0);
+                SB(x1, xRDI, 0);
+                ADDI(xRSI, xRSI, 1);
+                ADDI(xRDI, xRDI, 1);
+                SUBI(xRCX, xRCX, 1);
+                BNEZ_MARK(xRCX);
+                B_NEXT_nocond;
+                MARK2;  // Part with DF==1
+                LBU(x1, xRSI, 0);
+                SB(x1, xRDI, 0);
+                SUBI(xRSI, xRSI, 1);
+                SUBI(xRDI, xRDI, 1);
+                SUBI(xRCX, xRCX, 1);
+                BNEZ_MARK2(xRCX);
+                // done
+            } else {
+                INST_NAME("MOVSB");
+                GETDIR(x3, x1, 1);
+                LBU(x1, xRSI, 0);
+                SB(x1, xRDI, 0);
+                ADD(xRSI, xRSI, x3);
+                ADD(xRDI, xRDI, x3);
+            }
+            break;
         case 0xA5:
             if(rep) {
                 INST_NAME("REP MOVSW");
diff --git a/src/emu/x64run66.c b/src/emu/x64run66.c
index 536583bc..17199c71 100644
--- a/src/emu/x64run66.c
+++ b/src/emu/x64run66.c
@@ -477,7 +477,20 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr)
                 *(uint16_t*)F64 = R_AX;

         }

         break;

-

+    case 0xA4:                      /* (REP) MOVSB */

+        tmp8s = ACCESS_FLAG(F_DF)?-1:+1;

+        tmp64u = (rep)?R_RCX:1L;

+        while(tmp64u) {

+            #ifndef TEST_INTERPRETER

+            *(uint8_t*)R_RDI = *(uint8_t*)R_RSI;

+            #endif

+            R_RDI += tmp8s;

+            R_RSI += tmp8s;

+            --tmp64u;

+        }

+        if(rep)

+            R_RCX = tmp64u;

+        break;

     case 0xA5:              /* (REP) MOVSW */

         tmp8s = ACCESS_FLAG(F_DF)?-1:+1;

         tmp64u = (rep)?R_RCX:1L;