2018-05-25 17:55:37 +02:00
|
|
|
//===- TargetInstrPredicate.td - ---------------------------*- tablegen -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file defines MCInstPredicate classes and its subclasses.
|
|
|
|
//
|
|
|
|
// MCInstPredicate is used to describe constraints on the opcode/operand(s) of
|
|
|
|
// an instruction. Each MCInstPredicate class has a well-known semantic, and it
|
|
|
|
// is used by a PredicateExpander to generate code for MachineInstr and/or
|
|
|
|
// MCInst.
|
2018-07-30 21:41:25 +02:00
|
|
|
//
|
2018-05-25 17:55:37 +02:00
|
|
|
// MCInstPredicate definitions can be used to construct MCSchedPredicate
|
|
|
|
// definitions. An MCSchedPredicate can be used in place of a SchedPredicate
|
|
|
|
// when defining SchedReadVariant and SchedWriteVariant used by a processor
|
|
|
|
// scheduling model.
|
|
|
|
//
|
|
|
|
// Here is an example of MCInstPredicate definition:
|
|
|
|
//
|
|
|
|
// def MCInstPredicateExample : CheckAll<[
|
|
|
|
// CheckOpcode<[BLR]>,
|
|
|
|
// CheckIsRegOperand<0>,
|
|
|
|
// CheckNot<CheckRegOperand<0, LR>>]>;
|
|
|
|
//
|
|
|
|
// Predicate `MCInstPredicateExample` checks that the machine instruction in
|
|
|
|
// input is a BLR, and that operand at index 0 is register `LR`.
|
|
|
|
//
|
|
|
|
// That predicate could be used to rewrite the following definition (from
|
|
|
|
// AArch64SchedExynosM3.td):
|
|
|
|
//
|
|
|
|
// def M3BranchLinkFastPred : SchedPredicate<[{
|
|
|
|
// MI->getOpcode() == AArch64::BLR &&
|
|
|
|
// MI->getOperand(0).isReg() &&
|
|
|
|
// MI->getOperand(0).getReg() != AArch64::LR}]>;
|
|
|
|
//
|
|
|
|
// MCInstPredicate definitions are used to construct MCSchedPredicate (see the
|
|
|
|
// definition of class MCSchedPredicate in llvm/Target/TargetSchedule.td). An
|
|
|
|
// MCSchedPredicate can be used by a `SchedVar` to associate a predicate with a
|
|
|
|
// list of SchedReadWrites. Note that `SchedVar` are used to create SchedVariant
|
|
|
|
// definitions.
|
|
|
|
//
|
|
|
|
// Each MCInstPredicate class has a well known semantic. For example,
|
|
|
|
// `CheckOpcode` is only used to check the instruction opcode value.
|
|
|
|
//
|
|
|
|
// MCInstPredicate classes allow the definition of predicates in a declarative
|
|
|
|
// way. These predicates don't require a custom block of C++, and can be used
|
|
|
|
// to define conditions on instructions without being bound to a particular
|
|
|
|
// representation (i.e. MachineInstr vs MCInst).
|
|
|
|
//
|
|
|
|
// It also means that tablegen backends must know how to parse and expand them
|
|
|
|
// into code that works on MCInst (or MachineInst).
|
|
|
|
//
|
|
|
|
// Instances of class PredicateExpander (see utils/Tablegen/PredicateExpander.h)
|
|
|
|
// know how to expand a predicate. For each MCInstPredicate class, there must be
|
|
|
|
// an "expand" method available in the PredicateExpander interface.
|
|
|
|
//
|
|
|
|
// For example, a `CheckOpcode` predicate is expanded using method
|
|
|
|
// `PredicateExpander::expandCheckOpcode()`.
|
|
|
|
//
|
|
|
|
// New MCInstPredicate classes must be added to this file. For each new class
|
|
|
|
// XYZ, an "expandXYZ" method must be added to the PredicateExpander.
|
2018-07-30 21:41:25 +02:00
|
|
|
//
|
2018-05-25 17:55:37 +02:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
// Forward declarations.
|
|
|
|
class Instruction;
|
|
|
|
|
|
|
|
// A generic machine instruction predicate.
|
|
|
|
class MCInstPredicate;
|
|
|
|
|
|
|
|
class MCTrue : MCInstPredicate; // A predicate that always evaluates to True.
|
|
|
|
class MCFalse : MCInstPredicate; // A predicate that always evaluates to False.
|
|
|
|
def TruePred : MCTrue;
|
|
|
|
def FalsePred : MCFalse;
|
|
|
|
|
|
|
|
// A predicate used to negate the outcome of another predicate.
|
|
|
|
// It allows to easily express "set difference" operations. For example, it
|
|
|
|
// makes it easy to describe a check that tests if an opcode is not part of a
|
|
|
|
// set of opcodes.
|
|
|
|
class CheckNot<MCInstPredicate P> : MCInstPredicate {
|
|
|
|
MCInstPredicate Pred = P;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This class is used as a building block to define predicates on instruction
|
|
|
|
// operands. It is used to reference a specific machine operand.
|
|
|
|
class MCOperandPredicate<int Index> : MCInstPredicate {
|
|
|
|
int OpIndex = Index;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return true if machine operand at position `Index` is a register operand.
|
|
|
|
class CheckIsRegOperand<int Index> : MCOperandPredicate<Index>;
|
|
|
|
|
|
|
|
// Return true if machine operand at position `Index` is an immediate operand.
|
|
|
|
class CheckIsImmOperand<int Index> : MCOperandPredicate<Index>;
|
|
|
|
|
|
|
|
// Check if machine operands at index `First` and index `Second` both reference
|
|
|
|
// the same register.
|
|
|
|
class CheckSameRegOperand<int First, int Second> : MCInstPredicate {
|
|
|
|
int FirstIndex = First;
|
|
|
|
int SecondIndex = Second;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that the machine register operand at position `Index` references
|
|
|
|
// register R. This predicate assumes that we already checked that the machine
|
|
|
|
// operand at position `Index` is a register operand.
|
|
|
|
class CheckRegOperand<int Index, Register R> : MCOperandPredicate<Index> {
|
|
|
|
Register Reg = R;
|
|
|
|
}
|
|
|
|
|
2018-07-18 13:16:31 +02:00
|
|
|
// Check if register operand at index `Index` is the invalid register.
|
|
|
|
class CheckInvalidRegOperand<int Index> : MCOperandPredicate<Index>;
|
|
|
|
|
2018-05-25 17:55:37 +02:00
|
|
|
// Check that the operand at position `Index` is immediate `Imm`.
|
|
|
|
class CheckImmOperand<int Index, int Imm> : MCOperandPredicate<Index> {
|
|
|
|
int ImmVal = Imm;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Similar to CheckImmOperand, however the immediate is not a literal number.
|
|
|
|
// This is useful when we want to compare the value of an operand against an
|
|
|
|
// enum value, and we know the actual integer value of that enum.
|
|
|
|
class CheckImmOperand_s<int Index, string Value> : MCOperandPredicate<Index> {
|
|
|
|
string ImmVal = Value;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that the operand at position `Index` is immediate value zero.
|
|
|
|
class CheckZeroOperand<int Index> : CheckImmOperand<Index, 0>;
|
|
|
|
|
|
|
|
// Check that the instruction has exactly `Num` operands.
|
|
|
|
class CheckNumOperands<int Num> : MCInstPredicate {
|
|
|
|
int NumOps = Num;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that the instruction opcode is one of the opcodes in set `Opcodes`.
|
|
|
|
// This is a simple set membership query. The easier way to check if an opcode
|
|
|
|
// is not a member of the set is by using a `CheckNot<CheckOpcode<[...]>>`
|
|
|
|
// sequence.
|
|
|
|
class CheckOpcode<list<Instruction> Opcodes> : MCInstPredicate {
|
|
|
|
list<Instruction> ValidOpcodes = Opcodes;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that the instruction opcode is a pseudo opcode member of the set
|
|
|
|
// `Opcodes`. This check is always expanded to "false" if we are generating
|
|
|
|
// code for MCInst.
|
|
|
|
class CheckPseudo<list<Instruction> Opcodes> : CheckOpcode<Opcodes>;
|
|
|
|
|
|
|
|
// A non-portable predicate. Only to use as a last resort when a block of code
|
|
|
|
// cannot possibly be converted in a declarative way using other MCInstPredicate
|
|
|
|
// classes. This check is always expanded to "false" when generating code for
|
|
|
|
// MCInst.
|
|
|
|
class CheckNonPortable<string Code> : MCInstPredicate {
|
|
|
|
string CodeBlock = Code;
|
|
|
|
}
|
|
|
|
|
|
|
|
// A sequence of predicates. It is used as the base class for CheckAll, and
|
|
|
|
// CheckAny. It allows to describe compositions of predicates.
|
|
|
|
class CheckPredicateSequence<list<MCInstPredicate> Preds> : MCInstPredicate {
|
|
|
|
list<MCInstPredicate> Predicates = Preds;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that all of the predicates in `Preds` evaluate to true.
|
|
|
|
class CheckAll<list<MCInstPredicate> Sequence>
|
|
|
|
: CheckPredicateSequence<Sequence>;
|
|
|
|
|
|
|
|
// Check that at least one of the predicates in `Preds` evaluates to true.
|
|
|
|
class CheckAny<list<MCInstPredicate> Sequence>
|
|
|
|
: CheckPredicateSequence<Sequence>;
|
|
|
|
|
2018-08-09 17:32:48 +02:00
|
|
|
|
|
|
|
// Used to expand the body of a function predicate. See the definition of
|
|
|
|
// TIIPredicate below.
|
|
|
|
class MCStatement;
|
|
|
|
|
|
|
|
// Expands to a return statement. The return expression is a boolean expression
|
|
|
|
// described by a MCInstPredicate.
|
|
|
|
class MCReturnStatement<MCInstPredicate predicate> : MCStatement {
|
|
|
|
MCInstPredicate Pred = predicate;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Used to automatically construct cases of a switch statement where the switch
|
|
|
|
// variable is an instruction opcode. There is a 'case' for every opcode in the
|
|
|
|
// `opcodes` list, and each case is associated with MCStatement `caseStmt`.
|
|
|
|
class MCOpcodeSwitchCase<list<Instruction> opcodes, MCStatement caseStmt> {
|
|
|
|
list<Instruction> Opcodes = opcodes;
|
|
|
|
MCStatement CaseStmt = caseStmt;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Expands to a switch statement. The switch variable is an instruction opcode.
|
|
|
|
// The auto-generated switch is populated by a number of cases based on the
|
|
|
|
// `cases` list in input. A default case is automatically generated, and it
|
|
|
|
// evaluates to `default`.
|
|
|
|
class MCOpcodeSwitchStatement<list<MCOpcodeSwitchCase> cases,
|
|
|
|
MCStatement default> : MCStatement {
|
|
|
|
list<MCOpcodeSwitchCase> Cases = cases;
|
|
|
|
MCStatement DefaultCase = default;
|
|
|
|
}
|
|
|
|
|
2018-05-25 17:55:37 +02:00
|
|
|
// Check that a call to method `Name` in class "XXXGenInstrInfo" (where XXX is
|
|
|
|
// the `Target` name) returns true.
|
|
|
|
//
|
|
|
|
// TIIPredicate definitions are used to model calls to the target-specific
|
|
|
|
// InstrInfo. A TIIPredicate is treated specially by the InstrInfoEmitter
|
|
|
|
// tablegen backend, which will use it to automatically generate a definition in
|
|
|
|
// the target specific `GenInstrInfo` class.
|
2018-08-09 17:32:48 +02:00
|
|
|
class TIIPredicate<string Target, string Name, MCStatement body>
|
|
|
|
: MCInstPredicate {
|
2018-05-25 17:55:37 +02:00
|
|
|
string TargetName = Target;
|
|
|
|
string FunctionName = Name;
|
2018-08-09 17:32:48 +02:00
|
|
|
MCStatement Body = body;
|
2018-05-25 17:55:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// A function predicate that takes as input a machine instruction, and returns
|
|
|
|
// a boolean value.
|
|
|
|
//
|
|
|
|
// This predicate is expanded into a function call by the PredicateExpander.
|
|
|
|
// In particular, the PredicateExpander would either expand this predicate into
|
|
|
|
// a call to `MCInstFn`, or into a call to`MachineInstrFn` depending on whether
|
|
|
|
// it is lowering predicates for MCInst or MachineInstr.
|
|
|
|
//
|
|
|
|
// In this context, `MCInstFn` and `MachineInstrFn` are both function names.
|
|
|
|
class CheckFunctionPredicate<string MCInstFn, string MachineInstrFn> : MCInstPredicate {
|
|
|
|
string MCInstFnName = MCInstFn;
|
|
|
|
string MachineInstrFnName = MachineInstrFn;
|
|
|
|
}
|