[llvm] [Docs] Describe Tablegen Selection Structures (PR #178518)
Sam Elliott via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 10 23:47:14 PST 2026
https://github.com/lenary updated https://github.com/llvm/llvm-project/pull/178518
>From 50d4eca46d4f10c6c47bd985703ee25a76103494 Mon Sep 17 00:00:00 2001
From: Sam Elliott <aelliott at qti.qualcomm.com>
Date: Wed, 28 Jan 2026 13:30:43 -0800
Subject: [PATCH 1/6] [Docs] Describe Tablegen Selection Structures
This change adds documentation for some of the advanced parts of
the TableGen Selection structures:
- The `set`, `node` and `srcvalue` special DAG nodes
- The `SDNodeXForm` C++ snippet.
- The `PatFrags` predicate C++ snippet, and documentation for how the
`OperandTransform` item works in a little more detail.
- The `ImmLeaf` predicate code.
---
.../include/llvm/Target/TargetSelectionDAG.td | 108 +++++++++++++++++-
1 file changed, 107 insertions(+), 1 deletion(-)
diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td
index b297fd06711a5..c736c5b3afaf5 100644
--- a/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -371,11 +371,32 @@ class SDNode<string opcode, SDTypeProfile typeprof,
bits<32> TSFlags = 0;
}
-// Special TableGen-recognized dag nodes
+/// Special TableGen-recognized dag nodes
+
+// `set` is used to name outputs of a match pattern. For instance, in:
+// `(set GPR:$out, (add GPR:$in1, GPR:$in2))`.
+//
+// `set` has to be used for patterns defined directly on Instructions, where the
+// `(outs)` have names which need to match something in the pattern.
+//
+// `set` can also be used for Nodes which create multiple values (though chain
+// and glue do not need to be handled with this, and are handled with node
+// properties). A pattern with multiple outputs might look like:
+// `(set GPR:$RdLo, GPR:$RdHi, (smullohi GPR:$Rn, GPR:$Rm))`
def set;
+
+// `node` is used when defining pattern fragments, to represent "holes" in the
+// fragment that should be instantated with dags when the fragment is used. For
+// instance in the `def fmul_contract` below.
def node;
+
+// `srcvalue` is used in patterns when an argument of the pattern is not needed
+// in the result. A named value `ty:$name` could not be used in these cases
+// because all names in the pattern must appear in pattern output dag.
def srcvalue;
+/// dag nodes for specific SDNodes
+
def imm : SDNode<"ISD::Constant" , SDTIntLeaf , [], "ConstantSDNode">;
def timm : SDNode<"ISD::TargetConstant",SDTIntLeaf, [], "ConstantSDNode">;
def fpimm : SDNode<"ISD::ConstantFP", SDTFPLeaf , [], "ConstantFPSDNode">;
@@ -956,10 +977,30 @@ def SETNE : CondCode<"", "ICMP_NE">;
// values.
//
class SDNodeXForm<SDNode opc, code xformFunction> {
+ // The underlying node type to match and transform.
SDNode Opcode = opc;
+
+ // This C++ snippet will transform the associated node into a new node.
+ //
+ // The following variables are in scope:
+ // - `<opc.SDClass>* N` representing the node producing the value being
+ // transformed (already cast to the type of `opc.SDClass`, which is usually
+ // `SDNode`).
+ // - `SelectionDAG *CurDAG` representing the current DAG (really a member of
+ // the current DAGToDAGISel instance, documented here because this is how
+ // new nodes are made).
+ // - `SDValue V` representing the value being transformed (usually accessed
+ // with `N` instead).
+ // - `GET_DAGISEL_BODY *this` representing the target's DAGToDAGISel instance.
+ //
+ // It should `return` an `SDValue` for the transformation result.
code XFormFunction = xformFunction;
+
+ // The GlobalISel equivalent is defined using a `GICustomOperandRenderer` and
+ // a `GISDNodeXFormEquiv`.
}
+// The default transform does not change the matched node.
def NOOP_SDNodeXForm : SDNodeXForm<imm, [{}]>;
//===----------------------------------------------------------------------===//
@@ -979,11 +1020,65 @@ def NOOP_SDNodeXForm : SDNodeXForm<imm, [{}]>;
///
class PatFrags<dag ops, list<dag> frags, code pred = [{}],
SDNodeXForm xform = NOOP_SDNodeXForm> : SDPatternOperator {
+
+ // Named nested patterns
dag Operands = ops;
+
+ // The fragment matches *any* pattern in this list that matches. The patterns
+ // in this list should contain references to the named nested patterns in
+ // `ops`.
list<dag> Fragments = frags;
+
+ // This C++ snippet will be run against a matched node to ensure that it was
+ // intended to match. Some Predicates don't use this snippet and instead use
+ // the `bit`s below to generate the right C++.
+ //
+ // The following variables are in scope:
+ // - `SDNode *N` representing the node being checked. This might actually be
+ // of a more specific SDNode type - derived from the head nodes of the
+ // fragments.
+ // - `ArrayRef<SDValue> Operands` representing the operands, only if
+ // `PredicateCodeUsesOperands` (below) is true.
+ // - `SDValue Op` representing the value being checked (usually accessed with
+ // `N` instead).
+ // - `const GET_DAGISEL_BODY *this` representing the target's DAGToDAGISel
+ // instance.
+ //
+ // This should `return` a `bool` for whether the predicate matches or not.
code PredicateCode = pred;
+
+ // The equivalent of `PredicateCode` for GlobalISel.
+ //
+ // The following variables are in scope:
+ // - `const MachineInstr &MI` representing the MI being checked.
+ // - `std::array<const MachineOperand *, _>` representing the operands of the
+ // current fragment.
+ // - `const MachineFunction &MF` the current function.
+ // - `const MachineRegisterInfo &MRI` for the current function.
+ // - `const <target>InstructionSelector *this` representing the target's
+ // `InstructionSelector` instance.
+ // - `const MatcherState &State`
+ //
+ // This should `return` a `bool` for whether the predicate matches or not.
code GISelPredicateCode = [{}];
+
+ // Specific C++ Checks for Immediate Values. This code is shared between
+ // SDISel and GlobalISel. See `ImmLeaf` below.
+ //
+ // The following variables are in scope:
+ // - `int64_t Imm` representing the value of the immediate.
+ //
+ // This should return a `bool` for whether the predicate matches or not.
code ImmediateCode = [{}];
+
+ // After this node is matched as `NAME:$val`, `$val` is stored so it can be
+ // used later in the pattern result. This implicit transform means that `$val`
+ // will store the result of transforming the node, instead of the original
+ // node.
+ //
+ // PatFrags with OperandTransforms are most useful when defining a pattern
+ // directly on an instruction, where the transform cannot be written on the
+ // output of the pattern (which is implicit).
SDNodeXForm OperandTransform = xform;
// When this is set, the PredicateCode may refer to a constant Operands
@@ -1106,7 +1201,18 @@ class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm>
class ImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm,
SDNode ImmNode = imm>
: PatFrag<(ops), (vt ImmNode), [{}], xform> {
+
+ // Specific C++ Checks for Immediate Values. This code is shared between
+ // SDISel and GlobalISel.
+ //
+ // The following variables are in scope:
+ // - `Imm` representing the sign-extended value of the immediate. This might
+ // be an APInt, an APFloat, or a sign-extended int64_t, depending on the
+ // `IsAPInt` and `IsAPFloat` fields below.
+ //
+ // This should return a `bool` for whether the predicate matches or not.
let ImmediateCode = pred;
+
bit FastIselShouldIgnore = false;
// Is the data type of the immediate an APInt?
>From a66e3fc15488d36af4749d34b704f82c2162dd8d Mon Sep 17 00:00:00 2001
From: Sam Elliott <aelliott at qti.qualcomm.com>
Date: Wed, 28 Jan 2026 14:56:12 -0800
Subject: [PATCH 2/6] Review Suggestions
---
.../include/llvm/Target/TargetSelectionDAG.td | 29 ++++++++++---------
1 file changed, 16 insertions(+), 13 deletions(-)
diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td
index c736c5b3afaf5..0979eda438b73 100644
--- a/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -386,7 +386,7 @@ class SDNode<string opcode, SDTypeProfile typeprof,
def set;
// `node` is used when defining pattern fragments, to represent "holes" in the
-// fragment that should be instantated with dags when the fragment is used. For
+// fragment that should be instantiated with dags when the fragment is used. For
// instance in the `def fmul_contract` below.
def node;
@@ -1185,15 +1185,15 @@ class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm>
}
-// ImmLeaf is a pattern fragment with a constraint on the immediate. The
-// constraint is a function that is run on the immediate (always with the value
-// sign extended out to an int64_t) as Imm. For example:
+// ImmLeaf is a pattern fragment for immediates that match a constraint. The
+// constraint is a C++ snippet that is run on the immediate (always with the
+// value sign extended out to an int64_t) as Imm. For example:
//
// def immSExt8 : ImmLeaf<i16, [{ return (char)Imm == Imm; }]>;
//
// this is a more convenient form to match 'imm' nodes in than PatLeaf and also
// is preferred over using PatLeaf because it allows the code generator to
-// reason more about the constraint.
+// reason more about the constraint, and port the constraint to GlobalISel.
//
// If FastIsel should ignore all instructions that have an operand of this type,
// the FastIselShouldIgnore flag can be set. This is an optimization to reduce
@@ -1202,13 +1202,12 @@ class ImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm,
SDNode ImmNode = imm>
: PatFrag<(ops), (vt ImmNode), [{}], xform> {
- // Specific C++ Checks for Immediate Values. This code is shared between
- // SDISel and GlobalISel.
+ // Specific C++ Check for the Immediate Values.
//
// The following variables are in scope:
- // - `Imm` representing the sign-extended value of the immediate. This might
- // be an APInt, an APFloat, or a sign-extended int64_t, depending on the
- // `IsAPInt` and `IsAPFloat` fields below.
+ // - `Imm` representing the value of the immediate. The type of this variable
+ // depends on whether you are instantiating a `ImmLeaf`, a `IntImmLeaf`, or
+ // a `FPImmLeaf`.
//
// This should return a `bool` for whether the predicate matches or not.
let ImmediateCode = pred;
@@ -1224,11 +1223,15 @@ class ImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm,
// Convenience wrapper for ImmLeaf to use timm/TargetConstant instead
// of imm/Constant.
+//
+// `Imm` in the snippet is the value sign-extended to `int64_t`.
class TImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm,
SDNode ImmNode = timm> : ImmLeaf<vt, pred, xform, ImmNode>;
-// An ImmLeaf except that Imm is an APInt. This is useful when you need to
-// zero-extend the immediate instead of sign-extend it.
+// An ImmLeaf where the `Imm` in the C++ predicate is an `APInt`.
+//
+// This is useful when you need to zero-extend the immediate instead of
+// sign-extend it, or when the value does not fit into an `int64_t`.
//
// Note that FastISel does not currently understand IntImmLeaf and will not
// generate code for rules that make use of it. As such, it does not make sense
@@ -1240,7 +1243,7 @@ class IntImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm>
let FastIselShouldIgnore = true;
}
-// An ImmLeaf except that Imm is an APFloat.
+// An ImmLeaf where the `Imm` in the C++ predicate is an `APFloat`.
//
// Note that FastISel does not currently understand FPImmLeaf and will not
// generate code for rules that make use of it.
>From 7d98e734ec242ec3c1e58f24494b503c16643952 Mon Sep 17 00:00:00 2001
From: Sam Elliott <aelliott at qti.qualcomm.com>
Date: Wed, 28 Jan 2026 15:21:20 -0800
Subject: [PATCH 3/6] Add docs for PatLeaf.GISelLeafPredicateCode
---
.../include/llvm/Target/TargetSelectionDAG.td | 21 +++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td
index 0979eda438b73..25cd2418cc5be 100644
--- a/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -1050,14 +1050,13 @@ class PatFrags<dag ops, list<dag> frags, code pred = [{}],
// The equivalent of `PredicateCode` for GlobalISel.
//
// The following variables are in scope:
- // - `const MachineInstr &MI` representing the MI being checked.
- // - `std::array<const MachineOperand *, _>` representing the operands of the
- // current fragment.
+ // - `const MachineInstr &MI` representing the instruction being checked.
// - `const MachineFunction &MF` the current function.
// - `const MachineRegisterInfo &MRI` for the current function.
// - `const <target>InstructionSelector *this` representing the target's
// `InstructionSelector` instance.
// - `const MatcherState &State`
+ // - `std::array<const MachineOperand *, _> Operands`
//
// This should `return` a `bool` for whether the predicate matches or not.
code GISelPredicateCode = [{}];
@@ -1180,7 +1179,21 @@ class OutPatFrag<dag ops, dag frag>
// PatLeaf's are pattern fragments that have no operands. This is just a helper
// to define immediates and other common things concisely.
class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm>
- : PatFrag<(ops), frag, pred, xform> {
+ : PatFrag<(ops), frag, pred, xform> {
+
+ // The equivalent of `PredicateCode` for GlobalISel. Unlike with `PatFrag`,
+ // this is examining a `MachineOperand` rather than a `MachineInstruction`.
+ //
+ // The following variables are in scope:
+ // - `const MachineOperand &MO` representing the Operand being checked.
+ // - `const MachineFunction &MF` the current function.
+ // - `const MachineRegisterInfo &MRI` for the current function.
+ // - `const <target>InstructionSelector *this` representing the target's
+ // `InstructionSelector` instance.
+ // - `const MatcherState &State`
+ // - `std::array<const MachineOperand *, _> Operands`
+ //
+ // This should `return` a `bool` for whether the predicate matches or not.
code GISelLeafPredicateCode = ?;
}
>From 22d286be647f103c8effee48a92877be3740176e Mon Sep 17 00:00:00 2001
From: Sam Elliott <aelliott at qti.qualcomm.com>
Date: Wed, 28 Jan 2026 22:14:54 -0800
Subject: [PATCH 4/6] Document how to bind when the fragment has nested
patterns
---
llvm/include/llvm/Target/TargetSelectionDAG.td | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td
index 25cd2418cc5be..28908ed65a6a0 100644
--- a/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -1070,10 +1070,14 @@ class PatFrags<dag ops, list<dag> frags, code pred = [{}],
// This should return a `bool` for whether the predicate matches or not.
code ImmediateCode = [{}];
- // After this node is matched as `NAME:$val`, `$val` is stored so it can be
- // used later in the pattern result. This implicit transform means that `$val`
- // will store the result of transforming the node, instead of the original
- // node.
+ // When a node is matched as `frag:$name`, the matched node is bound to
+ // `$name` so it can be used in the pattern result. This implicit transform
+ // means that `$name` will store the result of transforming the matched node,
+ // instead of the original node.
+ //
+ // The syntax for binding in a pattern can be:
+ // - `(frag:$name <patterns...>)` when `frag` has nested patterns
+ // - `frag:$name` when `frag` is a `PatLeaf` (no nested patterns)
//
// PatFrags with OperandTransforms are most useful when defining a pattern
// directly on an instruction, where the transform cannot be written on the
>From 25c8b1bf5a45ffb588c8773fd156d330fe79a395 Mon Sep 17 00:00:00 2001
From: Sam Elliott <aelliott at qti.qualcomm.com>
Date: Fri, 30 Jan 2026 13:22:16 -0800
Subject: [PATCH 5/6] Add docs for ComplexPattern
---
.../include/llvm/Target/TargetSelectionDAG.td | 40 +++++++++++++++----
1 file changed, 33 insertions(+), 7 deletions(-)
diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td
index 28908ed65a6a0..12ecb59de5717 100644
--- a/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -1065,7 +1065,8 @@ class PatFrags<dag ops, list<dag> frags, code pred = [{}],
// SDISel and GlobalISel. See `ImmLeaf` below.
//
// The following variables are in scope:
- // - `int64_t Imm` representing the value of the immediate.
+ // - `Imm` representing the value of the immediate. The type of `Imm` depends
+ // on what kind of `ImmLeaf` is being instantiated.
//
// This should return a `bool` for whether the predicate matches or not.
code ImmediateCode = [{}];
@@ -2388,20 +2389,42 @@ class Pat<dag pattern, dag result> : Pattern<pattern, [result]>;
//
// Complex patterns, e.g. X86 addressing mode, requires pattern matching code
-// in C++. Ty is the type of return value; NumOperands is the number of operands
-// returned by the select function; SelectFunc is the name of the function used
-// to pattern match the max. pattern; RootNodes are the list of possible root nodes
-// of the sub-dags to match.
-// e.g. X86 addressing mode - def addr : ComplexPattern<iPTR, 4, "SelectAddr", [add]>;
-//
+// in C++: def addr : ComplexPattern<iPTR, 4, "SelectAddr", [add]>;
class ComplexPattern<ValueType ty, int numops, string fn,
list<SDNode> roots = [], list<SDNodeProperty> props = [],
int complexity = -1> {
+
+ // Type of the return value of the Pattern
ValueType Ty = ty;
+
+ // Number of operands returned by select function
int NumOperands = numops;
+
+ // Name of the select function in C++ used to pattern match. This should be
+ // defined on your `GET_DAGISEL_BODY` class (usually the DAGToDAGISel class
+ // for your target).
+ //
+ // The arguments to this function are:
+ // - `SDValue Root` for the root of the match if `WantsRoot` is true
+ // - `SDValue *Parent` for the parent of the operand, if `WantsParent` is
+ // true. This may be null if `N` is the root node.
+ // - `SDValue N` for the value being matched
+ // - one `SDValue &Out` for each operand returned
+ // - `SDValue &OutChain` for the output chain if `SDNPHasChain` is in `Properties`.
+ //
+ // This function should return a `bool` representing whether the pattern
+ // matched or not.
string SelectFunc = fn;
+
+ // The list of possible root nodes of the sub-dags to match
list<SDNode> RootNodes = roots;
+
+ // These properties are used to verify that the result instruction has similar
+ // properties to the pattern.
list<SDNodeProperty> Properties = props;
+
+ // Complexity of this pattern relative to others. Patterns with higher
+ // complexity are matched before those with lower complexity.
int Complexity = complexity;
// Set this to true if SelectFunc wants an additional argument
@@ -2411,4 +2434,7 @@ class ComplexPattern<ValueType ty, int numops, string fn,
// Set this to true if SelectFunc wants an additional argument
// that is the parent of the matched node.
bit WantsParent = false;
+
+ // The GlobalISel equivalent is defined using a `GIComplexOperandMatcher` and
+ // a `GIComplexPatternEquiv`.
}
>From c3e100bdd42b80b997950994102978fc19b73f01 Mon Sep 17 00:00:00 2001
From: Sam Elliott <aelliott at qti.qualcomm.com>
Date: Tue, 10 Feb 2026 23:46:57 -0800
Subject: [PATCH 6/6] Add more Method/Code Docs
---
llvm/include/llvm/Target/Target.td | 126 +++++++++++++++++++++++++----
1 file changed, 112 insertions(+), 14 deletions(-)
diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td
index 3d3cfe6948ded..9b3b4509da6bd 100644
--- a/llvm/include/llvm/Target/Target.td
+++ b/llvm/include/llvm/Target/Target.td
@@ -254,7 +254,24 @@ class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> {
// RegisterClass's and other Operand's.
class DAGOperand {
string OperandNamespace = "MCOI";
+
+ // Per-operand equivalent of InstructionEncoding's `DecoderMethod`.
+ //
+ // This will be called with one of the following signatures:
+ // ```
+ // // If the operand is decoded from a field in the instruction. `TmpType`
+ // // will either be the same as `InsnType` (if it's integral), or it will
+ // // be `uint64_t`. `InsnType` is templated type the generated
+ // // `decodeToMCInst` is used with.
+ // DecodeStatus DecoderMethod(MCInst &Inst, TmpType Field, int64_t Address,
+ // const MCDisassembler *Decoder)
+ // // If the operand does not appear in the instruction encoding
+ // DecodeStatus DecoderMethod(MCInst &Inst, const MCDisassembler *Decoder)
+ // ```
string DecoderMethod = "";
+
+ // Operand equivalent of InstructionEncoding's `hasCompleteDecoder`; if this
+ // is true, then other instructions will be tried before decoding fails.
bit hasCompleteDecoder = true;
}
@@ -560,6 +577,18 @@ class InstructionEncoding {
// List of predicates which will be turned into isel matching code.
list<Predicate> Predicates = [];
+ // The name of a custom C++ decoder method to use to decode this instruction.
+ //
+ // If the instruction has a `DecoderMethod`, then the fields for its operands
+ // are not automatically decoded, and the decoder method is responsible for
+ // constructing all the MCInst's operands.
+ //
+ // Will be called with the following signature (where `InsnType` is the
+ // template type that `decodeToMCInst` is called with):
+ // ```
+ // DecodeStatus DecoderMethod(MCInst &Inst, InsnType insn, int64_t Address,
+ // const MCDisassembler *Decoder)
+ // ```
string DecoderMethod = "";
// Is the instruction decoder method able to completely determine if the
@@ -747,6 +776,14 @@ class Instruction : InstructionEncoding {
/// discussion of inline assembly constraint strings.
string Constraints = "";
+ /// This is used by `getBinaryCodeForInstr` to fixup the instruction encoding
+ /// for the instruction.
+ /// It is called with the following signature, expecting to return the new
+ /// value of `Value`, after the operand has been encoded into `Value`:
+ /// ```
+ /// InstType = PostEncoderMethod(const MCInst &MI, InstType Value,
+ /// const MCSubtargetInfo &STI);
+ /// ```
string PostEncoderMethod = "";
/// Target-specific flags. This becomes the TSFlags field in TargetInstrDesc.
@@ -755,6 +792,14 @@ class Instruction : InstructionEncoding {
///@name Assembler Parser Support
///@{
+ /// Custom Assembly Converter. If non-zero, this is used for converting the
+ /// matched mnemonic's operand tokens into MCOperands and adding them to the
+ /// MCInst.
+ ///
+ /// Will be called as:
+ /// `void AsmMatchConverter(MCInst &Inst, const OperandVector &Operands);`
+ ///
+ /// See also: InstAlias.UseInstAsmMatchConverter.
string AsmMatchConverter = "";
/// TwoOperandAliasConstraint - Enable TableGen to auto-generate a
@@ -828,8 +873,15 @@ class PseudoInstExpansion<dag Result> {
/// Predicates - These are extra conditionals which are turned into instruction
/// selector matching code. Currently each predicate is just a string.
-class Predicate<string cond> {
- string CondString = cond;
+class Predicate<code cond> {
+
+ /// This is a C++ expression which can be evaluated to return a bool,
+ /// representing whether the predicate is satisifed.
+ ///
+ /// The following variables are in scope:
+ /// - `const GET_DAGISEL_BODY *this` representing the target's DAGToDAGISel
+ /// instance.
+ code CondString = cond;
/// AssemblerMatcherPredicate - If this feature can be used by the assembler
/// matcher, this is true. Targets should set this by inheriting their
@@ -989,7 +1041,9 @@ class AsmOperandClass {
/// The name of the method on the target specific operand to call to custom
/// handle the operand parsing. This is useful when the operands do not relate
/// to immediates or registers and are very instruction specific (as flags to
- /// set in a processor register, coprocessor number, ...).
+ /// set in a processor register, coprocessor number, ...). The method
+ /// signature should be:
+ /// ParseStatus ParserMethod(OperandVector &Operands);
string ParserMethod = ?;
// The diagnostic type to present when referencing this operand in a
@@ -1025,14 +1079,41 @@ def ImmAsmOperand : AsmOperandClass {
/// needed, though this should not be needed for RISC targets.
class Operand<ValueType ty> : DAGOperand {
ValueType Type = ty;
+
+ // Custom method for printing the current operand.
+ //
+ // This will be invoked with the following signature, on the class denoted
+ // by `TargetName # AsmWriter.AsmWriterClassName`
+ // ```
+ // void Class::PrintMethod(const MCInst *MI, unsigned OpNo,
+ // const MCSubtargetInfo &STI, raw_ostream &O);
+ // ```
string PrintMethod = "printOperand";
+
+ /// This method will be used to encode the operand into bits, which will be
+ /// placed into the final instruction according to the Encoding information.
+ ///
+ /// This will be called with the following signature:
+ /// ```
+ /// uint64_t MCCodeEmitter::EncoderMethod(const MCInst &MI, unsigned OpNo,
+ /// SmallVectorImpl<MCFixup> &Fixups,
+ /// const MCSubtargetInfo &STI) const;
+ /// ```
string EncoderMethod = "";
+
string OperandType = "OPERAND_UNKNOWN";
+
+ /// This operand may have sub-operands. Their use is complex, but this is
+ /// where they would be described.
dag MIOperandInfo = (ops);
- // MCOperandPredicate - Optionally, a code fragment operating on
- // const MCOperand &MCOp, and returning a bool, to indicate if
- // the value of MCOp is valid for the specific subclass of Operand
+ // MCOperandPredicate - Optionally, a C++ fragment returning a bool to
+ // indicate if the value of the operand is valid for this specific subclass of
+ // Operand.
+ //
+ // The following variables are in scope:
+ // - `const MCOperand &MCOp` representing the current Operand
+ // - `const MCSubtargetInfo &STI` representing the current subtarget.
code MCOperandPredicate;
// ParserMatchClass - The "match class" that operands of this type fit
@@ -1050,13 +1131,14 @@ class RegisterOperand<RegisterClassLike regclass, string pm = "printOperand">
: DAGOperand {
// RegClass - The register class of the operand.
RegisterClassLike RegClass = regclass;
+
// PrintMethod - The target method to call to print register operands of
// this type. The method normally will just use an alt-name index to look
// up the name to print. Default to the generic printOperand().
string PrintMethod = pm;
// EncoderMethod - The target method name to call to encode this register
- // operand.
+ // operand. See `Operand.EncoderMethod`.
string EncoderMethod = "";
// ParserMatchClass - The "match class" that operands of this type fit
@@ -1699,6 +1781,11 @@ class AsmParser {
// AsmParserInstCleanup - If non-empty, this is the name of a custom member
// function of the AsmParser class to call on every matched instruction.
// This can be used to perform target specific instruction post-processing.
+ //
+ // This will be invoked with the following signature:
+ // ```
+ // void AsmParserInstCleanup(MCInst &Inst);
+ // ```
string AsmParserInstCleanup = "";
// ShouldEmitMatchRegisterName - Set to false if the target needs a hand
@@ -1734,8 +1821,16 @@ class AsmParser {
bit ReportMultipleNearMisses = false;
// OperandParserMethod - If non-empty, this is the name of a custom
- // member function of the AsmParser class to call for every instruction
- // operand to be parsed.
+ // member function of the AsmParser class to call for every custom instruction
+ // operand to be parsed. If unset, this defaults to calling the generated
+ // `tryCustomParseOperand` implementation.
+ //
+ // This will be invoked with the following signature, on the target's
+ // `AsmParser` subclass. The `MCK` operand represents the generated
+ // Match Class Kind.
+ // ```
+ // ParseStatus OperandParserMethod(OperandVector &Operands, unsigned MCK);
+ // ```
string OperandParserMethod = "";
// CallCustomParserForAllOperands - Set to true if the custom parser
@@ -1745,15 +1840,15 @@ class AsmParser {
// PreferSmallerInstructions - Should the assembly matcher prefer the smaller
// instructions.
- //
+ //
// This is useful for the ARM instructions set where smaller encodings must
// be preferentially selected.
//
- // The preference order is:
+ // The preference order is:
// Instrution size (if this option is enabled, smallest first)
- // Number of Operands (least first),
- // Operand Classes (lexicographically by operand),
- // (Optional) Instruction id (see AsmMatcherEmitter.cpp for details),
+ // Number of Operands (least first),
+ // Operand Classes (lexicographically by operand),
+ // (Optional) Instruction id (see AsmMatcherEmitter.cpp for details),
// Number of required features (least first)
bit PreferSmallerInstructions = false;
}
@@ -1802,8 +1897,11 @@ def all_of;
/// AssemblerPredicate - This is a Predicate that can be used when the assembler
/// matches instructions and aliases.
class AssemblerPredicate<dag cond, string name = ""> {
+ // See `Predicate.AssemblerMatcherPredicate`
bit AssemblerMatcherPredicate = true;
+ // See: Predicate.AssemblerCondDag`
dag AssemblerCondDag = cond;
+ // See: Predicate.PredicateName
string PredicateName = name;
}
More information about the llvm-commits
mailing list