aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/Target
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Target')
-rw-r--r--include/llvm/Target/SubtargetFeature.h119
-rw-r--r--include/llvm/Target/Target.td39
-rw-r--r--include/llvm/Target/TargetAsmInfo.h4
-rw-r--r--include/llvm/Target/TargetInstrDesc.h520
-rw-r--r--include/llvm/Target/TargetInstrInfo.h44
-rw-r--r--include/llvm/Target/TargetInstrItineraries.h253
-rw-r--r--include/llvm/Target/TargetLowering.h7
-rw-r--r--include/llvm/Target/TargetMachine.h22
-rw-r--r--include/llvm/Target/TargetOptions.h4
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h126
-rw-r--r--include/llvm/Target/TargetRegistry.h134
11 files changed, 235 insertions, 1037 deletions
diff --git a/include/llvm/Target/SubtargetFeature.h b/include/llvm/Target/SubtargetFeature.h
deleted file mode 100644
index 4213d9b..0000000
--- a/include/llvm/Target/SubtargetFeature.h
+++ /dev/null
@@ -1,119 +0,0 @@
-//===-- llvm/Target/SubtargetFeature.h - CPU characteristics ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines and manages user or tool specified CPU characteristics.
-// The intent is to be able to package specific features that should or should
-// not be used on a specific target processor. A tool, such as llc, could, as
-// as example, gather chip info from the command line, a long with features
-// that should be used on that chip.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TARGET_SUBTARGETFEATURE_H
-#define LLVM_TARGET_SUBTARGETFEATURE_H
-
-#include <string>
-#include <vector>
-#include <cstring>
-#include "llvm/ADT/Triple.h"
-#include "llvm/Support/DataTypes.h"
-
-namespace llvm {
- class raw_ostream;
-
-//===----------------------------------------------------------------------===//
-///
-/// SubtargetFeatureKV - Used to provide key value pairs for feature and
-/// CPU bit flags.
-//
-struct SubtargetFeatureKV {
- const char *Key; // K-V key string
- const char *Desc; // Help descriptor
- uint64_t Value; // K-V integer value
- uint64_t Implies; // K-V bit mask
-
- // Compare routine for std binary search
- bool operator<(const SubtargetFeatureKV &S) const {
- return strcmp(Key, S.Key) < 0;
- }
-};
-
-//===----------------------------------------------------------------------===//
-///
-/// SubtargetInfoKV - Used to provide key value pairs for CPU and arbitrary
-/// pointers.
-//
-struct SubtargetInfoKV {
- const char *Key; // K-V key string
- void *Value; // K-V pointer value
-
- // Compare routine for std binary search
- bool operator<(const SubtargetInfoKV &S) const {
- return strcmp(Key, S.Key) < 0;
- }
-};
-
-//===----------------------------------------------------------------------===//
-///
-/// SubtargetFeatures - Manages the enabling and disabling of subtarget
-/// specific features. Features are encoded as a string of the form
-/// "cpu,+attr1,+attr2,-attr3,...,+attrN"
-/// A comma separates each feature from the next (all lowercase.)
-/// The first feature is always the CPU subtype (eg. pentiumm). If the CPU
-/// value is "generic" then the CPU subtype should be generic for the target.
-/// Each of the remaining features is prefixed with + or - indicating whether
-/// that feature should be enabled or disabled contrary to the cpu
-/// specification.
-///
-
-class SubtargetFeatures {
- std::vector<std::string> Features; // Subtarget features as a vector
-public:
- explicit SubtargetFeatures(const std::string &Initial = std::string());
-
- /// Features string accessors.
- std::string getString() const;
- void setString(const std::string &Initial);
-
- /// Set the CPU string. Replaces previous setting. Setting to "" clears CPU.
- void setCPU(const std::string &String);
-
- /// Setting CPU string only if no string is set.
- void setCPUIfNone(const std::string &String);
-
- /// Returns current CPU string.
- const std::string & getCPU() const;
-
- /// Adding Features.
- void AddFeature(const std::string &String, bool IsEnabled = true);
-
- /// Get feature bits.
- uint64_t getBits(const SubtargetFeatureKV *CPUTable,
- size_t CPUTableSize,
- const SubtargetFeatureKV *FeatureTable,
- size_t FeatureTableSize);
-
- /// Get info pointer
- void *getInfo(const SubtargetInfoKV *Table, size_t TableSize);
-
- /// Print feature string.
- void print(raw_ostream &OS) const;
-
- // Dump feature info.
- void dump() const;
-
- /// Retrieve a formatted string of the default features for the specified
- /// target triple.
- void getDefaultSubtargetFeatures(const std::string &CPU,
- const Triple& Triple);
-};
-
-} // End namespace llvm
-
-#endif
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index bc8be89..4d7116b 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -26,11 +26,19 @@ class SubRegIndex {
string Namespace = "";
}
+// RegAltNameIndex - The alternate name set to use for register operands of
+// this register class when printing.
+class RegAltNameIndex {
+ string Namespace = "";
+}
+def NoRegAltName : RegAltNameIndex;
+
// Register - You should define one instance of this class for each register
// in the target machine. String n will become the "name" of the register.
-class Register<string n> {
+class Register<string n, list<string> altNames = []> {
string Namespace = "";
string AsmName = n;
+ list<string> AltNames = altNames;
// Aliases - A list of registers that this register overlaps with. A read or
// modification of this register can potentially read or modify the aliased
@@ -48,6 +56,10 @@ class Register<string n> {
// SubRegs.
list<SubRegIndex> SubRegIndices = [];
+ // RegAltNameIndices - The alternate name indices which are valid for this
+ // register.
+ list<RegAltNameIndex> RegAltNameIndices = [];
+
// CompositeIndices - Specify subreg indices that don't correspond directly to
// a register in SubRegs and are not inherited. The following formats are
// supported:
@@ -92,7 +104,7 @@ class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> {
// registers by register allocators.
//
class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
- dag regList> {
+ dag regList, RegAltNameIndex idx = NoRegAltName> {
string Namespace = namespace;
// RegType - Specify the list ValueType of the registers in this register
@@ -124,6 +136,11 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
//
dag MemberList = regList;
+ // AltNameIndex - The alternate register name to use when printing operands
+ // of this register class. Every register in the register class must have
+ // a valid alternate name for the given index.
+ RegAltNameIndex altNameIndex = idx;
+
// SubRegClasses - Specify the register class of subregisters as a list of
// dags: (RegClass SubRegIndex, SubRegindex, ...)
list<dag> SubRegClasses = [];
@@ -466,6 +483,24 @@ class Operand<ValueType ty> {
AsmOperandClass ParserMatchClass = ImmAsmOperand;
}
+class RegisterOperand<RegisterClass regclass, string pm = "printOperand"> {
+ // RegClass - The register class of the operand.
+ RegisterClass 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;
+ // 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.
+ //
+ // The target specific parser must be able to classify an parsed operand into
+ // a unique class, which does not partially overlap with any other classes. It
+ // 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;
+}
+
def i1imm : Operand<i1>;
def i8imm : Operand<i8>;
def i16imm : Operand<i16>;
diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h
index abaed81..1a417a1 100644
--- a/include/llvm/Target/TargetAsmInfo.h
+++ b/include/llvm/Target/TargetAsmInfo.h
@@ -106,6 +106,10 @@ public:
int getSEHRegNum(unsigned RegNum) const {
return TRI->getSEHRegNum(RegNum);
}
+
+ int getCompactUnwindRegNum(unsigned RegNum) const {
+ return TRI->getCompactUnwindRegNum(RegNum);
+ }
};
}
diff --git a/include/llvm/Target/TargetInstrDesc.h b/include/llvm/Target/TargetInstrDesc.h
deleted file mode 100644
index 6e20e8a..0000000
--- a/include/llvm/Target/TargetInstrDesc.h
+++ /dev/null
@@ -1,520 +0,0 @@
-//===-- llvm/Target/TargetInstrDesc.h - Instruction Descriptors -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the TargetOperandInfo and TargetInstrDesc classes, which
-// are used to describe target instructions and their operands.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TARGET_TARGETINSTRDESC_H
-#define LLVM_TARGET_TARGETINSTRDESC_H
-
-#include "llvm/Support/DataTypes.h"
-
-namespace llvm {
-
-class TargetRegisterClass;
-class TargetRegisterInfo;
-
-//===----------------------------------------------------------------------===//
-// Machine Operand Flags and Description
-//===----------------------------------------------------------------------===//
-
-namespace TOI {
- // Operand constraints
- enum OperandConstraint {
- TIED_TO = 0, // Must be allocated the same register as.
- EARLY_CLOBBER // Operand is an early clobber register operand
- };
-
- /// OperandFlags - These are flags set on operands, but should be considered
- /// private, all access should go through the TargetOperandInfo accessors.
- /// See the accessors for a description of what these are.
- enum OperandFlags {
- LookupPtrRegClass = 0,
- Predicate,
- OptionalDef
- };
-}
-
-/// TargetOperandInfo - This holds information about one operand of a machine
-/// instruction, indicating the register class for register operands, etc.
-///
-class TargetOperandInfo {
-public:
- /// RegClass - This specifies the register class enumeration of the operand
- /// if the operand is a register. If isLookupPtrRegClass is set, then this is
- /// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to
- /// get a dynamic register class.
- ///
- /// NOTE: This member should be considered to be private, all access should go
- /// through "getRegClass(TRI)" below.
- short RegClass;
-
- /// Flags - These are flags from the TOI::OperandFlags enum.
- unsigned short Flags;
-
- /// Lower 16 bits are used to specify which constraints are set. The higher 16
- /// bits are used to specify the value of constraints (4 bits each).
- unsigned Constraints;
- /// Currently no other information.
-
- /// getRegClass - Get the register class for the operand, handling resolution
- /// of "symbolic" pointer register classes etc. If this is not a register
- /// operand, this returns null.
- const TargetRegisterClass *getRegClass(const TargetRegisterInfo *TRI) const;
-
-
- /// isLookupPtrRegClass - Set if this operand is a pointer value and it
- /// requires a callback to look up its register class.
- bool isLookupPtrRegClass() const { return Flags&(1 <<TOI::LookupPtrRegClass);}
-
- /// isPredicate - Set if this is one of the operands that made up of
- /// the predicate operand that controls an isPredicable() instruction.
- bool isPredicate() const { return Flags & (1 << TOI::Predicate); }
-
- /// isOptionalDef - Set if this operand is a optional def.
- ///
- bool isOptionalDef() const { return Flags & (1 << TOI::OptionalDef); }
-};
-
-
-//===----------------------------------------------------------------------===//
-// Machine Instruction Flags and Description
-//===----------------------------------------------------------------------===//
-
-/// TargetInstrDesc flags - These should be considered private to the
-/// implementation of the TargetInstrDesc class. Clients should use the
-/// predicate methods on TargetInstrDesc, not use these directly. These
-/// all correspond to bitfields in the TargetInstrDesc::Flags field.
-namespace TID {
- enum {
- Variadic = 0,
- HasOptionalDef,
- Return,
- Call,
- Barrier,
- Terminator,
- Branch,
- IndirectBranch,
- Compare,
- MoveImm,
- Bitcast,
- DelaySlot,
- FoldableAsLoad,
- MayLoad,
- MayStore,
- Predicable,
- NotDuplicable,
- UnmodeledSideEffects,
- Commutable,
- ConvertibleTo3Addr,
- UsesCustomInserter,
- Rematerializable,
- CheapAsAMove,
- ExtraSrcRegAllocReq,
- ExtraDefRegAllocReq
- };
-}
-
-/// TargetInstrDesc - Describe properties that are true of each
-/// instruction in the target description file. This captures information about
-/// side effects, register use and many other things. There is one instance of
-/// this struct for each target instruction class, and the MachineInstr class
-/// points to this struct directly to describe itself.
-class TargetInstrDesc {
-public:
- unsigned short Opcode; // The opcode number
- unsigned short NumOperands; // Num of args (may be more if variable_ops)
- unsigned short NumDefs; // Num of args that are definitions
- unsigned short SchedClass; // enum identifying instr sched class
- const char * Name; // Name of the instruction record in td file
- unsigned Flags; // Flags identifying machine instr class
- uint64_t TSFlags; // Target Specific Flag values
- const unsigned *ImplicitUses; // Registers implicitly read by this instr
- const unsigned *ImplicitDefs; // Registers implicitly defined by this instr
- const TargetRegisterClass **RCBarriers; // Reg classes completely "clobbered"
- const TargetOperandInfo *OpInfo; // 'NumOperands' entries about operands
-
- /// getOperandConstraint - Returns the value of the specific constraint if
- /// it is set. Returns -1 if it is not set.
- int getOperandConstraint(unsigned OpNum,
- TOI::OperandConstraint Constraint) const {
- if (OpNum < NumOperands &&
- (OpInfo[OpNum].Constraints & (1 << Constraint))) {
- unsigned Pos = 16 + Constraint * 4;
- return (int)(OpInfo[OpNum].Constraints >> Pos) & 0xf;
- }
- return -1;
- }
-
- /// getRegClass - Returns the register class constraint for OpNum, or NULL.
- const TargetRegisterClass *getRegClass(unsigned OpNum,
- const TargetRegisterInfo *TRI) const {
- return OpNum < NumOperands ? OpInfo[OpNum].getRegClass(TRI) : 0;
- }
-
- /// getOpcode - Return the opcode number for this descriptor.
- unsigned getOpcode() const {
- return Opcode;
- }
-
- /// getName - Return the name of the record in the .td file for this
- /// instruction, for example "ADD8ri".
- const char *getName() const {
- return Name;
- }
-
- /// getNumOperands - Return the number of declared MachineOperands for this
- /// MachineInstruction. Note that variadic (isVariadic() returns true)
- /// instructions may have additional operands at the end of the list, and note
- /// that the machine instruction may include implicit register def/uses as
- /// well.
- unsigned getNumOperands() const {
- return NumOperands;
- }
-
- /// getNumDefs - Return the number of MachineOperands that are register
- /// definitions. Register definitions always occur at the start of the
- /// machine operand list. This is the number of "outs" in the .td file,
- /// and does not include implicit defs.
- unsigned getNumDefs() const {
- return NumDefs;
- }
-
- /// isVariadic - Return true if this instruction can have a variable number of
- /// operands. In this case, the variable operands will be after the normal
- /// operands but before the implicit definitions and uses (if any are
- /// present).
- bool isVariadic() const {
- return Flags & (1 << TID::Variadic);
- }
-
- /// hasOptionalDef - Set if this instruction has an optional definition, e.g.
- /// ARM instructions which can set condition code if 's' bit is set.
- bool hasOptionalDef() const {
- return Flags & (1 << TID::HasOptionalDef);
- }
-
- /// getImplicitUses - Return a list of registers that are potentially
- /// read by any instance of this machine instruction. For example, on X86,
- /// the "adc" instruction adds two register operands and adds the carry bit in
- /// from the flags register. In this case, the instruction is marked as
- /// implicitly reading the flags. Likewise, the variable shift instruction on
- /// X86 is marked as implicitly reading the 'CL' register, which it always
- /// does.
- ///
- /// This method returns null if the instruction has no implicit uses.
- const unsigned *getImplicitUses() const {
- return ImplicitUses;
- }
-
- /// getNumImplicitUses - Return the number of implicit uses this instruction
- /// has.
- unsigned getNumImplicitUses() const {
- if (ImplicitUses == 0) return 0;
- unsigned i = 0;
- for (; ImplicitUses[i]; ++i) /*empty*/;
- return i;
- }
-
-
- /// getImplicitDefs - Return a list of registers that are potentially
- /// written by any instance of this machine instruction. For example, on X86,
- /// many instructions implicitly set the flags register. In this case, they
- /// are marked as setting the FLAGS. Likewise, many instructions always
- /// deposit their result in a physical register. For example, the X86 divide
- /// instruction always deposits the quotient and remainder in the EAX/EDX
- /// registers. For that instruction, this will return a list containing the
- /// EAX/EDX/EFLAGS registers.
- ///
- /// This method returns null if the instruction has no implicit defs.
- const unsigned *getImplicitDefs() const {
- return ImplicitDefs;
- }
-
- /// getNumImplicitDefs - Return the number of implicit defs this instruction
- /// has.
- unsigned getNumImplicitDefs() const {
- if (ImplicitDefs == 0) return 0;
- unsigned i = 0;
- for (; ImplicitDefs[i]; ++i) /*empty*/;
- return i;
- }
-
- /// hasImplicitUseOfPhysReg - Return true if this instruction implicitly
- /// uses the specified physical register.
- bool hasImplicitUseOfPhysReg(unsigned Reg) const {
- if (const unsigned *ImpUses = ImplicitUses)
- for (; *ImpUses; ++ImpUses)
- if (*ImpUses == Reg) return true;
- return false;
- }
-
- /// hasImplicitDefOfPhysReg - Return true if this instruction implicitly
- /// defines the specified physical register.
- bool hasImplicitDefOfPhysReg(unsigned Reg) const {
- if (const unsigned *ImpDefs = ImplicitDefs)
- for (; *ImpDefs; ++ImpDefs)
- if (*ImpDefs == Reg) return true;
- return false;
- }
-
- /// getRegClassBarriers - Return a list of register classes that are
- /// completely clobbered by this machine instruction. For example, on X86
- /// the call instructions will completely clobber all the registers in the
- /// fp stack and XMM classes.
- ///
- /// This method returns null if the instruction doesn't completely clobber
- /// any register class.
- const TargetRegisterClass **getRegClassBarriers() const {
- return RCBarriers;
- }
-
- /// getSchedClass - Return the scheduling class for this instruction. The
- /// scheduling class is an index into the InstrItineraryData table. This
- /// returns zero if there is no known scheduling information for the
- /// instruction.
- ///
- unsigned getSchedClass() const {
- return SchedClass;
- }
-
- bool isReturn() const {
- return Flags & (1 << TID::Return);
- }
-
- bool isCall() const {
- return Flags & (1 << TID::Call);
- }
-
- /// isBarrier - Returns true if the specified instruction stops control flow
- /// from executing the instruction immediately following it. Examples include
- /// unconditional branches and return instructions.
- bool isBarrier() const {
- return Flags & (1 << TID::Barrier);
- }
-
- /// isTerminator - Returns true if this instruction part of the terminator for
- /// a basic block. Typically this is things like return and branch
- /// instructions.
- ///
- /// Various passes use this to insert code into the bottom of a basic block,
- /// but before control flow occurs.
- bool isTerminator() const {
- return Flags & (1 << TID::Terminator);
- }
-
- /// isBranch - Returns true if this is a conditional, unconditional, or
- /// indirect branch. Predicates below can be used to discriminate between
- /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to
- /// get more information.
- bool isBranch() const {
- return Flags & (1 << TID::Branch);
- }
-
- /// isIndirectBranch - Return true if this is an indirect branch, such as a
- /// branch through a register.
- bool isIndirectBranch() const {
- return Flags & (1 << TID::IndirectBranch);
- }
-
- /// isConditionalBranch - Return true if this is a branch which may fall
- /// through to the next instruction or may transfer control flow to some other
- /// block. The TargetInstrInfo::AnalyzeBranch method can be used to get more
- /// information about this branch.
- bool isConditionalBranch() const {
- return isBranch() & !isBarrier() & !isIndirectBranch();
- }
-
- /// isUnconditionalBranch - Return true if this is a branch which always
- /// transfers control flow to some other block. The
- /// TargetInstrInfo::AnalyzeBranch method can be used to get more information
- /// about this branch.
- bool isUnconditionalBranch() const {
- return isBranch() & isBarrier() & !isIndirectBranch();
- }
-
- // isPredicable - Return true if this instruction has a predicate operand that
- // controls execution. It may be set to 'always', or may be set to other
- /// values. There are various methods in TargetInstrInfo that can be used to
- /// control and modify the predicate in this instruction.
- bool isPredicable() const {
- return Flags & (1 << TID::Predicable);
- }
-
- /// isCompare - Return true if this instruction is a comparison.
- bool isCompare() const {
- return Flags & (1 << TID::Compare);
- }
-
- /// isMoveImmediate - Return true if this instruction is a move immediate
- /// (including conditional moves) instruction.
- bool isMoveImmediate() const {
- return Flags & (1 << TID::MoveImm);
- }
-
- /// isBitcast - Return true if this instruction is a bitcast instruction.
- ///
- bool isBitcast() const {
- return Flags & (1 << TID::Bitcast);
- }
-
- /// isNotDuplicable - Return true if this instruction cannot be safely
- /// duplicated. For example, if the instruction has a unique labels attached
- /// to it, duplicating it would cause multiple definition errors.
- bool isNotDuplicable() const {
- return Flags & (1 << TID::NotDuplicable);
- }
-
- /// hasDelaySlot - Returns true if the specified instruction has a delay slot
- /// which must be filled by the code generator.
- bool hasDelaySlot() const {
- return Flags & (1 << TID::DelaySlot);
- }
-
- /// canFoldAsLoad - Return true for instructions that can be folded as
- /// memory operands in other instructions. The most common use for this
- /// is instructions that are simple loads from memory that don't modify
- /// the loaded value in any way, but it can also be used for instructions
- /// that can be expressed as constant-pool loads, such as V_SETALLONES
- /// on x86, to allow them to be folded when it is beneficial.
- /// This should only be set on instructions that return a value in their
- /// only virtual register definition.
- bool canFoldAsLoad() const {
- return Flags & (1 << TID::FoldableAsLoad);
- }
-
- //===--------------------------------------------------------------------===//
- // Side Effect Analysis
- //===--------------------------------------------------------------------===//
-
- /// mayLoad - Return true if this instruction could possibly read memory.
- /// Instructions with this flag set are not necessarily simple load
- /// instructions, they may load a value and modify it, for example.
- bool mayLoad() const {
- return Flags & (1 << TID::MayLoad);
- }
-
-
- /// mayStore - Return true if this instruction could possibly modify memory.
- /// Instructions with this flag set are not necessarily simple store
- /// instructions, they may store a modified value based on their operands, or
- /// may not actually modify anything, for example.
- bool mayStore() const {
- return Flags & (1 << TID::MayStore);
- }
-
- /// hasUnmodeledSideEffects - Return true if this instruction has side
- /// effects that are not modeled by other flags. This does not return true
- /// for instructions whose effects are captured by:
- ///
- /// 1. Their operand list and implicit definition/use list. Register use/def
- /// info is explicit for instructions.
- /// 2. Memory accesses. Use mayLoad/mayStore.
- /// 3. Calling, branching, returning: use isCall/isReturn/isBranch.
- ///
- /// Examples of side effects would be modifying 'invisible' machine state like
- /// a control register, flushing a cache, modifying a register invisible to
- /// LLVM, etc.
- ///
- bool hasUnmodeledSideEffects() const {
- return Flags & (1 << TID::UnmodeledSideEffects);
- }
-
- //===--------------------------------------------------------------------===//
- // Flags that indicate whether an instruction can be modified by a method.
- //===--------------------------------------------------------------------===//
-
- /// isCommutable - Return true if this may be a 2- or 3-address
- /// instruction (of the form "X = op Y, Z, ..."), which produces the same
- /// result if Y and Z are exchanged. If this flag is set, then the
- /// TargetInstrInfo::commuteInstruction method may be used to hack on the
- /// instruction.
- ///
- /// Note that this flag may be set on instructions that are only commutable
- /// sometimes. In these cases, the call to commuteInstruction will fail.
- /// Also note that some instructions require non-trivial modification to
- /// commute them.
- bool isCommutable() const {
- return Flags & (1 << TID::Commutable);
- }
-
- /// isConvertibleTo3Addr - Return true if this is a 2-address instruction
- /// which can be changed into a 3-address instruction if needed. Doing this
- /// transformation can be profitable in the register allocator, because it
- /// means that the instruction can use a 2-address form if possible, but
- /// degrade into a less efficient form if the source and dest register cannot
- /// be assigned to the same register. For example, this allows the x86
- /// backend to turn a "shl reg, 3" instruction into an LEA instruction, which
- /// is the same speed as the shift but has bigger code size.
- ///
- /// If this returns true, then the target must implement the
- /// TargetInstrInfo::convertToThreeAddress method for this instruction, which
- /// is allowed to fail if the transformation isn't valid for this specific
- /// instruction (e.g. shl reg, 4 on x86).
- ///
- bool isConvertibleTo3Addr() const {
- return Flags & (1 << TID::ConvertibleTo3Addr);
- }
-
- /// usesCustomInsertionHook - Return true if this instruction requires
- /// custom insertion support when the DAG scheduler is inserting it into a
- /// machine basic block. If this is true for the instruction, it basically
- /// means that it is a pseudo instruction used at SelectionDAG time that is
- /// expanded out into magic code by the target when MachineInstrs are formed.
- ///
- /// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method
- /// is used to insert this into the MachineBasicBlock.
- bool usesCustomInsertionHook() const {
- return Flags & (1 << TID::UsesCustomInserter);
- }
-
- /// isRematerializable - Returns true if this instruction is a candidate for
- /// remat. This flag is deprecated, please don't use it anymore. If this
- /// flag is set, the isReallyTriviallyReMaterializable() method is called to
- /// verify the instruction is really rematable.
- bool isRematerializable() const {
- return Flags & (1 << TID::Rematerializable);
- }
-
- /// isAsCheapAsAMove - Returns true if this instruction has the same cost (or
- /// less) than a move instruction. This is useful during certain types of
- /// optimizations (e.g., remat during two-address conversion or machine licm)
- /// where we would like to remat or hoist the instruction, but not if it costs
- /// more than moving the instruction into the appropriate register. Note, we
- /// are not marking copies from and to the same register class with this flag.
- bool isAsCheapAsAMove() const {
- return Flags & (1 << TID::CheapAsAMove);
- }
-
- /// hasExtraSrcRegAllocReq - Returns true if this instruction source operands
- /// have special register allocation requirements that are not captured by the
- /// operand register classes. e.g. ARM::STRD's two source registers must be an
- /// even / odd pair, ARM::STM registers have to be in ascending order.
- /// Post-register allocation passes should not attempt to change allocations
- /// for sources of instructions with this flag.
- bool hasExtraSrcRegAllocReq() const {
- return Flags & (1 << TID::ExtraSrcRegAllocReq);
- }
-
- /// hasExtraDefRegAllocReq - Returns true if this instruction def operands
- /// have special register allocation requirements that are not captured by the
- /// operand register classes. e.g. ARM::LDRD's two def registers must be an
- /// even / odd pair, ARM::LDM registers have to be in ascending order.
- /// Post-register allocation passes should not attempt to change allocations
- /// for definitions of instructions with this flag.
- bool hasExtraDefRegAllocReq() const {
- return Flags & (1 << TID::ExtraDefRegAllocReq);
- }
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index 418f3fe..70969eb 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -14,7 +14,7 @@
#ifndef LLVM_TARGET_TARGETINSTRINFO_H
#define LLVM_TARGET_TARGETINSTRINFO_H
-#include "llvm/Target/TargetInstrDesc.h"
+#include "llvm/MC/MCInstrInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
namespace llvm {
@@ -40,25 +40,20 @@ template<class T> class SmallVectorImpl;
///
/// TargetInstrInfo - Interface to description of machine instruction set
///
-class TargetInstrInfo {
- const TargetInstrDesc *Descriptors; // Raw array to allow static init'n
- unsigned NumOpcodes; // Number of entries in the desc array
-
+class TargetInstrInfo : public MCInstrInfo {
TargetInstrInfo(const TargetInstrInfo &); // DO NOT IMPLEMENT
void operator=(const TargetInstrInfo &); // DO NOT IMPLEMENT
public:
- TargetInstrInfo(const TargetInstrDesc *desc, unsigned NumOpcodes);
+ TargetInstrInfo(const MCInstrDesc *desc, unsigned NumOpcodes,
+ int CallFrameSetupOpcode = -1,
+ int CallFrameDestroyOpcode = -1);
virtual ~TargetInstrInfo();
- unsigned getNumOpcodes() const { return NumOpcodes; }
-
- /// get - Return the machine instruction descriptor that corresponds to the
- /// specified instruction opcode.
- ///
- const TargetInstrDesc &get(unsigned Opcode) const {
- assert(Opcode < NumOpcodes && "Invalid opcode!");
- return Descriptors[Opcode];
- }
+ /// getRegClass - Givem a machine instruction descriptor, returns the register
+ /// class constraint for OpNum, or NULL.
+ const TargetRegisterClass *getRegClass(const MCInstrDesc &TID,
+ unsigned OpNum,
+ const TargetRegisterInfo *TRI) const;
/// isTriviallyReMaterializable - Return true if the instruction is trivially
/// rematerializable, meaning it has no side effects and requires no operands
@@ -93,6 +88,15 @@ private:
AliasAnalysis *AA) const;
public:
+ /// getCallFrameSetup/DestroyOpcode - These methods return the opcode of the
+ /// frame setup/destroy instructions if they exist (-1 otherwise). Some
+ /// targets use pseudo instructions in order to abstract away the difference
+ /// between operating with a frame pointer and operating without, through the
+ /// use of these two instructions.
+ ///
+ int getCallFrameSetupOpcode() const { return CallFrameSetupOpcode; }
+ int getCallFrameDestroyOpcode() const { return CallFrameDestroyOpcode; }
+
/// isCoalescableExtInstr - Return true if the instruction is a "coalescable"
/// extension instruction. That is, it's like a copy where it's legal for the
/// source to overlap the destination. e.g. X86::MOVSX64rr32. If this returns
@@ -663,6 +667,9 @@ public:
virtual
bool hasLowDefLatency(const InstrItineraryData *ItinData,
const MachineInstr *DefMI, unsigned DefIdx) const;
+
+private:
+ int CallFrameSetupOpcode, CallFrameDestroyOpcode;
};
/// TargetInstrInfoImpl - This is the default implementation of
@@ -671,8 +678,11 @@ public:
/// libcodegen, not in libtarget.
class TargetInstrInfoImpl : public TargetInstrInfo {
protected:
- TargetInstrInfoImpl(const TargetInstrDesc *desc, unsigned NumOpcodes)
- : TargetInstrInfo(desc, NumOpcodes) {}
+ TargetInstrInfoImpl(const MCInstrDesc *desc, unsigned NumOpcodes,
+ int CallFrameSetupOpcode = -1,
+ int CallFrameDestroyOpcode = -1)
+ : TargetInstrInfo(desc, NumOpcodes,
+ CallFrameSetupOpcode, CallFrameDestroyOpcode) {}
public:
virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst,
MachineBasicBlock *NewDest) const;
diff --git a/include/llvm/Target/TargetInstrItineraries.h b/include/llvm/Target/TargetInstrItineraries.h
deleted file mode 100644
index 6011402..0000000
--- a/include/llvm/Target/TargetInstrItineraries.h
+++ /dev/null
@@ -1,253 +0,0 @@
-//===-- llvm/Target/TargetInstrItineraries.h - Scheduling -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file describes the structures used for instruction
-// itineraries, stages, and operand reads/writes. This is used by
-// schedulers to determine instruction stages and latencies.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TARGET_TARGETINSTRITINERARIES_H
-#define LLVM_TARGET_TARGETINSTRITINERARIES_H
-
-#include <algorithm>
-
-namespace llvm {
-
-//===----------------------------------------------------------------------===//
-/// Instruction stage - These values represent a non-pipelined step in
-/// the execution of an instruction. Cycles represents the number of
-/// discrete time slots needed to complete the stage. Units represent
-/// the choice of functional units that can be used to complete the
-/// stage. Eg. IntUnit1, IntUnit2. NextCycles indicates how many
-/// cycles should elapse from the start of this stage to the start of
-/// the next stage in the itinerary. A value of -1 indicates that the
-/// next stage should start immediately after the current one.
-/// For example:
-///
-/// { 1, x, -1 }
-/// indicates that the stage occupies FU x for 1 cycle and that
-/// the next stage starts immediately after this one.
-///
-/// { 2, x|y, 1 }
-/// indicates that the stage occupies either FU x or FU y for 2
-/// consecuative cycles and that the next stage starts one cycle
-/// after this stage starts. That is, the stage requirements
-/// overlap in time.
-///
-/// { 1, x, 0 }
-/// indicates that the stage occupies FU x for 1 cycle and that
-/// the next stage starts in this same cycle. This can be used to
-/// indicate that the instruction requires multiple stages at the
-/// same time.
-///
-/// FU reservation can be of two different kinds:
-/// - FUs which instruction actually requires
-/// - FUs which instruction just reserves. Reserved unit is not available for
-/// execution of other instruction. However, several instructions can reserve
-/// the same unit several times.
-/// Such two types of units reservation is used to model instruction domain
-/// change stalls, FUs using the same resource (e.g. same register file), etc.
-
-struct InstrStage {
- enum ReservationKinds {
- Required = 0,
- Reserved = 1
- };
-
- unsigned Cycles_; ///< Length of stage in machine cycles
- unsigned Units_; ///< Choice of functional units
- int NextCycles_; ///< Number of machine cycles to next stage
- ReservationKinds Kind_; ///< Kind of the FU reservation
-
- /// getCycles - returns the number of cycles the stage is occupied
- unsigned getCycles() const {
- return Cycles_;
- }
-
- /// getUnits - returns the choice of FUs
- unsigned getUnits() const {
- return Units_;
- }
-
- ReservationKinds getReservationKind() const {
- return Kind_;
- }
-
- /// getNextCycles - returns the number of cycles from the start of
- /// this stage to the start of the next stage in the itinerary
- unsigned getNextCycles() const {
- return (NextCycles_ >= 0) ? (unsigned)NextCycles_ : Cycles_;
- }
-};
-
-
-//===----------------------------------------------------------------------===//
-/// Instruction itinerary - An itinerary represents the scheduling
-/// information for an instruction. This includes a set of stages
-/// occupies by the instruction, and the pipeline cycle in which
-/// operands are read and written.
-///
-struct InstrItinerary {
- unsigned NumMicroOps; ///< # of micro-ops, 0 means it's variable
- unsigned FirstStage; ///< Index of first stage in itinerary
- unsigned LastStage; ///< Index of last + 1 stage in itinerary
- unsigned FirstOperandCycle; ///< Index of first operand rd/wr
- unsigned LastOperandCycle; ///< Index of last + 1 operand rd/wr
-};
-
-
-//===----------------------------------------------------------------------===//
-/// Instruction itinerary Data - Itinerary data supplied by a subtarget to be
-/// used by a target.
-///
-class InstrItineraryData {
-public:
- const InstrStage *Stages; ///< Array of stages selected
- const unsigned *OperandCycles; ///< Array of operand cycles selected
- const unsigned *Forwardings; ///< Array of pipeline forwarding pathes
- const InstrItinerary *Itineraries; ///< Array of itineraries selected
- unsigned IssueWidth; ///< Max issue per cycle. 0=Unknown.
-
- /// Ctors.
- ///
- InstrItineraryData() : Stages(0), OperandCycles(0), Forwardings(0),
- Itineraries(0), IssueWidth(0) {}
-
- InstrItineraryData(const InstrStage *S, const unsigned *OS,
- const unsigned *F, const InstrItinerary *I)
- : Stages(S), OperandCycles(OS), Forwardings(F), Itineraries(I),
- IssueWidth(0) {}
-
- /// isEmpty - Returns true if there are no itineraries.
- ///
- bool isEmpty() const { return Itineraries == 0; }
-
- /// isEndMarker - Returns true if the index is for the end marker
- /// itinerary.
- ///
- bool isEndMarker(unsigned ItinClassIndx) const {
- return ((Itineraries[ItinClassIndx].FirstStage == ~0U) &&
- (Itineraries[ItinClassIndx].LastStage == ~0U));
- }
-
- /// beginStage - Return the first stage of the itinerary.
- ///
- const InstrStage *beginStage(unsigned ItinClassIndx) const {
- unsigned StageIdx = Itineraries[ItinClassIndx].FirstStage;
- return Stages + StageIdx;
- }
-
- /// endStage - Return the last+1 stage of the itinerary.
- ///
- const InstrStage *endStage(unsigned ItinClassIndx) const {
- unsigned StageIdx = Itineraries[ItinClassIndx].LastStage;
- return Stages + StageIdx;
- }
-
- /// getStageLatency - Return the total stage latency of the given
- /// class. The latency is the maximum completion time for any stage
- /// in the itinerary.
- ///
- unsigned getStageLatency(unsigned ItinClassIndx) const {
- // If the target doesn't provide itinerary information, use a simple
- // non-zero default value for all instructions. Some target's provide a
- // dummy (Generic) itinerary which should be handled as if it's itinerary is
- // empty. We identify this by looking for a reference to stage zero (invalid
- // stage). This is different from beginStage == endState != 0, which could
- // be used for zero-latency pseudo ops.
- if (isEmpty() || Itineraries[ItinClassIndx].FirstStage == 0)
- return 1;
-
- // Calculate the maximum completion time for any stage.
- unsigned Latency = 0, StartCycle = 0;
- for (const InstrStage *IS = beginStage(ItinClassIndx),
- *E = endStage(ItinClassIndx); IS != E; ++IS) {
- Latency = std::max(Latency, StartCycle + IS->getCycles());
- StartCycle += IS->getNextCycles();
- }
-
- return Latency;
- }
-
- /// getOperandCycle - Return the cycle for the given class and
- /// operand. Return -1 if no cycle is specified for the operand.
- ///
- int getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const {
- if (isEmpty())
- return -1;
-
- unsigned FirstIdx = Itineraries[ItinClassIndx].FirstOperandCycle;
- unsigned LastIdx = Itineraries[ItinClassIndx].LastOperandCycle;
- if ((FirstIdx + OperandIdx) >= LastIdx)
- return -1;
-
- return (int)OperandCycles[FirstIdx + OperandIdx];
- }
-
- /// hasPipelineForwarding - Return true if there is a pipeline forwarding
- /// between instructions of itinerary classes DefClass and UseClasses so that
- /// value produced by an instruction of itinerary class DefClass, operand
- /// index DefIdx can be bypassed when it's read by an instruction of
- /// itinerary class UseClass, operand index UseIdx.
- bool hasPipelineForwarding(unsigned DefClass, unsigned DefIdx,
- unsigned UseClass, unsigned UseIdx) const {
- unsigned FirstDefIdx = Itineraries[DefClass].FirstOperandCycle;
- unsigned LastDefIdx = Itineraries[DefClass].LastOperandCycle;
- if ((FirstDefIdx + DefIdx) >= LastDefIdx)
- return false;
- if (Forwardings[FirstDefIdx + DefIdx] == 0)
- return false;
-
- unsigned FirstUseIdx = Itineraries[UseClass].FirstOperandCycle;
- unsigned LastUseIdx = Itineraries[UseClass].LastOperandCycle;
- if ((FirstUseIdx + UseIdx) >= LastUseIdx)
- return false;
-
- return Forwardings[FirstDefIdx + DefIdx] ==
- Forwardings[FirstUseIdx + UseIdx];
- }
-
- /// getOperandLatency - Compute and return the use operand latency of a given
- /// itinerary class and operand index if the value is produced by an
- /// instruction of the specified itinerary class and def operand index.
- int getOperandLatency(unsigned DefClass, unsigned DefIdx,
- unsigned UseClass, unsigned UseIdx) const {
- if (isEmpty())
- return -1;
-
- int DefCycle = getOperandCycle(DefClass, DefIdx);
- if (DefCycle == -1)
- return -1;
-
- int UseCycle = getOperandCycle(UseClass, UseIdx);
- if (UseCycle == -1)
- return -1;
-
- UseCycle = DefCycle - UseCycle + 1;
- if (UseCycle > 0 &&
- hasPipelineForwarding(DefClass, DefIdx, UseClass, UseIdx))
- // FIXME: This assumes one cycle benefit for every pipeline forwarding.
- --UseCycle;
- return UseCycle;
- }
-
- /// isMicroCoded - Return true if the instructions in the given class decode
- /// to more than one micro-ops.
- bool isMicroCoded(unsigned ItinClassIndx) const {
- if (isEmpty())
- return false;
- return Itineraries[ItinClassIndx].NumMicroOps != 1;
- }
-};
-
-
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index c3f5f2b..f684163 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -1421,13 +1421,6 @@ public:
/// is for this target.
virtual ConstraintType getConstraintType(const std::string &Constraint) const;
- /// getRegClassForInlineAsmConstraint - Given a constraint letter (e.g. "r"),
- /// return a list of registers that can be used to satisfy the constraint.
- /// This should only be used for C_RegisterClass constraints.
- virtual std::vector<unsigned>
- getRegClassForInlineAsmConstraint(const std::string &Constraint,
- EVT VT) const;
-
/// getRegForInlineAsmConstraint - Given a physical register constraint (e.g.
/// {edx}), return the register number and the register class for the
/// register.
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index 78f770c..6544ce2 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -14,29 +14,29 @@
#ifndef LLVM_TARGET_TARGETMACHINE_H
#define LLVM_TARGET_TARGETMACHINE_H
-#include "llvm/Target/TargetInstrItineraries.h"
#include <cassert>
#include <string>
namespace llvm {
-class Target;
+class InstrItineraryData;
+class JITCodeEmitter;
class MCAsmInfo;
+class MCContext;
+class Pass;
+class PassManager;
+class PassManagerBase;
+class Target;
class TargetData;
-class TargetSubtarget;
+class TargetELFWriterInfo;
+class TargetFrameLowering;
class TargetInstrInfo;
class TargetIntrinsicInfo;
class TargetJITInfo;
class TargetLowering;
-class TargetSelectionDAGInfo;
-class TargetFrameLowering;
-class JITCodeEmitter;
-class MCContext;
class TargetRegisterInfo;
-class PassManagerBase;
-class PassManager;
-class Pass;
-class TargetELFWriterInfo;
+class TargetSelectionDAGInfo;
+class TargetSubtarget;
class formatted_raw_ostream;
class raw_ostream;
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
index beed039..55d50d9 100644
--- a/include/llvm/Target/TargetOptions.h
+++ b/include/llvm/Target/TargetOptions.h
@@ -133,8 +133,8 @@ namespace llvm {
/// as their parent function, etc.), using an alternate ABI if necessary.
extern bool GuaranteedTailCallOpt;
- /// StackAlignment - Override default stack alignment for target.
- extern unsigned StackAlignment;
+ /// StackAlignmentOverride - Override default stack alignment for target.
+ extern unsigned StackAlignmentOverride;
/// RealignStack - This flag indicates whether the stack should be
/// automatically realigned, if needed.
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index 840b048..3f28f6c 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -16,6 +16,7 @@
#ifndef LLVM_TARGET_TARGETREGISTERINFO_H
#define LLVM_TARGET_TARGETREGISTERINFO_H
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/ADT/ArrayRef.h"
@@ -27,30 +28,10 @@ namespace llvm {
class BitVector;
class MachineFunction;
-class MachineMove;
class RegScavenger;
template<class T> class SmallVectorImpl;
class raw_ostream;
-/// TargetRegisterDesc - This record contains all of the information known about
-/// a particular register. The Overlaps field contains a pointer to a zero
-/// terminated array of registers that this register aliases, starting with
-/// itself. This is needed for architectures like X86 which have AL alias AX
-/// alias EAX. The SubRegs field is a zero terminated array of registers that
-/// are sub-registers of the specific register, e.g. AL, AH are sub-registers of
-/// AX. The SuperRegs field is a zero terminated array of registers that are
-/// super-registers of the specific register, e.g. RAX, EAX, are super-registers
-/// of AX.
-///
-struct TargetRegisterDesc {
- const char *Name; // Printable name for the reg (for debugging)
- const unsigned *Overlaps; // Overlapping registers, described above
- const unsigned *SubRegs; // Sub-register set, described above
- const unsigned *SuperRegs; // Super-register set, described above
- unsigned CostPerUse; // Extra cost of instructions using register.
- bool inAllocatableClass; // Register belongs to an allocatable regclass.
-};
-
class TargetRegisterClass {
public:
typedef const unsigned* iterator;
@@ -274,6 +255,12 @@ public:
bool isAllocatable() const { return Allocatable; }
};
+/// TargetRegisterInfoDesc - Extra information, not in MCRegisterDesc, about
+/// registers. These are used by codegen, not by MC.
+struct TargetRegisterInfoDesc {
+ unsigned CostPerUse; // Extra cost of instructions using register.
+ bool inAllocatableClass; // Register belongs to an allocatable regclass.
+};
/// TargetRegisterInfo base class - We assume that the target defines a static
/// array of TargetRegisterDesc objects that represent all of the machine
@@ -281,25 +268,19 @@ public:
/// to this array so that we can turn register number into a register
/// descriptor.
///
-class TargetRegisterInfo {
+class TargetRegisterInfo : public MCRegisterInfo {
public:
typedef const TargetRegisterClass * const * regclass_iterator;
private:
- const TargetRegisterDesc *Desc; // Pointer to the descriptor array
+ const TargetRegisterInfoDesc *InfoDesc; // Extra desc array for codegen
const char *const *SubRegIndexNames; // Names of subreg indexes.
- unsigned NumRegs; // Number of entries in the array
-
regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses
- int CallFrameSetupOpcode, CallFrameDestroyOpcode;
-
protected:
- TargetRegisterInfo(const TargetRegisterDesc *D, unsigned NR,
+ TargetRegisterInfo(const TargetRegisterInfoDesc *ID,
regclass_iterator RegClassBegin,
regclass_iterator RegClassEnd,
- const char *const *subregindexnames,
- int CallFrameSetupOpcode = -1,
- int CallFrameDestroyOpcode = -1);
+ const char *const *subregindexnames);
virtual ~TargetRegisterInfo();
public:
@@ -379,71 +360,16 @@ public:
BitVector getAllocatableSet(const MachineFunction &MF,
const TargetRegisterClass *RC = NULL) const;
- const TargetRegisterDesc &operator[](unsigned RegNo) const {
- assert(RegNo < NumRegs &&
- "Attempting to access record for invalid register number!");
- return Desc[RegNo];
- }
-
- /// Provide a get method, equivalent to [], but more useful if we have a
- /// pointer to this object.
- ///
- const TargetRegisterDesc &get(unsigned RegNo) const {
- return operator[](RegNo);
- }
-
- /// getAliasSet - Return the set of registers aliased by the specified
- /// register, or a null list of there are none. The list returned is zero
- /// terminated.
- ///
- const unsigned *getAliasSet(unsigned RegNo) const {
- // The Overlaps set always begins with Reg itself.
- return get(RegNo).Overlaps + 1;
- }
-
- /// getOverlaps - Return a list of registers that overlap Reg, including
- /// itself. This is the same as the alias set except Reg is included in the
- /// list.
- /// These are exactly the registers in { x | regsOverlap(x, Reg) }.
- ///
- const unsigned *getOverlaps(unsigned RegNo) const {
- return get(RegNo).Overlaps;
- }
-
- /// getSubRegisters - Return the list of registers that are sub-registers of
- /// the specified register, or a null list of there are none. The list
- /// returned is zero terminated and sorted according to super-sub register
- /// relations. e.g. X86::RAX's sub-register list is EAX, AX, AL, AH.
- ///
- const unsigned *getSubRegisters(unsigned RegNo) const {
- return get(RegNo).SubRegs;
- }
-
- /// getSuperRegisters - Return the list of registers that are super-registers
- /// of the specified register, or a null list of there are none. The list
- /// returned is zero terminated and sorted according to super-sub register
- /// relations. e.g. X86::AL's super-register list is AX, EAX, RAX.
- ///
- const unsigned *getSuperRegisters(unsigned RegNo) const {
- return get(RegNo).SuperRegs;
- }
-
- /// getName - Return the human-readable symbolic target-specific name for the
- /// specified physical register.
- const char *getName(unsigned RegNo) const {
- return get(RegNo).Name;
- }
-
/// getCostPerUse - Return the additional cost of using this register instead
/// of other registers in its class.
unsigned getCostPerUse(unsigned RegNo) const {
- return get(RegNo).CostPerUse;
+ return InfoDesc[RegNo].CostPerUse;
}
- /// getNumRegs - Return the number of registers this target has (useful for
- /// sizing arrays holding per register information)
- unsigned getNumRegs() const {
- return NumRegs;
+ /// isInAllocatableClass - Return true if the register is in the allocation
+ /// of any register class.
+ bool isInAllocatableClass(unsigned RegNo) const {
+ return InfoDesc[RegNo].inAllocatableClass;
}
/// getSubRegIndexName - Return the human-readable symbolic target-specific
@@ -566,7 +492,7 @@ public:
}
/// getRegClass - Returns the register class associated with the enumeration
- /// value. See class TargetOperandInfo.
+ /// value. See class MCOperandInfo.
const TargetRegisterClass *getRegClass(unsigned i) const {
assert(i < getNumRegClasses() && "Register Class ID out of range");
return RegClassBegin[i];
@@ -732,15 +658,6 @@ public:
return false; // Must return a value in order to compile with VS 2005
}
- /// getCallFrameSetup/DestroyOpcode - These methods return the opcode of the
- /// frame setup/destroy instructions if they exist (-1 otherwise). Some
- /// targets use pseudo instructions in order to abstract away the difference
- /// between operating with a frame pointer and operating without, through the
- /// use of these two instructions.
- ///
- int getCallFrameSetupOpcode() const { return CallFrameSetupOpcode; }
- int getCallFrameDestroyOpcode() const { return CallFrameDestroyOpcode; }
-
/// eliminateCallFramePseudoInstr - This method is called during prolog/epilog
/// code insertion to eliminate call frame setup and destroy pseudo
/// instructions (but only if the Target is using them). It is responsible
@@ -752,9 +669,6 @@ public:
eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const {
- assert(getCallFrameSetupOpcode()== -1 && getCallFrameDestroyOpcode()== -1 &&
- "eliminateCallFramePseudoInstr must be implemented if using"
- " call frame setup/destroy pseudo instructions!");
assert(0 && "Call Frame Pseudo Instructions do not exist on this target!");
}
@@ -806,6 +720,12 @@ public:
virtual int getSEHRegNum(unsigned i) const {
return i;
}
+
+ /// getCompactUnwindRegNum - This function maps the register to the number for
+ /// compact unwind encoding. Return -1 if the register isn't valid.
+ virtual int getCompactUnwindRegNum(unsigned) const {
+ return -1;
+ }
};
diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h
index a464822..8d44f66 100644
--- a/include/llvm/Target/TargetRegistry.h
+++ b/include/llvm/Target/TargetRegistry.h
@@ -33,6 +33,8 @@ namespace llvm {
class MCContext;
class MCDisassembler;
class MCInstPrinter;
+ class MCInstrInfo;
+ class MCRegisterInfo;
class MCStreamer;
class TargetAsmBackend;
class TargetAsmLexer;
@@ -64,9 +66,12 @@ namespace llvm {
typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
typedef MCAsmInfo *(*AsmInfoCtorFnTy)(const Target &T,
- StringRef TT);
+ StringRef TT);
+ typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void);
+ typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(void);
typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T,
const std::string &TT,
+ const std::string &CPU,
const std::string &Features);
typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM,
MCStreamer &Streamer);
@@ -120,8 +125,18 @@ namespace llvm {
/// HasJIT - Whether this target supports the JIT.
bool HasJIT;
+ /// AsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if
+ /// registered.
AsmInfoCtorFnTy AsmInfoCtorFn;
+ /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo,
+ /// if registered.
+ MCInstrInfoCtorFnTy MCInstrInfoCtorFn;
+
+ /// MCRegInfoCtorFn - Constructor function for this target's MCRegisterInfo,
+ /// if registered.
+ MCRegInfoCtorFnTy MCRegInfoCtorFn;
+
/// TargetMachineCtorFn - Construction function for this target's
/// TargetMachine, if registered.
TargetMachineCtorTy TargetMachineCtorFn;
@@ -231,6 +246,22 @@ namespace llvm {
return AsmInfoCtorFn(*this, Triple);
}
+ /// createMCInstrInfo - Create a MCInstrInfo implementation.
+ ///
+ MCInstrInfo *createMCInstrInfo() const {
+ if (!MCInstrInfoCtorFn)
+ return 0;
+ return MCInstrInfoCtorFn();
+ }
+
+ /// createMCRegInfo - Create a MCRegisterInfo implementation.
+ ///
+ MCRegisterInfo *createMCRegInfo() const {
+ if (!MCRegInfoCtorFn)
+ return 0;
+ return MCRegInfoCtorFn();
+ }
+
/// createTargetMachine - Create a target specific machine implementation
/// for the specified \arg Triple.
///
@@ -239,10 +270,11 @@ namespace llvm {
/// either the target triple from the module, or the target triple of the
/// host if that does not exist.
TargetMachine *createTargetMachine(const std::string &Triple,
+ const std::string &CPU,
const std::string &Features) const {
if (!TargetMachineCtorFn)
return 0;
- return TargetMachineCtorFn(*this, Triple, Features);
+ return TargetMachineCtorFn(*this, Triple, CPU, Features);
}
/// createAsmBackend - Create a target specific assembly parser.
@@ -444,6 +476,36 @@ namespace llvm {
T.AsmInfoCtorFn = Fn;
}
+ /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the
+ /// given target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct a MCInstrInfo for the target.
+ static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
+ // Ignore duplicate registration.
+ if (!T.MCInstrInfoCtorFn)
+ T.MCInstrInfoCtorFn = Fn;
+ }
+
+ /// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the
+ /// given target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct a MCRegisterInfo for the target.
+ static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) {
+ // Ignore duplicate registration.
+ if (!T.MCRegInfoCtorFn)
+ T.MCRegInfoCtorFn = Fn;
+ }
+
/// RegisterTargetMachine - Register a TargetMachine implementation for the
/// given target.
///
@@ -654,6 +716,71 @@ namespace llvm {
}
};
+ /// RegisterMCInstrInfo - Helper template for registering a target instruction
+ /// info implementation. This invokes the static "Create" method on the class
+ /// to actually do the construction. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCInstrInfo<FooMCInstrInfo> X(TheFooTarget);
+ /// }
+ template<class MCInstrInfoImpl>
+ struct RegisterMCInstrInfo {
+ RegisterMCInstrInfo(Target &T) {
+ TargetRegistry::RegisterMCInstrInfo(T, &Allocator);
+ }
+ private:
+ static MCInstrInfo *Allocator() {
+ return new MCInstrInfoImpl();
+ }
+ };
+
+ /// RegisterMCInstrInfoFn - Helper template for registering a target
+ /// instruction info implementation. This invokes the specified function to
+ /// do the construction. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCInstrInfoFn X(TheFooTarget, TheFunction);
+ /// }
+ struct RegisterMCInstrInfoFn {
+ RegisterMCInstrInfoFn(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
+ TargetRegistry::RegisterMCInstrInfo(T, Fn);
+ }
+ };
+
+ /// RegisterMCRegInfo - Helper template for registering a target register info
+ /// implementation. This invokes the static "Create" method on the class to
+ /// actually do the construction. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCRegInfo<FooMCRegInfo> X(TheFooTarget);
+ /// }
+ template<class MCRegisterInfoImpl>
+ struct RegisterMCRegInfo {
+ RegisterMCRegInfo(Target &T) {
+ TargetRegistry::RegisterMCRegInfo(T, &Allocator);
+ }
+ private:
+ static MCRegisterInfo *Allocator() {
+ return new MCRegisterInfoImpl();
+ }
+ };
+
+ /// RegisterMCRegInfoFn - Helper template for registering a target register
+ /// info implementation. This invokes the specified function to do the
+ /// construction. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCRegInfoFn X(TheFooTarget, TheFunction);
+ /// }
+ struct RegisterMCRegInfoFn {
+ RegisterMCRegInfoFn(Target &T, Target::MCRegInfoCtorFnTy Fn) {
+ TargetRegistry::RegisterMCRegInfo(T, Fn);
+ }
+ };
/// RegisterTargetMachine - Helper template for registering a target machine
/// implementation, for use in the target machine initialization
@@ -671,8 +798,9 @@ namespace llvm {
private:
static TargetMachine *Allocator(const Target &T, const std::string &TT,
+ const std::string &CPU,
const std::string &FS) {
- return new TargetMachineImpl(T, TT, FS);
+ return new TargetMachineImpl(T, TT, CPU, FS);
}
};