-//===- SystemZInstrInfo.h - SystemZ Instruction Information -------*- C++ -*-===//
+//===-- SystemZInstrInfo.h - SystemZ instruction information ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
#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
+ };
+ static inline unsigned getAccessSize(unsigned int Flags) {
+ return (Flags & AccessSizeMask) >> AccessSizeShift;
+ }
+
+ // 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
+ };
+ // Information about a branch instruction.
+ struct Branch {
+ // The type of the branch.
+ BranchType Type;
+
+ // CCMASK_<N> 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 ccMask, const MachineOperand *target)
+ : Type(type), CCMask(ccMask), Target(target) {}
};
}
-class SystemZInstrInfo : public TargetInstrInfoImpl {
+class SystemZInstrInfo : public SystemZGenInstrInfo {
const SystemZRegisterInfo RI;
SystemZTargetMachine &TM;
- IndexedMap<unsigned> 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; }
-
- bool copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
- unsigned DestReg, unsigned SrcReg,
- const TargetRegisterClass *DestRC,
- const TargetRegisterClass *SrcRC,
- DebugLoc DL) 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<CalleeSavedInfo> &CSI,
- const TargetRegisterInfo *TRI) const;
- virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MI,
- const std::vector<CalleeSavedInfo> &CSI,
- const TargetRegisterInfo *TRI) const;
-
- bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &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<MachineOperand> &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<MachineOperand> &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;
+ 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<MachineOperand> &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<unsigned> &Ops,
+ int FrameIndex) const;
+ virtual MachineInstr *
+ foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI,
+ const SmallVectorImpl<unsigned> &Ops,
+ MachineInstr* LoadMI) const;
+ virtual bool
+ expandPostRAPseudo(MachineBasicBlock::iterator MBBI) const LLVM_OVERRIDE;
+ virtual bool
+ ReverseBranchCondition(SmallVectorImpl<MachineOperand> &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 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