Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[X86] Support promoted ENQCMD, KEYLOCKER and USERMSR #77293

Merged
merged 14 commits into from
Jan 26, 2024

Conversation

XinWang10
Copy link
Contributor

@XinWang10 XinWang10 commented Jan 8, 2024

R16-R31 was added into GPRs in #70958,
This patch supports the promoted ENQCMD, KEYLOCKER and USER-MSR instructions in EVEX space.

RFC: https://discourse.llvm.org/t/rfc-design-for-apx-feature-egpr-and-ndd-support/73031/4

@XinWang10 XinWang10 changed the title [X86][MC] Support promoted ENQCMD and USER-MSR instructions [X86] Support promoted ENQCMD and USER-MSR instructions Jan 8, 2024
@llvmbot llvmbot added backend:X86 mc Machine (object) code llvm:support labels Jan 8, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 8, 2024

@llvm/pr-subscribers-backend-x86
@llvm/pr-subscribers-llvm-support

@llvm/pr-subscribers-mc

Author: None (XinWang10)

Changes

R16-R31 was added into GPRs in #70958,
This patch supports the promoted ENQCMD and USER-MSR instructions in EVEX space.

RFC: https://discourse.llvm.org/t/rfc-design-for-apx-feature-egpr-and-ndd-support/73031/4


Patch is 72.77 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/77293.diff

21 Files Affected:

  • (modified) llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h (+2)
  • (modified) llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp (+3)
  • (modified) llvm/lib/Target/X86/X86ISelDAGToDAG.cpp (+11-7)
  • (modified) llvm/lib/Target/X86/X86InstrKL.td (+59-37)
  • (modified) llvm/lib/Target/X86/X86InstrMisc.td (+30-10)
  • (modified) llvm/lib/Target/X86/X86InstrSystem.td (+18-2)
  • (modified) llvm/test/CodeGen/X86/enqcmd-intrinsics.ll (+13)
  • (modified) llvm/test/CodeGen/X86/keylocker-intrinsics-fast-isel.ll (+154)
  • (modified) llvm/test/CodeGen/X86/keylocker-intrinsics.ll (+145)
  • (modified) llvm/test/CodeGen/X86/usermsr-intrinsics.ll (+35)
  • (added) llvm/test/MC/Disassembler/X86/apx/enqcmd.txt (+38)
  • (added) llvm/test/MC/Disassembler/X86/apx/keylocker.txt (+102)
  • (added) llvm/test/MC/Disassembler/X86/apx/user-msr.txt (+38)
  • (added) llvm/test/MC/X86/apx/enqcmd-att.s (+41)
  • (added) llvm/test/MC/X86/apx/enqcmd-intel.s (+37)
  • (added) llvm/test/MC/X86/apx/keylocker-att.s (+105)
  • (added) llvm/test/MC/X86/apx/keylocker-intel.s (+101)
  • (added) llvm/test/MC/X86/apx/user-msr-att.s (+41)
  • (added) llvm/test/MC/X86/apx/user-msr-intel.s (+37)
  • (modified) llvm/utils/TableGen/X86DisassemblerTables.cpp (+7-1)
  • (modified) llvm/utils/TableGen/X86RecognizableInstr.cpp (+9-6)
