about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-05 10:42:40 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-05 10:42:40 +0100
commit3da0e6c633352d2105e8758e482b2e8689894df9 (patch)
tree80f9479ded151c1f79102aa216ba0c99bba1be53 /src
parent57730a4b14da3efe73ba312e5371c08797282877 (diff)
downloadbox64-3da0e6c633352d2105e8758e482b2e8689894df9.tar.gz
box64-3da0e6c633352d2105e8758e482b2e8689894df9.zip
Added REX 0F AF IMUL opcodes
Diffstat (limited to 'src')
-rwxr-xr-xsrc/emu/x64primop.h23
-rwxr-xr-xsrc/emu/x64run.c2
-rw-r--r--src/emu/x64run0f.c15
-rwxr-xr-xsrc/emu/x64run_private.h2
4 files changed, 37 insertions, 5 deletions
diff --git a/src/emu/x64primop.h b/src/emu/x64primop.h
index 377ae9aa..2b018548 100755
--- a/src/emu/x64primop.h
+++ b/src/emu/x64primop.h
@@ -544,6 +544,29 @@ static inline void imul32_eax(x64emu_t *emu, uint32_t s)
 	emu->op1 = R_EDX;
 }
 
+static inline void imul64_direct(uint64_t *res_lo, uint64_t* res_hi,uint64_t d, uint64_t s)
+{
+	__int128 res = (__int128)(int64_t)d * (int64_t)s;
+
+	*res_lo = (uint64_t)res;
+	*res_hi = (uint64_t)(res >> 64);
+}
+
+static inline uint64_t imul64(x64emu_t *emu, uint64_t op1, uint64_t op2)
+{
+	emu->df = d_imul64;
+	imul64_direct(&emu->res,&emu->op1,op1,op2);
+	return emu->res;
+}
+
+static inline void imul64_eax(x64emu_t *emu, uint64_t s)
+{
+	emu->df = d_imul64;
+	imul64_direct(&R_RAX,&R_RDX,R_RAX,s);
+	emu->res = R_RAX;
+	emu->op1 = R_RDX;
+}
+
 static inline void mul8(x64emu_t *emu, uint8_t s)
 {
 	emu->df = d_mul8;
diff --git a/src/emu/x64run.c b/src/emu/x64run.c
index af256e93..4031ec69 100755
--- a/src/emu/x64run.c
+++ b/src/emu/x64run.c
@@ -141,7 +141,7 @@ x64emurun:
         GO(0x00, add)                   /* ADD 0x00 -> 0x05 */
         GO(0x08, or)                    /*  OR 0x08 -> 0x0D */
         case 0x0F:                      /* More instructions */
-            if(Run0F(emu)) {
+            if(Run0F(emu, rex)) {
                 unimp = 1;
                 goto fini;
             }
diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c
index c084d1ec..a46e488e 100644
--- a/src/emu/x64run0f.c
+++ b/src/emu/x64run0f.c
@@ -43,12 +43,11 @@
 #define EB  oped

 #define GB  oped->byte[0]

 

-int Run0F(x64emu_t *emu)

+int Run0F(x64emu_t *emu, rex_t rex)

 {

     uint8_t opcode;

     uint8_t nextop;

     reg64_t *oped, *opgd;

-    rex_t rex = {0};

 

     opcode = F8;

     while(opcode>=0x40 && opcode<=0x4f) {

@@ -61,12 +60,22 @@ int Run0F(x64emu_t *emu)
         case 0x05:                      /* SYSCALL */

             x64Syscall(emu);

             break;

-            

+

         case 0x1F:                      /* NOP (multi-byte) */

             nextop = F8;

             GETED;

             break;

         

+        case 0xAF:                      /* IMUL Gd,Ed */

+            nextop = F8;

+            GETED;

+            GETGD;

+            if(rex.w)

+                GD->q[0] = imul64(emu, GD->q[0], ED->q[0]);

+            else

+                GD->dword[0] = imul32(emu, GD->dword[0], ED->dword[0]);

+            break;

+

         default:

             return 1;

     }

diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h
index 69ae17ff..e797c71f 100755
--- a/src/emu/x64run_private.h
+++ b/src/emu/x64run_private.h
@@ -227,7 +227,7 @@ void UpdateFlags(x64emu_t *emu);
 #define RESET_FLAGS(emu) emu->df = d_none
 
 //void Run67(x64emu_t *emu);
-int Run0F(x64emu_t *emu);
+int Run0F(x64emu_t *emu, rex_t rex);
 //void Run660F(x64emu_t *emu);
 //void Run66D9(x64emu_t *emu);    // x87
 //void Run6766(x64emu_t *emu);