decode: Group all VSIB handling in single branch
Most instructions don't use VSIB encoding, so move all VSIB-related handling to a single block behind a single branch.
This commit is contained in:
31
decode.c
31
decode.c
@@ -478,7 +478,6 @@ direct:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool vsib = UNLIKELY(DESC_VSIB(desc));
|
|
||||||
unsigned dispscale = 0;
|
unsigned dispscale = 0;
|
||||||
|
|
||||||
if (UNLIKELY(prefix_evex)) {
|
if (UNLIKELY(prefix_evex)) {
|
||||||
@@ -507,7 +506,7 @@ direct:
|
|||||||
// 16-bit address size implies different ModRM encoding
|
// 16-bit address size implies different ModRM encoding
|
||||||
if (UNLIKELY(addr_size == 1)) {
|
if (UNLIKELY(addr_size == 1)) {
|
||||||
ASSUME(mode == DECODE_32);
|
ASSUME(mode == DECODE_32);
|
||||||
if (vsib) // 16-bit address size + VSIB is UD
|
if (UNLIKELY(DESC_VSIB(desc))) // 16-bit addr size + VSIB is UD
|
||||||
return FD_ERR_UD;
|
return FD_ERR_UD;
|
||||||
if (rm < 6)
|
if (rm < 6)
|
||||||
op_modrm->misc = rm & 1 ? FD_REG_DI : FD_REG_SI;
|
op_modrm->misc = rm & 1 ? FD_REG_DI : FD_REG_SI;
|
||||||
@@ -538,8 +537,7 @@ direct:
|
|||||||
|
|
||||||
// SIB byte
|
// SIB byte
|
||||||
uint8_t base = rm;
|
uint8_t base = rm;
|
||||||
if (rm == 4)
|
if (rm == 4) {
|
||||||
{
|
|
||||||
if (UNLIKELY(off >= len))
|
if (UNLIKELY(off >= len))
|
||||||
return FD_ERR_PARTIAL;
|
return FD_ERR_PARTIAL;
|
||||||
uint8_t sib = buffer[off++];
|
uint8_t sib = buffer[off++];
|
||||||
@@ -547,22 +545,25 @@ direct:
|
|||||||
unsigned idx = (sib & 0x38) >> 3;
|
unsigned idx = (sib & 0x38) >> 3;
|
||||||
idx += prefix_rex & PREFIX_REXX ? 8 : 0;
|
idx += prefix_rex & PREFIX_REXX ? 8 : 0;
|
||||||
base = sib & 0x07;
|
base = sib & 0x07;
|
||||||
if (!vsib && idx == 4)
|
if (idx == 4)
|
||||||
idx = FD_REG_NONE;
|
idx = FD_REG_NONE;
|
||||||
if (vsib && prefix_evex) {
|
|
||||||
// EVEX.V':EVEX.X:SIB.idx
|
|
||||||
idx |= prefix_evex & 0x8 ? 0 : 0x10;
|
|
||||||
}
|
|
||||||
op_modrm->misc = scale | idx;
|
op_modrm->misc = scale | idx;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// VSIB must have a memory operand with SIB byte.
|
|
||||||
if (vsib)
|
|
||||||
return FD_ERR_UD;
|
|
||||||
op_modrm->misc = FD_REG_NONE;
|
op_modrm->misc = FD_REG_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (UNLIKELY(DESC_VSIB(desc))) {
|
||||||
|
// VSIB must have a memory operand with SIB byte.
|
||||||
|
if (rm != 4)
|
||||||
|
return FD_ERR_UD;
|
||||||
|
_Static_assert(FD_REG_NONE == 0x3f, "unexpected FD_REG_NONE");
|
||||||
|
// idx 4 is valid for VSIB
|
||||||
|
if ((op_modrm->misc & 0x3f) == FD_REG_NONE)
|
||||||
|
op_modrm->misc &= 0xc4;
|
||||||
|
if (prefix_evex) // EVEX.V':EVEX.X:SIB.idx
|
||||||
|
op_modrm->misc |= prefix_evex & 0x8 ? 0 : 0x10;
|
||||||
|
}
|
||||||
|
|
||||||
// RIP-relative addressing only if SIB-byte is absent
|
// RIP-relative addressing only if SIB-byte is absent
|
||||||
if (op_byte < 0x40 && rm == 5 && mode == DECODE_64)
|
if (op_byte < 0x40 && rm == 5 && mode == DECODE_64)
|
||||||
op_modrm->reg = FD_REG_IP;
|
op_modrm->reg = FD_REG_IP;
|
||||||
|
|||||||
Reference in New Issue
Block a user