about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-20 22:38:23 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-20 22:38:23 +0100
commit5ec0a8894920bc2821b941abbca26a3e3117d472 (patch)
tree6fb8586d5d5431d4163f1d0320e327e07b3645fe /src
parent12de3807997e8f3b8c484a082e941a383adf8432 (diff)
downloadbox64-5ec0a8894920bc2821b941abbca26a3e3117d472.tar.gz
box64-5ec0a8894920bc2821b941abbca26a3e3117d472.zip
[DYNAREC] Added (66) 69/6B IMUL opcodes
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/dynarec_arm64_00.c67
-rwxr-xr-xsrc/dynarec/dynarec_arm64_66.c28
2 files changed, 95 insertions, 0 deletions
diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c
index c46d78ff..5b0bf213 100755
--- a/src/dynarec/dynarec_arm64_00.c
+++ b/src/dynarec/dynarec_arm64_00.c
@@ -531,6 +531,73 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 PUSH1(x3);
             }
             break;
+        case 0x69:
+            INST_NAME("IMUL Gd, Ed, Id");
+            SETFLAGS(X_ALL, SF_PENDING);
+            nextop = F8;
+            GETGD;
+            GETED(4);
+            i64 = F32S;
+            MOV64xw(x1, i64);
+            if(rex.w) {
+                // 64bits imul
+                UFLAG_IF {
+                    SMULH(x3, ed, x1);
+                    MULx(gd, ed, x1);
+                    UFLAG_OP1(x3);
+                    UFLAG_RES(gd);
+                    UFLAG_DF(x3, d_imul64);
+                } else {
+                    MULxw(gd, ed, x1);
+                }
+            } else {
+                // 32bits imul
+                UFLAG_IF {
+                    SMULL(gd, ed, x1);
+                    UFLAG_RES(gd);
+                    LSRx(x3, gd, 32);
+                    UFLAG_OP1(x3);
+                    UFLAG_DF(x3, d_imul32);
+                    MOVw_REG(gd, gd);
+                } else {
+                    MULxw(gd, ed, x1);
+                }
+            }
+            break;
+
+        case 0x6B:
+            INST_NAME("IMUL Gd, Ed, Ib");
+            SETFLAGS(X_ALL, SF_PENDING);
+            nextop = F8;
+            GETGD;
+            GETED(1);
+            i64 = F8S;
+            MOV64xw(x1, i64);
+            if(rex.w) {
+                // 64bits imul
+                UFLAG_IF {
+                    SMULH(x3, ed, x1);
+                    MULx(gd, ed, x1);
+                    UFLAG_OP1(x3);
+                    UFLAG_RES(gd);
+                    UFLAG_DF(x3, d_imul64);
+                } else {
+                    MULxw(gd, ed, x1);
+                }
+            } else {
+                // 32bits imul
+                UFLAG_IF {
+                    SMULL(gd, ed, x1);
+                    UFLAG_RES(gd);
+                    LSRx(x3, gd, 32);
+                    UFLAG_OP1(x3);
+                    UFLAG_DF(x3, d_imul32);
+                    MOVw_REG(gd, gd);
+                } else {
+                    MULxw(gd, ed, x1);
+                }
+            }
+            break;
 
         #define GO(GETFLAGS, NO, YES, F)    \
             READFLAGS(F);                   \
diff --git a/src/dynarec/dynarec_arm64_66.c b/src/dynarec/dynarec_arm64_66.c
index 024404e0..edcbd1b7 100755
--- a/src/dynarec/dynarec_arm64_66.c
+++ b/src/dynarec/dynarec_arm64_66.c
@@ -287,6 +287,34 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             }

             break;

 

+        case 0x69:

+            INST_NAME("IMUL Gw,Ew,Iw");

+            SETFLAGS(X_ALL, SF_PENDING);

+            nextop = F8;

+            UFLAG_DF(x1, d_imul16);

+            GETSEW(x1, 2);

+            i32 = F16S;

+            MOV32w(x2, i32);

+            MULw(x2, x2, x1);

+            UFLAG_RES(x2);

+            gd=x2;

+            GWBACK;

+            break;

+

+        case 0x6B:

+            INST_NAME("IMUL Gw,Ew,Ib");

+            SETFLAGS(X_ALL, SF_PENDING);

+            nextop = F8;

+            UFLAG_DF(x1, d_imul16);

+            GETSEW(x1, 1);

+            i32 = F8S;

+            MOV32w(x2, i32);

+            MULw(x2, x2, x1);

+            UFLAG_RES(x2);

+            gd=x2;

+            GWBACK;

+            break;

+

         case 0xD1:

         case 0xD3:

             nextop = F8;