-
Notifications
You must be signed in to change notification settings - Fork 11.9k
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
Conversation
@llvm/pr-subscribers-backend-x86 @llvm/pr-subscribers-mc Author: None (XinWang10) ChangesR16-R31 was added into GPRs in #70958, 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:
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]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
240acca
to
f740e0b
Compare
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.
0a68477
to
7e54c5e
Compare
7e54c5e
to
301f89c
Compare
f4be7e1
to
989c592
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
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.
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