aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/X86/X86InstrPredicates.td
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/X86/X86InstrPredicates.td')
-rw-r--r--llvm/lib/Target/X86/X86InstrPredicates.td33
1 files changed, 33 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86InstrPredicates.td b/llvm/lib/Target/X86/X86InstrPredicates.td
index 94fa6e45ded9..cb751639a057 100644
--- a/llvm/lib/Target/X86/X86InstrPredicates.td
+++ b/llvm/lib/Target/X86/X86InstrPredicates.td
@@ -8,8 +8,41 @@
def TruePredicate : Predicate<"true">;
+// Intel x86 instructions have three separate encoding spaces: legacy, VEX, and
+// EVEX. Not all X86 instructions are extended for EGPR. The following is an
+// overview of which instructions are extended and how we implement them.
+//
+// * Legacy space
+// All instructions in legacy maps 0 and 1 that have explicit GPR or memory
+// operands can use the REX2 prefix to access the EGPR, except XSAVE*/XRSTOR.
+//
+// * EVEX space
+// All instructions in the EVEX space can access the EGPR in their
+// register/memory operands.
+//
+// For the above intructions, the only difference in encoding is reflected in
+// the REX2/EVEX prefix when EGPR is used, i.e. the opcode and opcode name are
+// unchanged. We don’t add new entries in TD, and instead we extend GPR with
+// R16-R31 and make them allocatable only when the feature EGPR is available.
+//
+// Besides, some instructions in legacy space with map 2/3 and VEX space are
+// promoted into EVEX space. Encoding space changes after the promotion, opcode
+// and opcode map may change too sometimes. For these instructions, we add new
+// entries in TD to avoid overcomplicating the assembler and disassembler.
+//
+// HasEGPR is for the new entries and NoEGPR is for the entries before
+// promotion, so that the promoted variant can be selected first to benefit RA.
def HasEGPR : Predicate<"Subtarget->hasEGPR()">;
def NoEGPR : Predicate<"!Subtarget->hasEGPR()">;
+
+// APX extends some instructions with a new form that has an extra register
+// operand called a new data destination (NDD). In such forms, NDD is the new
+// destination register receiving the result of the computation and all other
+// operands (including the original destination operand) become read-only source
+// operands.
+//
+// HasNDD is for the new NDD entries and NoNDD is for the legacy 2-address
+// entries, so that the NDD variant can be selected first to benefit RA.
def HasNDD : Predicate<"Subtarget->hasNDD()">;
def NoNDD : Predicate<"!Subtarget->hasNDD()">;
def HasCMOV : Predicate<"Subtarget->canUseCMOV()">;