X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=include%2Fllvm%2FTarget%2FTarget.td;h=01c6e343208736b643f458e133a0d8493746d87b;hp=1781e477f2c526198cb35a339443f7a9c012ef1b;hb=d2e1e42c1a10d05067832eae990ddc1fa55c9c34;hpb=0b8c9a80f20772c3793201ab5b251d3520b9cea3 diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 1781e477f2c..01c6e343208 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -22,12 +22,22 @@ include "llvm/IR/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 @@ -405,6 +441,30 @@ class Instruction { 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; @@ -421,6 +481,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 +531,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 +619,15 @@ class Operand : DAGOperand { 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. @@ -586,6 +656,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 +676,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 +696,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 +729,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 +765,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 +792,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 +819,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 +857,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 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; } } @@ -786,9 +932,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 +952,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 +1008,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 +1026,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 +1060,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 +1074,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 +1125,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