From: Craig Topper Date: Mon, 23 Oct 2017 02:26:24 +0000 (+0000) Subject: [X86] Fix disassembly of EVEX rounding control and SAE instructions. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0f7dce5b5ce30c25f17d1c60d9e4017ef96f62c5;p=llvm [X86] Fix disassembly of EVEX rounding control and SAE instructions. Fixes PR31955. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316308 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/Disassembler/X86Disassembler.cpp b/lib/Target/X86/Disassembler/X86Disassembler.cpp index e38c0bc53c7..c58254ae38c 100644 --- a/lib/Target/X86/Disassembler/X86Disassembler.cpp +++ b/lib/Target/X86/Disassembler/X86Disassembler.cpp @@ -959,6 +959,9 @@ static bool translateOperand(MCInst &mcInst, const OperandSpecifier &operand, insn, Dis); return false; + case ENCODING_IRC: + mcInst.addOperand(MCOperand::createImm(insn.RC)); + return false; case ENCODING_SI: return translateSrcIndex(mcInst, insn); case ENCODING_DI: diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp index e781c98b0bc..80acff22f7b 100644 --- a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp +++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp @@ -1803,6 +1803,10 @@ static int readOperands(struct InternalInstruction* insn) { if (readImmediate(insn, insn->addressSize)) return -1; break; + case ENCODING_IRC: + insn->RC = (l2FromEVEX4of4(insn->vectorExtensionPrefix[3]) << 1) | + lFromEVEX4of4(insn->vectorExtensionPrefix[3]); + break; case ENCODING_RB: if (readOpcodeRegister(insn, 1)) return -1; diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h index 6e0bbb2fc2e..ecd9d8dccaf 100644 --- a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h +++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h @@ -644,6 +644,9 @@ struct InternalInstruction { uint8_t sibScale; SIBBase sibBase; + // Embedded rounding control. + uint8_t RC; + ArrayRef operands; }; diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h b/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h index 9169d1aeef1..ad1404860fb 100644 --- a/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h +++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h @@ -382,6 +382,7 @@ enum ModRMDecisionType { \ ENUM_ENTRY(ENCODING_Iv, "Immediate of operand size") \ ENUM_ENTRY(ENCODING_Ia, "Immediate of address size") \ + ENUM_ENTRY(ENCODING_IRC, "Immediate for static rounding control") \ ENUM_ENTRY(ENCODING_Rv, "Register code of operand size added to the " \ "opcode byte") \ ENUM_ENTRY(ENCODING_DUP, "Duplicate of another operand; ID is encoded " \ diff --git a/test/MC/Disassembler/X86/avx-512.txt b/test/MC/Disassembler/X86/avx-512.txt index 7eda07f0d30..f617451bc96 100644 --- a/test/MC/Disassembler/X86/avx-512.txt +++ b/test/MC/Disassembler/X86/avx-512.txt @@ -288,3 +288,83 @@ # AVX512VPOPCNTDQ: vpopcntq (%rcx), %zmm17 0x62 0xe2 0xfd 0x48 0x55 0x09 + +##################################################### +# SAE ATTRIBUTE # +##################################################### + +# CHECK: vcomisd {sae}, %xmm2, %xmm1 +0x62 0xf1 0xfd 0x18 0x2f 0xca + +# Same as above but ignore EVEX L'L bits. +# CHECK: vcomisd {sae}, %xmm2, %xmm1 +0x62 0xf1 0xfd 0x78 0x2f 0xca + +# CHECK: vminpd {sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe1 0xf5 0x10 0x5d 0xda + +# Ignore EVEX L'L bits. +# CHECK: vminpd {sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe1 0xf5 0x30 0x5d 0xda + +# Ignore EVEX L'L bits. +# CHECK: vminpd {sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe1 0xf5 0x50 0x5d 0xda + +# Ignore EVEX L'L bits. +# CHECK: vminpd {sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe1 0xf5 0x70 0x5d 0xda + +# CHECK: vcmppd $127, {sae}, %zmm27, %zmm11, %k4 +0x62 0x91 0xa5 0x18 0xc2 0xe3 0x7f + +# CHECK: vrsqrt28pd {sae}, %zmm2, %zmm17 +0x62 0xe2 0xfd 0x18 0xcc 0xca + +##################################################### +# ROUNDING CONTROL # +##################################################### + +# Verify all rounding modes work. + +# CHECK: vaddps {rn-sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe1 0x74 0x10 0x58 0xda + +# CHECK: vaddps {rd-sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe1 0x74 0x30 0x58 0xda + +# CHECK: vaddps {ru-sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe1 0x74 0x50 0x58 0xda + +# CHECK: vaddps {rz-sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe1 0x74 0x70 0x58 0xda + +# CHECK: vmulss {rn-sae}, %xmm2, %xmm17, %xmm19 +0x62 0xe1 0x76 0x10 0x59 0xda + +# CHECK: vmulss {rd-sae}, %xmm2, %xmm17, %xmm19 +0x62 0xe1 0x76 0x30 0x59 0xda + +# CHECK: vmulss {ru-sae}, %xmm2, %xmm17, %xmm19 +0x62 0xe1 0x76 0x50 0x59 0xda + +# CHECK: vmulss {rz-sae}, %xmm2, %xmm17, %xmm19 +0x62 0xe1 0x76 0x70 0x59 0xda + +# CHECK: vscalefpd {rn-sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe2 0xf5 0x10 0x2c 0xda + +# CHECK: vscalefpd {rd-sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe2 0xf5 0x30 0x2c 0xda + +# CHECK: vscalefpd {ru-sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe2 0xf5 0x50 0x2c 0xda + +# CHECK: vscalefpd {rz-sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe2 0xf5 0x70 0x2c 0xda + +# CHECK: vcvtqq2ps {rd-sae}, %zmm2, %ymm17 +0x62 0xe1 0xfc 0x38 0x5b 0xca + +# CHECK: vsqrtpd {rd-sae}, %zmm2, %zmm17 +0x62 0xe1 0xfd 0x38 0x51 0xca diff --git a/utils/TableGen/X86DisassemblerTables.cpp b/utils/TableGen/X86DisassemblerTables.cpp index 8c69dfb01a2..027cca74b52 100644 --- a/utils/TableGen/X86DisassemblerTables.cpp +++ b/utils/TableGen/X86DisassemblerTables.cpp @@ -357,87 +357,192 @@ static inline bool inheritsFrom(InstructionContext child, case IC_EVEX_L2_W_OPSIZE_KZ: return false; case IC_EVEX_B: - return false; - case IC_EVEX_L_K_B: - case IC_EVEX_L_KZ_B: - case IC_EVEX_L_B: - return false; - case IC_EVEX_XS_K_B: - case IC_EVEX_XS_KZ_B: - return false; - case IC_EVEX_XD_K_B: - case IC_EVEX_XD_KZ_B: - return false; + return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_B)) || + (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_B)) || + (VEX_WIG && inheritsFrom(child, IC_EVEX_W_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_B)); case IC_EVEX_XS_B: + return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_B)) || + (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_B)) || + (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_B)); case IC_EVEX_XD_B: - case IC_EVEX_K_B: - return false; - case IC_EVEX_KZ_B: + return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_B)) || + (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_B)) || + (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_B)); case IC_EVEX_OPSIZE_B: + return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_B)) || + (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_B)) || + (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_B)); + case IC_EVEX_K_B: + return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_K_B)) || + (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_K_B)) || + (VEX_WIG && inheritsFrom(child, IC_EVEX_W_K_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L_K_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_K_B)); + case IC_EVEX_XS_K_B: + return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K_B)) || + (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K_B)) || + (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS_K_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_K_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_K_B)); + case IC_EVEX_XD_K_B: + return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K_B)) || + (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K_B)) || + (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD_K_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_K_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_K_B)); case IC_EVEX_OPSIZE_K_B: + return (VEX_LIG && VEX_WIG && + inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K_B)) || + (VEX_LIG && VEX_WIG && + inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K_B)) || + (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_K_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_K_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_K_B)); + case IC_EVEX_KZ_B: + return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_KZ_B)) || + (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ_B)) || + (VEX_WIG && inheritsFrom(child, IC_EVEX_W_KZ_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L_KZ_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_KZ_B)); + case IC_EVEX_XS_KZ_B: + return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ_B)) || + (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ_B)) || + (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XS_KZ_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XS_KZ_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XS_KZ_B)); + case IC_EVEX_XD_KZ_B: + return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ_B)) || + (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ_B)) || + (VEX_WIG && inheritsFrom(child, IC_EVEX_W_XD_KZ_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L_XD_KZ_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_XD_KZ_B)); case IC_EVEX_OPSIZE_KZ_B: - return false; + return (VEX_LIG && VEX_WIG && + inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ_B)) || + (VEX_LIG && VEX_WIG && + inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ_B)) || + (VEX_WIG && inheritsFrom(child, IC_EVEX_W_OPSIZE_KZ_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L_OPSIZE_KZ_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_OPSIZE_KZ_B)); case IC_EVEX_W_B: - case IC_EVEX_W_K_B: - case IC_EVEX_W_KZ_B: - case IC_EVEX_W_OPSIZE_B: - case IC_EVEX_W_OPSIZE_K_B: - return false; - case IC_EVEX_L_XD_B: - case IC_EVEX_L_XD_K_B: - case IC_EVEX_L_OPSIZE_B: - case IC_EVEX_L_OPSIZE_K_B: - return false; + return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_B)); case IC_EVEX_W_XS_B: + return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_B)); case IC_EVEX_W_XD_B: + return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_B)); + case IC_EVEX_W_OPSIZE_B: + return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_B)); + case IC_EVEX_W_K_B: + return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_K_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_K_B)); case IC_EVEX_W_XS_K_B: + return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_K_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K_B)); case IC_EVEX_W_XD_K_B: + return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_K_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K_B)); + case IC_EVEX_W_OPSIZE_K_B: + return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K_B)); + case IC_EVEX_W_KZ_B: + return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_KZ_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_KZ_B)); case IC_EVEX_W_XS_KZ_B: + return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ_B)); case IC_EVEX_W_XD_KZ_B: + return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ_B)); case IC_EVEX_W_OPSIZE_KZ_B: - return false; + return (VEX_LIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ_B)) || + (VEX_LIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ_B)); + case IC_EVEX_L_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_B); case IC_EVEX_L_XS_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_B); + case IC_EVEX_L_XD_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_B); + case IC_EVEX_L_OPSIZE_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_B); + case IC_EVEX_L_K_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_K_B); case IC_EVEX_L_XS_K_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_K_B); + case IC_EVEX_L_XD_K_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_K_B); + case IC_EVEX_L_OPSIZE_K_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_K_B); + case IC_EVEX_L_KZ_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_KZ_B); case IC_EVEX_L_XS_KZ_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XS_KZ_B); case IC_EVEX_L_XD_KZ_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_XD_KZ_B); case IC_EVEX_L_OPSIZE_KZ_B: - return false; + return VEX_WIG && inheritsFrom(child, IC_EVEX_L_W_OPSIZE_KZ_B); case IC_EVEX_L_W_B: - case IC_EVEX_L_W_K_B: case IC_EVEX_L_W_XS_B: - case IC_EVEX_L_W_XS_K_B: - case IC_EVEX_L_W_XS_KZ_B: + case IC_EVEX_L_W_XD_B: case IC_EVEX_L_W_OPSIZE_B: + return false; + case IC_EVEX_L_W_K_B: + case IC_EVEX_L_W_XS_K_B: + case IC_EVEX_L_W_XD_K_B: case IC_EVEX_L_W_OPSIZE_K_B: + return false; case IC_EVEX_L_W_KZ_B: - case IC_EVEX_L_W_XD_B: - case IC_EVEX_L_W_XD_K_B: + case IC_EVEX_L_W_XS_KZ_B: case IC_EVEX_L_W_XD_KZ_B: case IC_EVEX_L_W_OPSIZE_KZ_B: return false; case IC_EVEX_L2_B: - case IC_EVEX_L2_K_B: - case IC_EVEX_L2_KZ_B: - case IC_EVEX_L2_XS_K_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_B); case IC_EVEX_L2_XS_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_B); case IC_EVEX_L2_XD_B: - case IC_EVEX_L2_XD_K_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_B); case IC_EVEX_L2_OPSIZE_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_B); + case IC_EVEX_L2_K_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_K_B); + case IC_EVEX_L2_XS_K_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_K_B); + case IC_EVEX_L2_XD_K_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_K_B); case IC_EVEX_L2_OPSIZE_K_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_K_B); + case IC_EVEX_L2_KZ_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_KZ_B); case IC_EVEX_L2_XS_KZ_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XS_KZ_B); case IC_EVEX_L2_XD_KZ_B: + return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_XD_KZ_B); case IC_EVEX_L2_OPSIZE_KZ_B: - return false; + return VEX_WIG && inheritsFrom(child, IC_EVEX_L2_W_OPSIZE_KZ_B); case IC_EVEX_L2_W_B: - case IC_EVEX_L2_W_K_B: - case IC_EVEX_L2_W_KZ_B: case IC_EVEX_L2_W_XS_B: - case IC_EVEX_L2_W_XS_K_B: case IC_EVEX_L2_W_XD_B: case IC_EVEX_L2_W_OPSIZE_B: + return false; + case IC_EVEX_L2_W_K_B: + case IC_EVEX_L2_W_XS_K_B: + case IC_EVEX_L2_W_XD_K_B: case IC_EVEX_L2_W_OPSIZE_K_B: + return false; + case IC_EVEX_L2_W_KZ_B: case IC_EVEX_L2_W_XS_KZ_B: - case IC_EVEX_L2_W_XD_K_B: case IC_EVEX_L2_W_XD_KZ_B: case IC_EVEX_L2_W_OPSIZE_KZ_B: return false; diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index ec8580234d1..4f5b03d7801 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -100,6 +100,9 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables, HasVEX_LPrefix = Rec->getValueAsBit("hasVEX_L"); + EncodeRC = HasEVEX_B && + (Form == X86Local::MRMDestReg || Form == X86Local::MRMSrcReg); + // Check for 64-bit inst which does not require REX Is32Bit = false; Is64Bit = false; @@ -161,7 +164,7 @@ InstructionContext RecognizableInstr::insnContext() const { llvm_unreachable("Don't support VEX.L if EVEX_L2 is enabled"); } // VEX_L & VEX_W - if (HasVEX_LPrefix && VEX_WPrefix == X86Local::VEX_W1) { + if (!EncodeRC && HasVEX_LPrefix && VEX_WPrefix == X86Local::VEX_W1) { if (OpPrefix == X86Local::PD) insnContext = EVEX_KB(IC_EVEX_L_W_OPSIZE); else if (OpPrefix == X86Local::XS) @@ -174,7 +177,7 @@ InstructionContext RecognizableInstr::insnContext() const { errs() << "Instruction does not use a prefix: " << Name << "\n"; llvm_unreachable("Invalid prefix"); } - } else if (HasVEX_LPrefix) { + } else if (!EncodeRC && HasVEX_LPrefix) { // VEX_L if (OpPrefix == X86Local::PD) insnContext = EVEX_KB(IC_EVEX_L_OPSIZE); @@ -188,8 +191,8 @@ InstructionContext RecognizableInstr::insnContext() const { errs() << "Instruction does not use a prefix: " << Name << "\n"; llvm_unreachable("Invalid prefix"); } - } - else if (HasEVEX_L2Prefix && VEX_WPrefix == X86Local::VEX_W1) { + } else if (!EncodeRC && HasEVEX_L2Prefix && + VEX_WPrefix == X86Local::VEX_W1) { // EVEX_L2 & VEX_W if (OpPrefix == X86Local::PD) insnContext = EVEX_KB(IC_EVEX_L2_W_OPSIZE); @@ -203,7 +206,7 @@ InstructionContext RecognizableInstr::insnContext() const { errs() << "Instruction does not use a prefix: " << Name << "\n"; llvm_unreachable("Invalid prefix"); } - } else if (HasEVEX_L2Prefix) { + } else if (!EncodeRC && HasEVEX_L2Prefix) { // EVEX_L2 if (OpPrefix == X86Local::PD) insnContext = EVEX_KB(IC_EVEX_L2_OPSIZE); @@ -796,18 +799,12 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { for (currentOpcode = opcodeToSet; currentOpcode < opcodeToSet + 8; ++currentOpcode) - tables.setTableFields(opcodeType, - insnContext(), - currentOpcode, - *filter, - UID, Is32Bit, IgnoresVEX_L, + tables.setTableFields(opcodeType, insnContext(), currentOpcode, *filter, + UID, Is32Bit, IgnoresVEX_L || EncodeRC, VEX_WPrefix == X86Local::VEX_WIG, AddressSize); } else { - tables.setTableFields(opcodeType, - insnContext(), - opcodeToSet, - *filter, - UID, Is32Bit, IgnoresVEX_L, + tables.setTableFields(opcodeType, insnContext(), opcodeToSet, *filter, UID, + Is32Bit, IgnoresVEX_L || EncodeRC, VEX_WPrefix == X86Local::VEX_WIG, AddressSize); } @@ -964,7 +961,7 @@ RecognizableInstr::immediateEncodingFromString(const std::string &s, ENCODING("XOPCC", ENCODING_IB) ENCODING("AVXCC", ENCODING_IB) ENCODING("AVX512ICC", ENCODING_IB) - ENCODING("AVX512RC", ENCODING_IB) + ENCODING("AVX512RC", ENCODING_IRC) ENCODING("i16imm", ENCODING_Iv) ENCODING("i16i8imm", ENCODING_IB) ENCODING("i32imm", ENCODING_Iv) diff --git a/utils/TableGen/X86RecognizableInstr.h b/utils/TableGen/X86RecognizableInstr.h index ea99935f879..24509d16d63 100644 --- a/utils/TableGen/X86RecognizableInstr.h +++ b/utils/TableGen/X86RecognizableInstr.h @@ -191,6 +191,8 @@ private: bool HasEVEX_KZ; /// The hasEVEX_B field from the record bool HasEVEX_B; + /// Indicates that the instruction uses the L and L' fields for RC. + bool EncodeRC; /// The isCodeGenOnly field from the record bool IsCodeGenOnly; /// The ForceDisassemble field from the record