forked from OSchip/llvm-project
Fix disassembler handling of CRC32 which is an odd instruction that uses 0xf2 as an opcode extension and allows the opsize prefix. This necessitated adding IC_XD_OPSIZE and IC_64BIT_XD_OPSIZE contexts. Unfortunately, this increases the size of the disassembler tables. Fixes PR10702.
llvm-svn: 140954
This commit is contained in:
parent
a88cb23da7
commit
88cb33e0d4
|
@ -81,12 +81,15 @@ enum attributeBits {
|
|||
"but not the operands") \
|
||||
ENUM_ENTRY(IC_XS, 2, "may say something about the opcode " \
|
||||
"but not the operands") \
|
||||
ENUM_ENTRY(IC_XD_OPSIZE, 3, "requires an OPSIZE prefix, so " \
|
||||
"operands change width") \
|
||||
ENUM_ENTRY(IC_64BIT_REXW, 4, "requires a REX.W prefix, so operands "\
|
||||
"change width; overrides IC_OPSIZE") \
|
||||
ENUM_ENTRY(IC_64BIT_OPSIZE, 3, "Just as meaningful as IC_OPSIZE") \
|
||||
ENUM_ENTRY(IC_64BIT_XD, 5, "XD instructions are SSE; REX.W is " \
|
||||
"secondary") \
|
||||
ENUM_ENTRY(IC_64BIT_XS, 5, "Just as meaningful as IC_64BIT_XD") \
|
||||
ENUM_ENTRY(IC_64BIT_XD_OPSIZE, 3, "Just as meaningful as IC_XD_OPSIZE") \
|
||||
ENUM_ENTRY(IC_64BIT_REXW_XS, 6, "OPSIZE could mean a different " \
|
||||
"opcode") \
|
||||
ENUM_ENTRY(IC_64BIT_REXW_XD, 6, "Just as meaningful as " \
|
||||
|
|
|
@ -290,3 +290,15 @@
|
|||
|
||||
# CHECK: vroundsd $0, %xmm0, %xmm0, %xmm0
|
||||
0xc4 0xe3 0x79 0x0b 0xc0 0x00
|
||||
|
||||
# CHECK: crc32b %al, %eax
|
||||
0xf2 0x0f 0x38 0xf0 0xc0
|
||||
|
||||
# CHECK: crc32w %ax, %eax
|
||||
0x66 0xf2 0x0f 0x38 0xf1 0xc0
|
||||
|
||||
# CHECK: crc32l %eax, %eax
|
||||
0xf2 0x0f 0x38 0xf1 0xc0
|
||||
|
||||
# CHECK: crc32q %rax, %rax
|
||||
0xf2 0x48 0x0f 0x38 0xf1 0xc0
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
# CHECK: crc32w %ax, %eax
|
||||
0x66 0xf2 0x0f 0x38 0xf1 0xc0
|
||||
|
||||
# CHECK: crc32l %eax, %eax
|
||||
0xf2 0x0f 0x38 0xf1 0xc0
|
||||
|
||||
|
||||
# CHECK: int $33
|
||||
0xCD 0x21
|
||||
|
|
|
@ -51,8 +51,11 @@ static inline bool inheritsFrom(InstructionContext child,
|
|||
return inheritsFrom(child, IC_64BIT_OPSIZE);
|
||||
case IC_XD:
|
||||
return inheritsFrom(child, IC_64BIT_XD);
|
||||
inheritsFrom(child, IC_XD_OPSIZE);
|
||||
case IC_XS:
|
||||
return inheritsFrom(child, IC_64BIT_XS);
|
||||
case IC_XD_OPSIZE:
|
||||
return inheritsFrom(child, IC_64BIT_XD_OPSIZE);
|
||||
case IC_64BIT_REXW:
|
||||
return(inheritsFrom(child, IC_64BIT_REXW_XS) ||
|
||||
inheritsFrom(child, IC_64BIT_REXW_XD) ||
|
||||
|
@ -63,6 +66,8 @@ static inline bool inheritsFrom(InstructionContext child,
|
|||
return(inheritsFrom(child, IC_64BIT_REXW_XD));
|
||||
case IC_64BIT_XS:
|
||||
return(inheritsFrom(child, IC_64BIT_REXW_XS));
|
||||
case IC_64BIT_XD_OPSIZE:
|
||||
return false;
|
||||
case IC_64BIT_REXW_XD:
|
||||
return false;
|
||||
case IC_64BIT_REXW_XS:
|
||||
|
@ -521,6 +526,8 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const {
|
|||
else if ((index & ATTR_64BIT) && (index & ATTR_REXW) &&
|
||||
(index & ATTR_OPSIZE))
|
||||
o << "IC_64BIT_REXW_OPSIZE";
|
||||
else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE))
|
||||
o << "IC_64BIT_XD_OPSIZE";
|
||||
else if ((index & ATTR_64BIT) && (index & ATTR_XS))
|
||||
o << "IC_64BIT_XS";
|
||||
else if ((index & ATTR_64BIT) && (index & ATTR_XD))
|
||||
|
@ -531,6 +538,8 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const {
|
|||
o << "IC_64BIT_REXW";
|
||||
else if ((index & ATTR_64BIT))
|
||||
o << "IC_64BIT";
|
||||
else if ((index & ATTR_XD) && (index & ATTR_OPSIZE))
|
||||
o << "IC_XD_OPSIZE";
|
||||
else if (index & ATTR_XS)
|
||||
o << "IC_XS";
|
||||
else if (index & ATTR_XD)
|
||||
|
|
|
@ -309,13 +309,15 @@ InstructionContext RecognizableInstr::insnContext() const {
|
|||
} else if (Is64Bit || HasREX_WPrefix) {
|
||||
if (HasREX_WPrefix && HasOpSizePrefix)
|
||||
insnContext = IC_64BIT_REXW_OPSIZE;
|
||||
else if (HasOpSizePrefix && (Prefix == X86Local::XD || Prefix == X86Local::TF))
|
||||
insnContext = IC_64BIT_XD_OPSIZE;
|
||||
else if (HasOpSizePrefix)
|
||||
insnContext = IC_64BIT_OPSIZE;
|
||||
else if (HasREX_WPrefix && Prefix == X86Local::XS)
|
||||
insnContext = IC_64BIT_REXW_XS;
|
||||
else if (HasREX_WPrefix && Prefix == X86Local::XD)
|
||||
else if (HasREX_WPrefix && (Prefix == X86Local::XD || Prefix == X86Local::TF))
|
||||
insnContext = IC_64BIT_REXW_XD;
|
||||
else if (Prefix == X86Local::XD)
|
||||
else if (Prefix == X86Local::XD || Prefix == X86Local::TF)
|
||||
insnContext = IC_64BIT_XD;
|
||||
else if (Prefix == X86Local::XS)
|
||||
insnContext = IC_64BIT_XS;
|
||||
|
@ -324,11 +326,12 @@ InstructionContext RecognizableInstr::insnContext() const {
|
|||
else
|
||||
insnContext = IC_64BIT;
|
||||
} else {
|
||||
if (HasOpSizePrefix && Prefix == X86Local::TF)
|
||||
insnContext = IC_XD;
|
||||
if (HasOpSizePrefix &&
|
||||
(Prefix == X86Local::XD || Prefix == X86Local::TF))
|
||||
insnContext = IC_XD_OPSIZE;
|
||||
else if (HasOpSizePrefix)
|
||||
insnContext = IC_OPSIZE;
|
||||
else if (Prefix == X86Local::XD)
|
||||
else if (Prefix == X86Local::XD || Prefix == X86Local::TF)
|
||||
insnContext = IC_XD;
|
||||
else if (Prefix == X86Local::XS || Prefix == X86Local::REP)
|
||||
insnContext = IC_XS;
|
||||
|
@ -402,7 +405,7 @@ RecognizableInstr::filter_ret RecognizableInstr::filter() const {
|
|||
// Filter out alternate forms of AVX instructions
|
||||
if (Name.find("_alt") != Name.npos ||
|
||||
Name.find("XrYr") != Name.npos ||
|
||||
Name.find("r64r") != Name.npos ||
|
||||
(Name.find("r64r") != Name.npos && Name.find("r64r64") == Name.npos) ||
|
||||
Name.find("_64mr") != Name.npos ||
|
||||
Name.find("Xrr") != Name.npos ||
|
||||
Name.find("rr64") != Name.npos)
|
||||
|
|
Loading…
Reference in New Issue