diff --git a/llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h b/llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h
index 3aceb247a26c21..0dc974ea9efd8d 100644
--- a/llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h
+++ b/llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h
@@ -140,7 +140,9 @@ enum attributeBits {
   ENUM_ENTRY(IC_EVEX, 1, "requires an EVEX prefix")                            \
   ENUM_ENTRY(IC_EVEX_NF, 2, "requires EVEX and NF prefix")                     \
   ENUM_ENTRY(IC_EVEX_XS, 2, "requires EVEX and the XS prefix")                 \
+  ENUM_ENTRY(IC_EVEX_XS_ADSIZE, 3, "requires EVEX, XS and the ADSIZE prefix")  \
   ENUM_ENTRY(IC_EVEX_XD, 2, "requires EVEX and the XD prefix")                 \
+  ENUM_ENTRY(IC_EVEX_XD_ADSIZE, 3, "requires EVEX, XD and the ADSIZE prefix")  \
   ENUM_ENTRY(IC_EVEX_OPSIZE, 2, "requires EVEX and the OpSize prefix")         \
   ENUM_ENTRY(IC_EVEX_OPSIZE_NF, 3, "requires EVEX, NF and the OpSize prefix")  \
   ENUM_ENTRY(IC_EVEX_OPSIZE_ADSIZE, 3,                                         \
diff --git a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
index 347dc0d4ed43a7..a3d9fb3a5c246d 100644
--- a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
+++ b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
@@ -941,6 +941,9 @@ static bool readOpcode(struct InternalInstruction *insn) {
     case VEX_LOB_MAP6:
       insn->opcodeType = MAP6;
       return consume(insn, insn->opcode);
+    case VEX_LOB_MAP7:
+      insn->opcodeType = MAP7;
+      return consume(insn, insn->opcode);
     }
   } else if (insn->vectorExtensionType == TYPE_VEX_3B) {
     switch (mmmmmFromVEX2of3(insn->vectorExtensionPrefix[1])) {
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index 73b10cf3067e1a..80563918b3c95f 100644
--- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -5027,14 +5027,16 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
       unsigned Opcode;
       switch (IntNo) {
       default: llvm_unreachable("Impossible intrinsic");
-      case Intrinsic::x86_encodekey128: Opcode = X86::ENCODEKEY128; break;
-      case Intrinsic::x86_encodekey256: Opcode = X86::ENCODEKEY256; break;
+#define GET_EGPR_IF_ENABLED(OPC) Subtarget->hasEGPR() ? OPC##_EVEX : OPC
+      case Intrinsic::x86_encodekey128: Opcode = GET_EGPR_IF_ENABLED(X86::ENCODEKEY128); break;
+      case Intrinsic::x86_encodekey256: Opcode = GET_EGPR_IF_ENABLED(X86::ENCODEKEY256); break;
+#undef GET_EGPR_IF_ENABLED
       }
 
       SDValue Chain = Node->getOperand(0);
       Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0, Node->getOperand(3),
                                    SDValue());
-      if (Opcode == X86::ENCODEKEY256)
+      if (Opcode == X86::ENCODEKEY256 || Opcode == X86::ENCODEKEY256_EVEX)
         Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1, Node->getOperand(4),
                                      Chain.getValue(1));
 
@@ -6380,18 +6382,20 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
     switch (Node->getOpcode()) {
     default:
       llvm_unreachable("Unexpected opcode!");
+#define GET_EGPR_IF_ENABLED(OPC) Subtarget->hasEGPR() ? OPC##_EVEX : OPC
     case X86ISD::AESENCWIDE128KL:
-      Opcode = X86::AESENCWIDE128KL;
+      Opcode = GET_EGPR_IF_ENABLED(X86::AESENCWIDE128KL);
       break;
     case X86ISD::AESDECWIDE128KL:
-      Opcode = X86::AESDECWIDE128KL;
+      Opcode = GET_EGPR_IF_ENABLED(X86::AESDECWIDE128KL);
       break;
     case X86ISD::AESENCWIDE256KL:
-      Opcode = X86::AESENCWIDE256KL;
+      Opcode = GET_EGPR_IF_ENABLED(X86::AESENCWIDE256KL);
       break;
     case X86ISD::AESDECWIDE256KL:
-      Opcode = X86::AESDECWIDE256KL;
+      Opcode = GET_EGPR_IF_ENABLED(X86::AESDECWIDE256KL);
       break;
+#undef GET_EGPR_IF_ENABLED
     }
 
     SDValue Chain = Node->getOperand(0);
diff --git a/llvm/lib/Target/X86/X86InstrKL.td b/llvm/lib/Target/X86/X86InstrKL.td
index 4586fc541627fe..5dfd5e7493128b 100644
--- a/llvm/lib/Target/X86/X86InstrKL.td
+++ b/llvm/lib/Target/X86/X86InstrKL.td
@@ -14,61 +14,83 @@
 
 //===----------------------------------------------------------------------===//
 // Key Locker instructions
+class Encodekey<bits<8> opcode, string mnemonic>
+  : I<opcode, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src), mnemonic#"\t{$src, $dst|$dst, $src}", []>,
+    NoCD8, XS;
 
