instrs: Add several AMD-only instructions

- 3DNow! instructions have a trailing immediate byte which indicates the
  opcode. Decoding this with the existing table structure requires more
  effort (in particular, a new lookup table after decoding ModRM would
  be required). Given that AMD even removed 3DNow! over 10 years ago, it
  appears unlikely that this will ever be fully supported. Adding the
  RMI-encoded pseudo-instruction "3DNOW" just to support that opcode.
- FEMMS is a legacy 3DNow! instruction.
- EXTRQ/INSERTQ are instructions with an "unusual" encoding and
  operation mode. This is another instance of 16-bit immediates.
- SVM (AMD's variant of VMX) and SNP instructions are AMD-only.
This commit is contained in:
Alexis Engelke
2021-01-10 15:18:44 +01:00
parent 51072cac9c
commit 9245a97248
4 changed files with 40 additions and 1 deletions

View File

@@ -506,7 +506,9 @@ prefix_end:
uint8_t imm_size;
if (imm_byte)
imm_size = 1;
else if (UNLIKELY(instr->type == FDI_RET || instr->type == FDI_RETF))
else if (UNLIKELY(instr->type == FDI_RET || instr->type == FDI_RETF ||
instr->type == FDI_SSE_EXTRQ ||
instr->type == FDI_SSE_INSERTQ))
imm_size = 2;
else if (UNLIKELY(desc->type == FDI_JMPF || desc->type == FDI_CALLF))
imm_size = op_size + 2;

View File

@@ -342,6 +342,11 @@ fd_format_abs(const FdInstr* instr, uint64_t addr, char* buffer, size_t len)
switch (FD_TYPE(instr)) {
default:
goto nosplitimm;
case FDI_SSE_EXTRQ:
case FDI_SSE_INSERTQ:
splitimm = immediate & 0xff;
immediate = (immediate >> 8) & 0xff;
break;
case FDI_ENTER:
splitimm = immediate & 0xffff;
immediate = (immediate >> 16) & 0xff;

View File

@@ -352,6 +352,10 @@ F2.0f09 NP - - - - WBINVD
0f0d/5m M MEM8 - - - RESERVED_PREFETCH
0f0d/6m M MEM8 - - - RESERVED_PREFETCH
0f0d/7m M MEM8 - - - RESERVED_PREFETCH
0f0e NP - - - - FEMMS ONLYAMD
# TODO: actually decode 3DNow! instructions. Given that 3DNow! no longer exists,
# this is unlikely to happen, though.
0f0f RMI MMX MMX IMM8 - 3DNOW ONLYAMD
0f18/0m M MEM8 - - - PREFETCHNTA
0f18/1m M MEM8 - - - PREFETCHT0
0f18/2m M MEM8 - - - PREFETCHT1
@@ -703,6 +707,11 @@ F2.0f70 RMI XMM XMM IMM8 - SSE_PSHUFLW
66.0f74 RM XMM XMM - - SSE_PCMPEQB
66.0f75 RM XMM XMM - - SSE_PCMPEQW
66.0f76 RM XMM XMM - - SSE_PCMPEQD
# EXTRQ/INSERTQ immediate size handled in code.
66.0f78/0r MI XMM IMM16 - - SSE_EXTRQ ONLYAMD
F2.0f78/r RMI XMM XMM IMM16 - SSE_INSERTQ ONLYAMD
66.0f79/r RM XMM XMM - - SSE_EXTRQ ONLYAMD
F2.0f79/r RM XMM XMM - - SSE_INSERTQ ONLYAMD
66.0f7c RM XMM XMM - - SSE_HADDPD
F2.0f7c RM XMM XMM - - SSE_HADDPS
66.0f7d RM XMM XMM - - SSE_HSUBPD
@@ -1456,6 +1465,27 @@ F3.0fc7/6m M MEM64 - - - VMXON
66.0f01ce NP - - - - SEAMOPS
66.0f01cf NP - - - - SEAMCALL
# AMD SVM
NP.0f01d8 NP - - - - VMRUN ONLYAMD
NP.0f01d9 NP - - - - VMMCALL ONLYAMD
NP.0f01da NP - - - - VMLOAD ONLYAMD
NP.0f01db NP - - - - VMSAVE ONLYAMD
NP.0f01dc NP - - - - STGI ONLYAMD
NP.0f01dd NP - - - - CLGI ONLYAMD
NP.0f01de NP - - - - SKINIT ONLYAMD
NP.0f01df NP - - - - INVLPGA ONLYAMD
NP.0f01fa NP - - - - MONITORX ONLYAMD
F3.0f01fa NP - - - - MCOMMIT ONLYAMD
NP.0f01fb NP - - - - MWAITX ONLYAMD
NP.0f01fe NP - - - - INVLPGB ONLYAMD
NP.0f01ff NP - - - - TLBSYNC ONLYAMD
# AMD SNP
F3.0f01fe NP - - - - RMPADJUST ONLYAMD ONLY64
F2.0f01fe NP - - - - RMPUPDATE ONLYAMD ONLY64
F3.0f01ff NP - - - - PSMASH ONLYAMD ONLY64
F2.0f01ff NP - - - - PVALIDATE ONLYAMD ONLY64
# WAITPKG
66.0fae/6r M GP32 - - - TPAUSE
F3.0fae/6r M GP - - - UMONITOR

View File

@@ -315,6 +315,8 @@ main(int argc, char** argv)
TEST("\x66\x0f\x71\xd0\x01", "psrlw xmm0, 0x1");
TEST("\x66\x0f\x3a\x20\xc4\x01", "pinsrb xmm0, spl, 0x1");
TEST("\x66\x0f\x71\x10\x01", "UD");
TEST("\x66\x0f\x78\xc0\xab\xcd", "extrq xmm0, 0xab, 0xcd");
TEST("\xf2\x0f\x78\xc1\xab\xcd", "insertq xmm0, xmm1, 0xab, 0xcd");
TEST32("\xc4\x00", "les eax, fword ptr [eax]");
TEST32("\xc5\x00", "lds eax, fword ptr [eax]");