[X86] Teach the disassembler that some instructions use VEX.W==0 without a corresponding VEX.W==1 instruction and we shouldn't treat them as if VEX.W is ignored.

Fixes PR11304.

llvm-svn: 316285
This commit is contained in:
Craig Topper 2017-10-22 06:18:26 +00:00
parent a33846aca6
commit e975127db6
4 changed files with 32 additions and 16 deletions

View File

@ -4,3 +4,14 @@
# 64: warning: invalid instruction encoding # 64: warning: invalid instruction encoding
# 32: into # 32: into
0xce 0xce
# 64: invalid instruction encoding
0xc4,0x62,0xf9,0x18,0x20
# 64: invalid instruction encoding
0xc4,0x62,0xfd,0x18,0x20
# 64: invalid instruction encoding
0xc4,0xc2,0xfd,0x19,0xcc
# 64: invalid instruction encoding
0xc4,0xe2,0xfd,0x1a,0x08
# 64: invalid instruction encoding
0xc4,0xe3,0xfd,0x39,0xc5,0x01

View File

@ -75,7 +75,8 @@ static inline const char* stringForOperandEncoding(OperandEncoding encoding) {
/// @return - True if child is a subset of parent, false otherwise. /// @return - True if child is a subset of parent, false otherwise.
static inline bool inheritsFrom(InstructionContext child, static inline bool inheritsFrom(InstructionContext child,
InstructionContext parent, InstructionContext parent,
bool VEX_LIG = false, bool AdSize64 = false) { bool VEX_LIG = false, bool VEX_WIG = false,
bool AdSize64 = false) {
if (child == parent) if (child == parent)
return true; return true;
@ -133,20 +134,20 @@ static inline bool inheritsFrom(InstructionContext child,
case IC_64BIT_REXW_ADSIZE: case IC_64BIT_REXW_ADSIZE:
return false; return false;
case IC_VEX: case IC_VEX:
return (VEX_LIG && inheritsFrom(child, IC_VEX_L_W)) || return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W)) ||
inheritsFrom(child, IC_VEX_W) || (VEX_WIG && inheritsFrom(child, IC_VEX_W)) ||
(VEX_LIG && inheritsFrom(child, IC_VEX_L)); (VEX_LIG && inheritsFrom(child, IC_VEX_L));
case IC_VEX_XS: case IC_VEX_XS:
return (VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XS)) || return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W_XS)) ||
inheritsFrom(child, IC_VEX_W_XS) || (VEX_WIG && inheritsFrom(child, IC_VEX_W_XS)) ||
(VEX_LIG && inheritsFrom(child, IC_VEX_L_XS)); (VEX_LIG && inheritsFrom(child, IC_VEX_L_XS));
case IC_VEX_XD: case IC_VEX_XD:
return (VEX_LIG && inheritsFrom(child, IC_VEX_L_W_XD)) || return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W_XD)) ||
inheritsFrom(child, IC_VEX_W_XD) || (VEX_WIG && inheritsFrom(child, IC_VEX_W_XD)) ||
(VEX_LIG && inheritsFrom(child, IC_VEX_L_XD)); (VEX_LIG && inheritsFrom(child, IC_VEX_L_XD));
case IC_VEX_OPSIZE: case IC_VEX_OPSIZE:
return (VEX_LIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE)) || return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE)) ||
inheritsFrom(child, IC_VEX_W_OPSIZE) || (VEX_WIG && inheritsFrom(child, IC_VEX_W_OPSIZE)) ||
(VEX_LIG && inheritsFrom(child, IC_VEX_L_OPSIZE)); (VEX_LIG && inheritsFrom(child, IC_VEX_L_OPSIZE));
case IC_VEX_W: case IC_VEX_W:
return VEX_LIG && inheritsFrom(child, IC_VEX_L_W); return VEX_LIG && inheritsFrom(child, IC_VEX_L_W);
@ -157,13 +158,13 @@ static inline bool inheritsFrom(InstructionContext child,
case IC_VEX_W_OPSIZE: case IC_VEX_W_OPSIZE:
return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE); return VEX_LIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE);
case IC_VEX_L: case IC_VEX_L:
return inheritsFrom(child, IC_VEX_L_W); return VEX_WIG && inheritsFrom(child, IC_VEX_L_W);
case IC_VEX_L_XS: case IC_VEX_L_XS:
return inheritsFrom(child, IC_VEX_L_W_XS); return VEX_WIG && inheritsFrom(child, IC_VEX_L_W_XS);
case IC_VEX_L_XD: case IC_VEX_L_XD:
return inheritsFrom(child, IC_VEX_L_W_XD); return VEX_WIG && inheritsFrom(child, IC_VEX_L_W_XD);
case IC_VEX_L_OPSIZE: case IC_VEX_L_OPSIZE:
return inheritsFrom(child, IC_VEX_L_W_OPSIZE); return VEX_WIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE);
case IC_VEX_L_W: case IC_VEX_L_W:
case IC_VEX_L_W_XS: case IC_VEX_L_W_XS:
case IC_VEX_L_W_XD: case IC_VEX_L_W_XD:
@ -909,6 +910,7 @@ void DisassemblerTables::setTableFields(OpcodeType type,
InstrUID uid, InstrUID uid,
bool is32bit, bool is32bit,
bool ignoresVEX_L, bool ignoresVEX_L,
bool ignoresVEX_W,
unsigned addressSize) { unsigned addressSize) {
ContextDecision &decision = *Tables[type]; ContextDecision &decision = *Tables[type];
@ -920,7 +922,7 @@ void DisassemblerTables::setTableFields(OpcodeType type,
bool adSize64 = addressSize == 64; bool adSize64 = addressSize == 64;
if (inheritsFrom((InstructionContext)index, if (inheritsFrom((InstructionContext)index,
InstructionSpecifiers[uid].insnContext, ignoresVEX_L, InstructionSpecifiers[uid].insnContext, ignoresVEX_L,
adSize64)) ignoresVEX_W, adSize64))
setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode], setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode],
filter, filter,
uid, uid,

View File

@ -253,6 +253,7 @@ public:
InstrUID uid, InstrUID uid,
bool is32bit, bool is32bit,
bool ignoresVEX_L, bool ignoresVEX_L,
bool ignoresVEX_W,
unsigned AddrSize); unsigned AddrSize);
/// specForUID - Returns the instruction specifier for a given unique /// specForUID - Returns the instruction specifier for a given unique

View File

@ -800,13 +800,15 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
insnContext(), insnContext(),
currentOpcode, currentOpcode,
*filter, *filter,
UID, Is32Bit, IgnoresVEX_L, AddressSize); UID, Is32Bit, IgnoresVEX_L,
VEX_WPrefix == X86Local::VEX_WIG, AddressSize);
} else { } else {
tables.setTableFields(opcodeType, tables.setTableFields(opcodeType,
insnContext(), insnContext(),
opcodeToSet, opcodeToSet,
*filter, *filter,
UID, Is32Bit, IgnoresVEX_L, AddressSize); UID, Is32Bit, IgnoresVEX_L,
VEX_WPrefix == X86Local::VEX_WIG, AddressSize);
} }
delete filter; delete filter;