-let SchedRW = [WriteSystem], Predicates = [HasKL] in {
-  let Uses = [XMM0, EAX], Defs = [EFLAGS] in {
+class Aesencdec<bits<8> opcode, string mnemonic, SDNode node>
+  : I<opcode, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, opaquemem:$src2),
+      mnemonic#"\t{$src2, $src1|$src1, $src2}",
+      [(set VR128:$dst, EFLAGS, (node VR128:$src1, addr:$src2))]>, NoCD8, XS;
+
+let SchedRW = [WriteSystem] in {
+  let Uses = [XMM0, EAX], Defs = [EFLAGS], Predicates = [HasKL] in {
     def LOADIWKEY : I<0xDC, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
                       "loadiwkey\t{$src2, $src1|$src1, $src2}",
                       [(int_x86_loadiwkey XMM0, VR128:$src1, VR128:$src2, EAX)]>, T8, XS;
   }
 
+  let Predicates = [HasKL, NoEGPR] in {
   let Uses = [XMM0], Defs = [XMM0, XMM1, XMM2, XMM4, XMM5, XMM6, EFLAGS] in {
-    def ENCODEKEY128 : I<0xFA, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
-                         "encodekey128\t{$src, $dst|$dst, $src}", []>, T8, XS;
+    def ENCODEKEY128 : Encodekey<0xFA, "encodekey128">, T8;
   }
 
   let Uses = [XMM0, XMM1], Defs = [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, EFLAGS] in {
-    def ENCODEKEY256 : I<0xFB, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
-                         "encodekey256\t{$src, $dst|$dst, $src}", []>, T8, XS;
+    def ENCODEKEY256 : Encodekey<0xFB, "encodekey256">, T8;
   }
 
-  let Constraints = "$src1 = $dst",
-      Defs = [EFLAGS] in {
-   def AESENC128KL : I<0xDC, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, opaquemem:$src2),
-                       "aesenc128kl\t{$src2, $src1|$src1, $src2}",
-                       [(set VR128:$dst, EFLAGS,
-                         (X86aesenc128kl VR128:$src1, addr:$src2))]>, T8, XS;
-
-   def AESDEC128KL : I<0xDD, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, opaquemem:$src2),
-                       "aesdec128kl\t{$src2, $src1|$src1, $src2}",
-                       [(set VR128:$dst, EFLAGS,
-                         (X86aesdec128kl VR128:$src1, addr:$src2))]>, T8, XS;
-
-   def AESENC256KL : I<0xDE, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, opaquemem:$src2),
-                       "aesenc256kl\t{$src2, $src1|$src1, $src2}",
-                       [(set VR128:$dst, EFLAGS,
-                         (X86aesenc256kl VR128:$src1, addr:$src2))]>, T8, XS;
-
-   def AESDEC256KL : I<0xDF, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, opaquemem:$src2),
-                       "aesdec256kl\t{$src2, $src1|$src1, $src2}",
-                       [(set VR128:$dst, EFLAGS,
-                         (X86aesdec256kl VR128:$src1, addr:$src2))]>, T8, XS;
+  let Constraints = "$src1 = $dst", Defs = [EFLAGS], Predicates = [NoEGPR] in {
+   def AESENC128KL : Aesencdec<0xDC, "aesenc128kl", X86aesenc128kl>, T8;
+
+   def AESDEC128KL : Aesencdec<0xDD, "aesdec128kl", X86aesdec128kl>, T8;
+
+   def AESENC256KL : Aesencdec<0xDE, "aesenc256kl", X86aesenc256kl>, T8;
+
+   def AESDEC256KL : Aesencdec<0xDF, "aesdec256kl", X86aesdec256kl>, T8;
+  }
   }
 
