| Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 1 | //===-- SystemZInstrInfo.h - SystemZ instruction information ----*- C++ -*-===// | 
|  | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
|  | 10 | // This file contains the SystemZ implementation of the TargetInstrInfo class. | 
|  | 11 | // | 
|  | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 |  | 
|  | 14 | #ifndef LLVM_TARGET_SYSTEMZINSTRINFO_H | 
|  | 15 | #define LLVM_TARGET_SYSTEMZINSTRINFO_H | 
|  | 16 |  | 
|  | 17 | #include "SystemZ.h" | 
|  | 18 | #include "SystemZRegisterInfo.h" | 
|  | 19 | #include "llvm/Target/TargetInstrInfo.h" | 
|  | 20 |  | 
|  | 21 | #define GET_INSTRINFO_HEADER | 
|  | 22 | #include "SystemZGenInstrInfo.inc" | 
|  | 23 |  | 
|  | 24 | namespace llvm { | 
|  | 25 |  | 
|  | 26 | class SystemZTargetMachine; | 
|  | 27 |  | 
|  | 28 | namespace SystemZII { | 
|  | 29 | enum { | 
|  | 30 | // See comments in SystemZInstrFormats.td. | 
|  | 31 | SimpleBDXLoad  = (1 << 0), | 
|  | 32 | SimpleBDXStore = (1 << 1), | 
|  | 33 | Has20BitOffset = (1 << 2), | 
|  | 34 | HasIndex       = (1 << 3), | 
| Richard Sandiford | ed1fab6 | 2013-07-03 10:10:02 +0000 | [diff] [blame] | 35 | Is128Bit       = (1 << 4), | 
|  | 36 | AccessSizeMask = (31 << 5), | 
|  | 37 | AccessSizeShift = 5 | 
| Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 38 | }; | 
| Richard Sandiford | ed1fab6 | 2013-07-03 10:10:02 +0000 | [diff] [blame] | 39 | static inline unsigned getAccessSize(unsigned int Flags) { | 
|  | 40 | return (Flags & AccessSizeMask) >> AccessSizeShift; | 
|  | 41 | } | 
|  | 42 |  | 
| Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 43 | // SystemZ MachineOperand target flags. | 
|  | 44 | enum { | 
|  | 45 | // Masks out the bits for the access model. | 
|  | 46 | MO_SYMBOL_MODIFIER = (1 << 0), | 
|  | 47 |  | 
|  | 48 | // @GOT (aka @GOTENT) | 
|  | 49 | MO_GOT = (1 << 0) | 
|  | 50 | }; | 
| Richard Sandiford | 0fb90ab | 2013-05-28 10:41:11 +0000 | [diff] [blame] | 51 | // Classifies a branch. | 
|  | 52 | enum BranchType { | 
|  | 53 | // An instruction that branches on the current value of CC. | 
|  | 54 | BranchNormal, | 
|  | 55 |  | 
|  | 56 | // An instruction that peforms a 32-bit signed comparison and branches | 
|  | 57 | // on the result. | 
|  | 58 | BranchC, | 
|  | 59 |  | 
|  | 60 | // An instruction that peforms a 64-bit signed comparison and branches | 
|  | 61 | // on the result. | 
|  | 62 | BranchCG | 
|  | 63 | }; | 
| Richard Sandiford | 53c9efd | 2013-05-28 10:13:54 +0000 | [diff] [blame] | 64 | // Information about a branch instruction. | 
|  | 65 | struct Branch { | 
| Richard Sandiford | 0fb90ab | 2013-05-28 10:41:11 +0000 | [diff] [blame] | 66 | // The type of the branch. | 
|  | 67 | BranchType Type; | 
|  | 68 |  | 
| Richard Sandiford | 53c9efd | 2013-05-28 10:13:54 +0000 | [diff] [blame] | 69 | // CCMASK_<N> is set if the branch should be taken when CC == N. | 
|  | 70 | unsigned CCMask; | 
|  | 71 |  | 
|  | 72 | // The target of the branch. | 
|  | 73 | const MachineOperand *Target; | 
|  | 74 |  | 
| Richard Sandiford | 0fb90ab | 2013-05-28 10:41:11 +0000 | [diff] [blame] | 75 | Branch(BranchType type, unsigned ccMask, const MachineOperand *target) | 
|  | 76 | : Type(type), CCMask(ccMask), Target(target) {} | 
| Richard Sandiford | 53c9efd | 2013-05-28 10:13:54 +0000 | [diff] [blame] | 77 | }; | 
| Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 78 | } | 
|  | 79 |  | 
|  | 80 | class SystemZInstrInfo : public SystemZGenInstrInfo { | 
|  | 81 | const SystemZRegisterInfo RI; | 
| Richard Sandiford | ff6c5a5 | 2013-07-19 16:12:08 +0000 | [diff] [blame] | 82 | SystemZTargetMachine &TM; | 
| Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 83 |  | 
|  | 84 | void splitMove(MachineBasicBlock::iterator MI, unsigned NewOpcode) const; | 
|  | 85 | void splitAdjDynAlloc(MachineBasicBlock::iterator MI) const; | 
|  | 86 |  | 
|  | 87 | public: | 
|  | 88 | explicit SystemZInstrInfo(SystemZTargetMachine &TM); | 
|  | 89 |  | 
|  | 90 | // Override TargetInstrInfo. | 
|  | 91 | virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, | 
|  | 92 | int &FrameIndex) const LLVM_OVERRIDE; | 
|  | 93 | virtual unsigned isStoreToStackSlot(const MachineInstr *MI, | 
|  | 94 | int &FrameIndex) const LLVM_OVERRIDE; | 
| Richard Sandiford | c40f27b | 2013-07-05 14:38:48 +0000 | [diff] [blame] | 95 | virtual bool isStackSlotCopy(const MachineInstr *MI, int &DestFrameIndex, | 
|  | 96 | int &SrcFrameIndex) const LLVM_OVERRIDE; | 
| Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 97 | virtual bool AnalyzeBranch(MachineBasicBlock &MBB, | 
|  | 98 | MachineBasicBlock *&TBB, | 
|  | 99 | MachineBasicBlock *&FBB, | 
|  | 100 | SmallVectorImpl<MachineOperand> &Cond, | 
|  | 101 | bool AllowModify) const LLVM_OVERRIDE; | 
|  | 102 | virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const LLVM_OVERRIDE; | 
|  | 103 | virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, | 
|  | 104 | MachineBasicBlock *FBB, | 
|  | 105 | const SmallVectorImpl<MachineOperand> &Cond, | 
|  | 106 | DebugLoc DL) const LLVM_OVERRIDE; | 
| Richard Sandiford | c3f85d7 | 2013-07-25 09:34:38 +0000 | [diff] [blame^] | 107 | virtual bool analyzeCompare(const MachineInstr *MI, | 
|  | 108 | unsigned &SrcReg, unsigned &SrcReg2, | 
|  | 109 | int &Mask, int &Value) const LLVM_OVERRIDE; | 
|  | 110 | virtual bool optimizeCompareInstr(MachineInstr *CmpInstr, | 
|  | 111 | unsigned SrcReg, unsigned SrcReg2, | 
|  | 112 | int Mask, int Value, | 
|  | 113 | const MachineRegisterInfo *MRI) const | 
|  | 114 | LLVM_OVERRIDE; | 
| Richard Sandiford | f240416 | 2013-07-25 09:11:15 +0000 | [diff] [blame] | 115 | virtual bool isPredicable(MachineInstr *MI) const LLVM_OVERRIDE; | 
|  | 116 | virtual bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, | 
|  | 117 | unsigned ExtraPredCycles, | 
|  | 118 | const BranchProbability &Probability) const | 
|  | 119 | LLVM_OVERRIDE; | 
|  | 120 | virtual bool isProfitableToIfCvt(MachineBasicBlock &TMBB, | 
|  | 121 | unsigned NumCyclesT, | 
|  | 122 | unsigned ExtraPredCyclesT, | 
|  | 123 | MachineBasicBlock &FMBB, | 
|  | 124 | unsigned NumCyclesF, | 
|  | 125 | unsigned ExtraPredCyclesF, | 
|  | 126 | const BranchProbability &Probability) const | 
|  | 127 | LLVM_OVERRIDE; | 
|  | 128 | virtual bool | 
|  | 129 | PredicateInstruction(MachineInstr *MI, | 
|  | 130 | const SmallVectorImpl<MachineOperand> &Pred) const | 
|  | 131 | LLVM_OVERRIDE; | 
| Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 132 | virtual void copyPhysReg(MachineBasicBlock &MBB, | 
|  | 133 | MachineBasicBlock::iterator MBBI, DebugLoc DL, | 
|  | 134 | unsigned DestReg, unsigned SrcReg, | 
|  | 135 | bool KillSrc) const LLVM_OVERRIDE; | 
|  | 136 | virtual void | 
|  | 137 | storeRegToStackSlot(MachineBasicBlock &MBB, | 
|  | 138 | MachineBasicBlock::iterator MBBI, | 
|  | 139 | unsigned SrcReg, bool isKill, int FrameIndex, | 
|  | 140 | const TargetRegisterClass *RC, | 
|  | 141 | const TargetRegisterInfo *TRI) const LLVM_OVERRIDE; | 
|  | 142 | virtual void | 
|  | 143 | loadRegFromStackSlot(MachineBasicBlock &MBB, | 
|  | 144 | MachineBasicBlock::iterator MBBI, | 
|  | 145 | unsigned DestReg, int FrameIdx, | 
|  | 146 | const TargetRegisterClass *RC, | 
|  | 147 | const TargetRegisterInfo *TRI) const LLVM_OVERRIDE; | 
| Richard Sandiford | f6bae1e | 2013-07-02 15:28:56 +0000 | [diff] [blame] | 148 | virtual MachineInstr * | 
| Richard Sandiford | ff6c5a5 | 2013-07-19 16:12:08 +0000 | [diff] [blame] | 149 | convertToThreeAddress(MachineFunction::iterator &MFI, | 
|  | 150 | MachineBasicBlock::iterator &MBBI, | 
|  | 151 | LiveVariables *LV) const; | 
|  | 152 | virtual MachineInstr * | 
| Richard Sandiford | f6bae1e | 2013-07-02 15:28:56 +0000 | [diff] [blame] | 153 | foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, | 
|  | 154 | const SmallVectorImpl<unsigned> &Ops, | 
|  | 155 | int FrameIndex) const; | 
|  | 156 | virtual MachineInstr * | 
|  | 157 | foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI, | 
|  | 158 | const SmallVectorImpl<unsigned> &Ops, | 
|  | 159 | MachineInstr* LoadMI) const; | 
| Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 160 | virtual bool | 
|  | 161 | expandPostRAPseudo(MachineBasicBlock::iterator MBBI) const LLVM_OVERRIDE; | 
|  | 162 | virtual bool | 
|  | 163 | ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const | 
|  | 164 | LLVM_OVERRIDE; | 
|  | 165 |  | 
|  | 166 | // Return the SystemZRegisterInfo, which this class owns. | 
|  | 167 | const SystemZRegisterInfo &getRegisterInfo() const { return RI; } | 
|  | 168 |  | 
| Richard Sandiford | 312425f | 2013-05-20 14:23:08 +0000 | [diff] [blame] | 169 | // Return the size in bytes of MI. | 
|  | 170 | uint64_t getInstSizeInBytes(const MachineInstr *MI) const; | 
|  | 171 |  | 
| Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 172 | // Return true if MI is a conditional or unconditional branch. | 
|  | 173 | // When returning true, set Cond to the mask of condition-code | 
|  | 174 | // values on which the instruction will branch, and set Target | 
|  | 175 | // to the operand that contains the branch target.  This target | 
|  | 176 | // can be a register or a basic block. | 
| Richard Sandiford | 53c9efd | 2013-05-28 10:13:54 +0000 | [diff] [blame] | 177 | SystemZII::Branch getBranchInfo(const MachineInstr *MI) const; | 
| Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 178 |  | 
|  | 179 | // Get the load and store opcodes for a given register class. | 
|  | 180 | void getLoadStoreOpcodes(const TargetRegisterClass *RC, | 
|  | 181 | unsigned &LoadOpcode, unsigned &StoreOpcode) const; | 
|  | 182 |  | 
|  | 183 | // Opcode is the opcode of an instruction that has an address operand, | 
|  | 184 | // and the caller wants to perform that instruction's operation on an | 
|  | 185 | // address that has displacement Offset.  Return the opcode of a suitable | 
|  | 186 | // instruction (which might be Opcode itself) or 0 if no such instruction | 
|  | 187 | // exists. | 
|  | 188 | unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset) const; | 
|  | 189 |  | 
| Richard Sandiford | 0fb90ab | 2013-05-28 10:41:11 +0000 | [diff] [blame] | 190 | // If Opcode is a COMPARE opcode for which an associated COMPARE AND | 
|  | 191 | // BRANCH exists, return the opcode for the latter, otherwise return 0. | 
| Richard Sandiford | e1d9f00 | 2013-05-29 11:58:52 +0000 | [diff] [blame] | 192 | // MI, if nonnull, is the compare instruction. | 
|  | 193 | unsigned getCompareAndBranch(unsigned Opcode, | 
|  | 194 | const MachineInstr *MI = 0) const; | 
| Richard Sandiford | 0fb90ab | 2013-05-28 10:41:11 +0000 | [diff] [blame] | 195 |  | 
| Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 196 | // Emit code before MBBI in MI to move immediate value Value into | 
|  | 197 | // physical register Reg. | 
|  | 198 | void loadImmediate(MachineBasicBlock &MBB, | 
|  | 199 | MachineBasicBlock::iterator MBBI, | 
|  | 200 | unsigned Reg, uint64_t Value) const; | 
|  | 201 | }; | 
|  | 202 | } // end namespace llvm | 
|  | 203 |  | 
|  | 204 | #endif |