diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-07-05 10:29:38 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-07-05 10:29:38 +0200 |
| commit | 2010f8dcce4349e1420755a94f9af2211e9574c8 (patch) | |
| tree | c5322b1e68d26b62e9d00fd1223a3d2ba692c5d1 /src | |
| parent | abcb12f9ed9b154bcd3594686d7209b7dc3523ac (diff) | |
| download | box64-2010f8dcce4349e1420755a94f9af2211e9574c8.tar.gz box64-2010f8dcce4349e1420755a94f9af2211e9574c8.zip | |
Added 64 FF ocpodes (for #20)
Diffstat (limited to 'src')
| -rw-r--r-- | src/emu/x64run64.c | 74 |
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; |