-} // SchedRW, Predicates
+  let Predicates = [HasKL, HasEGPR, In64BitMode] in {
+  let Uses = [XMM0], Defs = [XMM0, XMM1, XMM2, XMM4, XMM5, XMM6, EFLAGS] in {
+    def ENCODEKEY128_EVEX : Encodekey<0xDA, "encodekey128">, EVEX, T_MAP4;
+  }
+
+  let Uses = [XMM0, XMM1], Defs = [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, EFLAGS] in {
+    def ENCODEKEY256_EVEX : Encodekey<0xDB, "encodekey256">, EVEX, T_MAP4;
+  }
 
-let SchedRW = [WriteSystem], Predicates = [HasWIDEKL] in {
+  let Constraints = "$src1 = $dst", Defs = [EFLAGS], Predicates = [HasEGPR, In64BitMode] in {
+   def AESENC128KL_EVEX : Aesencdec<0xDC, "aesenc128kl", X86aesenc128kl>, EVEX, T_MAP4;
+
+   def AESDEC128KL_EVEX : Aesencdec<0xDD, "aesdec128kl", X86aesdec128kl>, EVEX, T_MAP4;
+
+   def AESENC256KL_EVEX : Aesencdec<0xDE, "aesenc256kl", X86aesenc256kl>, EVEX, T_MAP4;
+
+   def AESDEC256KL_EVEX : Aesencdec<0xDF, "aesdec256kl", X86aesdec256kl>, EVEX, T_MAP4;
+  }
+  }
+} // SchedRW
+
+class Aesencdecwide<bits<8> opcode, Format f, string mnemonic>
+  : I<opcode, f, (outs), (ins opaquemem:$src), mnemonic#"\t$src", []>, NoCD8, XS;
+
+let SchedRW = [WriteSystem] in {
   let Uses = [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7],
       Defs = [EFLAGS, XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7],
       mayLoad = 1 in {
-    def AESENCWIDE128KL : I<0xD8, MRM0m, (outs), (ins opaquemem:$src),
-                            "aesencwide128kl\t$src", []>, T8, XS;
-    def AESDECWIDE128KL : I<0xD8, MRM1m, (outs), (ins opaquemem:$src),
-                            "aesdecwide128kl\t$src", []>, T8, XS;
-    def AESENCWIDE256KL : I<0xD8, MRM2m, (outs), (ins opaquemem:$src),
-                            "aesencwide256kl\t$src", []>, T8, XS;
-    def AESDECWIDE256KL : I<0xD8, MRM3m, (outs), (ins opaquemem:$src),
-                            "aesdecwide256kl\t$src", []>, T8, XS;
+  let Predicates = [HasWIDEKL, NoEGPR] in {
+    def AESENCWIDE128KL : Aesencdecwide<0xD8, MRM0m, "aesencwide128kl">, T8;
+    def AESDECWIDE128KL : Aesencdecwide<0xD8, MRM1m, "aesdecwide128kl">, T8;
+    def AESENCWIDE256KL : Aesencdecwide<0xD8, MRM2m, "aesencwide256kl">, T8;
+    def AESDECWIDE256KL : Aesencdecwide<0xD8, MRM3m, "aesdecwide256kl">, T8;
+  }
+
+  let Predicates = [HasWIDEKL, HasEGPR, In64BitMode] in {
+    def AESENCWIDE128KL_EVEX : Aesencdecwide<0xD8, MRM0m, "aesencwide128kl">, EVEX, T_MAP4;
+    def AESDECWIDE128KL_EVEX : Aesencdecwide<0xD8, MRM1m, "aesdecwide128kl">, EVEX, T_MAP4;
+    def AESENCWIDE256KL_EVEX : Aesencdecwide<0xD8, MRM2m, "aesencwide256kl">, EVEX, T_MAP4;
+    def AESDECWIDE256KL_EVEX : Aesencdecwide<0xD8, MRM3m, "aesdecwide256kl">, EVEX, T_MAP4;
+  }
   }
 
 } // SchedRW, Predicates
