about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2023-03-17 17:39:57 +0800
committerGitHub <noreply@github.com>2023-03-17 10:39:57 +0100
commitffa74500e601d0b561233b366b2f7963e5f057c5 (patch)
treeda3733feb16db6e4ea3070190a1203551be7e393 /src
parent356c135cbe7c0d75ebbab4948ebc92cd3a4dbcd7 (diff)
downloadbox64-ffa74500e601d0b561233b366b2f7963e5f057c5.tar.gz
box64-ffa74500e601d0b561233b366b2f7963e5f057c5.zip
[RV64_DYNAREC] Added 0F AF IMUL opcode (#579)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c32
-rw-r--r--src/dynarec/rv64/rv64_emitter.h11
2 files changed, 42 insertions, 1 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index ada4e23e..ed4d3c64 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -275,7 +275,37 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 }
             }
             break;
-
+        case 0xAF:
+            INST_NAME("IMUL Gd, Ed");
+            SETFLAGS(X_ALL, SF_PENDING);
+            nextop = F8;
+            GETGD;
+            GETED(0);
+            if(rex.w) {
+                // 64bits imul
+                UFLAG_IF {
+                    MULH(x3, gd, ed);
+                    MUL(gd, gd, ed);
+                    UFLAG_OP1(x3);
+                    UFLAG_RES(gd);
+                    UFLAG_DF(x3, d_imul64);
+                } else {
+                    MULxw(gd, gd, ed);
+                }
+            } else {
+                // 32bits imul
+                UFLAG_IF {
+                    MUL(gd, gd, ed);
+                    UFLAG_RES(gd);
+                    SRLI(x3, gd, 32);
+                    UFLAG_OP1(x3);
+                    UFLAG_DF(x3, d_imul32);
+                    SEXT_W(gd, gd);
+                } else {
+                    MULxw(gd, gd, ed);
+                }
+            }
+            break;
         default:
             DEFAULT;
     }
diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h
index 4601bee6..ea3f08c1 100644
--- a/src/dynarec/rv64/rv64_emitter.h
+++ b/src/dynarec/rv64/rv64_emitter.h
@@ -290,4 +290,15 @@ f28–31  ft8–11  FP temporaries                  Caller
 // Shift Right Arithmetic Immediate
 #define SRAIxw(rd, rs1, imm)        if (rex.w) { SRAI(rd, rs1, imm); } else { SRAIW(rd, rs1, imm); }
 
+// RV32M
+// rd = rs1 * rs2
+#define MUL(rd, rs1, rs2)           EMIT(R_type(0b0000001, rs2, rs1, 0b000, rd, 0b0110011))
+#define MULH(rd, rs1, rs2)          EMIT(R_type(0b0000001, rs2, rs1, 0b001, rd, 0b0110011))
+
+// RV64M
+// rd = rs1 * rs2
+#define MULW(rd, rs1, rs2)          EMIT(R_type(0b0000001, rs2, rs1, 0b000, rd, 0b0111011))
+// rd = rs1 * rs2
+#define MULxw(rd, rs1, rs2)         EMIT(R_type(0b0000001, rs2, rs1, 0b000, rd, rex.w?0b0110011:0b0111011))
+
 #endif //__RV64_EMITTER_H__