decode: Minor non-functional changes
This commit is contained in:
43
decode.c
43
decode.c
@@ -85,23 +85,23 @@ decode_prefixes(const uint8_t* buffer, int len, DecodeMode mode,
|
|||||||
while (LIKELY(off < len))
|
while (LIKELY(off < len))
|
||||||
{
|
{
|
||||||
uint8_t prefix = buffer[off];
|
uint8_t prefix = buffer[off];
|
||||||
switch (prefix)
|
switch (UNLIKELY(prefix))
|
||||||
{
|
{
|
||||||
default: goto out;
|
default: goto out;
|
||||||
// From segment overrides, the last one wins.
|
// From segment overrides, the last one wins.
|
||||||
case 0x26: *out_segment = FD_REG_ES; off++; break;
|
case 0x26: *out_segment = FD_REG_ES; break;
|
||||||
case 0x2e: *out_segment = FD_REG_CS; off++; break;
|
case 0x2e: *out_segment = FD_REG_CS; break;
|
||||||
case 0x36: *out_segment = FD_REG_SS; off++; break;
|
case 0x36: *out_segment = FD_REG_SS; break;
|
||||||
case 0x3e: *out_segment = FD_REG_DS; off++; break;
|
case 0x3e: *out_segment = FD_REG_DS; break;
|
||||||
case 0x64: *out_segment = FD_REG_FS; off++; break;
|
case 0x64: *out_segment = FD_REG_FS; break;
|
||||||
case 0x65: *out_segment = FD_REG_GS; off++; break;
|
case 0x65: *out_segment = FD_REG_GS; break;
|
||||||
case 0x67: prefixes |= PREFIX_ADDRSZ; off++; break;
|
case 0x67: prefixes |= PREFIX_ADDRSZ; break;
|
||||||
case 0xf0: prefixes |= PREFIX_LOCK; off++; break;
|
case 0xf0: prefixes |= PREFIX_LOCK; break;
|
||||||
case 0x66: prefixes |= PREFIX_OPSZ; off++; break;
|
case 0x66: prefixes |= PREFIX_OPSZ; break;
|
||||||
// From REP/REPE and REPNZ, the last one wins; and for mandatory
|
// From REP/REPE and REPNZ, the last one wins; and for mandatory
|
||||||
// prefixes they have a higher priority than 66h (handled below).
|
// prefixes they have a higher priority than 66h (handled below).
|
||||||
case 0xf3: rep = PREFIX_REP; *out_mandatory = 2; off++; break;
|
case 0xf3: rep = 2; break;
|
||||||
case 0xf2: rep = PREFIX_REPNZ; *out_mandatory = 3; off++; break;
|
case 0xf2: rep = 3; break;
|
||||||
#if defined(ARCH_X86_64)
|
#if defined(ARCH_X86_64)
|
||||||
case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45:
|
case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45:
|
||||||
case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b:
|
case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b:
|
||||||
@@ -114,10 +114,10 @@ decode_prefixes(const uint8_t* buffer, int len, DecodeMode mode,
|
|||||||
rex_prefix |= prefix & 0x4 ? PREFIX_REXR : 0;
|
rex_prefix |= prefix & 0x4 ? PREFIX_REXR : 0;
|
||||||
rex_prefix |= prefix & 0x8 ? PREFIX_REXW : 0;
|
rex_prefix |= prefix & 0x8 ? PREFIX_REXW : 0;
|
||||||
rex_off = off;
|
rex_off = off;
|
||||||
off++;
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
off++;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -128,9 +128,12 @@ out:
|
|||||||
// If there is no REP/REPNZ prefix and implied opcode extension from a VEX
|
// If there is no REP/REPNZ prefix and implied opcode extension from a VEX
|
||||||
// prefix, offer 66h as mandatory prefix. If there is a REP prefix, then the
|
// prefix, offer 66h as mandatory prefix. If there is a REP prefix, then the
|
||||||
// 66h prefix is ignored when evaluating mandatory prefixes.
|
// 66h prefix is ignored when evaluating mandatory prefixes.
|
||||||
if (*out_mandatory == 0 && (prefixes & PREFIX_OPSZ))
|
if (rep) {
|
||||||
|
*out_mandatory = rep;
|
||||||
|
prefixes |= rep == 3 ? PREFIX_REPNZ : PREFIX_REP;
|
||||||
|
} else if (prefixes & PREFIX_OPSZ)
|
||||||
*out_mandatory = 1;
|
*out_mandatory = 1;
|
||||||
*out_prefixes = prefixes | rep;
|
*out_prefixes = prefixes;
|
||||||
|
|
||||||
return off;
|
return off;
|
||||||
}
|
}
|
||||||
@@ -191,8 +194,7 @@ decode_modrm(const uint8_t* buffer, int len, DecodeMode mode, FdInstr* instr,
|
|||||||
|
|
||||||
uint8_t reg_idx = rm;
|
uint8_t reg_idx = rm;
|
||||||
#if defined(ARCH_X86_64)
|
#if defined(ARCH_X86_64)
|
||||||
if (!UNLIKELY(out_o1->misc == FD_RT_FPU || out_o1->misc == FD_RT_MMX ||
|
if (LIKELY(out_o1->misc == FD_RT_GPL || out_o1->misc == FD_RT_VEC))
|
||||||
out_o1->misc == FD_RT_MASK))
|
|
||||||
reg_idx += prefixes & PREFIX_REXB ? 8 : 0;
|
reg_idx += prefixes & PREFIX_REXB ? 8 : 0;
|
||||||
#endif
|
#endif
|
||||||
out_o1->type = FD_OT_REG;
|
out_o1->type = FD_OT_REG;
|
||||||
@@ -446,7 +448,7 @@ fd_decode(const uint8_t* buffer, size_t len_sz, int mode_int, uintptr_t address,
|
|||||||
instr->operands[i].misc = (0xf0857641 >> (4 * reg_type)) & 0xf;
|
instr->operands[i].misc = (0xf0857641 >> (4 * reg_type)) & 0xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DESC_HAS_IMPLICIT(desc))
|
if (UNLIKELY(DESC_HAS_IMPLICIT(desc)))
|
||||||
{
|
{
|
||||||
FdOp* operand = &instr->operands[DESC_IMPLICIT_IDX(desc)];
|
FdOp* operand = &instr->operands[DESC_IMPLICIT_IDX(desc)];
|
||||||
operand->type = FD_OT_REG;
|
operand->type = FD_OT_REG;
|
||||||
@@ -471,10 +473,9 @@ fd_decode(const uint8_t* buffer, size_t len_sz, int mode_int, uintptr_t address,
|
|||||||
// If there is no ModRM, but a Mod-Reg, its opcode-encoded.
|
// If there is no ModRM, but a Mod-Reg, its opcode-encoded.
|
||||||
FdOp* operand = &instr->operands[DESC_MODREG_IDX(desc)];
|
FdOp* operand = &instr->operands[DESC_MODREG_IDX(desc)];
|
||||||
uint8_t reg_idx = buffer[off - 1] & 7;
|
uint8_t reg_idx = buffer[off - 1] & 7;
|
||||||
// FIXME: don't apply REX.B to FPU, MMX, and MASK registers.
|
|
||||||
#if defined(ARCH_X86_64)
|
#if defined(ARCH_X86_64)
|
||||||
if (!UNLIKELY(operand->misc == FD_RT_FPU))
|
// Only used for GP registers, therefore always apply REX.B.
|
||||||
reg_idx += prefixes & PREFIX_REXB ? 8 : 0;
|
reg_idx += prefixes & PREFIX_REXB ? 8 : 0;
|
||||||
#endif
|
#endif
|
||||||
operand->type = FD_OT_REG;
|
operand->type = FD_OT_REG;
|
||||||
operand->reg = reg_idx;
|
operand->reg = reg_idx;
|
||||||
|
|||||||
12
instrs.txt
12
instrs.txt
@@ -346,14 +346,10 @@ F2.0f09 NP - - - - WBINVD
|
|||||||
0f18/6 M GP - - - RESERVED_NOP
|
0f18/6 M GP - - - RESERVED_NOP
|
||||||
0f18/7 M GP - - - RESERVED_NOP
|
0f18/7 M GP - - - RESERVED_NOP
|
||||||
0f1f M GP - - - NOP
|
0f1f M GP - - - NOP
|
||||||
0f20 MR GP32 CR - - MOV_CR NOMEM ONLY32
|
0f20 MR GP CR - - MOV_CR DEF64 IGN66
|
||||||
0f20 MR GP64 CR - - MOV_CR NOMEM ONLY64 DEF64
|
0f21 MR GP DR - - MOV_DR DEF64 IGN66
|
||||||
0f21 MR GP32 DR - - MOV_DR NOMEM ONLY32
|
0f22 RM CR GP - - MOV_CR DEF64 IGN66
|
||||||
0f21 MR GP64 DR - - MOV_DR NOMEM ONLY64 DEF64
|
0f23 RM DR GP - - MOV_DR DEF64 IGN66
|
||||||
0f22 RM CR GP32 - - MOV_CR NOMEM ONLY32
|
|
||||||
0f22 RM CR GP64 - - MOV_CR NOMEM ONLY64 DEF64
|
|
||||||
0f23 RM DR GP32 - - MOV_DR NOMEM ONLY32
|
|
||||||
0f23 RM DR GP64 - - MOV_DR NOMEM ONLY64 DEF64
|
|
||||||
0f30 NP - - - - WRMSR
|
0f30 NP - - - - WRMSR
|
||||||
0f31 NP - - - - RDTSC
|
0f31 NP - - - - RDTSC
|
||||||
0f32 NP - - - - RDMSR
|
0f32 NP - - - - RDMSR
|
||||||
|
|||||||
@@ -88,11 +88,14 @@ main(int argc, char** argv)
|
|||||||
TEST("\x0F\x01\xE2", "[SMSW reg4:r2]");
|
TEST("\x0F\x01\xE2", "[SMSW reg4:r2]");
|
||||||
TEST("\x66\x0F\x01\xE2", "[SMSW reg2:r2]");
|
TEST("\x66\x0F\x01\xE2", "[SMSW reg2:r2]");
|
||||||
TEST64("\x66\x48\x0F\x01\xE2", "[SMSW reg8:r2]");
|
TEST64("\x66\x48\x0F\x01\xE2", "[SMSW reg8:r2]");
|
||||||
TEST64("\x66\x0f\x20\x00", "[MOV_CR reg8:r0 reg0:r0]");
|
TEST32("\x66\x0f\x20\x00", "[MOV_CR reg4:r0 reg0:r0]"); // mod=0, 66h
|
||||||
TEST64("\x0f\x20\xc8", "UD");
|
TEST64("\x66\x0f\x20\x00", "[MOV_CR reg8:r0 reg0:r0]"); // mod=0, 66h
|
||||||
TEST64("\x0f\x20\xd0", "[MOV_CR reg8:r0 reg0:r2]");
|
TEST("\x0f\x20\xc8", "UD"); // cr1
|
||||||
TEST64("\x44\x0f\x20\x08", "UD");
|
TEST32("\x0f\x20\xd0", "[MOV_CR reg4:r0 reg0:r2]"); // cr2
|
||||||
TEST64("\x44\x0f\x21\x00", "UD");
|
TEST64("\x0f\x20\xd0", "[MOV_CR reg8:r0 reg0:r2]"); // cr2
|
||||||
|
TEST64("\x48\x0f\x20\xd0", "[MOV_CR reg8:r0 reg0:r2]"); // cr2 + REX.W
|
||||||
|
TEST64("\x44\x0f\x20\x08", "UD"); // cr9
|
||||||
|
TEST64("\x44\x0f\x21\x00", "UD"); // dr8
|
||||||
TEST("\x8c\xc0", "[MOV_S2G reg2:r0 reg2:r0]");
|
TEST("\x8c\xc0", "[MOV_S2G reg2:r0 reg2:r0]");
|
||||||
TEST64("\x44\x8c\xc0", "[MOV_S2G reg2:r0 reg2:r0]");
|
TEST64("\x44\x8c\xc0", "[MOV_S2G reg2:r0 reg2:r0]");
|
||||||
TEST("\x8e\xc0", "[MOV_G2S reg2:r0 reg2:r0]");
|
TEST("\x8e\xc0", "[MOV_G2S reg2:r0 reg2:r0]");
|
||||||
|
|||||||
Reference in New Issue
Block a user