diff --git a/llvm/lib/Target/X86/X86InstrMisc.td b/llvm/lib/Target/X86/X86InstrMisc.td
index 97c625a64cfc0b..14cc2fca572403 100644
--- a/llvm/lib/Target/X86/X86InstrMisc.td
+++ b/llvm/lib/Target/X86/X86InstrMisc.td
@@ -1523,31 +1523,51 @@ def MOVDIR64B64_EVEX : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem_GR64:$
 // ENQCMD/S - Enqueue 64-byte command as user with 64-byte write atomicity
 //
 let SchedRW = [WriteStore], Defs = [EFLAGS] in {
-  def ENQCMD16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src),
+  def ENQCMD16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem_GR16:$src),
                  "enqcmd\t{$src, $dst|$dst, $src}",
                  [(set EFLAGS, (X86enqcmd GR16:$dst, addr:$src))]>,
                  T8, XD, AdSize16, Requires<[HasENQCMD, Not64BitMode]>;
-  def ENQCMD32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src),
+  def ENQCMD32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem_GR32:$src),
                  "enqcmd\t{$src, $dst|$dst, $src}",
                  [(set EFLAGS, (X86enqcmd GR32:$dst, addr:$src))]>,
-                 T8, XD, AdSize32, Requires<[HasENQCMD]>;
-  def ENQCMD64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src),
+                 T8, XD, AdSize32, Requires<[HasENQCMD, NoEGPR]>;
+  def ENQCMD64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem_GR64:$src),
                  "enqcmd\t{$src, $dst|$dst, $src}",
                  [(set EFLAGS, (X86enqcmd GR64:$dst, addr:$src))]>,
-                 T8, XD, AdSize64, Requires<[HasENQCMD, In64BitMode]>;
+                 T8, XD, AdSize64, Requires<[HasENQCMD, NoEGPR, In64BitMode]>;
 
-  def ENQCMDS16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src),
+  def ENQCMDS16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem_GR16:$src),
                  "enqcmds\t{$src, $dst|$dst, $src}",
                  [(set EFLAGS, (X86enqcmds GR16:$dst, addr:$src))]>,
                  T8, XS, AdSize16, Requires<[HasENQCMD, Not64BitMode]>;
-  def ENQCMDS32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src),
+  def ENQCMDS32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem_GR32:$src),
                  "enqcmds\t{$src, $dst|$dst, $src}",
                  [(set EFLAGS, (X86enqcmds GR32:$dst, addr:$src))]>,
-                 T8, XS, AdSize32, Requires<[HasENQCMD]>;
-  def ENQCMDS64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src),
+                 T8, XS, AdSize32, Requires<[HasENQCMD, NoEGPR]>;
+  def ENQCMDS64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem_GR64:$src),
                  "enqcmds\t{$src, $dst|$dst, $src}",
                  [(set EFLAGS, (X86enqcmds GR64:$dst, addr:$src))]>,
