mirror of
https://github.com/holub/mame
synced 2025-05-29 09:03:08 +03:00
2966 lines
157 KiB
C++
2966 lines
157 KiB
C++
// license:BSD-3-Clause
|
|
// copyright-holders:Ville Linde, Peter Ferrie
|
|
/*
|
|
i386 Disassembler
|
|
|
|
Written by Ville Linde
|
|
*/
|
|
|
|
#include "emu.h"
|
|
#include "i386dasm.h"
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::i386_opcode_table1[256] =
|
|
{
|
|
// 0x00
|
|
{"add", MODRM, PARAM_RM8, PARAM_REG8, 0 },
|
|
{"add", MODRM, PARAM_RM, PARAM_REG, 0 },
|
|
{"add", MODRM, PARAM_REG8, PARAM_RM8, 0 },
|
|
{"add", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"add", 0, PARAM_AL, PARAM_UI8, 0 },
|
|
{"add", 0, PARAM_EAX, PARAM_IMM, 0 },
|
|
{"push es", 0, 0, 0, 0 },
|
|
{"pop es", 0, 0, 0, 0 },
|
|
{"or", MODRM, PARAM_RM8, PARAM_REG8, 0 },
|
|
{"or", MODRM, PARAM_RM, PARAM_REG, 0 },
|
|
{"or", MODRM, PARAM_REG8, PARAM_RM8, 0 },
|
|
{"or", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"or", 0, PARAM_AL, PARAM_UI8, 0 },
|
|
{"or", 0, PARAM_EAX, PARAM_IMM, 0 },
|
|
{"push cs", 0, 0, 0, 0 },
|
|
{"two_byte", TWO_BYTE, 0, 0, 0 },
|
|
// 0x10
|
|
{"adc", MODRM, PARAM_RM8, PARAM_REG8, 0 },
|
|
{"adc", MODRM, PARAM_RM, PARAM_REG, 0 },
|
|
{"adc", MODRM, PARAM_REG8, PARAM_RM8, 0 },
|
|
{"adc", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"adc", 0, PARAM_AL, PARAM_UI8, 0 },
|
|
{"adc", 0, PARAM_EAX, PARAM_IMM, 0 },
|
|
{"push ss", 0, 0, 0, 0 },
|
|
{"pop ss", 0, 0, 0, 0 },
|
|
{"sbb", MODRM, PARAM_RM8, PARAM_REG8, 0 },
|
|
{"sbb", MODRM, PARAM_RM, PARAM_REG, 0 },
|
|
{"sbb", MODRM, PARAM_REG8, PARAM_RM8, 0 },
|
|
{"sbb", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"sbb", 0, PARAM_AL, PARAM_UI8, 0 },
|
|
{"sbb", 0, PARAM_EAX, PARAM_IMM, 0 },
|
|
{"push ds", 0, 0, 0, 0 },
|
|
{"pop ds", 0, 0, 0, 0 },
|
|
// 0x20
|
|
{"and", MODRM, PARAM_RM8, PARAM_REG8, 0 },
|
|
{"and", MODRM, PARAM_RM, PARAM_REG, 0 },
|
|
{"and", MODRM, PARAM_REG8, PARAM_RM8, 0 },
|
|
{"and", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"and", 0, PARAM_AL, PARAM_UI8, 0 },
|
|
{"and", 0, PARAM_EAX, PARAM_IMM, 0 },
|
|
{"seg_es", SEG_ES, 0, 0, 0 },
|
|
{"daa", 0, 0, 0, 0 },
|
|
{"sub", MODRM, PARAM_RM8, PARAM_REG8, 0 },
|
|
{"sub", MODRM, PARAM_RM, PARAM_REG, 0 },
|
|
{"sub", MODRM, PARAM_REG8, PARAM_RM8, 0 },
|
|
{"sub", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"sub", 0, PARAM_AL, PARAM_UI8, 0 },
|
|
{"sub", 0, PARAM_EAX, PARAM_IMM, 0 },
|
|
{"seg_cs", SEG_CS, 0, 0, 0 },
|
|
{"das", 0, 0, 0, 0 },
|
|
// 0x30
|
|
{"xor", MODRM, PARAM_RM8, PARAM_REG8, 0 },
|
|
{"xor", MODRM, PARAM_RM, PARAM_REG, 0 },
|
|
{"xor", MODRM, PARAM_REG8, PARAM_RM8, 0 },
|
|
{"xor", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"xor", 0, PARAM_AL, PARAM_UI8, 0 },
|
|
{"xor", 0, PARAM_EAX, PARAM_IMM, 0 },
|
|
{"seg_ss", SEG_SS, 0, 0, 0 },
|
|
{"aaa", 0, 0, 0, 0 },
|
|
{"cmp", MODRM, PARAM_RM8, PARAM_REG8, 0 },
|
|
{"cmp", MODRM, PARAM_RM, PARAM_REG, 0 },
|
|
{"cmp", MODRM, PARAM_REG8, PARAM_RM8, 0 },
|
|
{"cmp", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"cmp", 0, PARAM_AL, PARAM_UI8, 0 },
|
|
{"cmp", 0, PARAM_EAX, PARAM_IMM, 0 },
|
|
{"seg_ds", SEG_DS, 0, 0, 0 },
|
|
{"aas", 0, 0, 0, 0 },
|
|
// 0x40
|
|
{"inc", ISREX, PARAM_EAX, 0, 0 },
|
|
{"inc", ISREX, PARAM_ECX, 0, 0 },
|
|
{"inc", ISREX, PARAM_EDX, 0, 0 },
|
|
{"inc", ISREX, PARAM_EBX, 0, 0 },
|
|
{"inc", ISREX, PARAM_ESP, 0, 0 },
|
|
{"inc", ISREX, PARAM_EBP, 0, 0 },
|
|
{"inc", ISREX, PARAM_ESI, 0, 0 },
|
|
{"inc", ISREX, PARAM_EDI, 0, 0 },
|
|
{"dec", ISREX, PARAM_EAX, 0, 0 },
|
|
{"dec", ISREX, PARAM_ECX, 0, 0 },
|
|
{"dec", ISREX, PARAM_EDX, 0, 0 },
|
|
{"dec", ISREX, PARAM_EBX, 0, 0 },
|
|
{"dec", ISREX, PARAM_ESP, 0, 0 },
|
|
{"dec", ISREX, PARAM_EBP, 0, 0 },
|
|
{"dec", ISREX, PARAM_ESI, 0, 0 },
|
|
{"dec", ISREX, PARAM_EDI, 0, 0 },
|
|
// 0x50
|
|
{"push", ALWAYS64, PARAM_EAX, 0, 0 },
|
|
{"push", ALWAYS64, PARAM_ECX, 0, 0 },
|
|
{"push", ALWAYS64, PARAM_EDX, 0, 0 },
|
|
{"push", ALWAYS64, PARAM_EBX, 0, 0 },
|
|
{"push", ALWAYS64, PARAM_ESP, 0, 0 },
|
|
{"push", ALWAYS64, PARAM_EBP, 0, 0 },
|
|
{"push", ALWAYS64, PARAM_ESI, 0, 0 },
|
|
{"push", ALWAYS64, PARAM_EDI, 0, 0 },
|
|
{"pop", ALWAYS64, PARAM_EAX, 0, 0 },
|
|
{"pop", ALWAYS64, PARAM_ECX, 0, 0 },
|
|
{"pop", ALWAYS64, PARAM_EDX, 0, 0 },
|
|
{"pop", ALWAYS64, PARAM_EBX, 0, 0 },
|
|
{"pop", ALWAYS64, PARAM_ESP, 0, 0 },
|
|
{"pop", ALWAYS64, PARAM_EBP, 0, 0 },
|
|
{"pop", ALWAYS64, PARAM_ESI, 0, 0 },
|
|
{"pop", ALWAYS64, PARAM_EDI, 0, 0 },
|
|
// 0x60
|
|
{"pusha\0pushad\0<invalid>",VAR_NAME,0, 0, 0 },
|
|
{"popa\0popad\0<invalid>", VAR_NAME,0, 0, 0 },
|
|
{"bound", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"arpl", MODRM | SPECIAL64_ENT(0),PARAM_RM, PARAM_REG16, 0 },
|
|
{"seg_fs", SEG_FS, 0, 0, 0 },
|
|
{"seg_gs", SEG_GS, 0, 0, 0 },
|
|
{"op_size", OP_SIZE, 0, 0, 0 },
|
|
{"addr_size", ADDR_SIZE, 0, 0, 0 },
|
|
{"push", 0, PARAM_IMM, 0, 0 },
|
|
{"imul", MODRM, PARAM_REG, PARAM_RM, PARAM_IMM },
|
|
{"push", 0, PARAM_I8, 0, 0 },
|
|
{"imul", MODRM, PARAM_REG, PARAM_RM, PARAM_I8 },
|
|
{"insb", 0, 0, 0, 0 },
|
|
{"insw\0insd\0insd",VAR_NAME, 0, 0, 0 },
|
|
{"outsb", 0, PARAM_PREIMP, 0, 0 },
|
|
{"outsw\0outsd\0outsd",VAR_NAME, PARAM_PREIMP, 0, 0 },
|
|
// 0x70
|
|
{"jo", 0, PARAM_REL8, 0, 0 },
|
|
{"jno", 0, PARAM_REL8, 0, 0 },
|
|
{"jb", 0, PARAM_REL8, 0, 0 },
|
|
{"jae", 0, PARAM_REL8, 0, 0 },
|
|
{"je", 0, PARAM_REL8, 0, 0 },
|
|
{"jne", 0, PARAM_REL8, 0, 0 },
|
|
{"jbe", 0, PARAM_REL8, 0, 0 },
|
|
{"ja", 0, PARAM_REL8, 0, 0 },
|
|
{"js", 0, PARAM_REL8, 0, 0 },
|
|
{"jns", 0, PARAM_REL8, 0, 0 },
|
|
{"jp", 0, PARAM_REL8, 0, 0 },
|
|
{"jnp", 0, PARAM_REL8, 0, 0 },
|
|
{"jl", 0, PARAM_REL8, 0, 0 },
|
|
{"jge", 0, PARAM_REL8, 0, 0 },
|
|
{"jle", 0, PARAM_REL8, 0, 0 },
|
|
{"jg", 0, PARAM_REL8, 0, 0 },
|
|
// 0x80
|
|
{"group80", GROUP, 0, 0, 0 },
|
|
{"group81", GROUP, 0, 0, 0 },
|
|
{"group80", GROUP, 0, 0, 0 },
|
|
{"group83", GROUP, 0, 0, 0 },
|
|
{"test", MODRM, PARAM_RM8, PARAM_REG8, 0 },
|
|
{"test", MODRM, PARAM_RM, PARAM_REG, 0 },
|
|
{"xchg", MODRM, PARAM_REG8, PARAM_RM8, 0 },
|
|
{"xchg", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"mov", MODRM, PARAM_RM8, PARAM_REG8, 0 },
|
|
{"mov", MODRM, PARAM_RM, PARAM_REG, 0 },
|
|
{"mov", MODRM, PARAM_REG8, PARAM_RM8, 0 },
|
|
{"mov", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"mov", MODRM, PARAM_RM, PARAM_SREG, 0 },
|
|
{"lea", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"mov", MODRM, PARAM_SREG, PARAM_RM, 0 },
|
|
{"pop", MODRM, PARAM_RM, 0, 0 },
|
|
// 0x90
|
|
{"nop\0???\0???\0pause", VAR_NAME4, 0, 0, 0 },
|
|
{"xchg", 0, PARAM_EAX, PARAM_ECX, 0 },
|
|
{"xchg", 0, PARAM_EAX, PARAM_EDX, 0 },
|
|
{"xchg", 0, PARAM_EAX, PARAM_EBX, 0 },
|
|
{"xchg", 0, PARAM_EAX, PARAM_ESP, 0 },
|
|
{"xchg", 0, PARAM_EAX, PARAM_EBP, 0 },
|
|
{"xchg", 0, PARAM_EAX, PARAM_ESI, 0 },
|
|
{"xchg", 0, PARAM_EAX, PARAM_EDI, 0 },
|
|
{"cbw\0cwde\0cdqe", VAR_NAME, 0, 0, 0 },
|
|
{"cwd\0cdq\0cqo", VAR_NAME, 0, 0, 0 },
|
|
{"call", ALWAYS64, PARAM_ADDR, 0, 0, STEP_OVER},
|
|
{"wait", 0, 0, 0, 0 },
|
|
{"pushf\0pushfd\0pushfq",VAR_NAME, 0, 0, 0 },
|
|
{"popf\0popfd\0popfq",VAR_NAME, 0, 0, 0 },
|
|
{"sahf", 0, 0, 0, 0 },
|
|
{"lahf", 0, 0, 0, 0 },
|
|
// 0xa0
|
|
{"mov", 0, PARAM_AL, PARAM_MEM_OFFS, 0 },
|
|
{"mov", 0, PARAM_EAX, PARAM_MEM_OFFS, 0 },
|
|
{"mov", 0, PARAM_MEM_OFFS, PARAM_AL, 0 },
|
|
{"mov", 0, PARAM_MEM_OFFS, PARAM_EAX, 0 },
|
|
{"movsb", 0, PARAM_PREIMP, 0, 0 },
|
|
{"movsw\0movsd\0movsq",VAR_NAME, PARAM_PREIMP, 0, 0 },
|
|
{"cmpsb", 0, PARAM_PREIMP, 0, 0 },
|
|
{"cmpsw\0cmpsd\0cmpsq",VAR_NAME, PARAM_PREIMP, 0, 0 },
|
|
{"test", 0, PARAM_AL, PARAM_UI8, 0 },
|
|
{"test", 0, PARAM_EAX, PARAM_IMM, 0 },
|
|
{"stosb", 0, 0, 0, 0 },
|
|
{"stosw\0stosd\0stosq",VAR_NAME, 0, 0, 0 },
|
|
{"lodsb", 0, PARAM_PREIMP, 0, 0 },
|
|
{"lodsw\0lodsd\0lodsq",VAR_NAME, PARAM_PREIMP, 0, 0 },
|
|
{"scasb", 0, 0, 0, 0 },
|
|
{"scasw\0scasd\0scasq",VAR_NAME, 0, 0, 0 },
|
|
// 0xb0
|
|
{"mov", 0, PARAM_AL, PARAM_UI8, 0 },
|
|
{"mov", 0, PARAM_CL, PARAM_UI8, 0 },
|
|
{"mov", 0, PARAM_DL, PARAM_UI8, 0 },
|
|
{"mov", 0, PARAM_BL, PARAM_UI8, 0 },
|
|
{"mov", 0, PARAM_AH, PARAM_UI8, 0 },
|
|
{"mov", 0, PARAM_CH, PARAM_UI8, 0 },
|
|
{"mov", 0, PARAM_DH, PARAM_UI8, 0 },
|
|
{"mov", 0, PARAM_BH, PARAM_UI8, 0 },
|
|
{"mov", 0, PARAM_EAX, PARAM_IMM64, 0 },
|
|
{"mov", 0, PARAM_ECX, PARAM_IMM64, 0 },
|
|
{"mov", 0, PARAM_EDX, PARAM_IMM64, 0 },
|
|
{"mov", 0, PARAM_EBX, PARAM_IMM64, 0 },
|
|
{"mov", 0, PARAM_ESP, PARAM_IMM64, 0 },
|
|
{"mov", 0, PARAM_EBP, PARAM_IMM64, 0 },
|
|
{"mov", 0, PARAM_ESI, PARAM_IMM64, 0 },
|
|
{"mov", 0, PARAM_EDI, PARAM_IMM64, 0 },
|
|
// 0xc0
|
|
{"groupC0", GROUP, 0, 0, 0 },
|
|
{"groupC1", GROUP, 0, 0, 0 },
|
|
{"ret", 0, PARAM_UI16, 0, 0, STEP_OUT},
|
|
{"ret", 0, 0, 0, 0, STEP_OUT},
|
|
{"les", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"lds", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"mov", MODRM, PARAM_RMPTR8, PARAM_UI8, 0 },
|
|
{"mov", MODRM, PARAM_RMPTR, PARAM_IMM, 0 },
|
|
{"enter", 0, PARAM_UI16, PARAM_UI8, 0 },
|
|
{"leave", 0, 0, 0, 0 },
|
|
{"retf", 0, PARAM_UI16, 0, 0, STEP_OUT},
|
|
{"retf", 0, 0, 0, 0, STEP_OUT},
|
|
{"int 3", 0, 0, 0, 0, STEP_OVER},
|
|
{"int", 0, PARAM_UI8, 0, 0, STEP_OVER},
|
|
{"into", 0, 0, 0, 0 },
|
|
{"iret", 0, 0, 0, 0, STEP_OUT},
|
|
// 0xd0
|
|
{"groupD0", GROUP, 0, 0, 0 },
|
|
{"groupD1", GROUP, 0, 0, 0 },
|
|
{"groupD2", GROUP, 0, 0, 0 },
|
|
{"groupD3", GROUP, 0, 0, 0 },
|
|
{"aam", 0, PARAM_UI8, 0, 0 },
|
|
{"aad", 0, PARAM_UI8, 0, 0 },
|
|
{"salc", 0, 0, 0, 0 }, //AMD docs name it
|
|
{"xlat", 0, 0, 0, 0 },
|
|
{"escape", FPU, 0, 0, 0 },
|
|
{"escape", FPU, 0, 0, 0 },
|
|
{"escape", FPU, 0, 0, 0 },
|
|
{"escape", FPU, 0, 0, 0 },
|
|
{"escape", FPU, 0, 0, 0 },
|
|
{"escape", FPU, 0, 0, 0 },
|
|
{"escape", FPU, 0, 0, 0 },
|
|
{"escape", FPU, 0, 0, 0 },
|
|
// 0xe0
|
|
{"loopne", 0, PARAM_REL8, 0, 0, STEP_OVER},
|
|
{"loopz", 0, PARAM_REL8, 0, 0, STEP_OVER},
|
|
{"loop", 0, PARAM_REL8, 0, 0, STEP_OVER},
|
|
{"jcxz\0jecxz\0jrcxz",VAR_NAME, PARAM_REL8, 0, 0 },
|
|
{"in", 0, PARAM_AL, PARAM_UI8, 0 },
|
|
{"in", 0, PARAM_EAX, PARAM_UI8, 0 },
|
|
{"out", 0, PARAM_UI8, PARAM_AL, 0 },
|
|
{"out", 0, PARAM_UI8, PARAM_EAX, 0 },
|
|
{"call", 0, PARAM_REL, 0, 0, STEP_OVER},
|
|
{"jmp", 0, PARAM_REL, 0, 0 },
|
|
{"jmp", 0, PARAM_ADDR, 0, 0 },
|
|
{"jmp", 0, PARAM_REL8, 0, 0 },
|
|
{"in", 0, PARAM_AL, PARAM_DX, 0 },
|
|
{"in", 0, PARAM_EAX, PARAM_DX, 0 },
|
|
{"out", 0, PARAM_DX, PARAM_AL, 0 },
|
|
{"out", 0, PARAM_DX, PARAM_EAX, 0 },
|
|
// 0xf0
|
|
{"lock", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"repne", PREFIX, 0, 0, 0 },
|
|
{"rep", PREFIX, 0, 0, 0, STEP_OVER},
|
|
{"hlt", 0, 0, 0, 0, STEP_OVER},
|
|
{"cmc", 0, 0, 0, 0 },
|
|
{"groupF6", GROUP, 0, 0, 0 },
|
|
{"groupF7", GROUP, 0, 0, 0 },
|
|
{"clc", 0, 0, 0, 0 },
|
|
{"stc", 0, 0, 0, 0 },
|
|
{"cli", 0, 0, 0, 0 },
|
|
{"sti", 0, 0, 0, 0 },
|
|
{"cld", 0, 0, 0, 0 },
|
|
{"std", 0, 0, 0, 0 },
|
|
{"groupFE", GROUP, 0, 0, 0 },
|
|
{"groupFF", GROUP, 0, 0, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::x64_opcode_alt[] =
|
|
{
|
|
{"movsxd", MODRM | ALWAYS64,PARAM_REG, PARAM_RMPTR32, 0 },
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::i386_opcode_table2[256] =
|
|
{
|
|
// 0x00
|
|
{"group0F00", GROUP, 0, 0, 0 },
|
|
{"group0F01", GROUP, 0, 0, 0 },
|
|
{"lar", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"lsl", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"syscall", 0, 0, 0, 0 },
|
|
{"clts", 0, 0, 0, 0 },
|
|
{"sysret", 0, 0, 0, 0 },
|
|
{"invd", 0, 0, 0, 0 },
|
|
{"wbinvd", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"ud2", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"group0F0D", GROUP, 0, 0, 0 }, //AMD only
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0x10
|
|
{"movups\0"
|
|
"movupd\0"
|
|
"movsd\0"
|
|
"movss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"movups\0"
|
|
"movupd\0"
|
|
"movsd\0"
|
|
"movss", MODRM|VAR_NAME4,PARAM_XMMM, PARAM_XMM, 0 },
|
|
{"group0F12", GROUP|GROUP_MOD, 0, 0, 0 },
|
|
{"movlps\0"
|
|
"movlpd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4,PARAM_XMMM, PARAM_XMM, 0 },
|
|
{"unpcklps\0"
|
|
"unpcklpd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"unpckhps\0"
|
|
"unpckhpd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{ "group0F16", GROUP|GROUP_MOD, 0, 0, 0 },
|
|
{"movhps\0"
|
|
"movhpd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4,PARAM_XMMM, PARAM_XMM, 0 },
|
|
{"group0F18", GROUP, 0, 0, 0 },
|
|
{"nop_hint", 0, PARAM_RMPTR8, 0, 0 },
|
|
{"nop_hint", 0, PARAM_RMPTR8, 0, 0 },
|
|
{"nop_hint", 0, PARAM_RMPTR8, 0, 0 },
|
|
{"nop_hint", 0, PARAM_RMPTR8, 0, 0 },
|
|
{"nop_hint", 0, PARAM_RMPTR8, 0, 0 },
|
|
{"nop_hint", 0, PARAM_RMPTR8, 0, 0 },
|
|
{"nop_hint", 0, PARAM_RMPTR8, 0, 0 },
|
|
// 0x20
|
|
{"mov", MODRM, PARAM_REG2_32, PARAM_CREG, 0 },
|
|
{"mov", MODRM, PARAM_REG2_32, PARAM_DREG, 0 },
|
|
{"mov", MODRM, PARAM_CREG, PARAM_REG2_32, 0 },
|
|
{"mov", MODRM, PARAM_DREG, PARAM_REG2_32, 0 },
|
|
{"mov", MODRM, PARAM_REG2_32, PARAM_TREG, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"mov", MODRM, PARAM_TREG, PARAM_REG2_32, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"movaps\0"
|
|
"movapd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"movaps\0"
|
|
"movapd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4,PARAM_XMMM, PARAM_XMM, 0 },
|
|
{"cvtpi2ps\0"
|
|
"cvtpi2pd\0"
|
|
"cvtsi2sd\0"
|
|
"cvtsi2ss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_RMXMM, 0 },
|
|
{"movntps\0"
|
|
"movntpd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4,PARAM_XMMM, PARAM_XMM, 0 },
|
|
{"cvttps2pi\0"
|
|
"cvttpd2pi\0"
|
|
"cvttsd2si\0"
|
|
"cvttss2si", MODRM|VAR_NAME4,PARAM_REGORXMM, PARAM_XMMM, 0 },
|
|
{"cvtps2pi\0"
|
|
"cvtpd2pi\0"
|
|
"cvtsd2si\0"
|
|
"cvtss2si", MODRM|VAR_NAME4,PARAM_REGORXMM, PARAM_XMMM, 0 },
|
|
{"ucomiss\0"
|
|
"ucomisd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"comiss\0"
|
|
"comisd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
// 0x30
|
|
{"wrmsr", 0, 0, 0, 0 },
|
|
{"rdtsc", 0, 0, 0, 0 },
|
|
{"rdmsr", 0, 0, 0, 0 },
|
|
{"rdpmc", 0, 0, 0, 0 },
|
|
{"sysenter", 0, 0, 0, 0 },
|
|
{"sysexit", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"three_byte", THREE_BYTE, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"three_byte", THREE_BYTE, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0x40
|
|
{"cmovo", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"cmovno", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"cmovb", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"cmovae", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"cmove", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"cmovne", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"cmovbe", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"cmova", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"cmovs", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"cmovns", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"cmovpe", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"cmovpo", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"cmovl", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"cmovge", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"cmovle", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"cmovg", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
// 0x50
|
|
{"movmskps\0"
|
|
"movmskpd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4,PARAM_REG3264, PARAM_XMMM, 0 },
|
|
{"sqrtps\0"
|
|
"sqrtpd\0"
|
|
"sqrtsd\0"
|
|
"sqrtss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"rsqrtps\0"
|
|
"???\0"
|
|
"???\0"
|
|
"rsqrtss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"rcpps\0"
|
|
"???\0"
|
|
"???\0"
|
|
"rcpss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"andps\0"
|
|
"andpd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"andnps\0"
|
|
"andnpd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"orps\0"
|
|
"orpd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"xorps\0"
|
|
"xorpd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"addps\0"
|
|
"addpd\0"
|
|
"addsd\0"
|
|
"addss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"mulps\0"
|
|
"mulpd\0"
|
|
"mulsd\0"
|
|
"mulss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"cvtps2pd\0"
|
|
"cvtpd2ps\0"
|
|
"cvtsd2ss\0"
|
|
"cvtss2sd", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"cvtdq2ps\0"
|
|
"cvtps2dq\0"
|
|
"???\0"
|
|
"cvttps2dq", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"subps\0"
|
|
"subpd\0"
|
|
"subsd\0"
|
|
"subss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"minps\0"
|
|
"minpd\0"
|
|
"minsd\0"
|
|
"minss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"divps\0"
|
|
"divpd\0"
|
|
"divsd\0"
|
|
"divss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"maxps\0"
|
|
"maxpd\0"
|
|
"maxsd\0"
|
|
"maxss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
// 0x60
|
|
{"punpcklbw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"punpcklwd", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"punpckldq", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"packsswb", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"pcmpgtb", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"pcmpgtw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"pcmpgtd", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"packuswb", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"punpckhbw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"punpckhwd", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"punpckhdq", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"packssdw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"???\0"
|
|
"punpcklqdq\0"
|
|
"???\0"
|
|
"???\0", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???\0"
|
|
"punpckhqdq\0"
|
|
"???\0"
|
|
"???\0", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"movd", MODRM, PARAM_MMX, PARAM_RM, 0 },
|
|
{"movq\0"
|
|
"movdqa\0"
|
|
"???\0"
|
|
"movdqu", MODRM|VAR_NAME4,PARAM_MMX, PARAM_MMXM, 0 },
|
|
// 0x70
|
|
{"pshufw\0"
|
|
"pshufd\0"
|
|
"pshuflw\0"
|
|
"pshufhw", MODRM|VAR_NAME4,PARAM_MMX, PARAM_MMXM, PARAM_UI8 },
|
|
{"group0F71", GROUP, 0, 0, 0 },
|
|
{"group0F72", GROUP, 0, 0, 0 },
|
|
{"group0F73", GROUP, 0, 0, 0 },
|
|
{"pcmpeqb", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"pcmpeqw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"pcmpeqd", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"emms", 0, 0, 0, 0 },
|
|
{"vmread", MODRM, PARAM_RM, PARAM_REG, 0 },
|
|
{"vmwrite", MODRM, PARAM_RM, PARAM_REG, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???\0"
|
|
"haddpd\0"
|
|
"haddps\0"
|
|
"???", MODRM|VAR_NAME4,PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"???\0"
|
|
"hsubpd\0"
|
|
"hsubps\0"
|
|
"???", MODRM|VAR_NAME4,PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"movd\0"
|
|
"movd\0"
|
|
"???\0"
|
|
"movq", MODRM|VAR_NAME4,PARAM_RM, PARAM_MMX, 0 },
|
|
{"movq\0"
|
|
"movdqa\0"
|
|
"???\0"
|
|
"movdqu", MODRM|VAR_NAME4,PARAM_MMXM, PARAM_MMX, 0 },
|
|
// 0x80
|
|
{"jo", 0, PARAM_REL, 0, 0 },
|
|
{"jno", 0, PARAM_REL, 0, 0 },
|
|
{"jb", 0, PARAM_REL, 0, 0 },
|
|
{"jae", 0, PARAM_REL, 0, 0 },
|
|
{"je", 0, PARAM_REL, 0, 0 },
|
|
{"jne", 0, PARAM_REL, 0, 0 },
|
|
{"jbe", 0, PARAM_REL, 0, 0 },
|
|
{"ja", 0, PARAM_REL, 0, 0 },
|
|
{"js", 0, PARAM_REL, 0, 0 },
|
|
{"jns", 0, PARAM_REL, 0, 0 },
|
|
{"jp", 0, PARAM_REL, 0, 0 },
|
|
{"jnp", 0, PARAM_REL, 0, 0 },
|
|
{"jl", 0, PARAM_REL, 0, 0 },
|
|
{"jge", 0, PARAM_REL, 0, 0 },
|
|
{"jle", 0, PARAM_REL, 0, 0 },
|
|
{"jg", 0, PARAM_REL, 0, 0 },
|
|
// 0x90
|
|
{"seto", MODRM, PARAM_RMPTR8, 0, 0 },
|
|
{"setno", MODRM, PARAM_RMPTR8, 0, 0 },
|
|
{"setb", MODRM, PARAM_RMPTR8, 0, 0 },
|
|
{"setae", MODRM, PARAM_RMPTR8, 0, 0 },
|
|
{"sete", MODRM, PARAM_RMPTR8, 0, 0 },
|
|
{"setne", MODRM, PARAM_RMPTR8, 0, 0 },
|
|
{"setbe", MODRM, PARAM_RMPTR8, 0, 0 },
|
|
{"seta", MODRM, PARAM_RMPTR8, 0, 0 },
|
|
{"sets", MODRM, PARAM_RMPTR8, 0, 0 },
|
|
{"setns", MODRM, PARAM_RMPTR8, 0, 0 },
|
|
{"setp", MODRM, PARAM_RMPTR8, 0, 0 },
|
|
{"setnp", MODRM, PARAM_RMPTR8, 0, 0 },
|
|
{"setl", MODRM, PARAM_RMPTR8, 0, 0 },
|
|
{"setge", MODRM, PARAM_RMPTR8, 0, 0 },
|
|
{"setle", MODRM, PARAM_RMPTR8, 0, 0 },
|
|
{"setg", MODRM, PARAM_RMPTR8, 0, 0 },
|
|
// 0xa0
|
|
{"push fs", 0, 0, 0, 0 },
|
|
{"pop fs", 0, 0, 0, 0 },
|
|
{"cpuid", 0, 0, 0, 0 },
|
|
{"bt", MODRM, PARAM_RM, PARAM_REG, 0 },
|
|
{"shld", MODRM, PARAM_RM, PARAM_REG, PARAM_UI8 },
|
|
{"shld", MODRM, PARAM_RM, PARAM_REG, PARAM_CL },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"push gs", 0, 0, 0, 0 },
|
|
{"pop gs", 0, 0, 0, 0 },
|
|
{"rsm", 0, 0, 0, 0 },
|
|
{"bts", MODRM, PARAM_RM, PARAM_REG, 0 },
|
|
{"shrd", MODRM, PARAM_RM, PARAM_REG, PARAM_UI8 },
|
|
{"shrd", MODRM, PARAM_RM, PARAM_REG, PARAM_CL },
|
|
{"group0FAE", GROUP, 0, 0, 0 },
|
|
{"imul", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
// 0xb0
|
|
{"cmpxchg", MODRM, PARAM_RM8, PARAM_REG, 0 },
|
|
{"cmpxchg", MODRM, PARAM_RM, PARAM_REG, 0 },
|
|
{"lss", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"btr", MODRM, PARAM_RM, PARAM_REG, 0 },
|
|
{"lfs", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"lgs", MODRM, PARAM_REG, PARAM_RM, 0 },
|
|
{"movzx", MODRM, PARAM_REG, PARAM_RMPTR8, 0 },
|
|
{"movzx", MODRM, PARAM_REG, PARAM_RMPTR16, 0 },
|
|
{"???\0"
|
|
"???\0"
|
|
"???\0"
|
|
"popcnt", MODRM|VAR_NAME4, PARAM_REG, PARAM_RM16, 0 },
|
|
{"ud2", 0, 0, 0, 0 },
|
|
{"group0FBA", GROUP, 0, 0, 0 },
|
|
{"btc", MODRM, PARAM_RM, PARAM_REG, 0 },
|
|
{"bsf\0"
|
|
"???\0"
|
|
"???\0"
|
|
"tzcnt", MODRM|VAR_NAME4, PARAM_REG, PARAM_RM, 0 },
|
|
{"bsr\0"
|
|
"???\0"
|
|
"???\0"
|
|
"lzcnt", MODRM|VAR_NAME4, PARAM_REG, PARAM_RM, 0, STEP_OVER},
|
|
{"movsx", MODRM, PARAM_REG, PARAM_RMPTR8, 0 },
|
|
{"movsx", MODRM, PARAM_REG, PARAM_RMPTR16, 0 },
|
|
// 0xc0
|
|
{"xadd", MODRM, PARAM_RM8, PARAM_REG, 0 },
|
|
{"xadd", MODRM, PARAM_RM, PARAM_REG, 0 },
|
|
{"cmpps\0"
|
|
"cmppd\0"
|
|
"cmpsd\0"
|
|
"cmpss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"movnti", MODRM, PARAM_RM, PARAM_REG, 0 },
|
|
{"pinsrw", MODRM, PARAM_MMX, PARAM_RM, PARAM_UI8 },
|
|
{"pextrw", MODRM, PARAM_MMX, PARAM_RM, PARAM_UI8 },
|
|
{"shufps\0"
|
|
"shufpd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
|
|
{"group0FC7", GROUP, 0, 0, 0 },
|
|
{"bswap", 0, PARAM_EAX, 0, 0 },
|
|
{"bswap", 0, PARAM_ECX, 0, 0 },
|
|
{"bswap", 0, PARAM_EDX, 0, 0 },
|
|
{"bswap", 0, PARAM_EBX, 0, 0 },
|
|
{"bswap", 0, PARAM_ESP, 0, 0 },
|
|
{"bswap", 0, PARAM_EBP, 0, 0 },
|
|
{"bswap", 0, PARAM_ESI, 0, 0 },
|
|
{"bswap", 0, PARAM_EDI, 0, 0 },
|
|
// 0xd0
|
|
{"???\0"
|
|
"addsubpd\0"
|
|
"addsubps\0"
|
|
"???\0", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"psrlw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"psrld", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"psrlq", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"paddq", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"pmullw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"???\0"
|
|
"movq\0"
|
|
"movdq2q\0"
|
|
"movq2dq", MODRM|VAR_NAME4,PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"pmovmskb", MODRM, PARAM_REG3264, PARAM_MMXM, 0 },
|
|
{"psubusb", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"psubusw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"pminub", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"pand", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"paddusb", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"paddusw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"pmaxub", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"pandn", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
// 0xe0
|
|
{"pavgb", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"psraw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"psrad", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"pavgw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"pmulhuw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"pmulhw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"???\0"
|
|
"cvttpd2dq\0"
|
|
"cvtpd2dq\0"
|
|
"cvtdq2pd", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"movntq\0"
|
|
"movntdq\0"
|
|
"???\0"
|
|
"???\0", MODRM|VAR_NAME4, PARAM_M64, PARAM_MMX, 0 },
|
|
{"psubsb", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"psubsw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"pminsw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"por", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"paddsb", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"paddsw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"pmaxsw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"pxor", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
// 0xf0
|
|
{"???\0"
|
|
"???\0"
|
|
"lddqu\0"
|
|
"???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"psllw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"pslld", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"psllq", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"pmuludq", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"pmaddwd", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"psadbw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"maskmovq\0"
|
|
"maskmovdqu\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4,PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"psubb", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"psubw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"psubd", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"psubq", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"paddb", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"paddw", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"paddd", MODRM, PARAM_MMX, PARAM_MMXM, 0 },
|
|
{"???", 0, 0, 0, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::i386_opcode_table0F38[256] =
|
|
{
|
|
// 0x00
|
|
{"pshufb\0"
|
|
"pshufb\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"phaddw\0"
|
|
"phaddw\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"phaddd\0"
|
|
"phadd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"phaddsw\0"
|
|
"phaddsw\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"pmaddubsw\0"
|
|
"pmaddubsw\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"phsubw\0"
|
|
"phsubw\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"phsubd\0"
|
|
"phsubd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"phsubsw\0"
|
|
"phsubsw\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"psignb\0"
|
|
"psignb\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"psignw\0"
|
|
"psignw\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"psignd\0"
|
|
"psignd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"pmulhrsw\0"
|
|
"pmulhrsw\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0x10
|
|
{"???\0"
|
|
"pblendvb\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_XMM0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???\0"
|
|
"blendvps\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_XMM0 },
|
|
{"???\0"
|
|
"blendvpd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_XMM0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???\0"
|
|
"ptest\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"pabsb\0"
|
|
"pabsb\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"pabsw\0"
|
|
"pabsw\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"pabsd\0"
|
|
"pabsd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0x20
|
|
{"???\0"
|
|
"pmovsxbw\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM64, 0 },
|
|
{"???\0"
|
|
"pmovsxbd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM32, 0 },
|
|
{"???\0"
|
|
"pmovsxbq\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM16, 0 },
|
|
{"???\0"
|
|
"pmovsxwd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM64, 0 },
|
|
{"???\0"
|
|
"pmovsxwq\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM32, 0 },
|
|
{"???\0"
|
|
"pmovsxdq\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM64, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???\0"
|
|
"pmuldq\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???\0"
|
|
"pcmpeqq\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???\0"
|
|
"movntdqa\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???\0"
|
|
"packusdw\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0x30
|
|
{"???\0"
|
|
"pmovzxbw\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM64, 0 },
|
|
{"???\0"
|
|
"pmovzxbd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM32, 0 },
|
|
{"???\0"
|
|
"pmovzxbq\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM16, 0 },
|
|
{"???\0"
|
|
"pmovzxwd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM64, 0 },
|
|
{"???\0"
|
|
"pmovzxwq\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM32, 0 },
|
|
{"???\0"
|
|
"pmovzxdq\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM64, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???\0"
|
|
"pcmpgtq\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???\0"
|
|
"pminsb\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???\0"
|
|
"pminsd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???\0"
|
|
"pminuw\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???\0"
|
|
"pminud\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???\0"
|
|
"pmaxsb\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???\0"
|
|
"pmaxsd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???\0"
|
|
"pmaxuw\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???\0"
|
|
"pmaxud\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
// 0x40
|
|
{"???\0"
|
|
"pmulld\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???\0"
|
|
"phminposuw\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0x50
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0x60
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0x70
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0x80
|
|
{"???\0"
|
|
"invept\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_REG32, PARAM_XMMM, 0 },
|
|
{"???\0"
|
|
"invvpid\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_REG32, PARAM_XMMM, 0 },
|
|
{"???\0"
|
|
"invpcid\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_REG32, PARAM_XMMM, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0x90
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0xa0
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0xb0
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0xc0
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0xd0
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???\0"
|
|
"aesimc\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???\0"
|
|
"aesenc\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???\0"
|
|
"aesenclast\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???\0"
|
|
"aesdec\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
{"???\0"
|
|
"aesdeclast\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
|
|
// 0xe0
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0xf0
|
|
{"movbe\0"
|
|
"???\0"
|
|
"crc32\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_REG32, PARAM_RMPTR, 0 }, // not quite correct
|
|
{"movbe\0"
|
|
"???\0"
|
|
"crc32\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_RMPTR, PARAM_REG32, 0 }, // not quite correct
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::i386_opcode_table0F3A[256] =
|
|
{
|
|
// 0x00
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???\0"
|
|
"roundps\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
|
|
{"???\0"
|
|
"roundpd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
|
|
{"???\0"
|
|
"roundss\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
|
|
{"???\0"
|
|
"roundsd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
|
|
{"???\0"
|
|
"blendps\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
|
|
{"???\0"
|
|
"blendpd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
|
|
{"???\0"
|
|
"pblendw\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
|
|
{"palignr\0"
|
|
"palignr\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
|
|
// 0x10
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???\0"
|
|
"pextrb\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_RM8, PARAM_XMM, PARAM_UI8 },
|
|
{"???\0"
|
|
"pextrw\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_RM16, PARAM_XMM, PARAM_UI8 },
|
|
{"???\0"
|
|
"pextrd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_RM8, PARAM_XMM, PARAM_UI8 },
|
|
{"???\0"
|
|
"extractps\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_RM32, PARAM_XMM, PARAM_UI8 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0x20
|
|
{"???\0"
|
|
"pinsrb\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_RM8, PARAM_UI8 },
|
|
{"???\0"
|
|
"insertps\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_RM8, PARAM_UI8 },
|
|
{"???\0"
|
|
"pinsrd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_RM32, PARAM_UI8 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0x30
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0x40
|
|
{"???\0"
|
|
"dpps\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
|
|
{"???\0"
|
|
"dppd\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
|
|
{"???\0"
|
|
"mpsadbw\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???\0"
|
|
"pclmulqdq\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0x50
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0x60
|
|
{"???\0"
|
|
"pcmestrm\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
|
|
{"???\0"
|
|
"pcmestri\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
|
|
{"???\0"
|
|
"pcmistrm\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
|
|
{"???\0"
|
|
"pcmistri\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0x70
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0x80
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0x90
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0xa0
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0xb0
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0xc0
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0xd0
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???\0"
|
|
"aeskeygenassist\0"
|
|
"???\0"
|
|
"???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
|
|
// 0xe0
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
// 0xf0
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::group80_table[8] =
|
|
{
|
|
{"add", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
|
|
{"or", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
|
|
{"adc", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
|
|
{"sbb", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
|
|
{"and", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
|
|
{"sub", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
|
|
{"xor", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
|
|
{"cmp", 0, PARAM_RMPTR8, PARAM_UI8, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::group81_table[8] =
|
|
{
|
|
{"add", 0, PARAM_RMPTR, PARAM_IMM, 0 },
|
|
{"or", 0, PARAM_RMPTR, PARAM_IMM, 0 },
|
|
{"adc", 0, PARAM_RMPTR, PARAM_IMM, 0 },
|
|
{"sbb", 0, PARAM_RMPTR, PARAM_IMM, 0 },
|
|
{"and", 0, PARAM_RMPTR, PARAM_IMM, 0 },
|
|
{"sub", 0, PARAM_RMPTR, PARAM_IMM, 0 },
|
|
{"xor", 0, PARAM_RMPTR, PARAM_IMM, 0 },
|
|
{"cmp", 0, PARAM_RMPTR, PARAM_IMM, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::group83_table[8] =
|
|
{
|
|
{"add", 0, PARAM_RMPTR, PARAM_I8, 0 },
|
|
{"or", 0, PARAM_RMPTR, PARAM_I8, 0 },
|
|
{"adc", 0, PARAM_RMPTR, PARAM_I8, 0 },
|
|
{"sbb", 0, PARAM_RMPTR, PARAM_I8, 0 },
|
|
{"and", 0, PARAM_RMPTR, PARAM_I8, 0 },
|
|
{"sub", 0, PARAM_RMPTR, PARAM_I8, 0 },
|
|
{"xor", 0, PARAM_RMPTR, PARAM_I8, 0 },
|
|
{"cmp", 0, PARAM_RMPTR, PARAM_I8, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::groupC0_table[8] =
|
|
{
|
|
{"rol", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
|
|
{"ror", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
|
|
{"rcl", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
|
|
{"rcr", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
|
|
{"shl", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
|
|
{"shr", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
|
|
{"sal", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
|
|
{"sar", 0, PARAM_RMPTR8, PARAM_UI8, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::groupC1_table[8] =
|
|
{
|
|
{"rol", 0, PARAM_RMPTR, PARAM_UI8, 0 },
|
|
{"ror", 0, PARAM_RMPTR, PARAM_UI8, 0 },
|
|
{"rcl", 0, PARAM_RMPTR, PARAM_UI8, 0 },
|
|
{"rcr", 0, PARAM_RMPTR, PARAM_UI8, 0 },
|
|
{"shl", 0, PARAM_RMPTR, PARAM_UI8, 0 },
|
|
{"shr", 0, PARAM_RMPTR, PARAM_UI8, 0 },
|
|
{"sal", 0, PARAM_RMPTR, PARAM_UI8, 0 },
|
|
{"sar", 0, PARAM_RMPTR, PARAM_UI8, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::groupD0_table[8] =
|
|
{
|
|
{"rol", 0, PARAM_RMPTR8, PARAM_1, 0 },
|
|
{"ror", 0, PARAM_RMPTR8, PARAM_1, 0 },
|
|
{"rcl", 0, PARAM_RMPTR8, PARAM_1, 0 },
|
|
{"rcr", 0, PARAM_RMPTR8, PARAM_1, 0 },
|
|
{"shl", 0, PARAM_RMPTR8, PARAM_1, 0 },
|
|
{"shr", 0, PARAM_RMPTR8, PARAM_1, 0 },
|
|
{"sal", 0, PARAM_RMPTR8, PARAM_1, 0 },
|
|
{"sar", 0, PARAM_RMPTR8, PARAM_1, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::groupD1_table[8] =
|
|
{
|
|
{"rol", 0, PARAM_RMPTR, PARAM_1, 0 },
|
|
{"ror", 0, PARAM_RMPTR, PARAM_1, 0 },
|
|
{"rcl", 0, PARAM_RMPTR, PARAM_1, 0 },
|
|
{"rcr", 0, PARAM_RMPTR, PARAM_1, 0 },
|
|
{"shl", 0, PARAM_RMPTR, PARAM_1, 0 },
|
|
{"shr", 0, PARAM_RMPTR, PARAM_1, 0 },
|
|
{"sal", 0, PARAM_RMPTR, PARAM_1, 0 },
|
|
{"sar", 0, PARAM_RMPTR, PARAM_1, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::groupD2_table[8] =
|
|
{
|
|
{"rol", 0, PARAM_RMPTR8, PARAM_CL, 0 },
|
|
{"ror", 0, PARAM_RMPTR8, PARAM_CL, 0 },
|
|
{"rcl", 0, PARAM_RMPTR8, PARAM_CL, 0 },
|
|
{"rcr", 0, PARAM_RMPTR8, PARAM_CL, 0 },
|
|
{"shl", 0, PARAM_RMPTR8, PARAM_CL, 0 },
|
|
{"shr", 0, PARAM_RMPTR8, PARAM_CL, 0 },
|
|
{"sal", 0, PARAM_RMPTR8, PARAM_CL, 0 },
|
|
{"sar", 0, PARAM_RMPTR8, PARAM_CL, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::groupD3_table[8] =
|
|
{
|
|
{"rol", 0, PARAM_RMPTR, PARAM_CL, 0 },
|
|
{"ror", 0, PARAM_RMPTR, PARAM_CL, 0 },
|
|
{"rcl", 0, PARAM_RMPTR, PARAM_CL, 0 },
|
|
{"rcr", 0, PARAM_RMPTR, PARAM_CL, 0 },
|
|
{"shl", 0, PARAM_RMPTR, PARAM_CL, 0 },
|
|
{"shr", 0, PARAM_RMPTR, PARAM_CL, 0 },
|
|
{"sal", 0, PARAM_RMPTR, PARAM_CL, 0 },
|
|
{"sar", 0, PARAM_RMPTR, PARAM_CL, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::groupF6_table[8] =
|
|
{
|
|
{"test", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
|
|
{"test", 0, PARAM_RMPTR8, PARAM_UI8, 0 },
|
|
{"not", 0, PARAM_RMPTR8, 0, 0 },
|
|
{"neg", 0, PARAM_RMPTR8, 0, 0 },
|
|
{"mul", 0, PARAM_RMPTR8, 0, 0 },
|
|
{"imul", 0, PARAM_RMPTR8, 0, 0 },
|
|
{"div", 0, PARAM_RMPTR8, 0, 0 },
|
|
{"idiv", 0, PARAM_RMPTR8, 0, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::groupF7_table[8] =
|
|
{
|
|
{"test", 0, PARAM_RMPTR, PARAM_IMM, 0 },
|
|
{"test", 0, PARAM_RMPTR, PARAM_IMM, 0 },
|
|
{"not", 0, PARAM_RMPTR, 0, 0 },
|
|
{"neg", 0, PARAM_RMPTR, 0, 0 },
|
|
{"mul", 0, PARAM_RMPTR, 0, 0 },
|
|
{"imul", 0, PARAM_RMPTR, 0, 0 },
|
|
{"div", 0, PARAM_RMPTR, 0, 0 },
|
|
{"idiv", 0, PARAM_RMPTR, 0, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::groupFE_table[8] =
|
|
{
|
|
{"inc", 0, PARAM_RMPTR8, 0, 0 },
|
|
{"dec", 0, PARAM_RMPTR8, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::groupFF_table[8] =
|
|
{
|
|
{"inc", 0, PARAM_RMPTR, 0, 0 },
|
|
{"dec", 0, PARAM_RMPTR, 0, 0 },
|
|
{"call", ALWAYS64, PARAM_RMPTR, 0, 0, STEP_OVER},
|
|
{"call far ptr ",0, PARAM_RM, 0, 0, STEP_OVER},
|
|
{"jmp", ALWAYS64, PARAM_RMPTR, 0, 0 },
|
|
{"jmp far ptr ",0, PARAM_RM, 0, 0 },
|
|
{"push", 0, PARAM_RMPTR, 0, 0 },
|
|
{"???", 0, 0, 0, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::group0F00_table[8] =
|
|
{
|
|
{"sldt", 0, PARAM_RM, 0, 0 },
|
|
{"str", 0, PARAM_RM, 0, 0 },
|
|
{"lldt", 0, PARAM_RM, 0, 0 },
|
|
{"ltr", 0, PARAM_RM, 0, 0 },
|
|
{"verr", 0, PARAM_RM, 0, 0 },
|
|
{"verw", 0, PARAM_RM, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::group0F01_table[8] =
|
|
{
|
|
{"sgdt", 0, PARAM_RM, 0, 0 },
|
|
{"sidt", 0, PARAM_RM, 0, 0 },
|
|
{"lgdt", 0, PARAM_RM, 0, 0 },
|
|
{"lidt", 0, PARAM_RM, 0, 0 },
|
|
{"smsw", 0, PARAM_RM, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"lmsw", 0, PARAM_RM, 0, 0 },
|
|
{"invlpg", 0, PARAM_RM, 0, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::group0F0D_table[8] =
|
|
{
|
|
{"prefetch", 0, PARAM_RM8, 0, 0 },
|
|
{"prefetchw", 0, PARAM_RM8, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::group0F12_table[4] =
|
|
{
|
|
{ "movlps\0"
|
|
"movlpd\0"
|
|
"movddup\0"
|
|
"movsldup", VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{ "movlps\0"
|
|
"movlpd\0"
|
|
"movddup\0"
|
|
"movsldup", VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{ "movlps\0"
|
|
"movlpd\0"
|
|
"movddup\0"
|
|
"movsldup", VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{ "movhlps\0"
|
|
"???\0"
|
|
"movddup\0"
|
|
"movsldup", VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::group0F16_table[4] =
|
|
{
|
|
{ "movhps\0"
|
|
"movhpd\0"
|
|
"???\0"
|
|
"movshdup", VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{ "movhps\0"
|
|
"movhpd\0"
|
|
"???\0"
|
|
"movshdup", VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{ "movhps\0"
|
|
"movhpd\0"
|
|
"???\0"
|
|
"movshdup", VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
|
|
{ "movlhps\0"
|
|
"movhpd\0"
|
|
"???\0"
|
|
"movshdup", VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::group0F18_table[8] =
|
|
{
|
|
{"prefetchnta", 0, PARAM_RM8, 0, 0 },
|
|
{"prefetch0", 0, PARAM_RM8, 0, 0 },
|
|
{"prefetch1", 0, PARAM_RM8, 0, 0 },
|
|
{"prefetch2", 0, PARAM_RM8, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::group0F71_table[8] =
|
|
{
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"psrlw", 0, PARAM_MMX2, PARAM_UI8, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"psraw", 0, PARAM_MMX2, PARAM_UI8, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"psllw", 0, PARAM_MMX2, PARAM_UI8, 0 },
|
|
{"???", 0, 0, 0, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::group0F72_table[8] =
|
|
{
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"psrld", 0, PARAM_MMX2, PARAM_UI8, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"psrad", 0, PARAM_MMX2, PARAM_UI8, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"pslld", 0, PARAM_MMX2, PARAM_UI8, 0 },
|
|
{"???", 0, 0, 0, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::group0F73_table[8] =
|
|
{
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"psrlq", 0, PARAM_MMX2, PARAM_UI8, 0 },
|
|
{"psrldq", 0, PARAM_MMX2, PARAM_UI8, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"psllq", 0, PARAM_MMX2, PARAM_UI8, 0 },
|
|
{"pslldq", 0, PARAM_MMX2, PARAM_UI8, 0 },
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::group0FAE_table[8] =
|
|
{
|
|
{"fxsave", 0, PARAM_RM, 0, 0 },
|
|
{"fxrstor", 0, PARAM_RM, 0, 0 },
|
|
{"ldmxcsr", 0, PARAM_RM, 0, 0 },
|
|
{"stmxscr", 0, PARAM_RM, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"lfence", 0, 0, 0, 0 },
|
|
{"mfence", 0, 0, 0, 0 },
|
|
{"sfence", 0, 0, 0, 0 }
|
|
};
|
|
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::group0FBA_table[8] =
|
|
{
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"bt", 0, PARAM_RM, PARAM_UI8, 0 },
|
|
{"bts", 0, PARAM_RM, PARAM_UI8, 0 },
|
|
{"btr", 0, PARAM_RM, PARAM_UI8, 0 },
|
|
{"btc", 0, PARAM_RM, PARAM_UI8, 0 }
|
|
};
|
|
|
|
const i386_disassembler::I386_OPCODE i386_disassembler::group0FC7_table[8] =
|
|
{
|
|
{"???", 0, 0, 0, 0 },
|
|
{"cmpxchg8b", MODRM, PARAM_M64PTR, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"???", 0, 0, 0, 0 },
|
|
{"vmptrld\0"
|
|
"vmclear\0"
|
|
"???\0"
|
|
"vmxon", MODRM|VAR_NAME4, PARAM_M64PTR, 0, 0 },
|
|
{"vmptrtst", MODRM, PARAM_M64PTR, 0, 0 }
|
|
};
|
|
|
|
const i386_disassembler::GROUP_OP i386_disassembler::group_op_table[] =
|
|
{
|
|
{ "group80", group80_table },
|
|
{ "group81", group81_table },
|
|
{ "group83", group83_table },
|
|
{ "groupC0", groupC0_table },
|
|
{ "groupC1", groupC1_table },
|
|
{ "groupD0", groupD0_table },
|
|
{ "groupD1", groupD1_table },
|
|
{ "groupD2", groupD2_table },
|
|
{ "groupD3", groupD3_table },
|
|
{ "groupF6", groupF6_table },
|
|
{ "groupF7", groupF7_table },
|
|
{ "groupFE", groupFE_table },
|
|
{ "groupFF", groupFF_table },
|
|
{ "group0F00", group0F00_table },
|
|
{ "group0F01", group0F01_table },
|
|
{ "group0F0D", group0F0D_table },
|
|
{ "group0F12", group0F12_table },
|
|
{ "group0F16", group0F16_table },
|
|
{ "group0F18", group0F18_table },
|
|
{ "group0F71", group0F71_table },
|
|
{ "group0F72", group0F72_table },
|
|
{ "group0F73", group0F73_table },
|
|
{ "group0FAE", group0FAE_table },
|
|
{ "group0FBA", group0FBA_table },
|
|
{ "group0FC7", group0FC7_table }
|
|
};
|
|
|
|
|
|
|
|
const char *const i386_disassembler::i386_reg[3][16] =
|
|
{
|
|
{"ax", "cx", "dx", "bx", "sp", "bp", "si", "di", "r8w", "r9w", "r10w","r11w","r12w","r13w","r14w","r15w"},
|
|
{"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "r8d", "r9d", "r10d","r11d","r12d","r13d","r14d","r15d"},
|
|
{"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}
|
|
};
|
|
|
|
const char *const i386_disassembler::i386_reg8[8] = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"};
|
|
const char *const i386_disassembler::i386_reg8rex[16] = {"al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", "r8l", "r9l", "r10l", "r11l", "r12l", "r13l", "r14l", "r15l"};
|
|
const char *const i386_disassembler::i386_sreg[8] = {"es", "cs", "ss", "ds", "fs", "gs", "???", "???"};
|
|
|
|
inline uint8_t i386_disassembler::FETCH(offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
|
|
{
|
|
if ((pc - base_pc) + 1 > max_length)
|
|
return 0xff;
|
|
uint8_t d = opcodes.r8(pc);
|
|
pc++;
|
|
return d;
|
|
}
|
|
|
|
inline uint16_t i386_disassembler::FETCH16(offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
|
|
{
|
|
if ((pc - base_pc) + 2 > max_length)
|
|
return 0xffff;
|
|
uint16_t d = opcodes.r16(pc);
|
|
pc += 2;
|
|
return d;
|
|
}
|
|
|
|
inline uint32_t i386_disassembler::FETCH32(offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
|
|
{
|
|
if ((pc - base_pc) + 4 > max_length)
|
|
return 0xffffffff;
|
|
uint32_t d = opcodes.r32(pc);
|
|
pc += 4;
|
|
return d;
|
|
}
|
|
|
|
inline uint8_t i386_disassembler::FETCHD(offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
|
|
{
|
|
return FETCH(base_pc, pc, opcodes);
|
|
}
|
|
|
|
inline uint16_t i386_disassembler::FETCHD16(offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
|
|
{
|
|
return FETCH16(base_pc, pc, opcodes);
|
|
}
|
|
|
|
inline uint32_t i386_disassembler::FETCHD32(offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
|
|
{
|
|
return FETCH32(base_pc, pc, opcodes);
|
|
}
|
|
|
|
char *i386_disassembler::hexstring(uint32_t value, int digits)
|
|
{
|
|
static char buffer[20];
|
|
buffer[0] = '0';
|
|
if (digits)
|
|
sprintf(&buffer[1], "%0*Xh", digits, value);
|
|
else
|
|
sprintf(&buffer[1], "%Xh", value);
|
|
return (buffer[1] >= '0' && buffer[1] <= '9') ? &buffer[1] : &buffer[0];
|
|
}
|
|
|
|
char *i386_disassembler::hexstring64(uint32_t lo, uint32_t hi)
|
|
{
|
|
static char buffer[40];
|
|
buffer[0] = '0';
|
|
if (hi != 0)
|
|
sprintf(&buffer[1], "%X%08Xh", hi, lo);
|
|
else
|
|
sprintf(&buffer[1], "%Xh", lo);
|
|
return (buffer[1] >= '0' && buffer[1] <= '9') ? &buffer[1] : &buffer[0];
|
|
}
|
|
|
|
char *i386_disassembler::hexstringpc(uint64_t pc)
|
|
{
|
|
if (m_config->get_mode() == 64)
|
|
return hexstring64((uint32_t)pc, (uint32_t)(pc >> 32));
|
|
else
|
|
return hexstring((uint32_t)pc, 0);
|
|
}
|
|
|
|
char *i386_disassembler::shexstring(uint32_t value, int digits, bool always)
|
|
{
|
|
static char buffer[20];
|
|
if (value >= 0x80000000)
|
|
sprintf(buffer, "-%s", hexstring(-value, digits));
|
|
else if (always)
|
|
sprintf(buffer, "+%s", hexstring(value, digits));
|
|
else
|
|
return hexstring(value, digits);
|
|
return buffer;
|
|
}
|
|
|
|
void i386_disassembler::handle_sib_byte(std::ostream &stream, uint8_t mod, offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
|
|
{
|
|
uint32_t i32;
|
|
uint8_t scale, i, base;
|
|
uint8_t sib = FETCHD(base_pc, pc, opcodes);
|
|
|
|
scale = (sib >> 6) & 0x3;
|
|
i = ((sib >> 3) & 0x7) | sibex;
|
|
base = (sib & 0x7) | rmex;
|
|
|
|
if (base == 5 && mod == 0) {
|
|
i32 = FETCHD32(base_pc, pc, opcodes);
|
|
util::stream_format(stream, "%s", hexstring(i32, 0));
|
|
} else if (base != 5 || mod != 3)
|
|
util::stream_format(stream, "%s", i386_reg[address_size][base]);
|
|
|
|
if ( i != 4 ) {
|
|
util::stream_format(stream, "+%s", i386_reg[address_size][i]);
|
|
if (scale)
|
|
util::stream_format(stream, "*%d", 1 << scale);
|
|
}
|
|
}
|
|
|
|
void i386_disassembler::handle_modrm(std::ostream &stream, offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
|
|
{
|
|
int8_t disp8;
|
|
int16_t disp16;
|
|
int32_t disp32;
|
|
uint8_t mod, rm;
|
|
|
|
modrm = FETCHD(base_pc, pc, opcodes);
|
|
mod = (modrm >> 6) & 0x3;
|
|
rm = (modrm & 0x7) | rmex;
|
|
|
|
if( modrm >= 0xc0 )
|
|
return;
|
|
|
|
switch(segment)
|
|
{
|
|
case SEG_CS: util::stream_format(stream, "cs:"); break;
|
|
case SEG_DS: util::stream_format(stream, "ds:"); break;
|
|
case SEG_ES: util::stream_format(stream, "es:"); break;
|
|
case SEG_FS: util::stream_format(stream, "fs:"); break;
|
|
case SEG_GS: util::stream_format(stream, "gs:"); break;
|
|
case SEG_SS: util::stream_format(stream, "ss:"); break;
|
|
}
|
|
|
|
util::stream_format(stream, "[" );
|
|
if( address_size == 2 ) {
|
|
if ((rm & 7) == 4)
|
|
handle_sib_byte(stream, mod, base_pc, pc, opcodes);
|
|
else if ((rm & 7) == 5 && mod == 0) {
|
|
disp32 = FETCHD32(base_pc, pc, opcodes);
|
|
util::stream_format(stream, "rip%s", shexstring(disp32, 0, true));
|
|
} else
|
|
util::stream_format(stream, "%s", i386_reg[2][rm]);
|
|
if( mod == 1 ) {
|
|
disp8 = FETCHD(base_pc, pc, opcodes);
|
|
if (disp8 != 0)
|
|
util::stream_format(stream, "%s", shexstring((int32_t)disp8, 0, true) );
|
|
} else if( mod == 2 ) {
|
|
disp32 = FETCHD32(base_pc, pc, opcodes);
|
|
if (disp32 != 0)
|
|
util::stream_format(stream, "%s", shexstring(disp32, 0, true) );
|
|
}
|
|
} else if (address_size == 1) {
|
|
if ((rm & 7) == 4)
|
|
handle_sib_byte(stream, mod, base_pc, pc, opcodes);
|
|
else if ((rm & 7) == 5 && mod == 0) {
|
|
disp32 = FETCHD32(base_pc, pc, opcodes);
|
|
if (m_config->get_mode() == 64)
|
|
util::stream_format(stream, "eip%s", shexstring(disp32, 0, true) );
|
|
else
|
|
util::stream_format(stream, "%s", hexstring(disp32, 0) );
|
|
} else
|
|
util::stream_format(stream, "%s", i386_reg[1][rm]);
|
|
if( mod == 1 ) {
|
|
disp8 = FETCHD(base_pc, pc, opcodes);
|
|
if (disp8 != 0)
|
|
util::stream_format(stream, "%s", shexstring((int32_t)disp8, 0, true) );
|
|
} else if( mod == 2 ) {
|
|
disp32 = FETCHD32(base_pc, pc, opcodes);
|
|
if (disp32 != 0)
|
|
util::stream_format(stream, "%s", shexstring(disp32, 0, true) );
|
|
}
|
|
} else {
|
|
switch( rm )
|
|
{
|
|
case 0: util::stream_format(stream, "bx+si" ); break;
|
|
case 1: util::stream_format(stream, "bx+di" ); break;
|
|
case 2: util::stream_format(stream, "bp+si" ); break;
|
|
case 3: util::stream_format(stream, "bp+di" ); break;
|
|
case 4: util::stream_format(stream, "si" ); break;
|
|
case 5: util::stream_format(stream, "di" ); break;
|
|
case 6:
|
|
if( mod == 0 ) {
|
|
disp16 = FETCHD16(base_pc, pc, opcodes);
|
|
util::stream_format(stream, "%s", hexstring((unsigned) (uint16_t) disp16, 0) );
|
|
} else {
|
|
util::stream_format(stream, "bp" );
|
|
}
|
|
break;
|
|
case 7: util::stream_format(stream, "bx" ); break;
|
|
}
|
|
if( mod == 1 ) {
|
|
disp8 = FETCHD(base_pc, pc, opcodes);
|
|
if (disp8 != 0)
|
|
util::stream_format(stream, "%s", shexstring((int32_t)disp8, 0, true) );
|
|
} else if( mod == 2 ) {
|
|
disp16 = FETCHD16(base_pc, pc, opcodes);
|
|
if (disp16 != 0)
|
|
util::stream_format(stream, "%s", shexstring((int32_t)disp16, 0, true) );
|
|
}
|
|
}
|
|
util::stream_format(stream, "]" );
|
|
}
|
|
|
|
void i386_disassembler::handle_modrm(std::string &buffer, offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
|
|
{
|
|
std::stringstream stream;
|
|
handle_modrm(stream, base_pc, pc, opcodes);
|
|
buffer = stream.str();
|
|
}
|
|
|
|
void i386_disassembler::handle_param(std::ostream &stream, uint32_t param, offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
|
|
{
|
|
uint8_t i8;
|
|
uint16_t i16;
|
|
uint32_t i32;
|
|
uint16_t ptr;
|
|
uint32_t addr;
|
|
int8_t d8;
|
|
int16_t d16;
|
|
int32_t d32;
|
|
|
|
switch(param)
|
|
{
|
|
case PARAM_REG:
|
|
util::stream_format(stream, "%s", i386_reg[operand_size][MODRM_REG1() | regex] );
|
|
break;
|
|
|
|
case PARAM_REG8:
|
|
util::stream_format(stream, "%s", (rex ? i386_reg8rex : i386_reg8)[MODRM_REG1() | regex] );
|
|
break;
|
|
|
|
case PARAM_REG16:
|
|
util::stream_format(stream, "%s", i386_reg[0][MODRM_REG1() | regex] );
|
|
break;
|
|
|
|
case PARAM_REG32:
|
|
util::stream_format(stream, "%s", i386_reg[1][MODRM_REG1() | regex] );
|
|
break;
|
|
|
|
case PARAM_REG3264:
|
|
util::stream_format(stream, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG1() | regex] );
|
|
break;
|
|
|
|
case PARAM_MMX:
|
|
if (pre0f == 0x66 || pre0f == 0xf2 || pre0f == 0xf3)
|
|
util::stream_format(stream, "xmm%d", MODRM_REG1() | regex );
|
|
else
|
|
util::stream_format(stream, "mm%d", MODRM_REG1() | regex );
|
|
break;
|
|
|
|
case PARAM_MMX2:
|
|
if (pre0f == 0x66 || pre0f == 0xf2 || pre0f == 0xf3)
|
|
util::stream_format(stream, "xmm%d", MODRM_REG2() | regex );
|
|
else
|
|
util::stream_format(stream, "mm%d", MODRM_REG2() | regex );
|
|
break;
|
|
|
|
case PARAM_XMM:
|
|
util::stream_format(stream, "xmm%d", MODRM_REG1() | regex );
|
|
break;
|
|
|
|
case PARAM_REGORXMM:
|
|
if (pre0f != 0xf2 && pre0f != 0xf3)
|
|
util::stream_format(stream, "xmm%d", MODRM_REG1() | regex );
|
|
else
|
|
util::stream_format(stream, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG1() | regex] );
|
|
break;
|
|
|
|
case PARAM_REG2_32:
|
|
util::stream_format(stream, "%s", i386_reg[1][MODRM_REG2() | rmex] );
|
|
break;
|
|
|
|
case PARAM_RM:
|
|
case PARAM_RMPTR:
|
|
if( modrm >= 0xc0 ) {
|
|
util::stream_format(stream, "%s", i386_reg[operand_size][MODRM_REG2() | rmex] );
|
|
} else {
|
|
if (param == PARAM_RMPTR)
|
|
{
|
|
if( operand_size == 2 )
|
|
util::stream_format(stream, "qword ptr " );
|
|
else if (operand_size == 1)
|
|
util::stream_format(stream, "dword ptr " );
|
|
else
|
|
util::stream_format(stream, "word ptr " );
|
|
}
|
|
util::stream_format(stream, "%s", modrm_string );
|
|
}
|
|
break;
|
|
|
|
case PARAM_RM8:
|
|
case PARAM_RMPTR8:
|
|
if( modrm >= 0xc0 ) {
|
|
util::stream_format(stream, "%s", (rex ? i386_reg8rex : i386_reg8)[MODRM_REG2() | rmex] );
|
|
} else {
|
|
if (param == PARAM_RMPTR8)
|
|
util::stream_format(stream, "byte ptr " );
|
|
util::stream_format(stream, "%s", modrm_string );
|
|
}
|
|
break;
|
|
|
|
case PARAM_RM16:
|
|
case PARAM_RMPTR16:
|
|
if( modrm >= 0xc0 ) {
|
|
util::stream_format(stream, "%s", i386_reg[0][MODRM_REG2() | rmex] );
|
|
} else {
|
|
if (param == PARAM_RMPTR16)
|
|
util::stream_format(stream, "word ptr " );
|
|
util::stream_format(stream, "%s", modrm_string );
|
|
}
|
|
break;
|
|
|
|
case PARAM_RM32:
|
|
case PARAM_RMPTR32:
|
|
if( modrm >= 0xc0 ) {
|
|
util::stream_format(stream, "%s", i386_reg[1][MODRM_REG2() | rmex] );
|
|
} else {
|
|
if (param == PARAM_RMPTR32)
|
|
util::stream_format(stream, "dword ptr " );
|
|
util::stream_format(stream, "%s", modrm_string );
|
|
}
|
|
break;
|
|
|
|
case PARAM_RMXMM:
|
|
if( modrm >= 0xc0 ) {
|
|
if (pre0f != 0xf2 && pre0f != 0xf3)
|
|
util::stream_format(stream, "xmm%d", MODRM_REG2() | rmex );
|
|
else
|
|
util::stream_format(stream, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG2() | rmex] );
|
|
} else {
|
|
if (param == PARAM_RMPTR32)
|
|
util::stream_format(stream, "dword ptr " );
|
|
util::stream_format(stream, "%s", modrm_string );
|
|
}
|
|
break;
|
|
|
|
case PARAM_M64:
|
|
case PARAM_M64PTR:
|
|
if( modrm >= 0xc0 ) {
|
|
util::stream_format(stream, "???" );
|
|
} else {
|
|
if (param == PARAM_M64PTR)
|
|
util::stream_format(stream, "qword ptr " );
|
|
util::stream_format(stream, "%s", modrm_string );
|
|
}
|
|
break;
|
|
|
|
case PARAM_MMXM:
|
|
if( modrm >= 0xc0 ) {
|
|
if (pre0f == 0x66 || pre0f == 0xf2 || pre0f == 0xf3)
|
|
util::stream_format(stream, "xmm%d", MODRM_REG2() | rmex );
|
|
else
|
|
util::stream_format(stream, "mm%d", MODRM_REG2() | rmex );
|
|
} else {
|
|
util::stream_format(stream, "%s", modrm_string );
|
|
}
|
|
break;
|
|
|
|
case PARAM_XMMM:
|
|
if( modrm >= 0xc0 ) {
|
|
util::stream_format(stream, "xmm%d", MODRM_REG2() | rmex );
|
|
} else {
|
|
util::stream_format(stream, "%s", modrm_string );
|
|
}
|
|
break;
|
|
|
|
case PARAM_I4:
|
|
i8 = FETCHD(base_pc, pc, opcodes);
|
|
util::stream_format(stream, "%d", i8 & 0x0f );
|
|
break;
|
|
|
|
case PARAM_I8:
|
|
i8 = FETCHD(base_pc, pc, opcodes);
|
|
util::stream_format(stream, "%s", shexstring((int8_t)i8, 0, false) );
|
|
break;
|
|
|
|
case PARAM_I16:
|
|
i16 = FETCHD16(base_pc, pc, opcodes);
|
|
util::stream_format(stream, "%s", shexstring((int16_t)i16, 0, false) );
|
|
break;
|
|
|
|
case PARAM_UI8:
|
|
i8 = FETCHD(base_pc, pc, opcodes);
|
|
util::stream_format(stream, "%s", shexstring((uint8_t)i8, 0, false) );
|
|
break;
|
|
|
|
case PARAM_UI16:
|
|
i16 = FETCHD16(base_pc, pc, opcodes);
|
|
util::stream_format(stream, "%s", shexstring((uint16_t)i16, 0, false) );
|
|
break;
|
|
|
|
case PARAM_IMM64:
|
|
if (operand_size == 2) {
|
|
uint32_t lo32 = FETCHD32(base_pc, pc, opcodes);
|
|
i32 = FETCHD32(base_pc, pc, opcodes);
|
|
util::stream_format(stream, "%s", hexstring64(lo32, i32) );
|
|
} else if( operand_size ) {
|
|
i32 = FETCHD32(base_pc, pc, opcodes);
|
|
util::stream_format(stream, "%s", hexstring(i32, 0) );
|
|
} else {
|
|
i16 = FETCHD16(base_pc, pc, opcodes);
|
|
util::stream_format(stream, "%s", hexstring(i16, 0) );
|
|
}
|
|
break;
|
|
|
|
case PARAM_IMM:
|
|
if( operand_size ) {
|
|
i32 = FETCHD32(base_pc, pc, opcodes);
|
|
util::stream_format(stream, "%s", hexstring(i32, 0) );
|
|
} else {
|
|
i16 = FETCHD16(base_pc, pc, opcodes);
|
|
util::stream_format(stream, "%s", hexstring(i16, 0) );
|
|
}
|
|
break;
|
|
|
|
case PARAM_ADDR:
|
|
if( operand_size ) {
|
|
addr = FETCHD32(base_pc, pc, opcodes);
|
|
ptr = FETCHD16(base_pc, pc, opcodes);
|
|
util::stream_format(stream, "%s:", hexstring(ptr, 4) );
|
|
util::stream_format(stream, "%s", hexstring(addr, 0) );
|
|
} else {
|
|
addr = FETCHD16(base_pc, pc, opcodes);
|
|
ptr = FETCHD16(base_pc, pc, opcodes);
|
|
util::stream_format(stream, "%s:", hexstring(ptr, 4) );
|
|
util::stream_format(stream, "%s", hexstring(addr, 0) );
|
|
}
|
|
break;
|
|
|
|
case PARAM_REL:
|
|
if( operand_size ) {
|
|
d32 = FETCHD32(base_pc, pc, opcodes);
|
|
util::stream_format(stream, "%s", hexstringpc(pc + d32) );
|
|
} else {
|
|
/* make sure to keep the relative offset within the segment */
|
|
d16 = FETCHD16(base_pc, pc, opcodes);
|
|
util::stream_format(stream, "%s", hexstringpc((pc & 0xFFFF0000) | ((pc + d16) & 0x0000FFFF)) );
|
|
}
|
|
break;
|
|
|
|
case PARAM_REL8:
|
|
d8 = FETCHD(base_pc, pc, opcodes);
|
|
util::stream_format(stream, "%s", hexstringpc(pc + d8) );
|
|
break;
|
|
|
|
case PARAM_MEM_OFFS:
|
|
switch(segment)
|
|
{
|
|
case SEG_CS: util::stream_format(stream, "cs:" ); break;
|
|
case SEG_DS: util::stream_format(stream, "ds:" ); break;
|
|
case SEG_ES: util::stream_format(stream, "es:" ); break;
|
|
case SEG_FS: util::stream_format(stream, "fs:" ); break;
|
|
case SEG_GS: util::stream_format(stream, "gs:" ); break;
|
|
case SEG_SS: util::stream_format(stream, "ss:" ); break;
|
|
}
|
|
|
|
if( address_size ) {
|
|
i32 = FETCHD32(base_pc, pc, opcodes);
|
|
util::stream_format(stream, "[%s]", hexstring(i32, 0) );
|
|
} else {
|
|
i16 = FETCHD16(base_pc, pc, opcodes);
|
|
util::stream_format(stream, "[%s]", hexstring(i16, 0) );
|
|
}
|
|
break;
|
|
|
|
case PARAM_PREIMP:
|
|
switch(segment)
|
|
{
|
|
case SEG_CS: util::stream_format(stream, "cs:" ); break;
|
|
case SEG_DS: util::stream_format(stream, "ds:" ); break;
|
|
case SEG_ES: util::stream_format(stream, "es:" ); break;
|
|
case SEG_FS: util::stream_format(stream, "fs:" ); break;
|
|
case SEG_GS: util::stream_format(stream, "gs:" ); break;
|
|
case SEG_SS: util::stream_format(stream, "ss:" ); break;
|
|
}
|
|
break;
|
|
|
|
case PARAM_SREG:
|
|
util::stream_format(stream, "%s", i386_sreg[MODRM_REG1()] );
|
|
break;
|
|
|
|
case PARAM_CREG:
|
|
util::stream_format(stream, "cr%d", MODRM_REG1() | regex );
|
|
break;
|
|
|
|
case PARAM_TREG:
|
|
util::stream_format(stream, "tr%d", MODRM_REG1() | regex );
|
|
break;
|
|
|
|
case PARAM_DREG:
|
|
util::stream_format(stream, "dr%d", MODRM_REG1() | regex );
|
|
break;
|
|
|
|
case PARAM_1:
|
|
util::stream_format(stream, "1" );
|
|
break;
|
|
|
|
case PARAM_DX:
|
|
util::stream_format(stream, "dx" );
|
|
break;
|
|
|
|
case PARAM_XMM0:
|
|
util::stream_format(stream, "xmm0" );
|
|
break;
|
|
|
|
case PARAM_AL: util::stream_format(stream, "al" ); break;
|
|
case PARAM_CL: util::stream_format(stream, "cl" ); break;
|
|
case PARAM_DL: util::stream_format(stream, "dl" ); break;
|
|
case PARAM_BL: util::stream_format(stream, "bl" ); break;
|
|
case PARAM_AH: util::stream_format(stream, "ah" ); break;
|
|
case PARAM_CH: util::stream_format(stream, "ch" ); break;
|
|
case PARAM_DH: util::stream_format(stream, "dh" ); break;
|
|
case PARAM_BH: util::stream_format(stream, "bh" ); break;
|
|
|
|
case PARAM_EAX: util::stream_format(stream, "%s", i386_reg[operand_size][0 | rmex] ); break;
|
|
case PARAM_ECX: util::stream_format(stream, "%s", i386_reg[operand_size][1 | rmex] ); break;
|
|
case PARAM_EDX: util::stream_format(stream, "%s", i386_reg[operand_size][2 | rmex] ); break;
|
|
case PARAM_EBX: util::stream_format(stream, "%s", i386_reg[operand_size][3 | rmex] ); break;
|
|
case PARAM_ESP: util::stream_format(stream, "%s", i386_reg[operand_size][4 | rmex] ); break;
|
|
case PARAM_EBP: util::stream_format(stream, "%s", i386_reg[operand_size][5 | rmex] ); break;
|
|
case PARAM_ESI: util::stream_format(stream, "%s", i386_reg[operand_size][6 | rmex] ); break;
|
|
case PARAM_EDI: util::stream_format(stream, "%s", i386_reg[operand_size][7 | rmex] ); break;
|
|
}
|
|
}
|
|
|
|
void i386_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2, offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
|
|
{
|
|
switch (op1 & 0x7)
|
|
{
|
|
case 0: // Group D8
|
|
{
|
|
if (op2 < 0xc0)
|
|
{
|
|
pc--; // adjust fetch pointer, so modrm byte read again
|
|
handle_modrm(modrm_string, base_pc, pc, opcodes);
|
|
switch ((op2 >> 3) & 0x7)
|
|
{
|
|
case 0: util::stream_format(stream, "fadd dword ptr %s", modrm_string); break;
|
|
case 1: util::stream_format(stream, "fmul dword ptr %s", modrm_string); break;
|
|
case 2: util::stream_format(stream, "fcom dword ptr %s", modrm_string); break;
|
|
case 3: util::stream_format(stream, "fcomp dword ptr %s", modrm_string); break;
|
|
case 4: util::stream_format(stream, "fsub dword ptr %s", modrm_string); break;
|
|
case 5: util::stream_format(stream, "fsubr dword ptr %s", modrm_string); break;
|
|
case 6: util::stream_format(stream, "fdiv dword ptr %s", modrm_string); break;
|
|
case 7: util::stream_format(stream, "fdivr dword ptr %s", modrm_string); break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch ((op2 >> 3) & 0x7)
|
|
{
|
|
case 0: util::stream_format(stream, "fadd st(0),st(%d)", op2 & 0x7); break;
|
|
case 1: util::stream_format(stream, "fmul st(0),st(%d)", op2 & 0x7); break;
|
|
case 2: util::stream_format(stream, "fcom st(0),st(%d)", op2 & 0x7); break;
|
|
case 3: util::stream_format(stream, "fcomp st(0),st(%d)", op2 & 0x7); break;
|
|
case 4: util::stream_format(stream, "fsub st(0),st(%d)", op2 & 0x7); break;
|
|
case 5: util::stream_format(stream, "fsubr st(0),st(%d)", op2 & 0x7); break;
|
|
case 6: util::stream_format(stream, "fdiv st(0),st(%d)", op2 & 0x7); break;
|
|
case 7: util::stream_format(stream, "fdivr st(0),st(%d)", op2 & 0x7); break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case 1: // Group D9
|
|
{
|
|
if (op2 < 0xc0)
|
|
{
|
|
pc--; // adjust fetch pointer, so modrm byte read again
|
|
handle_modrm(modrm_string, base_pc, pc, opcodes);
|
|
switch ((op2 >> 3) & 0x7)
|
|
{
|
|
case 0: util::stream_format(stream, "fld dword ptr %s", modrm_string); break;
|
|
case 1: util::stream_format(stream, "??? (FPU)"); break;
|
|
case 2: util::stream_format(stream, "fst dword ptr %s", modrm_string); break;
|
|
case 3: util::stream_format(stream, "fstp dword ptr %s", modrm_string); break;
|
|
case 4: util::stream_format(stream, "fldenv word ptr %s", modrm_string); break;
|
|
case 5: util::stream_format(stream, "fldcw word ptr %s", modrm_string); break;
|
|
case 6: util::stream_format(stream, "fstenv word ptr %s", modrm_string); break;
|
|
case 7: util::stream_format(stream, "fstcw word ptr %s", modrm_string); break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (op2 & 0x3f)
|
|
{
|
|
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
|
|
util::stream_format(stream, "fld st(0),st(%d)", op2 & 0x7); break;
|
|
|
|
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
|
|
util::stream_format(stream, "fxch st(0),st(%d)", op2 & 0x7); break;
|
|
|
|
case 0x10: util::stream_format(stream, "fnop"); break;
|
|
case 0x20: util::stream_format(stream, "fchs"); break;
|
|
case 0x21: util::stream_format(stream, "fabs"); break;
|
|
case 0x24: util::stream_format(stream, "ftst"); break;
|
|
case 0x25: util::stream_format(stream, "fxam"); break;
|
|
case 0x28: util::stream_format(stream, "fld1"); break;
|
|
case 0x29: util::stream_format(stream, "fldl2t"); break;
|
|
case 0x2a: util::stream_format(stream, "fldl2e"); break;
|
|
case 0x2b: util::stream_format(stream, "fldpi"); break;
|
|
case 0x2c: util::stream_format(stream, "fldlg2"); break;
|
|
case 0x2d: util::stream_format(stream, "fldln2"); break;
|
|
case 0x2e: util::stream_format(stream, "fldz"); break;
|
|
case 0x30: util::stream_format(stream, "f2xm1"); break;
|
|
case 0x31: util::stream_format(stream, "fyl2x"); break;
|
|
case 0x32: util::stream_format(stream, "fptan"); break;
|
|
case 0x33: util::stream_format(stream, "fpatan"); break;
|
|
case 0x34: util::stream_format(stream, "fxtract"); break;
|
|
case 0x35: util::stream_format(stream, "fprem1"); break;
|
|
case 0x36: util::stream_format(stream, "fdecstp"); break;
|
|
case 0x37: util::stream_format(stream, "fincstp"); break;
|
|
case 0x38: util::stream_format(stream, "fprem"); break;
|
|
case 0x39: util::stream_format(stream, "fyl2xp1"); break;
|
|
case 0x3a: util::stream_format(stream, "fsqrt"); break;
|
|
case 0x3b: util::stream_format(stream, "fsincos"); break;
|
|
case 0x3c: util::stream_format(stream, "frndint"); break;
|
|
case 0x3d: util::stream_format(stream, "fscale"); break;
|
|
case 0x3e: util::stream_format(stream, "fsin"); break;
|
|
case 0x3f: util::stream_format(stream, "fcos"); break;
|
|
|
|
default: util::stream_format(stream, "??? (FPU)"); break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case 2: // Group DA
|
|
{
|
|
if (op2 < 0xc0)
|
|
{
|
|
pc--; // adjust fetch pointer, so modrm byte read again
|
|
handle_modrm(modrm_string, base_pc, pc, opcodes);
|
|
switch ((op2 >> 3) & 0x7)
|
|
{
|
|
case 0: util::stream_format(stream, "fiadd dword ptr %s", modrm_string); break;
|
|
case 1: util::stream_format(stream, "fimul dword ptr %s", modrm_string); break;
|
|
case 2: util::stream_format(stream, "ficom dword ptr %s", modrm_string); break;
|
|
case 3: util::stream_format(stream, "ficomp dword ptr %s", modrm_string); break;
|
|
case 4: util::stream_format(stream, "fisub dword ptr %s", modrm_string); break;
|
|
case 5: util::stream_format(stream, "fisubr dword ptr %s", modrm_string); break;
|
|
case 6: util::stream_format(stream, "fidiv dword ptr %s", modrm_string); break;
|
|
case 7: util::stream_format(stream, "fidivr dword ptr %s", modrm_string); break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (op2 & 0x3f)
|
|
{
|
|
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
|
|
util::stream_format(stream, "fcmovb st(0),st(%d)", op2 & 0x7); break;
|
|
|
|
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
|
|
util::stream_format(stream, "fcmove st(0),st(%d)", op2 & 0x7); break;
|
|
|
|
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
|
|
util::stream_format(stream, "fcmovbe st(0),st(%d)", op2 & 0x7); break;
|
|
|
|
case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
|
|
util::stream_format(stream, "fcmovu st(0),st(%d)", op2 & 0x7); break;
|
|
case 0x29:
|
|
util::stream_format(stream, "fucompp"); break;
|
|
|
|
default: util::stream_format(stream, "??? (FPU)"); break;
|
|
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case 3: // Group DB
|
|
{
|
|
if (op2 < 0xc0)
|
|
{
|
|
pc--; // adjust fetch pointer, so modrm byte read again
|
|
handle_modrm(modrm_string, base_pc, pc, opcodes);
|
|
switch ((op2 >> 3) & 0x7)
|
|
{
|
|
case 0: util::stream_format(stream, "fild dword ptr %s", modrm_string); break;
|
|
case 1: util::stream_format(stream, "fisttp dword ptr %s", modrm_string); break;
|
|
case 2: util::stream_format(stream, "fist dword ptr %s", modrm_string); break;
|
|
case 3: util::stream_format(stream, "fistp dword ptr %s", modrm_string); break;
|
|
case 4: util::stream_format(stream, "??? (FPU)"); break;
|
|
case 5: util::stream_format(stream, "fld tword ptr %s", modrm_string); break;
|
|
case 6: util::stream_format(stream, "??? (FPU)"); break;
|
|
case 7: util::stream_format(stream, "fstp tword ptr %s", modrm_string); break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (op2 & 0x3f)
|
|
{
|
|
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
|
|
util::stream_format(stream, "fcmovnb st(0),st(%d)", op2 & 0x7); break;
|
|
|
|
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
|
|
util::stream_format(stream, "fcmovne st(0),st(%d)", op2 & 0x7); break;
|
|
|
|
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
|
|
util::stream_format(stream, "fcmovnbe st(0),st(%d)", op2 & 0x7); break;
|
|
|
|
case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
|
|
util::stream_format(stream, "fcmovnu st(0),st(%d)", op2 & 0x7); break;
|
|
|
|
case 0x22: util::stream_format(stream, "fclex"); break;
|
|
case 0x23: util::stream_format(stream, "finit"); break;
|
|
|
|
case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
|
|
util::stream_format(stream, "fucomi st(0),st(%d)", op2 & 0x7); break;
|
|
|
|
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
|
|
util::stream_format(stream, "fcomi st(0),st(%d)", op2 & 0x7); break;
|
|
|
|
default: util::stream_format(stream, "??? (FPU)"); break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case 4: // Group DC
|
|
{
|
|
if (op2 < 0xc0)
|
|
{
|
|
pc--; // adjust fetch pointer, so modrm byte read again
|
|
handle_modrm(modrm_string, base_pc, pc, opcodes);
|
|
switch ((op2 >> 3) & 0x7)
|
|
{
|
|
case 0: util::stream_format(stream, "fadd qword ptr %s", modrm_string); break;
|
|
case 1: util::stream_format(stream, "fmul qword ptr %s", modrm_string); break;
|
|
case 2: util::stream_format(stream, "fcom qword ptr %s", modrm_string); break;
|
|
case 3: util::stream_format(stream, "fcomp qword ptr %s", modrm_string); break;
|
|
case 4: util::stream_format(stream, "fsub qword ptr %s", modrm_string); break;
|
|
case 5: util::stream_format(stream, "fsubr qword ptr %s", modrm_string); break;
|
|
case 6: util::stream_format(stream, "fdiv qword ptr %s", modrm_string); break;
|
|
case 7: util::stream_format(stream, "fdivr qword ptr %s", modrm_string); break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (op2 & 0x3f)
|
|
{
|
|
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
|
|
util::stream_format(stream, "fadd st(%d),st(0)", op2 & 0x7); break;
|
|
|
|
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
|
|
util::stream_format(stream, "fmul st(%d),st(0)", op2 & 0x7); break;
|
|
|
|
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
|
|
util::stream_format(stream, "fsubr st(%d),st(0)", op2 & 0x7); break;
|
|
|
|
case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
|
|
util::stream_format(stream, "fsub st(%d),st(0)", op2 & 0x7); break;
|
|
|
|
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
|
|
util::stream_format(stream, "fdivr st(%d),st(0)", op2 & 0x7); break;
|
|
|
|
case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
|
|
util::stream_format(stream, "fdiv st(%d),st(0)", op2 & 0x7); break;
|
|
|
|
default: util::stream_format(stream, "??? (FPU)"); break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case 5: // Group DD
|
|
{
|
|
if (op2 < 0xc0)
|
|
{
|
|
pc--; // adjust fetch pointer, so modrm byte read again
|
|
handle_modrm(modrm_string, base_pc, pc, opcodes);
|
|
switch ((op2 >> 3) & 0x7)
|
|
{
|
|
case 0: util::stream_format(stream, "fld qword ptr %s", modrm_string); break;
|
|
case 1: util::stream_format(stream, "fisttp qword ptr %s", modrm_string); break;
|
|
case 2: util::stream_format(stream, "fst qword ptr %s", modrm_string); break;
|
|
case 3: util::stream_format(stream, "fstp qword ptr %s", modrm_string); break;
|
|
case 4: util::stream_format(stream, "frstor %s", modrm_string); break;
|
|
case 5: util::stream_format(stream, "??? (FPU)"); break;
|
|
case 6: util::stream_format(stream, "fsave %s", modrm_string); break;
|
|
case 7: util::stream_format(stream, "fstsw word ptr %s", modrm_string); break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (op2 & 0x3f)
|
|
{
|
|
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
|
|
util::stream_format(stream, "ffree st(%d)", op2 & 0x7); break;
|
|
|
|
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
|
|
util::stream_format(stream, "fst st(%d)", op2 & 0x7); break;
|
|
|
|
case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
|
|
util::stream_format(stream, "fstp st(%d)", op2 & 0x7); break;
|
|
|
|
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
|
|
util::stream_format(stream, "fucom st(%d), st(0)", op2 & 0x7); break;
|
|
|
|
case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
|
|
util::stream_format(stream, "fucomp st(%d)", op2 & 0x7); break;
|
|
|
|
default: util::stream_format(stream, "??? (FPU)"); break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case 6: // Group DE
|
|
{
|
|
if (op2 < 0xc0)
|
|
{
|
|
pc--; // adjust fetch pointer, so modrm byte read again
|
|
handle_modrm(modrm_string, base_pc, pc, opcodes);
|
|
switch ((op2 >> 3) & 0x7)
|
|
{
|
|
case 0: util::stream_format(stream, "fiadd word ptr %s", modrm_string); break;
|
|
case 1: util::stream_format(stream, "fimul word ptr %s", modrm_string); break;
|
|
case 2: util::stream_format(stream, "ficom word ptr %s", modrm_string); break;
|
|
case 3: util::stream_format(stream, "ficomp word ptr %s", modrm_string); break;
|
|
case 4: util::stream_format(stream, "fisub word ptr %s", modrm_string); break;
|
|
case 5: util::stream_format(stream, "fisubr word ptr %s", modrm_string); break;
|
|
case 6: util::stream_format(stream, "fidiv word ptr %s", modrm_string); break;
|
|
case 7: util::stream_format(stream, "fidivr word ptr %s", modrm_string); break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (op2 & 0x3f)
|
|
{
|
|
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
|
|
util::stream_format(stream, "faddp st(%d)", op2 & 0x7); break;
|
|
|
|
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
|
|
util::stream_format(stream, "fmulp st(%d)", op2 & 0x7); break;
|
|
|
|
case 0x19: util::stream_format(stream, "fcompp"); break;
|
|
|
|
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
|
|
util::stream_format(stream, "fsubrp st(%d)", op2 & 0x7); break;
|
|
|
|
case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
|
|
util::stream_format(stream, "fsubp st(%d)", op2 & 0x7); break;
|
|
|
|
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
|
|
util::stream_format(stream, "fdivrp st(%d), st(0)", op2 & 0x7); break;
|
|
|
|
case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
|
|
util::stream_format(stream, "fdivp st(%d)", op2 & 0x7); break;
|
|
|
|
default: util::stream_format(stream, "??? (FPU)"); break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case 7: // Group DF
|
|
{
|
|
if (op2 < 0xc0)
|
|
{
|
|
pc--; // adjust fetch pointer, so modrm byte read again
|
|
handle_modrm(modrm_string, base_pc, pc, opcodes);
|
|
switch ((op2 >> 3) & 0x7)
|
|
{
|
|
case 0: util::stream_format(stream, "fild word ptr %s", modrm_string); break;
|
|
case 1: util::stream_format(stream, "fisttp word ptr %s", modrm_string); break;
|
|
case 2: util::stream_format(stream, "fist word ptr %s", modrm_string); break;
|
|
case 3: util::stream_format(stream, "fistp word ptr %s", modrm_string); break;
|
|
case 4: util::stream_format(stream, "fbld %s", modrm_string); break;
|
|
case 5: util::stream_format(stream, "fild qword ptr %s", modrm_string); break;
|
|
case 6: util::stream_format(stream, "fbstp %s", modrm_string); break;
|
|
case 7: util::stream_format(stream, "fistp qword ptr %s", modrm_string); break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (op2 & 0x3f)
|
|
{
|
|
case 0x20: util::stream_format(stream, "fstsw ax"); break;
|
|
|
|
case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
|
|
util::stream_format(stream, "fucomip st(%d)", op2 & 0x7); break;
|
|
|
|
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
|
|
util::stream_format(stream, "fcomip st(%d),st(0)", op2 & 0x7); break;
|
|
|
|
default: util::stream_format(stream, "??? (FPU)"); break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void i386_disassembler::decode_opcode(std::ostream &stream, const I386_OPCODE *op, uint8_t op1, offs_t base_pc, offs_t &pc, const data_buffer &opcodes)
|
|
{
|
|
int i;
|
|
uint8_t op2;
|
|
|
|
if ((op->flags & SPECIAL64) && (address_size == 2))
|
|
op = &x64_opcode_alt[op->flags >> 24];
|
|
|
|
switch( op->flags & FLAGS_MASK )
|
|
{
|
|
case ISREX:
|
|
if (m_config->get_mode() == 64)
|
|
{
|
|
rex = op1;
|
|
operand_size = (op1 & 8) ? 2 : 1;
|
|
regex = (op1 << 1) & 8;
|
|
sibex = (op1 << 2) & 8;
|
|
rmex = (op1 << 3) & 8;
|
|
op2 = FETCH(base_pc, pc, opcodes);
|
|
decode_opcode(stream, &i386_opcode_table1[op2], op1, base_pc, pc, opcodes);
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case OP_SIZE:
|
|
rex = regex = sibex = rmex = 0;
|
|
if (operand_size < 2 && operand_prefix == 0)
|
|
{
|
|
operand_size ^= 1;
|
|
operand_prefix = 1;
|
|
}
|
|
op2 = FETCH(base_pc, pc, opcodes);
|
|
decode_opcode(stream, &i386_opcode_table1[op2], op2, base_pc, pc, opcodes);
|
|
return;
|
|
|
|
case ADDR_SIZE:
|
|
rex = regex = sibex = rmex = 0;
|
|
if(address_prefix == 0)
|
|
{
|
|
if (m_config->get_mode() != 64)
|
|
address_size ^= 1;
|
|
else
|
|
address_size ^= 3;
|
|
address_prefix = 1;
|
|
}
|
|
op2 = FETCH(base_pc, pc, opcodes);
|
|
decode_opcode(stream, &i386_opcode_table1[op2], op2, base_pc, pc, opcodes);
|
|
return;
|
|
|
|
case TWO_BYTE:
|
|
if (pc - 2 >= base_pc)
|
|
pre0f = opcodes.r8(pc-2);
|
|
op2 = FETCHD(base_pc, pc, opcodes);
|
|
decode_opcode(stream, &i386_opcode_table2[op2], op1, base_pc, pc, opcodes);
|
|
return;
|
|
|
|
case THREE_BYTE:
|
|
op2 = FETCHD(base_pc, pc, opcodes);
|
|
if (opcodes.r8(pc-2) == 0x38)
|
|
decode_opcode(stream, &i386_opcode_table0F38[op2], op1, base_pc, pc, opcodes);
|
|
else
|
|
decode_opcode(stream, &i386_opcode_table0F3A[op2], op1, base_pc, pc, opcodes);
|
|
return;
|
|
|
|
case SEG_CS:
|
|
case SEG_DS:
|
|
case SEG_ES:
|
|
case SEG_FS:
|
|
case SEG_GS:
|
|
case SEG_SS:
|
|
rex = regex = sibex = rmex = 0;
|
|
segment = op->flags;
|
|
op2 = FETCH(base_pc, pc, opcodes);
|
|
decode_opcode(stream, &i386_opcode_table1[op2], op2, base_pc, pc, opcodes);
|
|
return;
|
|
|
|
case PREFIX:
|
|
op2 = FETCH(base_pc, pc, opcodes);
|
|
if ((op2 != 0x0f) && (op2 != 0x90))
|
|
util::stream_format(stream, "%-7s ", op->mnemonic );
|
|
if ((op2 == 0x90) && !pre0f)
|
|
pre0f = op1;
|
|
decode_opcode(stream, &i386_opcode_table1[op2], op2, base_pc, pc, opcodes);
|
|
dasm_flags |= op->dasm_flags;
|
|
return;
|
|
|
|
case GROUP:
|
|
handle_modrm(modrm_string, base_pc, pc, opcodes);
|
|
for( i=0; i < ARRAY_LENGTH(group_op_table); i++ ) {
|
|
if( strcmp(op->mnemonic, group_op_table[i].mnemonic) == 0 ) {
|
|
if (op->flags & GROUP_MOD)
|
|
decode_opcode(stream, &group_op_table[i].opcode[MODRM_MOD()], op1, base_pc, pc, opcodes);
|
|
else
|
|
decode_opcode(stream, &group_op_table[i].opcode[MODRM_REG1()], op1, base_pc, pc, opcodes);
|
|
return;
|
|
}
|
|
}
|
|
goto handle_unknown;
|
|
|
|
case FPU:
|
|
op2 = FETCHD(base_pc, pc, opcodes);
|
|
handle_fpu(stream, op1, op2, base_pc, pc, opcodes);
|
|
return;
|
|
|
|
case MODRM:
|
|
handle_modrm(modrm_string, base_pc, pc, opcodes);
|
|
break;
|
|
}
|
|
|
|
if ((op->flags & ALWAYS64) && m_config->get_mode() == 64)
|
|
operand_size = 2;
|
|
|
|
if ((op->flags & VAR_NAME) && operand_size > 0)
|
|
{
|
|
const char *mnemonic = op->mnemonic + strlen(op->mnemonic) + 1;
|
|
if (operand_size == 2)
|
|
mnemonic += strlen(mnemonic) + 1;
|
|
util::stream_format(stream, "%-7s ", mnemonic );
|
|
}
|
|
else if (op->flags & VAR_NAME4)
|
|
{
|
|
const char *mnemonic = op->mnemonic;
|
|
int which = (pre0f == 0xf3) ? 3 : (pre0f == 0xf2) ? 2 : (pre0f == 0x66) ? 1 : 0;
|
|
while (which--)
|
|
mnemonic += strlen(mnemonic) + 1;
|
|
util::stream_format(stream, "%-7s ", mnemonic );
|
|
}
|
|
else
|
|
util::stream_format(stream, "%-7s ", op->mnemonic );
|
|
dasm_flags = op->dasm_flags;
|
|
|
|
if( op->param1 != 0 ) {
|
|
handle_param(stream, op->param1, base_pc, pc, opcodes);
|
|
}
|
|
|
|
if( op->param2 != 0 ) {
|
|
util::stream_format(stream, "," );
|
|
handle_param(stream, op->param2, base_pc, pc, opcodes);
|
|
}
|
|
|
|
if( op->param3 != 0 ) {
|
|
util::stream_format(stream, "," );
|
|
handle_param(stream, op->param3, base_pc, pc, opcodes);
|
|
}
|
|
return;
|
|
|
|
handle_unknown:
|
|
util::stream_format(stream, "???");
|
|
}
|
|
|
|
offs_t i386_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms)
|
|
{
|
|
offs_t base_pc = pc;
|
|
uint8_t op;
|
|
|
|
switch(m_config->get_mode())
|
|
{
|
|
case 1: /* 8086/8088/80186/80188 */
|
|
address_size = 0;
|
|
operand_size = 0;
|
|
max_length = 8; /* maximum without redundant prefixes - not enforced by chip */
|
|
break;
|
|
case 2: /* 80286 */
|
|
address_size = 0;
|
|
operand_size = 0;
|
|
max_length = 10;
|
|
break;
|
|
case 16: /* 80386+ 16-bit code segment */
|
|
address_size = 0;
|
|
operand_size = 0;
|
|
max_length = 15;
|
|
break;
|
|
case 32: /* 80386+ 32-bit code segment */
|
|
address_size = 1;
|
|
operand_size = 1;
|
|
max_length = 15;
|
|
break;
|
|
case 64: /* x86_64 */
|
|
address_size = 2;
|
|
operand_size = 1;
|
|
max_length = 15;
|
|
break;
|
|
}
|
|
dasm_flags = 0;
|
|
segment = 0;
|
|
pre0f = 0;
|
|
rex = regex = sibex = rmex = 0;
|
|
address_prefix = 0;
|
|
operand_prefix = 0;
|
|
|
|
op = FETCH(base_pc, pc, opcodes);
|
|
|
|
decode_opcode( stream, &i386_opcode_table1[op], op, base_pc, pc, opcodes);
|
|
return (pc-base_pc) | dasm_flags | SUPPORTED;
|
|
}
|
|
|
|
i386_disassembler::i386_disassembler(config *conf) : m_config(conf)
|
|
{
|
|
}
|
|
|
|
u32 i386_disassembler::opcode_alignment() const
|
|
{
|
|
return 1;
|
|
}
|