| Jia Liu | 9f61011 | 2012-02-17 08:55:11 +0000 | [diff] [blame] | 1 | //===-- MipsInstrInfo.cpp - Mips Instruction Information ------------------===// | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
| Chris Lattner | f3ebc3f | 2007-12-29 20:36:04 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 7 | // | 
| Akira Hatanaka | e248912 | 2011-04-15 21:51:11 +0000 | [diff] [blame] | 8 | //===----------------------------------------------------------------------===// | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 9 | // | 
|  | 10 | // This file contains the Mips implementation of the TargetInstrInfo class. | 
|  | 11 | // | 
| Akira Hatanaka | e248912 | 2011-04-15 21:51:11 +0000 | [diff] [blame] | 12 | //===----------------------------------------------------------------------===// | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 13 |  | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 14 | #include "MipsInstrInfo.h" | 
| Akira Hatanaka | 9c6028f | 2011-07-07 23:56:50 +0000 | [diff] [blame] | 15 | #include "InstPrinter/MipsInstPrinter.h" | 
| Chandler Carruth | ed0881b | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 16 | #include "MipsAnalyzeImmediate.h" | 
|  | 17 | #include "MipsMachineFunction.h" | 
| Eric Christopher | d8abc3a | 2015-01-08 18:18:54 +0000 | [diff] [blame] | 18 | #include "MipsSubtarget.h" | 
| Chandler Carruth | ed0881b | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 19 | #include "llvm/ADT/STLExtras.h" | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 20 | #include "llvm/CodeGen/MachineInstrBuilder.h" | 
| Dan Gohman | d5ca7064 | 2009-06-03 20:30:14 +0000 | [diff] [blame] | 21 | #include "llvm/CodeGen/MachineRegisterInfo.h" | 
| Torok Edwin | 56d0659 | 2009-07-11 20:10:48 +0000 | [diff] [blame] | 22 | #include "llvm/Support/ErrorHandling.h" | 
| Evan Cheng | 2bb4035 | 2011-08-24 18:08:43 +0000 | [diff] [blame] | 23 | #include "llvm/Support/TargetRegistry.h" | 
| Evan Cheng | 1e210d0 | 2011-06-28 20:07:07 +0000 | [diff] [blame] | 24 |  | 
| Chandler Carruth | d174b72 | 2014-04-22 02:03:14 +0000 | [diff] [blame] | 25 | using namespace llvm; | 
|  | 26 |  | 
| Juergen Ributzka | d12ccbd | 2013-11-19 00:57:56 +0000 | [diff] [blame] | 27 | #define GET_INSTRINFO_CTOR_DTOR | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 28 | #include "MipsGenInstrInfo.inc" | 
|  | 29 |  | 
| Juergen Ributzka | d12ccbd | 2013-11-19 00:57:56 +0000 | [diff] [blame] | 30 | // Pin the vtable to this file. | 
|  | 31 | void MipsInstrInfo::anchor() {} | 
|  | 32 |  | 
| Eric Christopher | 675cb4d | 2014-07-18 23:25:00 +0000 | [diff] [blame] | 33 | MipsInstrInfo::MipsInstrInfo(const MipsSubtarget &STI, unsigned UncondBr) | 
|  | 34 | : MipsGenInstrInfo(Mips::ADJCALLSTACKDOWN, Mips::ADJCALLSTACKUP), | 
|  | 35 | Subtarget(STI), UncondBrOpc(UncondBr) {} | 
| Akira Hatanaka | 9c6028f | 2011-07-07 23:56:50 +0000 | [diff] [blame] | 36 |  | 
| Eric Christopher | 675cb4d | 2014-07-18 23:25:00 +0000 | [diff] [blame] | 37 | const MipsInstrInfo *MipsInstrInfo::create(MipsSubtarget &STI) { | 
|  | 38 | if (STI.inMips16Mode()) | 
|  | 39 | return llvm::createMips16InstrInfo(STI); | 
| Akira Hatanaka | fab8929 | 2012-08-02 18:21:47 +0000 | [diff] [blame] | 40 |  | 
| Eric Christopher | 675cb4d | 2014-07-18 23:25:00 +0000 | [diff] [blame] | 41 | return llvm::createMipsSEInstrInfo(STI); | 
| Akira Hatanaka | fab8929 | 2012-08-02 18:21:47 +0000 | [diff] [blame] | 42 | } | 
|  | 43 |  | 
| Akira Hatanaka | b7fa3c9 | 2012-07-31 21:49:49 +0000 | [diff] [blame] | 44 | bool MipsInstrInfo::isZeroImm(const MachineOperand &op) const { | 
| Dan Gohman | 0d1e9a8 | 2008-10-03 15:45:36 +0000 | [diff] [blame] | 45 | return op.isImm() && op.getImm() == 0; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 46 | } | 
|  | 47 |  | 
| Bruno Cardoso Lopes | 7b616f5 | 2007-08-18 01:56:48 +0000 | [diff] [blame] | 48 | /// insertNoop - If data hazard condition is found insert the target nop | 
|  | 49 | /// instruction. | 
|  | 50 | void MipsInstrInfo:: | 
| Bruno Cardoso Lopes | ed874ef | 2011-03-04 17:51:39 +0000 | [diff] [blame] | 51 | insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const | 
| Bruno Cardoso Lopes | 7b616f5 | 2007-08-18 01:56:48 +0000 | [diff] [blame] | 52 | { | 
| Chris Lattner | 6f306d7 | 2010-04-02 20:16:16 +0000 | [diff] [blame] | 53 | DebugLoc DL; | 
| Bill Wendling | f6d609a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 54 | BuildMI(MBB, MI, DL, get(Mips::NOP)); | 
| Bruno Cardoso Lopes | 7b616f5 | 2007-08-18 01:56:48 +0000 | [diff] [blame] | 55 | } | 
|  | 56 |  | 
| Akira Hatanaka | b7fa3c9 | 2012-07-31 21:49:49 +0000 | [diff] [blame] | 57 | MachineMemOperand *MipsInstrInfo::GetMemOperand(MachineBasicBlock &MBB, int FI, | 
|  | 58 | unsigned Flag) const { | 
| Akira Hatanaka | 1cf7576 | 2011-12-24 03:11:18 +0000 | [diff] [blame] | 59 | MachineFunction &MF = *MBB.getParent(); | 
|  | 60 | MachineFrameInfo &MFI = *MF.getFrameInfo(); | 
|  | 61 | unsigned Align = MFI.getObjectAlignment(FI); | 
| Jia Liu | f54f60f | 2012-02-28 07:46:26 +0000 | [diff] [blame] | 62 |  | 
| Akira Hatanaka | 1cf7576 | 2011-12-24 03:11:18 +0000 | [diff] [blame] | 63 | return MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI), Flag, | 
|  | 64 | MFI.getObjectSize(FI), Align); | 
|  | 65 | } | 
|  | 66 |  | 
| Akira Hatanaka | e248912 | 2011-04-15 21:51:11 +0000 | [diff] [blame] | 67 | //===----------------------------------------------------------------------===// | 
| Bruno Cardoso Lopes | 7b616f5 | 2007-08-18 01:56:48 +0000 | [diff] [blame] | 68 | // Branch Analysis | 
| Akira Hatanaka | e248912 | 2011-04-15 21:51:11 +0000 | [diff] [blame] | 69 | //===----------------------------------------------------------------------===// | 
| Bruno Cardoso Lopes | 7b616f5 | 2007-08-18 01:56:48 +0000 | [diff] [blame] | 70 |  | 
| Akira Hatanaka | b7fa3c9 | 2012-07-31 21:49:49 +0000 | [diff] [blame] | 71 | void MipsInstrInfo::AnalyzeCondBr(const MachineInstr *Inst, unsigned Opc, | 
|  | 72 | MachineBasicBlock *&BB, | 
|  | 73 | SmallVectorImpl<MachineOperand> &Cond) const { | 
| Akira Hatanaka | 067d815 | 2013-05-13 17:43:19 +0000 | [diff] [blame] | 74 | assert(getAnalyzableBrOpc(Opc) && "Not an analyzable branch"); | 
| Akira Hatanaka | 93f898f | 2011-04-01 17:39:08 +0000 | [diff] [blame] | 75 | int NumOp = Inst->getNumExplicitOperands(); | 
| Jia Liu | f54f60f | 2012-02-28 07:46:26 +0000 | [diff] [blame] | 76 |  | 
| Akira Hatanaka | 93f898f | 2011-04-01 17:39:08 +0000 | [diff] [blame] | 77 | // for both int and fp branches, the last explicit operand is the | 
|  | 78 | // MBB. | 
|  | 79 | BB = Inst->getOperand(NumOp-1).getMBB(); | 
|  | 80 | Cond.push_back(MachineOperand::CreateImm(Opc)); | 
| Bruno Cardoso Lopes | bcaf6e5 | 2008-07-28 19:11:24 +0000 | [diff] [blame] | 81 |  | 
| Akira Hatanaka | 93f898f | 2011-04-01 17:39:08 +0000 | [diff] [blame] | 82 | for (int i=0; i<NumOp-1; i++) | 
|  | 83 | Cond.push_back(Inst->getOperand(i)); | 
| Bruno Cardoso Lopes | 7b616f5 | 2007-08-18 01:56:48 +0000 | [diff] [blame] | 84 | } | 
|  | 85 |  | 
| Bruno Cardoso Lopes | ed874ef | 2011-03-04 17:51:39 +0000 | [diff] [blame] | 86 | bool MipsInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, | 
| Bruno Cardoso Lopes | 7b616f5 | 2007-08-18 01:56:48 +0000 | [diff] [blame] | 87 | MachineBasicBlock *&TBB, | 
|  | 88 | MachineBasicBlock *&FBB, | 
| Evan Cheng | 64dfcac | 2009-02-09 07:14:22 +0000 | [diff] [blame] | 89 | SmallVectorImpl<MachineOperand> &Cond, | 
| Akira Hatanaka | 7320b23 | 2013-03-01 01:10:17 +0000 | [diff] [blame] | 90 | bool AllowModify) const { | 
|  | 91 | SmallVector<MachineInstr*, 2> BranchInstrs; | 
|  | 92 | BranchType BT = AnalyzeBranch(MBB, TBB, FBB, Cond, AllowModify, BranchInstrs); | 
| Akira Hatanaka | fcdd9b1 | 2012-09-13 17:12:37 +0000 | [diff] [blame] | 93 |  | 
| Akira Hatanaka | 7320b23 | 2013-03-01 01:10:17 +0000 | [diff] [blame] | 94 | return (BT == BT_None) || (BT == BT_Indirect); | 
| Jia Liu | f54f60f | 2012-02-28 07:46:26 +0000 | [diff] [blame] | 95 | } | 
|  | 96 |  | 
| Eric Christopher | 754d54f | 2014-07-18 20:35:49 +0000 | [diff] [blame] | 97 | void | 
|  | 98 | MipsInstrInfo::BuildCondBr(MachineBasicBlock &MBB, MachineBasicBlock *TBB, | 
|  | 99 | DebugLoc DL, | 
|  | 100 | const SmallVectorImpl<MachineOperand> &Cond) const { | 
| Akira Hatanaka | 93f898f | 2011-04-01 17:39:08 +0000 | [diff] [blame] | 101 | unsigned Opc = Cond[0].getImm(); | 
| Evan Cheng | 6cc775f | 2011-06-28 19:10:37 +0000 | [diff] [blame] | 102 | const MCInstrDesc &MCID = get(Opc); | 
|  | 103 | MachineInstrBuilder MIB = BuildMI(&MBB, DL, MCID); | 
| Akira Hatanaka | 93f898f | 2011-04-01 17:39:08 +0000 | [diff] [blame] | 104 |  | 
| Akira Hatanaka | fcdd9b1 | 2012-09-13 17:12:37 +0000 | [diff] [blame] | 105 | for (unsigned i = 1; i < Cond.size(); ++i) { | 
|  | 106 | if (Cond[i].isReg()) | 
|  | 107 | MIB.addReg(Cond[i].getReg()); | 
|  | 108 | else if (Cond[i].isImm()) | 
|  | 109 | MIB.addImm(Cond[i].getImm()); | 
|  | 110 | else | 
|  | 111 | assert(true && "Cannot copy operand"); | 
|  | 112 | } | 
| Akira Hatanaka | 93f898f | 2011-04-01 17:39:08 +0000 | [diff] [blame] | 113 | MIB.addMBB(TBB); | 
| Bruno Cardoso Lopes | 7b616f5 | 2007-08-18 01:56:48 +0000 | [diff] [blame] | 114 | } | 
|  | 115 |  | 
| Eric Christopher | 754d54f | 2014-07-18 20:35:49 +0000 | [diff] [blame] | 116 | unsigned MipsInstrInfo::InsertBranch( | 
|  | 117 | MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, | 
|  | 118 | const SmallVectorImpl<MachineOperand> &Cond, DebugLoc DL) const { | 
| Bruno Cardoso Lopes | 7b616f5 | 2007-08-18 01:56:48 +0000 | [diff] [blame] | 119 | // Shouldn't be a fall through. | 
|  | 120 | assert(TBB && "InsertBranch must not be told to insert a fallthrough"); | 
| Bruno Cardoso Lopes | 7b616f5 | 2007-08-18 01:56:48 +0000 | [diff] [blame] | 121 |  | 
| Akira Hatanaka | 93f898f | 2011-04-01 17:39:08 +0000 | [diff] [blame] | 122 | // # of condition operands: | 
|  | 123 | //  Unconditional branches: 0 | 
|  | 124 | //  Floating point branches: 1 (opc) | 
|  | 125 | //  Int BranchZero: 2 (opc, reg) | 
|  | 126 | //  Int Branch: 3 (opc, reg0, reg1) | 
|  | 127 | assert((Cond.size() <= 3) && | 
|  | 128 | "# of Mips branch conditions must be <= 3!"); | 
| Bruno Cardoso Lopes | ed874ef | 2011-03-04 17:51:39 +0000 | [diff] [blame] | 129 |  | 
| Bruno Cardoso Lopes | 7b616f5 | 2007-08-18 01:56:48 +0000 | [diff] [blame] | 130 | // Two-way Conditional branch. | 
| Akira Hatanaka | 93f898f | 2011-04-01 17:39:08 +0000 | [diff] [blame] | 131 | if (FBB) { | 
|  | 132 | BuildCondBr(MBB, TBB, DL, Cond); | 
| Akira Hatanaka | 5d5e0d8 | 2011-12-12 22:39:35 +0000 | [diff] [blame] | 133 | BuildMI(&MBB, DL, get(UncondBrOpc)).addMBB(FBB); | 
| Akira Hatanaka | 93f898f | 2011-04-01 17:39:08 +0000 | [diff] [blame] | 134 | return 2; | 
|  | 135 | } | 
| Bruno Cardoso Lopes | 7b616f5 | 2007-08-18 01:56:48 +0000 | [diff] [blame] | 136 |  | 
| Akira Hatanaka | 93f898f | 2011-04-01 17:39:08 +0000 | [diff] [blame] | 137 | // One way branch. | 
|  | 138 | // Unconditional branch. | 
|  | 139 | if (Cond.empty()) | 
| Akira Hatanaka | 5d5e0d8 | 2011-12-12 22:39:35 +0000 | [diff] [blame] | 140 | BuildMI(&MBB, DL, get(UncondBrOpc)).addMBB(TBB); | 
| Akira Hatanaka | 93f898f | 2011-04-01 17:39:08 +0000 | [diff] [blame] | 141 | else // Conditional branch. | 
|  | 142 | BuildCondBr(MBB, TBB, DL, Cond); | 
|  | 143 | return 1; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 144 | } | 
| Bruno Cardoso Lopes | 7b616f5 | 2007-08-18 01:56:48 +0000 | [diff] [blame] | 145 |  | 
| Eric Christopher | 754d54f | 2014-07-18 20:35:49 +0000 | [diff] [blame] | 146 | unsigned MipsInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { | 
| Akira Hatanaka | 93f898f | 2011-04-01 17:39:08 +0000 | [diff] [blame] | 147 | MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend(); | 
|  | 148 | MachineBasicBlock::reverse_iterator FirstBr; | 
|  | 149 | unsigned removed; | 
| Bruno Cardoso Lopes | ed874ef | 2011-03-04 17:51:39 +0000 | [diff] [blame] | 150 |  | 
| Akira Hatanaka | 93f898f | 2011-04-01 17:39:08 +0000 | [diff] [blame] | 151 | // Skip all the debug instructions. | 
|  | 152 | while (I != REnd && I->isDebugValue()) | 
|  | 153 | ++I; | 
| Bruno Cardoso Lopes | ed874ef | 2011-03-04 17:51:39 +0000 | [diff] [blame] | 154 |  | 
| Akira Hatanaka | 93f898f | 2011-04-01 17:39:08 +0000 | [diff] [blame] | 155 | FirstBr = I; | 
| Bruno Cardoso Lopes | ed874ef | 2011-03-04 17:51:39 +0000 | [diff] [blame] | 156 |  | 
| Akira Hatanaka | 93f898f | 2011-04-01 17:39:08 +0000 | [diff] [blame] | 157 | // Up to 2 branches are removed. | 
|  | 158 | // Note that indirect branches are not removed. | 
| Eric Christopher | 675cb4d | 2014-07-18 23:25:00 +0000 | [diff] [blame] | 159 | for (removed = 0; I != REnd && removed < 2; ++I, ++removed) | 
| Akira Hatanaka | 067d815 | 2013-05-13 17:43:19 +0000 | [diff] [blame] | 160 | if (!getAnalyzableBrOpc(I->getOpcode())) | 
| Akira Hatanaka | 93f898f | 2011-04-01 17:39:08 +0000 | [diff] [blame] | 161 | break; | 
| Bruno Cardoso Lopes | ed874ef | 2011-03-04 17:51:39 +0000 | [diff] [blame] | 162 |  | 
| Akira Hatanaka | 93f898f | 2011-04-01 17:39:08 +0000 | [diff] [blame] | 163 | MBB.erase(I.base(), FirstBr.base()); | 
|  | 164 |  | 
|  | 165 | return removed; | 
| Bruno Cardoso Lopes | 7b616f5 | 2007-08-18 01:56:48 +0000 | [diff] [blame] | 166 | } | 
|  | 167 |  | 
| Bruno Cardoso Lopes | ed874ef | 2011-03-04 17:51:39 +0000 | [diff] [blame] | 168 | /// ReverseBranchCondition - Return the inverse opcode of the | 
| Bruno Cardoso Lopes | 7b616f5 | 2007-08-18 01:56:48 +0000 | [diff] [blame] | 169 | /// specified Branch instruction. | 
| Eric Christopher | 754d54f | 2014-07-18 20:35:49 +0000 | [diff] [blame] | 170 | bool MipsInstrInfo::ReverseBranchCondition( | 
|  | 171 | SmallVectorImpl<MachineOperand> &Cond) const { | 
| Akira Hatanaka | 93f898f | 2011-04-01 17:39:08 +0000 | [diff] [blame] | 172 | assert( (Cond.size() && Cond.size() <= 3) && | 
| Bruno Cardoso Lopes | 7b616f5 | 2007-08-18 01:56:48 +0000 | [diff] [blame] | 173 | "Invalid Mips branch condition!"); | 
| Akira Hatanaka | 067d815 | 2013-05-13 17:43:19 +0000 | [diff] [blame] | 174 | Cond[0].setImm(getOppositeBranchOpc(Cond[0].getImm())); | 
| Bruno Cardoso Lopes | 7b616f5 | 2007-08-18 01:56:48 +0000 | [diff] [blame] | 175 | return false; | 
|  | 176 | } | 
| Dan Gohman | d5ca7064 | 2009-06-03 20:30:14 +0000 | [diff] [blame] | 177 |  | 
| Eric Christopher | 754d54f | 2014-07-18 20:35:49 +0000 | [diff] [blame] | 178 | MipsInstrInfo::BranchType MipsInstrInfo::AnalyzeBranch( | 
|  | 179 | MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, | 
|  | 180 | SmallVectorImpl<MachineOperand> &Cond, bool AllowModify, | 
|  | 181 | SmallVectorImpl<MachineInstr *> &BranchInstrs) const { | 
| Akira Hatanaka | 7320b23 | 2013-03-01 01:10:17 +0000 | [diff] [blame] | 182 |  | 
|  | 183 | MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend(); | 
|  | 184 |  | 
|  | 185 | // Skip all the debug instructions. | 
|  | 186 | while (I != REnd && I->isDebugValue()) | 
|  | 187 | ++I; | 
|  | 188 |  | 
|  | 189 | if (I == REnd || !isUnpredicatedTerminator(&*I)) { | 
|  | 190 | // This block ends with no branches (it just falls through to its succ). | 
|  | 191 | // Leave TBB/FBB null. | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 192 | TBB = FBB = nullptr; | 
| Akira Hatanaka | 7320b23 | 2013-03-01 01:10:17 +0000 | [diff] [blame] | 193 | return BT_NoBranch; | 
|  | 194 | } | 
|  | 195 |  | 
|  | 196 | MachineInstr *LastInst = &*I; | 
|  | 197 | unsigned LastOpc = LastInst->getOpcode(); | 
|  | 198 | BranchInstrs.push_back(LastInst); | 
|  | 199 |  | 
|  | 200 | // Not an analyzable branch (e.g., indirect jump). | 
| Akira Hatanaka | 067d815 | 2013-05-13 17:43:19 +0000 | [diff] [blame] | 201 | if (!getAnalyzableBrOpc(LastOpc)) | 
| Akira Hatanaka | 7320b23 | 2013-03-01 01:10:17 +0000 | [diff] [blame] | 202 | return LastInst->isIndirectBranch() ? BT_Indirect : BT_None; | 
|  | 203 |  | 
|  | 204 | // Get the second to last instruction in the block. | 
|  | 205 | unsigned SecondLastOpc = 0; | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 206 | MachineInstr *SecondLastInst = nullptr; | 
| Akira Hatanaka | 7320b23 | 2013-03-01 01:10:17 +0000 | [diff] [blame] | 207 |  | 
|  | 208 | if (++I != REnd) { | 
|  | 209 | SecondLastInst = &*I; | 
| Akira Hatanaka | 067d815 | 2013-05-13 17:43:19 +0000 | [diff] [blame] | 210 | SecondLastOpc = getAnalyzableBrOpc(SecondLastInst->getOpcode()); | 
| Akira Hatanaka | 7320b23 | 2013-03-01 01:10:17 +0000 | [diff] [blame] | 211 |  | 
|  | 212 | // Not an analyzable branch (must be an indirect jump). | 
|  | 213 | if (isUnpredicatedTerminator(SecondLastInst) && !SecondLastOpc) | 
|  | 214 | return BT_None; | 
|  | 215 | } | 
|  | 216 |  | 
| Akira Hatanaka | 7320b23 | 2013-03-01 01:10:17 +0000 | [diff] [blame] | 217 | // If there is only one terminator instruction, process it. | 
|  | 218 | if (!SecondLastOpc) { | 
| Matheus Almeida | 6de62d3 | 2013-10-01 12:53:00 +0000 | [diff] [blame] | 219 | // Unconditional branch. | 
| Akira Hatanaka | 7320b23 | 2013-03-01 01:10:17 +0000 | [diff] [blame] | 220 | if (LastOpc == UncondBrOpc) { | 
|  | 221 | TBB = LastInst->getOperand(0).getMBB(); | 
|  | 222 | return BT_Uncond; | 
|  | 223 | } | 
|  | 224 |  | 
|  | 225 | // Conditional branch | 
|  | 226 | AnalyzeCondBr(LastInst, LastOpc, TBB, Cond); | 
|  | 227 | return BT_Cond; | 
|  | 228 | } | 
|  | 229 |  | 
|  | 230 | // If we reached here, there are two branches. | 
|  | 231 | // If there are three terminators, we don't know what sort of block this is. | 
|  | 232 | if (++I != REnd && isUnpredicatedTerminator(&*I)) | 
|  | 233 | return BT_None; | 
|  | 234 |  | 
| Akira Hatanaka | 28dc83c | 2013-03-01 01:22:26 +0000 | [diff] [blame] | 235 | BranchInstrs.insert(BranchInstrs.begin(), SecondLastInst); | 
|  | 236 |  | 
| Akira Hatanaka | 7320b23 | 2013-03-01 01:10:17 +0000 | [diff] [blame] | 237 | // If second to last instruction is an unconditional branch, | 
|  | 238 | // analyze it and remove the last instruction. | 
|  | 239 | if (SecondLastOpc == UncondBrOpc) { | 
|  | 240 | // Return if the last instruction cannot be removed. | 
|  | 241 | if (!AllowModify) | 
|  | 242 | return BT_None; | 
|  | 243 |  | 
|  | 244 | TBB = SecondLastInst->getOperand(0).getMBB(); | 
|  | 245 | LastInst->eraseFromParent(); | 
|  | 246 | BranchInstrs.pop_back(); | 
|  | 247 | return BT_Uncond; | 
|  | 248 | } | 
|  | 249 |  | 
|  | 250 | // Conditional branch followed by an unconditional branch. | 
|  | 251 | // The last one must be unconditional. | 
|  | 252 | if (LastOpc != UncondBrOpc) | 
|  | 253 | return BT_None; | 
|  | 254 |  | 
|  | 255 | AnalyzeCondBr(SecondLastInst, SecondLastOpc, TBB, Cond); | 
|  | 256 | FBB = LastInst->getOperand(0).getMBB(); | 
|  | 257 |  | 
|  | 258 | return BT_CondUncond; | 
|  | 259 | } | 
|  | 260 |  | 
| Akira Hatanaka | acd1a7d | 2012-06-14 01:16:45 +0000 | [diff] [blame] | 261 | /// Return the number of bytes of code the specified instruction may be. | 
|  | 262 | unsigned MipsInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { | 
|  | 263 | switch (MI->getOpcode()) { | 
|  | 264 | default: | 
|  | 265 | return MI->getDesc().getSize(); | 
|  | 266 | case  TargetOpcode::INLINEASM: {       // Inline Asm: Variable size. | 
|  | 267 | const MachineFunction *MF = MI->getParent()->getParent(); | 
|  | 268 | const char *AsmStr = MI->getOperand(0).getSymbolName(); | 
|  | 269 | return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo()); | 
|  | 270 | } | 
| Reed Kotler | 91ae982 | 2013-10-27 21:57:36 +0000 | [diff] [blame] | 271 | case Mips::CONSTPOOL_ENTRY: | 
|  | 272 | // If this machine instr is a constant pool entry, its size is recorded as | 
|  | 273 | // operand #2. | 
|  | 274 | return MI->getOperand(2).getImm(); | 
| Akira Hatanaka | acd1a7d | 2012-06-14 01:16:45 +0000 | [diff] [blame] | 275 | } | 
|  | 276 | } | 
| Akira Hatanaka | 310e26a | 2013-05-13 17:57:42 +0000 | [diff] [blame] | 277 |  | 
|  | 278 | MachineInstrBuilder | 
|  | 279 | MipsInstrInfo::genInstrWithNewOpc(unsigned NewOpc, | 
|  | 280 | MachineBasicBlock::iterator I) const { | 
|  | 281 | MachineInstrBuilder MIB; | 
|  | 282 | MIB = BuildMI(*I->getParent(), I, I->getDebugLoc(), get(NewOpc)); | 
|  | 283 |  | 
|  | 284 | for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J) | 
|  | 285 | MIB.addOperand(I->getOperand(J)); | 
|  | 286 |  | 
|  | 287 | MIB.setMemRefs(I->memoperands_begin(), I->memoperands_end()); | 
|  | 288 | return MIB; | 
|  | 289 | } |