-                 T8, XS, AdSize64, Requires<[HasENQCMD, In64BitMode]>;
+                 T8, XS, AdSize64, Requires<[HasENQCMD, NoEGPR, In64BitMode]>;
+
+let Predicates = [HasENQCMD, HasEGPR, In64BitMode] in {
+  def ENQCMD32_EVEX : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem_GR32:$src),
+                        "enqcmd\t{$src, $dst|$dst, $src}",
+                        [(set EFLAGS, (X86enqcmd GR32:$dst, addr:$src))]>,
+                      EVEX, NoCD8, T_MAP4, XD, AdSize32;
+  def ENQCMD64_EVEX : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem_GR64:$src),
+                        "enqcmd\t{$src, $dst|$dst, $src}",
+                        [(set EFLAGS, (X86enqcmd GR64:$dst, addr:$src))]>,
+                      EVEX, NoCD8, T_MAP4, XD, AdSize64;
+
+  def ENQCMDS32_EVEX : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem_GR32:$src),
+                         "enqcmds\t{$src, $dst|$dst, $src}",
+                         [(set EFLAGS, (X86enqcmds GR32:$dst, addr:$src))]>,
+                       EVEX, NoCD8, T_MAP4, XS, AdSize32;
+  def ENQCMDS64_EVEX : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem_GR64:$src),
+                         "enqcmds\t{$src, $dst|$dst, $src}",
+                         [(set EFLAGS, (X86enqcmds GR64:$dst, addr:$src))]>,
+                       EVEX, NoCD8, T_MAP4, XS, AdSize64;
+}
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/X86/X86InstrSystem.td b/llvm/lib/Target/X86/X86InstrSystem.td
index b1be4739617dfc..166c796d3c5145 100644
--- a/llvm/lib/Target/X86/X86InstrSystem.td
+++ b/llvm/lib/Target/X86/X86InstrSystem.td
@@ -436,7 +436,7 @@ def WRMSRLIST : I<0x01, MRM_C6, (outs), (ins), "wrmsrlist", []>, TB, XS;
 def RDMSRLIST : I<0x01, MRM_C6, (outs), (ins), "rdmsrlist", []>, TB, XD;
 }
 
