about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-07-05 10:29:38 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-07-05 10:29:38 +0200
commit2010f8dcce4349e1420755a94f9af2211e9574c8 (patch)
treec5322b1e68d26b62e9d00fd1223a3d2ba692c5d1 /src
parentabcb12f9ed9b154bcd3594686d7209b7dc3523ac (diff)
downloadbox64-2010f8dcce4349e1420755a94f9af2211e9574c8.tar.gz
box64-2010f8dcce4349e1420755a94f9af2211e9574c8.zip
Added 64 FF ocpodes (for #20)
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64run64.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/src/emu/x64run64.c b/src/emu/x64run64.c
index 9e789b0f..e01b4e5a 100644
--- a/src/emu/x64run64.c
+++ b/src/emu/x64run64.c
@@ -406,7 +406,79 @@ int Run64(x64emu_t *emu, rex_t rex, int seg)
             }

             break;

 

-       default:

+        case 0xFF:                      /* GRP 5 Ed */

+            nextop = F8;

+            GETED_OFFS(0, tlsdata);

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

+                case 0:                 /* INC Ed */

+                    if(rex.w)

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

+                    else {

+                        if(MODREG)

+                            ED->q[0] = inc32(emu, ED->dword[0]);

+                        else

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

+                    }

+                    break;

+                case 1:                 /* DEC Ed */

+                    if(rex.w)

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

+                    else {

+                        if(MODREG)

+                            ED->q[0] = dec32(emu, ED->dword[0]);

+                        else

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

+                    }

+                    break;

+                case 2:                 /* CALL NEAR Ed */

+                    tmp64u = (uintptr_t)getAlternate((void*)ED->q[0]);

+                    Push(emu, R_RIP);

+                    R_RIP = tmp64u;

+                    break;

+                case 3:                 /* CALL FAR Ed */

+                    if(nextop>0xC0) {

+                        R_RIP = emu->old_ip;

+                        printf_log(LOG_NONE, "Illegal Opcode %p: %02X %02X %02X %02X\n", (void*)R_RIP, opcode, nextop, PK(2), PK(3));

+                        emu->quit=1;

+                        emu->error |= ERR_ILLEGAL;

+                        return 0;

+                    } else {

+                        Push16(emu, R_CS);

+                        Push(emu, R_RIP);

+                        R_RIP = ED->dword[0];

+                        R_CS = (ED+1)->word[0];

+                        return 0;  // exit loop to recompute new CS...

+                    }

+                    break;

+                case 4:                 /* JMP NEAR Ed */

+                    R_RIP = (uintptr_t)getAlternate((void*)ED->q[0]);

+                    break;

+                case 5:                 /* JMP FAR Ed */

+                    if(nextop>0xc0) {

+                        R_RIP = emu->old_ip;

+                        printf_log(LOG_NONE, "Illegal Opcode %p: 0x%02X 0x%02X %02X %02X\n", (void*)R_RIP, opcode, nextop, PK(2), PK(3));

+                        emu->quit=1;

+                        emu->error |= ERR_ILLEGAL;

+                        return 0;

+                    } else {

+                        R_RIP = ED->q[0];

+                        R_CS = (ED+1)->word[0];

+                        return 0;  // exit loop to recompute CS...

+                    }

+                    break;

+                case 6:                 /* Push Ed */

+                    tmp64u = ED->q[0];  // rex.w ignored

+                    Push(emu, tmp64u);  // avoid potential issue with push [esp+...]

+                    break;

+                default:

+                    R_RIP = emu->old_ip;

+                    printf_log(LOG_NONE, "Illegal Opcode %p: %02X %02X %02X %02X %02X %02X\n",(void*)R_RIP, opcode, nextop, PK(2), PK(3), PK(4), PK(5));

+                    emu->quit=1;

+                    emu->error |= ERR_ILLEGAL;

+                    return 0;

+            }

+            break;

+        default:

             return 1;

     }

     return 0;