about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2023-03-22 14:45:57 +0800
committerGitHub <noreply@github.com>2023-03-22 07:45:57 +0100
commitda88b872790f838ad85f979a7153658bf746479a (patch)
treeb2208597269496685efef03c8f81ee2465ac80d3 /src
parent900f38779da63d30625c6951291ce0e39ff3c598 (diff)
downloadbox64-da88b872790f838ad85f979a7153658bf746479a.tar.gz
box64-da88b872790f838ad85f979a7153658bf746479a.zip
[RV64_DYNAREC] Added AB STOSD opcode (#611)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00.c26
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h16
2 files changed, 40 insertions, 2 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c
index b6153b06..9b0c4a63 100644
--- a/src/dynarec/rv64/dynarec_rv64_00.c
+++ b/src/dynarec/rv64/dynarec_rv64_00.c
@@ -644,7 +644,31 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             MOV64xw(x2, i64);
             emit_test32(dyn, ninst, rex, xRAX, x2, x3, x4, x5);
             break;
-
+        case 0xAB:
+            if(rep) {
+                INST_NAME("REP STOSD");
+                CBZ_NEXT(xRCX);
+                ANDI(x1, xFlags, 1<<F_DF);
+                BNEZ_MARK2(x1);
+                MARK;   // Part with DF==0
+                SDxw(xRAX, xRDI, 0);
+                ADDI(xRDI, xRDI, rex.w?8:4);
+                ADDI(xRCX, xRCX, -1);
+                BNEZ_MARK(xRCX);
+                B_NEXT_nocond;
+                MARK2;  // Part with DF==1
+                SDxw(xRAX, xRDI, 0);
+                ADDI(xRDI, xRDI, rex.w?-8:-4);
+                ADDI(xRCX, xRCX, -1);
+                BNEZ_MARK2(xRCX);
+                // done
+            } else {
+                INST_NAME("STOSD");
+                GETDIR(x3, x1, rex.w?8:4);
+                SDxw(xRAX, xRDI, 0);
+                ADD(xRDI, xRDI, x3);
+            }
+            break;
         case 0xB0:
         case 0xB1:
         case 0xB2:
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index e8e2cf6c..fd369085 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -244,6 +244,14 @@
                     OR(wback, wback, ed);               \
                 }
 
+// Get direction with size Z and based of F_DF flag, on register r ready for load/store fetching
+// using s as scratch.
+#define GETDIR(r, s, Z)             \
+    MOV32w(r, Z); /* mask=1<<10 */  \
+    ANDI(s, xFlags, 1<<F_DF);       \
+    BEQZ(s, 8);                     \
+    SUB(r, xZR, r);                 \
+
 // CALL will use x6 for the call address. Return value can be put in ret (unless ret is -1)
 // R0 will not be pushed/popd if ret is -2
 #define CALL(F, ret) call_c(dyn, ninst, F, x6, ret, 1, 0)
@@ -275,6 +283,8 @@
 #define BEQ_MARK(reg1, reg2) Bxx_gen(EQ, MARK, reg1, reg2)
 // Branch to MARK if reg1!=reg2 (use j64)
 #define BNE_MARK(reg1, reg2) Bxx_gen(NE, MARK, reg1, reg2)
+// Branch to MARK if reg1!=0 (use j64)
+#define BNEZ_MARK(reg) BNE_MARK(reg, xZR)
 // Branch to MARK if reg1<reg2 (use j64)
 #define BLT_MARK(reg1, reg2) Bxx_gen(LT, MARK, reg1, reg2)
 // Branch to MARK if reg1>=reg2 (use j64)
@@ -283,12 +293,16 @@
 #define BEQ_MARK2(reg1, reg2) Bxx_gen(EQ, MARK2, reg1,reg2)
 // Branch to MARK2 if reg1!=reg2 (use j64)
 #define BNE_MARK2(reg1, reg2) Bxx_gen(NE, MARK2, reg1,reg2)
-// Branch to MARK2 if reg1<>reg2 (use j64)
+// Branch to MARK2 if reg1!=0 (use j64)
+#define BNEZ_MARK2(reg) BNE_MARK2(reg, xZR)
+// Branch to MARK2 if reg1<reg2 (use j64)
 #define BLT_MARK2(reg1, reg2) Bxx_gen(LT, MARK2, reg1,reg2)
 // Branch to MARK3 if reg1==reg2 (use j64)
 #define BEQ_MARK3(reg1, reg2) Bxx_gen(EQ, MARK3, reg1, reg2)
 // Branch to MARK3 if reg1!=reg2 (use j64)
 #define BNE_MARK3(reg1, reg2) Bxx_gen(NE, MARK3, reg1, reg2)
+// Branch to MARK3 if reg1!=0 (use j64)
+#define BNEZ_MARK3(reg) BNE_MARK3(reg, xZR)
 // Branch to MARKLOCK if reg1!=reg2 (use j64)
 #define BNE_MARKLOCK(reg1, reg2) Bxx_gen(NE, MARKLOCK, reg1, reg2)
 // Branch to MARKLOCK if reg1!=0 (use j64)