]> granicus.if.org Git - llvm/commitdiff
[X86] Fix disassembly of EVEX rounding control and SAE instructions.
authorCraig Topper <craig.topper@intel.com>
Mon, 23 Oct 2017 02:26:24 +0000 (02:26 +0000)
committerCraig Topper <craig.topper@intel.com>
Mon, 23 Oct 2017 02:26:24 +0000 (02:26 +0000)
Fixes PR31955.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316308 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/Disassembler/X86Disassembler.cpp
lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h
test/MC/Disassembler/X86/avx-512.txt
utils/TableGen/X86DisassemblerTables.cpp
utils/TableGen/X86RecognizableInstr.cpp
utils/TableGen/X86RecognizableInstr.h

index e38c0bc53c71fa03279750779ce9fb6b85795fcd..c58254ae38c193ec2f33ebd7763ed2e9032e1641 100644 (file)
@@ -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:
index e781c98b0bc94d16a1ab25526114e642941c6c0a..80acff22f7bc060caac3e849b22c64764f5fac26 100644 (file)
@@ -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;
index 6e0bbb2fc2ea20c265f8b52994df79134203b3fa..ecd9d8dccafaa5e0694690d07192a7275b0b9593 100644 (file)
@@ -644,6 +644,9 @@ struct InternalInstruction {
   uint8_t                       sibScale;
   SIBBase                       sibBase;
 
+  // Embedded rounding control.
+  uint8_t                       RC;
+
   ArrayRef<OperandSpecifier> operands;
 };
 
index 9169d1aeef12cae97cbe3562bf85d9352d97a104..ad1404860fb6b8e6940105701038325f20a96116 100644 (file)
@@ -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 "   \
index 7eda07f0d30cc094e9ee7240436fd61977a19ef9..f617451bc96c35e397e4e96de88439b359ebe77d 100644 (file)
 
 # 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
index 8c69dfb01a2e5ab759a300e9b7b4239933a94a02..027cca74b5263e133a906b2d43a29768b3f24961 100644 (file)
@@ -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;
index ec8580234d1ff5598d9714cdfd7adfe69d43544f..4f5b03d7801874343b1b5206cb7c6bf3016a1288 100644 (file)
@@ -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)
index ea99935f8790922ec3ad34555a6a4fad41314df7..24509d16d6380fe77c6df948d429016fe31822d4 100644 (file)
@@ -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