X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=include%2Fllvm%2FTarget%2FTarget.td;h=4d6958e92a05219c87d6f6e33af56cb542343098;hp=a68eb8339d2a1e25be579a7be637f8f4a2604f3e;hb=80f927c1c1915a4a302952e6ff71c55b27e8cbef;hpb=1008f8c789a9f821f6a2034781983b7747e78769 diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index a68eb8339d2..4d6958e92a0 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// // 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 @@ -22,12 +22,22 @@ include "llvm/Intrinsics.td" class RegisterClass; // Forward def // SubRegIndex - Use instances of SubRegIndex to identify subregisters. -class SubRegIndex comps = []> { +class SubRegIndex { 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 ComposedOf = comps; + // See ComposedSubRegIndex. + list ComposedOf = []; // CoveringSubRegIndices - A list of two or more sub-register indexes that // cover this sub-register. @@ -48,6 +58,16 @@ class SubRegIndex comps = []> { list 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 { + // See SubRegIndex. + let ComposedOf = [A, B]; +} + // RegAltNameIndex - The alternate name set to use for register operands of // this register class when printing. class RegAltNameIndex { @@ -187,6 +207,12 @@ class RegisterClass regTypes, int alignment, // 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 @@ -355,22 +381,29 @@ class Instruction { 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 = ?; - bit neverHasSideEffects = 0; // Is this instruction a "real" instruction (with a distinct machine // encoding), or is it a pseudo instruction used for codegen modeling @@ -396,6 +429,9 @@ class Instruction { InstrItinClass Itinerary = NoItinerary;// Execution steps used for scheduling. + // Scheduling information from TargetSchedule.td. + list SchedRW; + string Constraints = ""; // OperandConstraint, e.g. $src = $dst. /// DisableEncoding - List of operand names (e.g. "$op1,$op2") that should not @@ -421,6 +457,11 @@ class Instruction { 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. @@ -466,7 +507,7 @@ class Requires preds> { /// 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; @@ -554,10 +595,14 @@ class Operand : DAGOperand { string PrintMethod = "printOperand"; string EncoderMethod = ""; string DecoderMethod = ""; - string AsmOperandLowerMethod = ?; 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. @@ -586,6 +631,9 @@ class RegisterOperand // 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 { @@ -603,6 +651,11 @@ def f64imm : Operand; /// 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 @@ -618,7 +671,7 @@ class OperandWithDefaultOps /// AlwaysVal specifies the value of this predicate when set to "always /// execute". class PredicateOperand - : OperandWithDefaultOps { + : OperandWithDefaultOps, PredicateOp { let MIOperandInfo = OpTypes; } @@ -651,6 +704,27 @@ class InstrInfo { // // 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. @@ -666,9 +740,9 @@ def INLINEASM : Instruction { 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 = ""; @@ -693,26 +767,26 @@ def KILL : Instruction { 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; } @@ -720,33 +794,33 @@ def SUBREG_TO_REG : Instruction { 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 { @@ -758,13 +832,60 @@ def LIFETIME_START : Instruction { let OutOperandList = (outs); let InOperandList = (ins i32imm:$id); let AsmString = "LIFETIME_START"; - let neverHasSideEffects = 1; + let hasSideEffects = 0; } def LIFETIME_END : Instruction { let OutOperandList = (outs); let InOperandList = (ins i32imm:$id); let AsmString = "LIFETIME_END"; - let neverHasSideEffects = 1; + 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 FRAME_ALLOC : 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; } } @@ -786,9 +907,12 @@ class AsmParser { // 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 + // 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; @@ -803,6 +927,9 @@ class AsmParserVariant { // 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. @@ -856,9 +983,16 @@ class TokenAlias { /// def : MnemonicAlias<"pushf", "pushfq">, Requires<[In64BitMode]>; /// def : MnemonicAlias<"pushf", "pushfl">, Requires<[In32BitMode]>; /// -class MnemonicAlias { +/// 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 FromMnemonic = From; string ToMnemonic = To; + string AsmVariantName = VariantName; // Predicates - Predicates that must be true for this remapping to happen. list Predicates = []; @@ -867,13 +1001,27 @@ class MnemonicAlias { /// InstAlias - This defines an alternate assembly syntax that is allowed to /// match an instruction that has a different (more canonical) assembly /// representation. -class InstAlias { +class InstAlias { 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 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; } //===----------------------------------------------------------------------===// @@ -887,7 +1035,12 @@ class AsmWriter { // 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 @@ -896,22 +1049,6 @@ class AsmWriter { // 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; @@ -963,6 +1100,17 @@ class SubtargetFeature Implies = i; } +/// Specifies a Subtarget feature that this instruction is deprecated on. +class Deprecated { + SubtargetFeature DeprecatedFeatureMask = dep; +} + +/// A custom predicate used to determine if an instruction is +/// deprecated or not. +class ComplexDeprecationPredicate { + string ComplexDeprecationPredicate = dep; +} + //===----------------------------------------------------------------------===// // Processor chip sets - These values represent each of the chip sets supported // by the scheduler. Each Processor definition requires corresponding @@ -997,6 +1145,55 @@ class ProcessorModel 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 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 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 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 > ValueCols = []; +} + //===----------------------------------------------------------------------===// // Pull in the common support for calling conventions. //