about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64run0f.c28
-rw-r--r--src/emu/x64run660f.c19
-rw-r--r--src/emu/x64runf20f.c28
3 files changed, 75 insertions, 0 deletions
diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c
index e48c0eb6..ec055fb2 100644
--- a/src/emu/x64run0f.c
+++ b/src/emu/x64run0f.c
@@ -34,6 +34,7 @@ int Run0F(x64emu_t *emu, rex_t rex)
     uint8_t tmp8u;

     int32_t tmp32s, tmp32s2;

     uint32_t tmp32u;

+    uint64_t tmp64u;

     reg64_t *oped, *opgd;

     sse_regs_t *opex, *opgx;

     mmx87_regs_t *opem, *opgm;

@@ -595,6 +596,33 @@ int Run0F(x64emu_t *emu, rex_t rex)
             }

             break;

 

+        case 0xBD:                      /* BSR Ed,Gd */

+            CHECK_FLAGS(emu);

+            nextop = F8;

+            GETED(0);

+            GETGD;

+            if(rex.w) {

+                tmp64u = ED->q[0];

+                if(tmp64u) {

+                    CLEAR_FLAG(F_ZF);

+                    tmp8u = 63;

+                    while(!(tmp64u&(1L<<tmp8u))) --tmp8u;

+                    GD->q[0] = tmp8u;

+                } else {

+                    SET_FLAG(F_ZF);

+                }

+            } else {

+                tmp32u = ED->dword[0];

+                if(tmp32u) {

+                    CLEAR_FLAG(F_ZF);

+                    tmp8u = 31;

+                    while(!(tmp32u&(1<<tmp8u))) --tmp8u;

+                    GD->q[0] = tmp8u;

+                } else {

+                    SET_FLAG(F_ZF);

+                }

+            }

+            break;

         case 0xBE:                      /* MOVSX Gd,Eb */

             nextop = F8;

             GETEB(0);

diff --git a/src/emu/x64run660f.c b/src/emu/x64run660f.c
index 3d1939ca..660ac028 100644
--- a/src/emu/x64run660f.c
+++ b/src/emu/x64run660f.c
@@ -123,6 +123,15 @@ int Run660F(x64emu_t *emu, rex_t rex)
         CLEAR_FLAG(F_OF); CLEAR_FLAG(F_AF); CLEAR_FLAG(F_SF);

         break;

 

+    GOCOND(0x40

+        , nextop = F8;

+        CHECK_FLAGS(emu);

+        GETEW(0);

+        GETGW;

+        , if(rex.w) GW->q[0] = EW->q[0]; else GW->word[0] = EW->word[0];

+        ,

+    )                               /* 0x40 -> 0x4F CMOVxx Gw,Ew */ // conditional move, no sign

+

     case 0x54:                      /* ANDPD Gx, Ex */

         nextop = F8;

         GETEX(0);

@@ -377,6 +386,16 @@ int Run660F(x64emu_t *emu, rex_t rex)
         EX->q[1] = GX->q[1];

         break;

 

+    case 0xBE:                      /* MOVSX Gw,Eb */

+        nextop = F8;

+        GETEB(0);

+        GETGW;

+        if(rex.w)

+            GW->sq[0] = EB->sbyte[0];

+        else

+            GW->sword[0] = EB->sbyte[0];

+        break;

+

     case 0xD6:                      /* MOVQ Ex,Gx */

         nextop = F8;

         GETEX(0);

diff --git a/src/emu/x64runf20f.c b/src/emu/x64runf20f.c
index a45a23d9..cd50f6f6 100644
--- a/src/emu/x64runf20f.c
+++ b/src/emu/x64runf20f.c
@@ -30,6 +30,9 @@ int RunF20F(x64emu_t *emu, rex_t rex)
 {

     uint8_t opcode;

     uint8_t nextop;

+    int8_t tmp8s;

+    uint8_t tmp8u;

+    int32_t tmp32s;

     reg64_t *oped, *opgd;

     sse_regs_t *opex, *opgx;

 

@@ -120,6 +123,31 @@ int RunF20F(x64emu_t *emu, rex_t rex)
             GX->d[0] = EX->d[0];

         break;

 

+    GOCOND(0x80

+        , tmp32s = F32S; CHECK_FLAGS(emu);

+        , R_RIP += tmp32s;

+        ,

+    )                               /* 0x80 -> 0x8F Jxx */

+        

+    case 0xC2:  /* CMPSD Gx, Ex, Ib */

+        nextop = F8;

+        GETEX(0);

+        GETGX;

+        tmp8u = F8;

+        tmp8s = 0;

+        switch(tmp8u&7) {

+            case 0: tmp8s=(GX->d[0] == EX->d[0]); break;

+            case 1: tmp8s=isless(GX->d[0], EX->d[0]); break;

+            case 2: tmp8s=islessequal(GX->d[0], EX->d[0]); break;

+            case 3: tmp8s=isnan(GX->d[0]) || isnan(EX->d[0]); break;

+            case 4: tmp8s=(GX->d[0] != EX->d[0]); break;

+            case 5: tmp8s=isnan(GX->d[0]) || isnan(EX->d[0]) || isgreaterequal(GX->d[0], EX->d[0]); break;

+            case 6: tmp8s=isnan(GX->d[0]) || isnan(EX->d[0]) || isgreater(GX->d[0], EX->d[0]); break;

+            case 7: tmp8s=!isnan(GX->d[0]) && !isnan(EX->d[0]); break;

+        }

+        GX->q[0]=(tmp8s)?0xffffffffffffffffLL:0LL;

+        break;

+

     default:

         return 1;

     }