-let Predicates = [HasUSERMSR], mayLoad = 1 in {
+let Predicates = [HasUSERMSR, NoEGPR], mayLoad = 1 in {
   def URDMSRrr : I<0xf8, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
                 "urdmsr\t{$src, $dst|$dst, $src}",
                 [(set GR64:$dst, (int_x86_urdmsr GR64:$src))]>, T8, XD;
@@ -444,7 +444,7 @@ let Predicates = [HasUSERMSR], mayLoad = 1 in {
                 "urdmsr\t{$imm, $dst|$dst, $imm}",
                 [(set GR64:$dst, (int_x86_urdmsr i64immSExt32_su:$imm))]>, T_MAP7, XD, VEX;
 }
-let Predicates = [HasUSERMSR], mayStore = 1 in {
+let Predicates = [HasUSERMSR, NoEGPR], mayStore = 1 in {
   def UWRMSRrr : I<0xf8, MRMSrcReg, (outs), (ins GR64:$src1, GR64:$src2),
                 "uwrmsr\t{$src2, $src1|$src1, $src2}",
                 [(int_x86_uwrmsr GR64:$src1, GR64:$src2)]>, T8, XS;
@@ -452,6 +452,22 @@ let Predicates = [HasUSERMSR], mayStore = 1 in {
                 "uwrmsr\t{$src, $imm|$imm, $src}",
                 [(int_x86_uwrmsr i64immSExt32_su:$imm, GR64:$src)]>, T_MAP7, XS, VEX;
 }
+let Predicates = [HasUSERMSR, HasEGPR, In64BitMode], mayLoad = 1 in {
+  def URDMSRrr_EVEX : I<0xf8, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
+                        "urdmsr\t{$src, $dst|$dst, $src}",
+                        [(set GR64:$dst, (int_x86_urdmsr GR64:$src))]>, T_MAP4, XD, EVEX, NoCD8;
+  def URDMSRri_EVEX : Ii32<0xf8, MRM0r, (outs GR64:$dst), (ins i64i32imm:$imm),
+                        "urdmsr\t{$imm, $dst|$dst, $imm}",
+                        [(set GR64:$dst, (int_x86_urdmsr i64immSExt32_su:$imm))]>, T_MAP7, XD, EVEX, NoCD8;
+}
+let Predicates = [HasUSERMSR, HasEGPR, In64BitMode], mayStore = 1 in {
+  def UWRMSRrr_EVEX : I<0xf8, MRMSrcReg, (outs), (ins GR64:$src1, GR64:$src2),
+                        "uwrmsr\t{$src2, $src1|$src1, $src2}",
+                        [(int_x86_uwrmsr GR64:$src1, GR64:$src2)]>, T_MAP4, XS, EVEX, NoCD8;
+  def UWRMSRir_EVEX : Ii32<0xf8, MRM0r, (outs), (ins GR64:$src, i64i32imm:$imm),
+                        "uwrmsr\t{$src, $imm|$imm, $src}",
+                        [(int_x86_uwrmsr i64immSExt32_su:$imm, GR64:$src)]>, T_MAP7, XS, EVEX, NoCD8;
+}
 let Defs = [RAX, RDX], Uses = [ECX] in
 def RDPMC : I<0x33, RawFrm, (outs), (ins), "rdpmc", []>, TB;
 
diff --git a/llvm/test/CodeGen/X86/enqcmd-intrinsics.ll b/llvm/test/CodeGen/X86/enqcmd-intrinsics.ll
index e5a6d2ead72d36..230a2ffc059413 100644
--- a/llvm/test/CodeGen/X86/enqcmd-intrinsics.ll
+++ b/llvm/test/CodeGen/X86/enqcmd-intrinsics.ll
@@ -2,6 +2,7 @@
 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+enqcmd | FileCheck %s --check-prefix=X64
 ; RUN: llc < %s -mtriple=i386-unknown-unknown -mattr=+enqcmd | FileCheck %s --check-prefix=X86
 ; RUN: llc < %s -mtriple=x86_64-linux-gnux32 -mattr=+enqcmd | FileCheck %s --check-prefix=X32
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+enqcmd,+egpr --show-mc-encoding | FileCheck %s --check-prefix=EGPR
 
 define i8 @test_enqcmd(ptr %dst, ptr %src) {
 ; X64-LABEL: test_enqcmd:
@@ -23,6 +24,12 @@ define i8 @test_enqcmd(ptr %dst, ptr %src) {
 ; X32-NEXT:    enqcmd (%esi), %edi
 ; X32-NEXT:    sete %al
 ; X32-NEXT:    retq
+;
+; EGPR-LABEL: test_enqcmd:
+; EGPR:       # %bb.0: # %entry
+; EGPR-NEXT:    enqcmd (%rsi), %rdi # encoding: [0x62,0xf4,0x7f,0x08,0xf8,0x3e]
+; EGPR-NEXT:    sete %al # encoding: [0x0f,0x94,0xc0]
+; EGPR-NEXT:    retq # encoding: [0xc3]
 entry:
 
 
@@ -50,6 +57,12 @@ define i8 @test_enqcmds(ptr %dst, ptr %src) {
 ; X32-NEXT:    enqcmds (%esi), %edi
 ; X32-NEXT:    sete %al
 ; X32-NEXT:    retq
+;
+; EGPR-LABEL: test_enqcmds:
+; EGPR:       # %bb.0: # %entry
+; EGPR-NEXT:    enqcmds (%rsi), %rdi # encoding: [0x62,0xf4,0x7e,0x08,0xf8,0x3e]
+; EGPR-NEXT:    sete %al # encoding: [0x0f,0x94,0xc0]
+; EGPR-NEXT:    retq # encoding: [0xc3]
 entry:
 
 
diff --git a/llvm/test/CodeGen/X86/keylocker-intrinsics-fast-isel.ll b/llvm/test/CodeGen/X86/keylocker-intrinsics-fast-isel.ll
index 78eecdaf29e2cb..1d90d1c31d5ca8 100644
--- a/llvm/test/CodeGen/X86/keylocker-intrinsics-fast-isel.ll
+++ b/llvm/test/CodeGen/X86/keylocker-intrinsics-fast-isel.ll
@@ -1,5 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc < %s -fast-isel -mtriple=x86_64-unknown-unknown -mattr=+kl,+widekl | FileCheck %s
+; RUN: llc < %s -fast-isel -mtriple=x86_64-unknown-unknown -mattr=+kl,+widekl,+egpr --show-mc-encoding | FileCheck %s --check-prefix=EGPR
 
 ; NOTE: This should use IR equivalent to what is generated by clang/test/CodeGen/X86/keylocker-builtins.c
 
@@ -9,6 +10,12 @@ define void @test_loadiwkey(i32 %ctl, <2 x i64> %intkey, <2 x i64> %enkey_lo, <2
 ; CHECK-NEXT:    movl %edi, %eax
 ; CHECK-NEXT:    loadiwkey %xmm2, %xmm1
 ; CHECK-NEXT:    retq
+;
+; EGPR-LABEL: test_loadiwkey:
+; EGPR:       # %bb.0: # %entry
+; EGPR-NEXT:    movl %edi, %eax # encoding: [0x89,0xf8]
+; EGPR-NEXT:    loadiwkey %xmm2, %xmm1 # encoding: [0xf3,0x0f,0x38,0xdc,0xca]
+; EGPR-NEXT:    retq # encoding: [0xc3]
 entry:
   tail call void @llvm.x86.loadiwkey(<2 x i64> %intkey, <2 x i64> %enkey_lo, <2 x i64> %enkey_hi, i32 %ctl)
   ret void
@@ -25,6 +32,17 @@ define i32 @test_encodekey128_u32(i32 %htype, <2 x i64> %key, ptr nocapture %h)
 ; CHECK-NEXT:    movups %xmm5, 64(%rsi)
 ; CHECK-NEXT:    movups %xmm6, 80(%rsi)
 ; CHECK-NEXT:    retq
+;
+; EGPR-LABEL: test_encodekey128_u32:
+; EGPR:       # %bb.0: # %entry
+; EGPR-NEXT:    encodekey128 %edi, %eax # encoding: [0x62,0xf4,0x7e,0x08,0xda,0xc7]
+; EGPR-NEXT:    movups %xmm0, (%rsi) # encoding: [0x0f,0x11,0x06]
+; EGPR-NEXT:    movups %xmm1, 16(%rsi) # encoding: [0x0f,0x11,0x4e,0x10]
+; EGPR-NEXT:    movups %xmm2, 32(%rsi) # encoding: [0x0f,0x11,0x56,0x20]
+; EGPR-NEXT:    movups %xmm4, 48(%rsi) # encoding: [0x0f,0x11,0x66,0x30]
+; EGP...
[truncated]

Copy link

github-actions bot commented Jan 8, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@XinWang10 XinWang10 changed the title [X86] Support promoted ENQCMD and USER-MSR instructions [X86] Support promoted ENQCMD, KEYLOCKER and USER-MSR instructions Jan 9, 2024
XinWang10 added a commit that referenced this pull request Jan 11, 2024
Mentioned in #77293,
enqcmd/enqcmds are special for its mem operand, like movdir64b(see
4dd5e9c60efa9), 0x67 prefix
can not only modify its address size, so it's mem base and index reg
should be the same type as source reg.
@KanRobert KanRobert marked this pull request as draft January 18, 2024 05:09
@XinWang10 XinWang10 marked this pull request as ready for review January 19, 2024 08:50
@XinWang10 XinWang10 changed the title [X86] Support promoted ENQCMD, KEYLOCKER and USER-MSR instructions [X86] Support promoted ENQCMD, KEYLOCKER instructions Jan 25, 2024
@XinWang10 XinWang10 changed the title [X86] Support promoted ENQCMD, KEYLOCKER instructions [X86] Support promoted ENQCMD, KEYLOCKER instructions and USER-MSR Jan 25, 2024
Copy link
Contributor

@KanRobert KanRobert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@KanRobert KanRobert changed the title [X86] Support promoted ENQCMD, KEYLOCKER instructions and USER-MSR [X86] Support promoted ENQCMD, KEYLOCKER and USERMSR Jan 25, 2024
@XinWang10 XinWang10 merged commit 6d0080b into llvm:main Jan 26, 2024
3 of 4 checks passed
justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this pull request Jan 28, 2024
Mentioned in llvm#77293,
enqcmd/enqcmds are special for its mem operand, like movdir64b(see
llvm@4dd5e9c60efa9), 0x67 prefix
can not only modify its address size, so it's mem base and index reg
should be the same type as source reg.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants