X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FSystemZ%2FSystemZInstrInfo.h;h=3c4e8af0e61411b56722d4871d7eb1072bbf43dc;hb=30632d2fbb3c46e552a68aa7961b12eb44cece01;hp=0559619248a63e7395c300dad519217a98bf581f;hpb=f7d55b97f01ce133eb830ca93411df4caa9d65da;p=oota-llvm.git diff --git a/lib/Target/SystemZ/SystemZInstrInfo.h b/lib/Target/SystemZ/SystemZInstrInfo.h index 0559619248a..3c4e8af0e61 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.h +++ b/lib/Target/SystemZ/SystemZInstrInfo.h @@ -1,4 +1,4 @@ -//===- SystemZInstrInfo.h - SystemZ Instruction Information -------*- C++ -*-===// +//===-- SystemZInstrInfo.h - SystemZ instruction information ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,108 +16,222 @@ #include "SystemZ.h" #include "SystemZRegisterInfo.h" -#include "llvm/ADT/IndexedMap.h" #include "llvm/Target/TargetInstrInfo.h" +#define GET_INSTRINFO_HEADER +#include "SystemZGenInstrInfo.inc" + namespace llvm { class SystemZTargetMachine; -/// SystemZII - This namespace holds all of the target specific flags that -/// instruction info tracks. -/// namespace SystemZII { enum { - //===------------------------------------------------------------------===// - // SystemZ Specific MachineOperand flags. - - MO_NO_FLAG = 0, - - /// MO_GOTENT - On a symbol operand this indicates that the immediate is - /// the offset to the location of the symbol name from the base of the GOT. - /// - /// SYMBOL_LABEL @GOTENT - MO_GOTENT = 1, - - /// MO_PLT - On a symbol operand this indicates that the immediate is - /// offset to the PLT entry of symbol name from the current code location. - /// - /// SYMBOL_LABEL @PLT - MO_PLT = 2 + // See comments in SystemZInstrFormats.td. + SimpleBDXLoad = (1 << 0), + SimpleBDXStore = (1 << 1), + Has20BitOffset = (1 << 2), + HasIndex = (1 << 3), + Is128Bit = (1 << 4), + AccessSizeMask = (31 << 5), + AccessSizeShift = 5, + CCValuesMask = (15 << 10), + CCValuesShift = 10, + CompareZeroCCMaskMask = (15 << 14), + CompareZeroCCMaskShift = 14, + CCMaskFirst = (1 << 18), + CCMaskLast = (1 << 19), + IsLogical = (1 << 20) + }; + static inline unsigned getAccessSize(unsigned int Flags) { + return (Flags & AccessSizeMask) >> AccessSizeShift; + } + static inline unsigned getCCValues(unsigned int Flags) { + return (Flags & CCValuesMask) >> CCValuesShift; + } + static inline unsigned getCompareZeroCCMask(unsigned int Flags) { + return (Flags & CompareZeroCCMaskMask) >> CompareZeroCCMaskShift; + } + + // SystemZ MachineOperand target flags. + enum { + // Masks out the bits for the access model. + MO_SYMBOL_MODIFIER = (1 << 0), + + // @GOT (aka @GOTENT) + MO_GOT = (1 << 0) + }; + // Classifies a branch. + enum BranchType { + // An instruction that branches on the current value of CC. + BranchNormal, + + // An instruction that peforms a 32-bit signed comparison and branches + // on the result. + BranchC, + + // An instruction that peforms a 64-bit signed comparison and branches + // on the result. + BranchCG, + + // An instruction that decrements a 32-bit register and branches if + // the result is nonzero. + BranchCT, + + // An instruction that decrements a 64-bit register and branches if + // the result is nonzero. + BranchCTG + }; + // Information about a branch instruction. + struct Branch { + // The type of the branch. + BranchType Type; + + // CCMASK_ is set if CC might be equal to N. + unsigned CCValid; + + // CCMASK_ is set if the branch should be taken when CC == N. + unsigned CCMask; + + // The target of the branch. + const MachineOperand *Target; + + Branch(BranchType type, unsigned ccValid, unsigned ccMask, + const MachineOperand *target) + : Type(type), CCValid(ccValid), CCMask(ccMask), Target(target) {} }; } -class SystemZInstrInfo : public TargetInstrInfoImpl { +class SystemZInstrInfo : public SystemZGenInstrInfo { const SystemZRegisterInfo RI; SystemZTargetMachine &TM; - IndexedMap RegSpillOffsets; + + void splitMove(MachineBasicBlock::iterator MI, unsigned NewOpcode) const; + void splitAdjDynAlloc(MachineBasicBlock::iterator MI) const; + public: explicit SystemZInstrInfo(SystemZTargetMachine &TM); - /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As - /// such, whenever a client has an instance of instruction info, it should - /// always be able to get register info as well (through this method). - /// - virtual const SystemZRegisterInfo &getRegisterInfo() const { return RI; } - - virtual void copyPhysReg(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, DebugLoc DL, - unsigned DestReg, unsigned SrcReg, - bool KillSrc) const; - - bool isMoveInstr(const MachineInstr& MI, - unsigned &SrcReg, unsigned &DstReg, - unsigned &SrcSubIdx, unsigned &DstSubIdx) const; - unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const; - unsigned isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const; - - virtual void storeRegToStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned SrcReg, bool isKill, - int FrameIndex, - const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const; - virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned DestReg, int FrameIdx, - const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const; - - virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector &CSI, - const TargetRegisterInfo *TRI) const; - virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector &CSI, - const TargetRegisterInfo *TRI) const; - - bool ReverseBranchCondition(SmallVectorImpl &Cond) const; - virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const; + // Override TargetInstrInfo. + virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, + int &FrameIndex) const LLVM_OVERRIDE; + virtual unsigned isStoreToStackSlot(const MachineInstr *MI, + int &FrameIndex) const LLVM_OVERRIDE; + virtual bool isStackSlotCopy(const MachineInstr *MI, int &DestFrameIndex, + int &SrcFrameIndex) const LLVM_OVERRIDE; virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl &Cond, - bool AllowModify) const; + bool AllowModify) const LLVM_OVERRIDE; + virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const LLVM_OVERRIDE; virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, const SmallVectorImpl &Cond, - DebugLoc DL) const; - virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const; - - SystemZCC::CondCodes getOppositeCondition(SystemZCC::CondCodes CC) const; - SystemZCC::CondCodes getCondFromBranchOpc(unsigned Opc) const; - const TargetInstrDesc& getBrCond(SystemZCC::CondCodes CC) const; - const TargetInstrDesc& getLongDispOpc(unsigned Opc) const; - - const TargetInstrDesc& getMemoryInstr(unsigned Opc, int64_t Offset = 0) const { - if (Offset < 0 || Offset >= 4096) - return getLongDispOpc(Opc); - else - return get(Opc); - } + DebugLoc DL) const LLVM_OVERRIDE; + bool analyzeCompare(const MachineInstr *MI, unsigned &SrcReg, + unsigned &SrcReg2, int &Mask, int &Value) const + LLVM_OVERRIDE; + bool optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, + unsigned SrcReg2, int Mask, int Value, + const MachineRegisterInfo *MRI) const LLVM_OVERRIDE; + virtual bool isPredicable(MachineInstr *MI) const LLVM_OVERRIDE; + virtual bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, + unsigned ExtraPredCycles, + const BranchProbability &Probability) const + LLVM_OVERRIDE; + virtual bool isProfitableToIfCvt(MachineBasicBlock &TMBB, + unsigned NumCyclesT, + unsigned ExtraPredCyclesT, + MachineBasicBlock &FMBB, + unsigned NumCyclesF, + unsigned ExtraPredCyclesF, + const BranchProbability &Probability) const + LLVM_OVERRIDE; + virtual bool + PredicateInstruction(MachineInstr *MI, + const SmallVectorImpl &Pred) const + LLVM_OVERRIDE; + virtual void copyPhysReg(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, DebugLoc DL, + unsigned DestReg, unsigned SrcReg, + bool KillSrc) const LLVM_OVERRIDE; + virtual void + storeRegToStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + unsigned SrcReg, bool isKill, int FrameIndex, + const TargetRegisterClass *RC, + const TargetRegisterInfo *TRI) const LLVM_OVERRIDE; + virtual void + loadRegFromStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + unsigned DestReg, int FrameIdx, + const TargetRegisterClass *RC, + const TargetRegisterInfo *TRI) const LLVM_OVERRIDE; + virtual MachineInstr * + convertToThreeAddress(MachineFunction::iterator &MFI, + MachineBasicBlock::iterator &MBBI, + LiveVariables *LV) const; + virtual MachineInstr * + foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, + const SmallVectorImpl &Ops, + int FrameIndex) const; + virtual MachineInstr * + foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI, + const SmallVectorImpl &Ops, + MachineInstr* LoadMI) const; + virtual bool + expandPostRAPseudo(MachineBasicBlock::iterator MBBI) const LLVM_OVERRIDE; + virtual bool + ReverseBranchCondition(SmallVectorImpl &Cond) const + LLVM_OVERRIDE; + + // Return the SystemZRegisterInfo, which this class owns. + const SystemZRegisterInfo &getRegisterInfo() const { return RI; } + + // Return the size in bytes of MI. + uint64_t getInstSizeInBytes(const MachineInstr *MI) const; + + // Return true if MI is a conditional or unconditional branch. + // When returning true, set Cond to the mask of condition-code + // values on which the instruction will branch, and set Target + // to the operand that contains the branch target. This target + // can be a register or a basic block. + SystemZII::Branch getBranchInfo(const MachineInstr *MI) const; + + // Get the load and store opcodes for a given register class. + void getLoadStoreOpcodes(const TargetRegisterClass *RC, + unsigned &LoadOpcode, unsigned &StoreOpcode) const; + + // Opcode is the opcode of an instruction that has an address operand, + // and the caller wants to perform that instruction's operation on an + // address that has displacement Offset. Return the opcode of a suitable + // instruction (which might be Opcode itself) or 0 if no such instruction + // exists. + unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset) const; + + // If Opcode is a load instruction that has a LOAD AND TEST form, + // return the opcode for the testing form, otherwise return 0. + unsigned getLoadAndTest(unsigned Opcode) const; + + // Return true if ROTATE AND ... SELECTED BITS can be used to select bits + // Mask of the R2 operand, given that only the low BitSize bits of Mask are + // significant. Set Start and End to the I3 and I4 operands if so. + bool isRxSBGMask(uint64_t Mask, unsigned BitSize, + unsigned &Start, unsigned &End) const; + + // If Opcode is a COMPARE opcode for which an associated COMPARE AND + // BRANCH exists, return the opcode for the latter, otherwise return 0. + // MI, if nonnull, is the compare instruction. + unsigned getCompareAndBranch(unsigned Opcode, + const MachineInstr *MI = 0) const; + + // Emit code before MBBI in MI to move immediate value Value into + // physical register Reg. + void loadImmediate(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + unsigned Reg, uint64_t Value) const; }; - -} +} // end namespace llvm #endif