//===----------------------------------------------------------------------===//
// Include all information about LLVM intrinsics.
-include "llvm/Intrinsics.td"
+include "llvm/IR/Intrinsics.td"
//===----------------------------------------------------------------------===//
// Register file description - These classes are used to fill in the target
class RegisterClass; // Forward def
// SubRegIndex - Use instances of SubRegIndex to identify subregisters.
-class SubRegIndex<list<SubRegIndex> comps = []> {
+class SubRegIndex<int size, int offset = 0> {
string Namespace = "";
+ // Size - Size (in bits) of the sub-registers represented by this index.
+ int Size = size;
+
+ // Offset - Offset of the first bit that is part of this sub-register index.
+ // Set it to -1 if the same index is used to represent sub-registers that can
+ // be at different offsets (for example when using an index to access an
+ // element in a register tuple).
+ int Offset = offset;
+
// ComposedOf - A list of two SubRegIndex instances, [A, B].
// This indicates that this SubRegIndex is the result of composing A and B.
- list<SubRegIndex> ComposedOf = comps;
+ // See ComposedSubRegIndex.
+ list<SubRegIndex> ComposedOf = [];
// CoveringSubRegIndices - A list of two or more sub-register indexes that
// cover this sub-register.
list<SubRegIndex> CoveringSubRegIndices = [];
}
+// ComposedSubRegIndex - A sub-register that is the result of composing A and B.
+// Offset is set to the sum of A and B's Offsets. Size is set to B's Size.
+class ComposedSubRegIndex<SubRegIndex A, SubRegIndex B>
+ : SubRegIndex<B.Size, !if(!eq(A.Offset, -1), -1,
+ !if(!eq(B.Offset, -1), -1,
+ !add(A.Offset, B.Offset)))> {
+ // See SubRegIndex.
+ let ComposedOf = [A, B];
+}
+
// RegAltNameIndex - The alternate name set to use for register operands of
// this register class when printing.
class RegAltNameIndex {
// The function should return 0 to select the default order defined by
// MemberList, 1 to select the first AltOrders entry and so on.
code AltOrderSelect = [{}];
+
+ // Specify allocation priority for register allocators using a greedy
+ // heuristic. Classes with higher priority values are assigned first. This is
+ // useful as it is sometimes beneficial to assign registers to highly
+ // constrained classes first. The value has to be in the range [0,63].
+ int AllocationPriority = 0;
}
// The memberList in a RegisterClass is a dag of set operations. TableGen
bit isBarrier = 0; // Can control flow fall through this instruction?
bit isCall = 0; // Is this instruction a call instruction?
bit canFoldAsLoad = 0; // Can this be folded as a simple memory operand?
- bit mayLoad = 0; // Is it possible for this inst to read memory?
- bit mayStore = 0; // Is it possible for this inst to write memory?
+ bit mayLoad = ?; // Is it possible for this inst to read memory?
+ bit mayStore = ?; // Is it possible for this inst to write memory?
bit isConvertibleToThreeAddress = 0; // Can this 2-addr instruction promote?
bit isCommutable = 0; // Is this 3 operand instruction commutable?
bit isTerminator = 0; // Is this part of the terminator for a basic block?
bit hasPostISelHook = 0; // To be *adjusted* after isel by target hook.
bit hasCtrlDep = 0; // Does this instruction r/w ctrl-flow chains?
bit isNotDuplicable = 0; // Is it unsafe to duplicate this instruction?
+ bit isConvergent = 0; // Is this instruction convergent?
bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction.
bit hasExtraSrcRegAllocReq = 0; // Sources have special regalloc requirement?
bit hasExtraDefRegAllocReq = 0; // Defs have special regalloc requirement?
+ bit isRegSequence = 0; // Is this instruction a kind of reg sequence?
+ // If so, make sure to override
+ // TargetInstrInfo::getRegSequenceLikeInputs.
bit isPseudo = 0; // Is this instruction a pseudo-instruction?
// If so, won't have encoding information for
// the [MC]CodeEmitter stuff.
+ bit isExtractSubreg = 0; // Is this instruction a kind of extract subreg?
+ // If so, make sure to override
+ // TargetInstrInfo::getExtractSubregLikeInputs.
+ bit isInsertSubreg = 0; // Is this instruction a kind of insert subreg?
+ // If so, make sure to override
+ // TargetInstrInfo::getInsertSubregLikeInputs.
// Side effect flags - When set, the flags have these meanings:
//
// hasSideEffects - The instruction has side effects that are not
// captured by any operands of the instruction or other flags.
//
- // neverHasSideEffects - Set on an instruction with no pattern if it has no
- // side effects.
- bit hasSideEffects = 0;
- bit neverHasSideEffects = 0;
+ bit hasSideEffects = ?;
// Is this instruction a "real" instruction (with a distinct machine
// encoding), or is it a pseudo instruction used for codegen modeling
InstrItinClass Itinerary = NoItinerary;// Execution steps used for scheduling.
+ // Scheduling information from TargetSchedule.td.
+ list<SchedReadWrite> SchedRW;
+
string Constraints = ""; // OperandConstraint, e.g. $src = $dst.
/// DisableEncoding - List of operand names (e.g. "$op1,$op2") that should not
string PostEncoderMethod = "";
string DecoderMethod = "";
+ // Is the instruction decoder method able to completely determine if the
+ // given instruction is valid or not. If the TableGen definition of the
+ // instruction specifies bitpattern A??B where A and B are static bits, the
+ // hasCompleteDecoder flag says whether the decoder method fully handles the
+ // ?? space, i.e. if it is a final arbiter for the instruction validity.
+ // If not then the decoder attempts to continue decoding when the decoder
+ // method fails.
+ //
+ // This allows to handle situations where the encoding is not fully
+ // orthogonal. Example:
+ // * InstA with bitpattern 0b0000????,
+ // * InstB with bitpattern 0b000000?? but the associated decoder method
+ // DecodeInstB() returns Fail when ?? is 0b00 or 0b11.
+ //
+ // The decoder tries to decode a bitpattern that matches both InstA and
+ // InstB bitpatterns first as InstB (because it is the most specific
+ // encoding). In the default case (hasCompleteDecoder = 1), when
+ // DecodeInstB() returns Fail the bitpattern gets rejected. By setting
+ // hasCompleteDecoder = 0 in InstB, the decoder is informed that
+ // DecodeInstB() is not able to determine if all possible values of ?? are
+ // valid or not. If DecodeInstB() returns Fail the decoder will attempt to
+ // decode the bitpattern as InstA too.
+ bit hasCompleteDecoder = 1;
+
/// Target-specific flags. This becomes the TSFlags field in TargetInstrDesc.
bits<64> TSFlags = 0;
string TwoOperandAliasConstraint = "";
///@}
+
+ /// UseNamedOperandTable - If set, the operand indices of this instruction
+ /// can be queried via the getNamedOperandIdx() function which is generated
+ /// by TableGen.
+ bit UseNamedOperandTable = 0;
}
/// PseudoInstExpansion - Expansion information for a pseudo-instruction.
/// ops definition - This is just a simple marker used to identify the operand
/// list for an instruction. outs and ins are identical both syntactically and
-/// semanticallyr; they are used to define def operands and use operands to
+/// semantically; they are used to define def operands and use operands to
/// improve readibility. This should be used like this:
/// (outs R32:$dst), (ins R32:$src1, R32:$src2) or something similar.
def ops;
/// unknown definition - Mark this operand as being of unknown type, causing
/// it to be resolved by inference in the context it is used.
-def unknown;
+class unknown_class;
+def unknown : unknown_class;
/// AsmOperandClass - Representation for the kinds of operands which the target
/// specific parser can create and the assembly matcher may need to distinguish.
string PrintMethod = "printOperand";
string EncoderMethod = "";
string DecoderMethod = "";
- string AsmOperandLowerMethod = ?;
+ bit hasCompleteDecoder = 1;
string OperandType = "OPERAND_UNKNOWN";
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
+ code MCOperandPredicate;
+
// ParserMatchClass - The "match class" that operands of this type fit
// in. Match classes are used to define the order in which instructions are
// match, to ensure that which instructions gets matched is deterministic.
// can match a subset of some other class, in which case the AsmOperandClass
// should declare the other operand as one of its super classes.
AsmOperandClass ParserMatchClass;
+
+ string OperandNamespace = "MCOI";
+ string OperandType = "OPERAND_REGISTER";
}
let OperandType = "OPERAND_IMMEDIATE" in {
///
def zero_reg;
+/// All operands which the MC layer classifies as predicates should inherit from
+/// this class in some manner. This is already handled for the most commonly
+/// used PredicateOperand, but may be useful in other circumstances.
+class PredicateOp;
+
+/// OperandWithDefaultOps - This Operand class can be used as the parent class
+/// for an Operand that needs to be initialized with a default value if
+/// no value is supplied in a pattern. This class can be used to simplify the
+/// pattern definitions for instructions that have target specific flags
+/// encoded as immediate operands.
+class OperandWithDefaultOps<ValueType ty, dag defaultops>
+ : Operand<ty> {
+ dag DefaultOps = defaultops;
+}
+
/// PredicateOperand - This can be used to define a predicate operand for an
/// instruction. OpTypes specifies the MIOperandInfo for the operand, and
/// AlwaysVal specifies the value of this predicate when set to "always
/// execute".
class PredicateOperand<ValueType ty, dag OpTypes, dag AlwaysVal>
- : Operand<ty> {
+ : OperandWithDefaultOps<ty, AlwaysVal>, PredicateOp {
let MIOperandInfo = OpTypes;
- dag DefaultOps = AlwaysVal;
}
/// OptionalDefOperand - This is used to define a optional definition operand
/// for an instruction. DefaultOps is the register the operand represents if
/// none is supplied, e.g. zero_reg.
class OptionalDefOperand<ValueType ty, dag OpTypes, dag defaultops>
- : Operand<ty> {
+ : OperandWithDefaultOps<ty, defaultops> {
let MIOperandInfo = OpTypes;
- dag DefaultOps = defaultops;
}
// Sparc manual specifies its instructions in the format [31..0] (big), while
// PowerPC specifies them using the format [0..31] (little).
bit isLittleEndianEncoding = 0;
+
+ // The instruction properties mayLoad, mayStore, and hasSideEffects are unset
+ // by default, and TableGen will infer their value from the instruction
+ // pattern when possible.
+ //
+ // Normally, TableGen will issue an error it it can't infer the value of a
+ // property that hasn't been set explicitly. When guessInstructionProperties
+ // is set, it will guess a safe value instead.
+ //
+ // This option is a temporary migration help. It will go away.
+ bit guessInstructionProperties = 1;
+
+ // TableGen's instruction encoder generator has support for matching operands
+ // to bit-field variables both by name and by position. While matching by
+ // name is preferred, this is currently not possible for complex operands,
+ // and some targets still reply on the positional encoding rules. When
+ // generating a decoder for such targets, the positional encoding rules must
+ // be used by the decoder generator as well.
+ //
+ // This option is temporary; it will go away once the TableGen decoder
+ // generator has better support for complex operands and targets have
+ // migrated away from using positionally encoded operands.
+ bit decodePositionallyEncodedOperands = 0;
+
+ // When set, this indicates that there will be no overlap between those
+ // operands that are matched by ordering (positional operands) and those
+ // matched by name.
+ //
+ // This option is temporary; it will go away once the TableGen decoder
+ // generator has better support for complex operands and targets have
+ // migrated away from using positionally encoded operands.
+ bit noNamedPositionallyEncodedOperands = 0;
}
// Standard Pseudo Instructions.
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "";
- let neverHasSideEffects = 1; // Note side effect is encoded in an operand.
+ let hasSideEffects = 0; // Note side effect is encoded in an operand.
}
-def PROLOG_LABEL : Instruction {
+def CFI_INSTRUCTION : Instruction {
let OutOperandList = (outs);
let InOperandList = (ins i32imm:$id);
let AsmString = "";
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "";
- let neverHasSideEffects = 1;
+ let hasSideEffects = 0;
}
def EXTRACT_SUBREG : Instruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$supersrc, i32imm:$subidx);
let AsmString = "";
- let neverHasSideEffects = 1;
+ let hasSideEffects = 0;
}
def INSERT_SUBREG : Instruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$supersrc, unknown:$subsrc, i32imm:$subidx);
let AsmString = "";
- let neverHasSideEffects = 1;
+ let hasSideEffects = 0;
let Constraints = "$supersrc = $dst";
}
def IMPLICIT_DEF : Instruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins);
let AsmString = "";
- let neverHasSideEffects = 1;
+ let hasSideEffects = 0;
let isReMaterializable = 1;
let isAsCheapAsAMove = 1;
}
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$implsrc, unknown:$subsrc, i32imm:$subidx);
let AsmString = "";
- let neverHasSideEffects = 1;
+ let hasSideEffects = 0;
}
def COPY_TO_REGCLASS : Instruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$src, i32imm:$regclass);
let AsmString = "";
- let neverHasSideEffects = 1;
+ let hasSideEffects = 0;
let isAsCheapAsAMove = 1;
}
def DBG_VALUE : Instruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "DBG_VALUE";
- let neverHasSideEffects = 1;
+ let hasSideEffects = 0;
}
def REG_SEQUENCE : Instruction {
let OutOperandList = (outs unknown:$dst);
- let InOperandList = (ins variable_ops);
+ let InOperandList = (ins unknown:$supersrc, variable_ops);
let AsmString = "";
- let neverHasSideEffects = 1;
+ let hasSideEffects = 0;
let isAsCheapAsAMove = 1;
}
def COPY : Instruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$src);
let AsmString = "";
- let neverHasSideEffects = 1;
+ let hasSideEffects = 0;
let isAsCheapAsAMove = 1;
}
def BUNDLE : Instruction {
let InOperandList = (ins variable_ops);
let AsmString = "BUNDLE";
}
+def LIFETIME_START : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins i32imm:$id);
+ let AsmString = "LIFETIME_START";
+ let hasSideEffects = 0;
+}
+def LIFETIME_END : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins i32imm:$id);
+ let AsmString = "LIFETIME_END";
+ let hasSideEffects = 0;
+}
+def STACKMAP : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins i64imm:$id, i32imm:$nbytes, variable_ops);
+ let isCall = 1;
+ let mayLoad = 1;
+ let usesCustomInserter = 1;
+}
+def PATCHPOINT : Instruction {
+ let OutOperandList = (outs unknown:$dst);
+ let InOperandList = (ins i64imm:$id, i32imm:$nbytes, unknown:$callee,
+ i32imm:$nargs, i32imm:$cc, variable_ops);
+ let isCall = 1;
+ let mayLoad = 1;
+ let usesCustomInserter = 1;
+}
+def STATEPOINT : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins variable_ops);
+ let usesCustomInserter = 1;
+ let mayLoad = 1;
+ let mayStore = 1;
+ let hasSideEffects = 1;
+ let isCall = 1;
+}
+def LOAD_STACK_GUARD : Instruction {
+ let OutOperandList = (outs ptr_rc:$dst);
+ let InOperandList = (ins);
+ let mayLoad = 1;
+ bit isReMaterializable = 1;
+ let hasSideEffects = 0;
+ bit isPseudo = 1;
+}
+def LOCAL_ESCAPE : Instruction {
+ // This instruction is really just a label. It has to be part of the chain so
+ // that it doesn't get dropped from the DAG, but it produces nothing and has
+ // no side effects.
+ let OutOperandList = (outs);
+ let InOperandList = (ins ptr_rc:$symbol, i32imm:$id);
+ let hasSideEffects = 0;
+ let hasCtrlDep = 1;
+}
+def FAULTING_LOAD_OP : Instruction {
+ let OutOperandList = (outs unknown:$dst);
+ let InOperandList = (ins variable_ops);
+ let usesCustomInserter = 1;
+ let mayLoad = 1;
+}
}
//===----------------------------------------------------------------------===//
// function of the AsmParser class to call on every matched instruction.
// This can be used to perform target specific instruction post-processing.
string AsmParserInstCleanup = "";
+
+ // ShouldEmitMatchRegisterName - Set to false if the target needs a hand
+ // written register name matcher
+ bit ShouldEmitMatchRegisterName = 1;
+
+ /// Does the instruction mnemonic allow '.'
+ bit MnemonicContainsDot = 0;
}
def DefaultAsmParser : AsmParser;
// assembly language.
int Variant = 0;
+ // Name - The AsmParser variant name (e.g., AT&T vs Intel).
+ string Name = "";
+
// CommentDelimiter - If given, the delimiter string used to recognize
// comments which are hard coded in the .td assembler strings for individual
// instructions.
/// def : MnemonicAlias<"pushf", "pushfq">, Requires<[In64BitMode]>;
/// def : MnemonicAlias<"pushf", "pushfl">, Requires<[In32BitMode]>;
///
-class MnemonicAlias<string From, string To> {
+/// Mnemonic aliases can also be constrained to specific variants, e.g.:
+///
+/// def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>;
+///
+/// If no variant (e.g., "att" or "intel") is specified then the alias is
+/// applied unconditionally.
+class MnemonicAlias<string From, string To, string VariantName = ""> {
string FromMnemonic = From;
string ToMnemonic = To;
+ string AsmVariantName = VariantName;
// Predicates - Predicates that must be true for this remapping to happen.
list<Predicate> Predicates = [];
/// InstAlias - This defines an alternate assembly syntax that is allowed to
/// match an instruction that has a different (more canonical) assembly
/// representation.
-class InstAlias<string Asm, dag Result, bit Emit = 0b1> {
+class InstAlias<string Asm, dag Result, int Emit = 1> {
string AsmString = Asm; // The .s format to match the instruction with.
dag ResultInst = Result; // The MCInst to generate.
- bit EmitAlias = Emit; // Emit the alias instead of what's aliased.
+
+ // This determines which order the InstPrinter detects aliases for
+ // printing. A larger value makes the alias more likely to be
+ // emitted. The Instruction's own definition is notionally 0.5, so 0
+ // disables printing and 1 enables it if there are no conflicting aliases.
+ int EmitPriority = Emit;
// Predicates - Predicates that must be true for this to match.
list<Predicate> Predicates = [];
+
+ // If the instruction specified in Result has defined an AsmMatchConverter
+ // then setting this to 1 will cause the alias to use the AsmMatchConverter
+ // function when converting the OperandVector into an MCInst instead of the
+ // function that is generated by the dag Result.
+ // Setting this to 0 will cause the alias to ignore the Result instruction's
+ // defined AsmMatchConverter and instead use the function generated by the
+ // dag Result.
+ bit UseInstAsmMatchConverter = 1;
}
//===----------------------------------------------------------------------===//
// AsmWriterClassName - This specifies the suffix to use for the asmwriter
// class. Generated AsmWriter classes are always prefixed with the target
// name.
- string AsmWriterClassName = "AsmPrinter";
+ string AsmWriterClassName = "InstPrinter";
+
+ // PassSubtarget - Determines whether MCSubtargetInfo should be passed to
+ // the various print methods.
+ // FIXME: Remove after all ports are updated.
+ int PassSubtarget = 0;
// Variant - AsmWriters can be of multiple different variants. Variants are
// used to support targets that need to emit assembly code in ways that are
// will specify which alternative to use. For example "{x|y|z}" with Variant
// == 1, will expand to "y".
int Variant = 0;
-
-
- // FirstOperandColumn/OperandSpacing - If the assembler syntax uses a columnar
- // layout, the asmwriter can actually generate output in this columns (in
- // verbose-asm mode). These two values indicate the width of the first column
- // (the "opcode" area) and the width to reserve for subsequent operands. When
- // verbose asm mode is enabled, operands will be indented to respect this.
- int FirstOperandColumn = -1;
-
- // OperandSpacing - Space between operand columns.
- int OperandSpacing = -1;
-
- // isMCAsmWriter - Is this assembly writer for an MC emitter? This controls
- // generation of the printInstruction() method. For MC printers, it takes
- // an MCInstr* operand, otherwise it takes a MachineInstr*.
- bit isMCAsmWriter = 0;
}
def DefaultAsmWriter : AsmWriter;
list<SubtargetFeature> Implies = i;
}
+/// Specifies a Subtarget feature that this instruction is deprecated on.
+class Deprecated<SubtargetFeature dep> {
+ SubtargetFeature DeprecatedFeatureMask = dep;
+}
+
+/// A custom predicate used to determine if an instruction is
+/// deprecated or not.
+class ComplexDeprecationPredicate<string dep> {
+ string ComplexDeprecationPredicate = dep;
+}
+
//===----------------------------------------------------------------------===//
// Processor chip sets - These values represent each of the chip sets supported
// by the scheduler. Each Processor definition requires corresponding
// ProcessorModel allows subtargets to specify the more general
// SchedMachineModel instead if a ProcessorItinerary. Subtargets will
// gradually move to this newer form.
+//
+// Although this class always passes NoItineraries to the Processor
+// class, the SchedMachineModel may still define valid Itineraries.
class ProcessorModel<string n, SchedMachineModel m, list<SubtargetFeature> f>
: Processor<n, NoItineraries, f> {
let SchedModel = m;
}
+//===----------------------------------------------------------------------===//
+// InstrMapping - This class is used to create mapping tables to relate
+// instructions with each other based on the values specified in RowFields,
+// ColFields, KeyCol and ValueCols.
+//
+class InstrMapping {
+ // FilterClass - Used to limit search space only to the instructions that
+ // define the relationship modeled by this InstrMapping record.
+ string FilterClass;
+
+ // RowFields - List of fields/attributes that should be same for all the
+ // instructions in a row of the relation table. Think of this as a set of
+ // properties shared by all the instructions related by this relationship
+ // model and is used to categorize instructions into subgroups. For instance,
+ // if we want to define a relation that maps 'Add' instruction to its
+ // predicated forms, we can define RowFields like this:
+ //
+ // let RowFields = BaseOp
+ // All add instruction predicated/non-predicated will have to set their BaseOp
+ // to the same value.
+ //
+ // def Add: { let BaseOp = 'ADD'; let predSense = 'nopred' }
+ // def Add_predtrue: { let BaseOp = 'ADD'; let predSense = 'true' }
+ // def Add_predfalse: { let BaseOp = 'ADD'; let predSense = 'false' }
+ list<string> RowFields = [];
+
+ // List of fields/attributes that are same for all the instructions
+ // in a column of the relation table.
+ // Ex: let ColFields = 'predSense' -- It means that the columns are arranged
+ // based on the 'predSense' values. All the instruction in a specific
+ // column have the same value and it is fixed for the column according
+ // to the values set in 'ValueCols'.
+ list<string> ColFields = [];
+
+ // Values for the fields/attributes listed in 'ColFields'.
+ // Ex: let KeyCol = 'nopred' -- It means that the key instruction (instruction
+ // that models this relation) should be non-predicated.
+ // In the example above, 'Add' is the key instruction.
+ list<string> KeyCol = [];
+
+ // List of values for the fields/attributes listed in 'ColFields', one for
+ // each column in the relation table.
+ //
+ // Ex: let ValueCols = [['true'],['false']] -- It adds two columns in the
+ // table. First column requires all the instructions to have predSense
+ // set to 'true' and second column requires it to be 'false'.
+ list<list<string> > ValueCols = [];
+}
+
//===----------------------------------------------------------------------===//
// Pull in the common support for calling conventions.
//