| 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), | 
|  | 35 | Is128Bit       = (1 << 4) | 
|  | 36 | }; | 
|  | 37 | // SystemZ MachineOperand target flags. | 
|  | 38 | enum { | 
|  | 39 | // Masks out the bits for the access model. | 
|  | 40 | MO_SYMBOL_MODIFIER = (1 << 0), | 
|  | 41 |  | 
|  | 42 | // @GOT (aka @GOTENT) | 
|  | 43 | MO_GOT = (1 << 0) | 
|  | 44 | }; | 
| Richard Sandiford | 0fb90ab | 2013-05-28 10:41:11 +0000 | [diff] [blame] | 45 | // Classifies a branch. | 
|  | 46 | enum BranchType { | 
|  | 47 | // An instruction that branches on the current value of CC. | 
|  | 48 | BranchNormal, | 
|  | 49 |  | 
|  | 50 | // An instruction that peforms a 32-bit signed comparison and branches | 
|  | 51 | // on the result. | 
|  | 52 | BranchC, | 
|  | 53 |  | 
|  | 54 | // An instruction that peforms a 64-bit signed comparison and branches | 
|  | 55 | // on the result. | 
|  | 56 | BranchCG | 
|  | 57 | }; | 
| Richard Sandiford | 53c9efd | 2013-05-28 10:13:54 +0000 | [diff] [blame] | 58 | // Information about a branch instruction. | 
|  | 59 | struct Branch { | 
| Richard Sandiford | 0fb90ab | 2013-05-28 10:41:11 +0000 | [diff] [blame] | 60 | // The type of the branch. | 
|  | 61 | BranchType Type; | 
|  | 62 |  | 
| Richard Sandiford | 53c9efd | 2013-05-28 10:13:54 +0000 | [diff] [blame] | 63 | // CCMASK_<N> is set if the branch should be taken when CC == N. | 
|  | 64 | unsigned CCMask; | 
|  | 65 |  | 
|  | 66 | // The target of the branch. | 
|  | 67 | const MachineOperand *Target; | 
|  | 68 |  | 
| Richard Sandiford | 0fb90ab | 2013-05-28 10:41:11 +0000 | [diff] [blame] | 69 | Branch(BranchType type, unsigned ccMask, const MachineOperand *target) | 
|  | 70 | : Type(type), CCMask(ccMask), Target(target) {} | 
| Richard Sandiford | 53c9efd | 2013-05-28 10:13:54 +0000 | [diff] [blame] | 71 | }; | 
| Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 72 | } | 
|  | 73 |  | 
|  | 74 | class SystemZInstrInfo : public SystemZGenInstrInfo { | 
|  | 75 | const SystemZRegisterInfo RI; | 
|  | 76 |  | 
|  | 77 | void splitMove(MachineBasicBlock::iterator MI, unsigned NewOpcode) const; | 
|  | 78 | void splitAdjDynAlloc(MachineBasicBlock::iterator MI) const; | 
|  | 79 |  | 
|  | 80 | public: | 
|  | 81 | explicit SystemZInstrInfo(SystemZTargetMachine &TM); | 
|  | 82 |  | 
|  | 83 | // Override TargetInstrInfo. | 
|  | 84 | virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, | 
|  | 85 | int &FrameIndex) const LLVM_OVERRIDE; | 
|  | 86 | virtual unsigned isStoreToStackSlot(const MachineInstr *MI, | 
|  | 87 | int &FrameIndex) const LLVM_OVERRIDE; | 
|  | 88 | virtual bool AnalyzeBranch(MachineBasicBlock &MBB, | 
|  | 89 | MachineBasicBlock *&TBB, | 
|  | 90 | MachineBasicBlock *&FBB, | 
|  | 91 | SmallVectorImpl<MachineOperand> &Cond, | 
|  | 92 | bool AllowModify) const LLVM_OVERRIDE; | 
|  | 93 | virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const LLVM_OVERRIDE; | 
|  | 94 | virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, | 
|  | 95 | MachineBasicBlock *FBB, | 
|  | 96 | const SmallVectorImpl<MachineOperand> &Cond, | 
|  | 97 | DebugLoc DL) const LLVM_OVERRIDE; | 
|  | 98 | virtual void copyPhysReg(MachineBasicBlock &MBB, | 
|  | 99 | MachineBasicBlock::iterator MBBI, DebugLoc DL, | 
|  | 100 | unsigned DestReg, unsigned SrcReg, | 
|  | 101 | bool KillSrc) const LLVM_OVERRIDE; | 
|  | 102 | virtual void | 
|  | 103 | storeRegToStackSlot(MachineBasicBlock &MBB, | 
|  | 104 | MachineBasicBlock::iterator MBBI, | 
|  | 105 | unsigned SrcReg, bool isKill, int FrameIndex, | 
|  | 106 | const TargetRegisterClass *RC, | 
|  | 107 | const TargetRegisterInfo *TRI) const LLVM_OVERRIDE; | 
|  | 108 | virtual void | 
|  | 109 | loadRegFromStackSlot(MachineBasicBlock &MBB, | 
|  | 110 | MachineBasicBlock::iterator MBBI, | 
|  | 111 | unsigned DestReg, int FrameIdx, | 
|  | 112 | const TargetRegisterClass *RC, | 
|  | 113 | const TargetRegisterInfo *TRI) const LLVM_OVERRIDE; | 
| Richard Sandiford | f6bae1e | 2013-07-02 15:28:56 +0000 | [diff] [blame^] | 114 | virtual MachineInstr * | 
|  | 115 | foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, | 
|  | 116 | const SmallVectorImpl<unsigned> &Ops, | 
|  | 117 | int FrameIndex) const; | 
|  | 118 | virtual MachineInstr * | 
|  | 119 | foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI, | 
|  | 120 | const SmallVectorImpl<unsigned> &Ops, | 
|  | 121 | MachineInstr* LoadMI) const; | 
| Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 122 | virtual bool | 
|  | 123 | expandPostRAPseudo(MachineBasicBlock::iterator MBBI) const LLVM_OVERRIDE; | 
|  | 124 | virtual bool | 
|  | 125 | ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const | 
|  | 126 | LLVM_OVERRIDE; | 
|  | 127 |  | 
|  | 128 | // Return the SystemZRegisterInfo, which this class owns. | 
|  | 129 | const SystemZRegisterInfo &getRegisterInfo() const { return RI; } | 
|  | 130 |  | 
| Richard Sandiford | 312425f | 2013-05-20 14:23:08 +0000 | [diff] [blame] | 131 | // Return the size in bytes of MI. | 
|  | 132 | uint64_t getInstSizeInBytes(const MachineInstr *MI) const; | 
|  | 133 |  | 
| Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 134 | // Return true if MI is a conditional or unconditional branch. | 
|  | 135 | // When returning true, set Cond to the mask of condition-code | 
|  | 136 | // values on which the instruction will branch, and set Target | 
|  | 137 | // to the operand that contains the branch target.  This target | 
|  | 138 | // can be a register or a basic block. | 
| Richard Sandiford | 53c9efd | 2013-05-28 10:13:54 +0000 | [diff] [blame] | 139 | SystemZII::Branch getBranchInfo(const MachineInstr *MI) const; | 
| Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 140 |  | 
|  | 141 | // Get the load and store opcodes for a given register class. | 
|  | 142 | void getLoadStoreOpcodes(const TargetRegisterClass *RC, | 
|  | 143 | unsigned &LoadOpcode, unsigned &StoreOpcode) const; | 
|  | 144 |  | 
|  | 145 | // Opcode is the opcode of an instruction that has an address operand, | 
|  | 146 | // and the caller wants to perform that instruction's operation on an | 
|  | 147 | // address that has displacement Offset.  Return the opcode of a suitable | 
|  | 148 | // instruction (which might be Opcode itself) or 0 if no such instruction | 
|  | 149 | // exists. | 
|  | 150 | unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset) const; | 
|  | 151 |  | 
| Richard Sandiford | 0fb90ab | 2013-05-28 10:41:11 +0000 | [diff] [blame] | 152 | // If Opcode is a COMPARE opcode for which an associated COMPARE AND | 
|  | 153 | // BRANCH exists, return the opcode for the latter, otherwise return 0. | 
| Richard Sandiford | e1d9f00 | 2013-05-29 11:58:52 +0000 | [diff] [blame] | 154 | // MI, if nonnull, is the compare instruction. | 
|  | 155 | unsigned getCompareAndBranch(unsigned Opcode, | 
|  | 156 | const MachineInstr *MI = 0) const; | 
| Richard Sandiford | 0fb90ab | 2013-05-28 10:41:11 +0000 | [diff] [blame] | 157 |  | 
| Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 158 | // Emit code before MBBI in MI to move immediate value Value into | 
|  | 159 | // physical register Reg. | 
|  | 160 | void loadImmediate(MachineBasicBlock &MBB, | 
|  | 161 | MachineBasicBlock::iterator MBBI, | 
|  | 162 | unsigned Reg, uint64_t Value) const; | 
|  | 163 | }; | 
|  | 164 | } // end namespace llvm | 
|  | 165 |  | 
|  | 166 | #endif |