about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-05-21 15:55:59 +0800
committerGitHub <noreply@github.com>2024-05-21 09:55:59 +0200
commit7842c9e34d7ee5a2e8dd8e5cb690404e71553a45 (patch)
treed0d7419f6f5b3711d3369e0ca6c7ed138b2b72fb /src
parent3882a9875543ac7a64fb5c7f1a9b070ccb266033 (diff)
downloadbox64-7842c9e34d7ee5a2e8dd8e5cb690404e71553a45.tar.gz
box64-7842c9e34d7ee5a2e8dd8e5cb690404e71553a45.zip
[INTERPRETER] Added more opcodes and fixed some opcodes too (#1511)
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64run0f.c127
1 files changed, 116 insertions, 11 deletions
diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c
index 7a4df2cf..f2666e5e 100644
--- a/src/emu/x64run0f.c
+++ b/src/emu/x64run0f.c
@@ -211,7 +211,7 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
             GETGX;

             EX->u128 = GX->u128;

             break;

-        case 0x12:                      

+        case 0x12:

             nextop = F8;

             GETEX(0);

             GETGX;

@@ -407,6 +407,47 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
                             GM->ub[i] = eam1.ub[EM->ub[i]&7];

                     }

                     break;

+                case 0x01: /* PHADDW Gm,Em */

+                    nextop = F8;

+                    GETEM(0);

+                    GETGM;

+                    for (int i = 0; i < 2; ++i)

+                        GM->sw[i] = GM->sw[i * 2 + 0] + GM->sw[i * 2 + 1];

+                    if (GM == EM) {

+                        GM->sd[1] = GM->sd[0];

+                    } else {

+                        for (int i = 0; i < 2; ++i)

+                            GM->sw[2 + i] = EM->sw[i * 2 + 0] + EM->sw[i * 2 + 1];

+                    }

+                    break;

+                case 0x02: /* PHADDD Gm,Em */

+                    nextop = F8;

+                    GETEM(0);

+                    GETGM;

+                    GM->sd[0] = GM->sd[0] + GM->sd[1];

+                    if (GM == EM) {

+                        GM->sd[1] = GM->sd[0];

+                    } else {

+                        GM->sd[1] = EM->sd[0] + EM->sd[1];

+                    }

+                    break;

+                case 0x03: /* PHADDSW Gm,Em */

+                    nextop = F8;

+                    GETEM(0);

+                    GETGM;

+                    for (int i = 0; i < 2; ++i) {

+                        tmp32s = GM->sw[i * 2 + 0] + GM->sw[i * 2 + 1];

+                        GM->sw[i] = (tmp32s < -32768) ? -32768 : ((tmp32s > 32767) ? 32767 : tmp32s);

+                    }

+                    if (GM == EM) {

+                        GM->sd[1] = GM->sd[0];

+                    } else {

+                        for (int i = 0; i < 2; ++i) {

+                            tmp32s = EM->sw[i * 2 + 0] + EM->sw[i * 2 + 1];

+                            GM->sw[2 + i] = (tmp32s < -32768) ? -32768 : ((tmp32s > 32767) ? 32767 : tmp32s);

+                        }

+                    }

+                    break;

                 case 0x04:  /* PMADDUBSW Gm,Em */

                     nextop = F8;

                     GETEM(0);

@@ -416,6 +457,68 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
                         GM->sw[i] = (tmp32s>32767)?32767:((tmp32s<-32768)?-32768:tmp32s);

                     }

                     break;

+                case 0x05: /* PHSUBW Gm,Em */

+                    nextop = F8;

+                    GETEM(0);

+                    GETGM;

+                    for (int i = 0; i < 2; ++i)

+                        GM->sw[i] = GM->sw[i * 2 + 0] - GM->sw[i * 2 + 1];

+                    if (GM == EM) {

+                        GM->sd[1] = GM->sd[0];

+                    } else {

+                        for (int i = 0; i < 2; ++i)

+                            GM->sw[2 + i] = EM->sw[i * 2 + 0] - EM->sw[i * 2 + 1];

+                    }

+                    break;

+                case 0x06: /* PHSUBD Gm,Em */

+                    nextop = F8;

+                    GETEM(0);

+                    GETGM;

+                    GM->sd[0] = GM->sd[0] - GM->sd[1];

+                    if (GM == EM) {

+                        GM->sd[1] = GM->sd[0];

+                    } else {

+                        GM->sd[1] = EM->sd[0] - EM->sd[1];

+                    }

