[llvm] eb1248f - [X86][MC] Add missing support for pseudo rex/rex2 prefix in assembler

Shengchen Kan via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 13 19:19:13 PDT 2024


Author: Shengchen Kan
Date: 2024-06-14T10:18:21+08:00
New Revision: eb1248f20a86eb1bc8a7cc61d4ce71293a6caa75

URL: https://github.com/llvm/llvm-project/commit/eb1248f20a86eb1bc8a7cc61d4ce71293a6caa75
DIFF: https://github.com/llvm/llvm-project/commit/eb1248f20a86eb1bc8a7cc61d4ce71293a6caa75.diff

LOG: [X86][MC] Add missing support for pseudo rex/rex2 prefix in assembler

This fixes https://github.com/llvm/llvm-project/issues/95417

Added: 
    llvm/test/MC/X86/apx/pseudo-rex2.s
    llvm/test/MC/X86/pseudo-rex.s

Modified: 
    llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
    llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
    llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
    llvm/test/MC/X86/x86_errors.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index ffd66aa800584..c0f54b223877c 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -90,6 +90,8 @@ class X86AsmParser : public MCTargetAsmParser {
 
   enum OpcodePrefix {
     OpcodePrefix_Default,
+    OpcodePrefix_REX,
+    OpcodePrefix_REX2,
     OpcodePrefix_VEX,
     OpcodePrefix_VEX2,
     OpcodePrefix_VEX3,
@@ -3201,7 +3203,11 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
         return Error(Parser.getTok().getLoc(), "Expected '}'");
       Parser.Lex(); // Eat curly.
 
-      if (Prefix == "vex")
+      if (Prefix == "rex")
+        ForcedOpcodePrefix = OpcodePrefix_REX;
+      else if (Prefix == "rex2")
+        ForcedOpcodePrefix = OpcodePrefix_REX2;
+      else if (Prefix == "vex")
         ForcedOpcodePrefix = OpcodePrefix_VEX;
       else if (Prefix == "vex2")
         ForcedOpcodePrefix = OpcodePrefix_VEX2;
@@ -4025,9 +4031,13 @@ bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
 
   MCInst Inst;
 
-  // If VEX/EVEX encoding is forced, we need to pass the USE_* flag to the
-  // encoder and printer.
-  if (ForcedOpcodePrefix == OpcodePrefix_VEX)
+  // If REX/REX2/VEX/EVEX encoding is forced, we need to pass the USE_* flag to
+  // the encoder and printer.
+  if (ForcedOpcodePrefix == OpcodePrefix_REX)
+    Prefixes |= X86::IP_USE_REX;
+  else if (ForcedOpcodePrefix == OpcodePrefix_REX2)
+    Prefixes |= X86::IP_USE_REX2;
+  else if (ForcedOpcodePrefix == OpcodePrefix_VEX)
     Prefixes |= X86::IP_USE_VEX;
   else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)
     Prefixes |= X86::IP_USE_VEX2;
@@ -4095,24 +4105,34 @@ bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
 unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
   unsigned Opc = Inst.getOpcode();
   const MCInstrDesc &MCID = MII.get(Opc);
+  uint64_t TSFlags = MCID.TSFlags;
 
   if (UseApxExtendedReg && !X86II::canUseApxExtendedReg(MCID))
     return Match_Unsupported;
-  if (ForcedNoFlag == !(MCID.TSFlags & X86II::EVEX_NF) && !X86::isCFCMOVCC(Opc))
+  if (ForcedNoFlag == !(TSFlags & X86II::EVEX_NF) && !X86::isCFCMOVCC(Opc))
     return Match_Unsupported;
 
-  if (ForcedOpcodePrefix == OpcodePrefix_EVEX &&
-      (MCID.TSFlags & X86II::EncodingMask) != X86II::EVEX)
-    return Match_Unsupported;
-
-  if ((ForcedOpcodePrefix == OpcodePrefix_VEX ||
-       ForcedOpcodePrefix == OpcodePrefix_VEX2 ||
-       ForcedOpcodePrefix == OpcodePrefix_VEX3) &&
-      (MCID.TSFlags & X86II::EncodingMask) != X86II::VEX)
-    return Match_Unsupported;
+  switch (ForcedOpcodePrefix) {
+  case OpcodePrefix_Default:
+    break;
+  case OpcodePrefix_REX:
+  case OpcodePrefix_REX2:
+    if (TSFlags & X86II::EncodingMask)
+      return Match_Unsupported;
+    break;
+  case OpcodePrefix_VEX:
+  case OpcodePrefix_VEX2:
+  case OpcodePrefix_VEX3:
+    if ((TSFlags & X86II::EncodingMask) != X86II::VEX)
+      return Match_Unsupported;
+    break;
+  case OpcodePrefix_EVEX:
+    if ((TSFlags & X86II::EncodingMask) != X86II::EVEX)
+      return Match_Unsupported;
+    break;
+  }
 
-  if ((MCID.TSFlags & X86II::ExplicitOpPrefixMask) ==
-          X86II::ExplicitVEXPrefix &&
+  if ((TSFlags & X86II::ExplicitOpPrefixMask) == X86II::ExplicitVEXPrefix &&
       (ForcedOpcodePrefix != OpcodePrefix_VEX &&
        ForcedOpcodePrefix != OpcodePrefix_VEX2 &&
        ForcedOpcodePrefix != OpcodePrefix_VEX3))

diff  --git a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
index 8e40157836415..a89408bb79b06 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
@@ -56,12 +56,14 @@ enum IPREFIXES {
   IP_HAS_REPEAT = 1U << 3,
   IP_HAS_LOCK = 1U << 4,
   IP_HAS_NOTRACK = 1U << 5,
-  IP_USE_VEX = 1U << 6,
-  IP_USE_VEX2 = 1U << 7,
-  IP_USE_VEX3 = 1U << 8,
-  IP_USE_EVEX = 1U << 9,
-  IP_USE_DISP8 = 1U << 10,
-  IP_USE_DISP32 = 1U << 11,
+  IP_USE_REX = 1U << 6,
+  IP_USE_REX2 = 1U << 7,
+  IP_USE_VEX = 1U << 8,
+  IP_USE_VEX2 = 1U << 9,
+  IP_USE_VEX3 = 1U << 10,
+  IP_USE_EVEX = 1U << 11,
+  IP_USE_DISP8 = 1U << 12,
+  IP_USE_DISP32 = 1U << 13,
 };
 
 enum OperandType : unsigned {

diff  --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index b4633b91bee32..72219c136c7e1 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -1365,7 +1365,10 @@ PrefixKind X86MCCodeEmitter::emitREXPrefix(int MemOperand, const MCInst &MI,
       }
     }
   }
-  if ((TSFlags & X86II::ExplicitOpPrefixMask) == X86II::ExplicitREX2Prefix)
+  if (MI.getFlags() & X86::IP_USE_REX)
+    Prefix.setLowerBound(REX);
+  if ((TSFlags & X86II::ExplicitOpPrefixMask) == X86II::ExplicitREX2Prefix ||
+      MI.getFlags() & X86::IP_USE_REX2)
     Prefix.setLowerBound(REX2);
   switch (TSFlags & X86II::FormMask) {
   default:

diff  --git a/llvm/test/MC/X86/apx/pseudo-rex2.s b/llvm/test/MC/X86/apx/pseudo-rex2.s
new file mode 100644
index 0000000000000..bbe1508524381
--- /dev/null
+++ b/llvm/test/MC/X86/apx/pseudo-rex2.s
@@ -0,0 +1,9 @@
+# RUN: llvm-mc -triple x86_64 -show-encoding %s | FileCheck %s
+
+# CHECK: addl    %ebx, %ecx
+# CHECK: encoding: [0xd5,0x00,0x01,0xd9]
+{rex2} addl %ebx, %ecx
+
+# CHECK: popcntl %edi, %esi
+# CHECK: encoding: [0xf3,0xd5,0x80,0xb8,0xf7]
+{rex2} popcnt %edi,%esi

diff  --git a/llvm/test/MC/X86/pseudo-rex.s b/llvm/test/MC/X86/pseudo-rex.s
new file mode 100644
index 0000000000000..fc4c4dad54343
--- /dev/null
+++ b/llvm/test/MC/X86/pseudo-rex.s
@@ -0,0 +1,9 @@
+# RUN: llvm-mc -triple x86_64 -show-encoding %s | FileCheck %s
+
+# CHECK: addl    %ebx, %ecx
+# CHECK: encoding: [0x40,0x01,0xd9]
+{rex} addl %ebx, %ecx
+
+# CHECK: popcntl %edi, %esi
+# CHECK: encoding: [0xf3,0x40,0x0f,0xb8,0xf7]
+{rex} popcnt %edi,%esi

diff  --git a/llvm/test/MC/X86/x86_errors.s b/llvm/test/MC/X86/x86_errors.s
index da8659f3621e3..543575f38815a 100644
--- a/llvm/test/MC/X86/x86_errors.s
+++ b/llvm/test/MC/X86/x86_errors.s
@@ -168,6 +168,14 @@ cltq
 // X86: error: instruction requires: 64-bit mode
 cmpxchg16b (%eax)
 
+// X86: error: unsupported instruction
+// X64: error: unsupported instruction
+{rex} vmovdqu32 %xmm0, %xmm0
+
+// X86: error: unsupported instruction
+// X64: error: unsupported instruction
+{rex2} vmovdqu32 %xmm0, %xmm0
+
 // X86: error: unsupported instruction
 // X64: error: unsupported instruction
 {vex} vmovdqu32 %xmm0, %xmm0


        


More information about the llvm-commits mailing list