+                    break;

+                case 0x07: /* PHSUBSW Gm,Em */

+                    nextop = F8;

+                    GETEM(0);

+                    GETGM;

+                    for (int i = 0; i < 2; ++i) {

+                        tmp32s = GM->sw[i * 2 + 0] - GM->sw[i * 2 + 1];

+                        GM->sw[i] = (tmp32s < -32768) ? -32768 : ((tmp32s > 32767) ? 32767 : tmp32s);

+                    }

+                    if (GM == EM) {

+                        GM->sd[1] = GM->sd[0];

+                    } else {

+                        for (int i = 0; i < 2; ++i) {

+                            tmp32s = EM->sw[i * 2 + 0] - EM->sw[i * 2 + 1];

+                            GM->sw[2 + i] = (tmp32s < -32768) ? -32768 : ((tmp32s > 32767) ? 32767 : tmp32s);

+                        }

+                    }

+                    break;

+                case 0x08: /* PSIGNB Gm,Em */

+                    nextop = F8;

+                    GETEM(0);

+                    GETGM;

+                    for (int i = 0; i < 8; ++i)

+                        GM->sb[i] *= (EM->sb[i] < 0) ? -1 : ((EM->sb[i] > 0) ? 1 : 0);

+                    break;

+                case 0x09: /* PSIGNW Gm,Em */

+                    nextop = F8;

+                    GETEM(0);

+                    GETGM;

+                    for (int i = 0; i < 4; ++i)

+                        GM->sw[i] *= (EM->sw[i] < 0) ? -1 : ((EM->sw[i] > 0) ? 1 : 0);

+                    break;

+                case 0x0A: /* PSIGND Gm,Em */

+                    nextop = F8;

+                    GETEM(0);

+                    GETGM;

+                    for (int i = 0; i < 2; ++i)

+                        GM->sd[i] *= (EM->sd[i] < 0) ? -1 : ((EM->sd[i] > 0) ? 1 : 0);

+                    break;

                 case 0x0B:  /* PMULHRSW Gm, Em */

                     nextop = F8;

                     GETEM(0);

@@ -519,21 +622,22 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
         case 0x3A:

             opcode = F8;

             switch(opcode) {

-                case 0xF:  /* palignr */

+                case 0xF: /* PALIGNR Gm, Em, Ib */

                     nextop = F8;

                     GETEM(1);

                     GETGM;

                     tmp8u = F8;

+                    tmp64u = EM->q;

                     if (tmp8u >= 16) {

                         GM->q = 0;

-                    } else if (tmp8u > 8) {

+                    } else if (tmp8u >= 8) {

                         tmp8u -= 8;

-                        GM->q >>= tmp8u*8;

-                    } else if (tmp8u == 8 || tmp8u == 0) {

-

+                        GM->q >>= tmp8u * 8;

+                    } else if (tmp8u == 0) {

+                        GM->q = tmp64u;

                     } else {

-                        GM->q <<= (8-tmp8u)*8;

-                        GM->q |= (EM->q >> tmp8u*8);

+                        GM->q <<= (8 - tmp8u) * 8;

+                        GM->q |= (tmp64u >> tmp8u * 8);

                     }

                     break;

 

@@ -565,7 +669,7 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
             , if(!rex.w) GD->dword[1] = 0;

             ,

         )                               /* 0x40 -> 0x4F CMOVxx Gd,Ed */ // conditional move, no sign

-        

+

         case 0x50:                      /* MOVMSKPS Gd, Ex */

             nextop = F8;

             GETEX(0);

@@ -889,6 +993,7 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
                     break;

                 case 4:                 /* PSRAD Em, Ib */

                     tmp8u = F8;

+                    if (tmp8u > 31) tmp8u = 31;

                     for (int i=0; i<2; ++i) EM->sd[i] >>= tmp8u;

                     break;

                 case 6:                 /* PSLLD Em, Ib */

@@ -1286,7 +1391,7 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
             GD->q[0] = EW->word[0];

             break;

 

-        case 0xBA:                      

+        case 0xBA:

             nextop = F8;

             switch((nextop>>3)&7) {

                 case 4:                 /* BT Ed,Ib */

@@ -1634,7 +1739,7 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
             GETEM(0);

             GETGM;

             if(EM->q>15)

-                GM->q=0; 

+                GM->q = 0;

             else {

                 tmp8u = EM->ub[0];

                 for(int i=0; i<4; ++i)