blob: 64904ec5fcf21c3118de74d480fa7b00b3ae3a0c [file] [log] [blame]
Eugene Zelenko79220eae2017-08-03 22:12:30 +00001//===- MipsLongBranch.cpp - Emit long branches ----------------------------===//
Akira Hatanakaa2159292012-06-14 01:22:24 +00002//
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 pass expands a branch or jump instruction into a long branch if its
11// offset is too large to fit into its immediate field.
12//
Sasa Stankovic7b061a42014-04-30 15:06:25 +000013// FIXME: Fix pc-region jump instructions which cross 256MB segment boundaries.
Akira Hatanakaa2159292012-06-14 01:22:24 +000014//===----------------------------------------------------------------------===//
15
Eugene Zelenko926883e2017-02-01 01:22:51 +000016#include "MCTargetDesc/MipsABIInfo.h"
Akira Hatanakaa2159292012-06-14 01:22:24 +000017#include "MCTargetDesc/MipsBaseInfo.h"
Sasa Stankovic67814262014-06-05 13:52:08 +000018#include "MCTargetDesc/MipsMCNaCl.h"
Eugene Zelenko79220eae2017-08-03 22:12:30 +000019#include "MCTargetDesc/MipsMCTargetDesc.h"
Eugene Zelenko926883e2017-02-01 01:22:51 +000020#include "Mips.h"
21#include "MipsInstrInfo.h"
Eric Christopher79cc1e32014-09-02 22:28:02 +000022#include "MipsMachineFunction.h"
Eugene Zelenko926883e2017-02-01 01:22:51 +000023#include "MipsSubtarget.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000024#include "MipsTargetMachine.h"
Eugene Zelenko926883e2017-02-01 01:22:51 +000025#include "llvm/ADT/SmallVector.h"
Akira Hatanakaa2159292012-06-14 01:22:24 +000026#include "llvm/ADT/Statistic.h"
Eugene Zelenko926883e2017-02-01 01:22:51 +000027#include "llvm/ADT/StringRef.h"
28#include "llvm/CodeGen/MachineBasicBlock.h"
29#include "llvm/CodeGen/MachineFunction.h"
Akira Hatanakaa2159292012-06-14 01:22:24 +000030#include "llvm/CodeGen/MachineFunctionPass.h"
Eugene Zelenko926883e2017-02-01 01:22:51 +000031#include "llvm/CodeGen/MachineInstr.h"
Akira Hatanakaa2159292012-06-14 01:22:24 +000032#include "llvm/CodeGen/MachineInstrBuilder.h"
Eugene Zelenko926883e2017-02-01 01:22:51 +000033#include "llvm/CodeGen/MachineOperand.h"
34#include "llvm/IR/DebugLoc.h"
Akira Hatanakaa2159292012-06-14 01:22:24 +000035#include "llvm/Support/CommandLine.h"
Eugene Zelenko926883e2017-02-01 01:22:51 +000036#include "llvm/Support/ErrorHandling.h"
Akira Hatanakaa2159292012-06-14 01:22:24 +000037#include "llvm/Support/MathExtras.h"
Akira Hatanakaa2159292012-06-14 01:22:24 +000038#include "llvm/Target/TargetMachine.h"
Eugene Zelenko79220eae2017-08-03 22:12:30 +000039#include "llvm/Target/TargetSubtargetInfo.h"
Eugene Zelenko926883e2017-02-01 01:22:51 +000040#include <cassert>
41#include <cstdint>
42#include <iterator>
Akira Hatanakaa2159292012-06-14 01:22:24 +000043
44using namespace llvm;
45
Chandler Carruth84e68b22014-04-22 02:41:26 +000046#define DEBUG_TYPE "mips-long-branch"
47
Akira Hatanakaa2159292012-06-14 01:22:24 +000048STATISTIC(LongBranches, "Number of long branches.");
49
50static cl::opt<bool> SkipLongBranch(
51 "skip-mips-long-branch",
52 cl::init(false),
53 cl::desc("MIPS: Skip long branch pass."),
54 cl::Hidden);
55
56static cl::opt<bool> ForceLongBranch(
57 "force-mips-long-branch",
58 cl::init(false),
59 cl::desc("MIPS: Expand all branches to long format."),
60 cl::Hidden);
61
62namespace {
Eugene Zelenko926883e2017-02-01 01:22:51 +000063
Eugene Zelenko79220eae2017-08-03 22:12:30 +000064 using Iter = MachineBasicBlock::iterator;
65 using ReverseIter = MachineBasicBlock::reverse_iterator;
Akira Hatanakaa2159292012-06-14 01:22:24 +000066
67 struct MBBInfo {
Eugene Zelenko926883e2017-02-01 01:22:51 +000068 uint64_t Size = 0;
69 uint64_t Address;
70 bool HasLongBranch = false;
71 MachineInstr *Br = nullptr;
Akira Hatanakaa2159292012-06-14 01:22:24 +000072
Eugene Zelenko926883e2017-02-01 01:22:51 +000073 MBBInfo() = default;
Akira Hatanakaa2159292012-06-14 01:22:24 +000074 };
75
76 class MipsLongBranch : public MachineFunctionPass {
Akira Hatanakaa2159292012-06-14 01:22:24 +000077 public:
78 static char ID;
Eugene Zelenko926883e2017-02-01 01:22:51 +000079
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +000080 MipsLongBranch()
81 : MachineFunctionPass(ID), ABI(MipsABIInfo::Unknown()) {}
Akira Hatanakaa2159292012-06-14 01:22:24 +000082
Mehdi Amini117296c2016-10-01 02:56:57 +000083 StringRef getPassName() const override { return "Mips Long Branch"; }
Akira Hatanakaa2159292012-06-14 01:22:24 +000084
Craig Topper56c590a2014-04-29 07:58:02 +000085 bool runOnMachineFunction(MachineFunction &F) override;
Akira Hatanakaa2159292012-06-14 01:22:24 +000086
Derek Schuff1dbf7a52016-04-04 17:09:25 +000087 MachineFunctionProperties getRequiredProperties() const override {
88 return MachineFunctionProperties().set(
Matthias Braun1eb47362016-08-25 01:27:13 +000089 MachineFunctionProperties::Property::NoVRegs);
Derek Schuff1dbf7a52016-04-04 17:09:25 +000090 }
91
Akira Hatanakaa2159292012-06-14 01:22:24 +000092 private:
93 void splitMBB(MachineBasicBlock *MBB);
94 void initMBBInfo();
95 int64_t computeOffset(const MachineInstr *Br);
Benjamin Kramerbdc49562016-06-12 15:39:02 +000096 void replaceBranch(MachineBasicBlock &MBB, Iter Br, const DebugLoc &DL,
Akira Hatanakaa2159292012-06-14 01:22:24 +000097 MachineBasicBlock *MBBOpnd);
98 void expandToLongBranch(MBBInfo &Info);
99
Akira Hatanakaa2159292012-06-14 01:22:24 +0000100 MachineFunction *MF;
101 SmallVector<MBBInfo, 16> MBBInfos;
Akira Hatanakab5af7122012-08-28 03:03:05 +0000102 bool IsPIC;
Daniel Sanderse2e25da2014-10-24 16:15:27 +0000103 MipsABIInfo ABI;
Akira Hatanakab5af7122012-08-28 03:03:05 +0000104 unsigned LongBranchSeqSize;
Akira Hatanakaa2159292012-06-14 01:22:24 +0000105 };
106
Eugene Zelenko926883e2017-02-01 01:22:51 +0000107} // end anonymous namespace
Akira Hatanakaa2159292012-06-14 01:22:24 +0000108
Eugene Zelenko79220eae2017-08-03 22:12:30 +0000109char MipsLongBranch::ID = 0;
110
Akira Hatanakaa2159292012-06-14 01:22:24 +0000111/// Iterate over list of Br's operands and search for a MachineBasicBlock
112/// operand.
113static MachineBasicBlock *getTargetMBB(const MachineInstr &Br) {
114 for (unsigned I = 0, E = Br.getDesc().getNumOperands(); I < E; ++I) {
115 const MachineOperand &MO = Br.getOperand(I);
116
117 if (MO.isMBB())
118 return MO.getMBB();
119 }
120
Craig Topperd3c02f12015-01-05 10:15:49 +0000121 llvm_unreachable("This instruction does not have an MBB operand.");
Akira Hatanakaa2159292012-06-14 01:22:24 +0000122}
123
124// Traverse the list of instructions backwards until a non-debug instruction is
125// found or it reaches E.
Benjamin Kramerbdc49562016-06-12 15:39:02 +0000126static ReverseIter getNonDebugInstr(ReverseIter B, const ReverseIter &E) {
Akira Hatanakaa2159292012-06-14 01:22:24 +0000127 for (; B != E; ++B)
128 if (!B->isDebugValue())
129 return B;
130
131 return E;
132}
133
134// Split MBB if it has two direct jumps/branches.
135void MipsLongBranch::splitMBB(MachineBasicBlock *MBB) {
136 ReverseIter End = MBB->rend();
137 ReverseIter LastBr = getNonDebugInstr(MBB->rbegin(), End);
138
139 // Return if MBB has no branch instructions.
140 if ((LastBr == End) ||
141 (!LastBr->isConditionalBranch() && !LastBr->isUnconditionalBranch()))
142 return;
143
Benjamin Kramerb6d0bd42014-03-02 12:27:27 +0000144 ReverseIter FirstBr = getNonDebugInstr(std::next(LastBr), End);
Akira Hatanakaa2159292012-06-14 01:22:24 +0000145
146 // MBB has only one branch instruction if FirstBr is not a branch
147 // instruction.
148 if ((FirstBr == End) ||
149 (!FirstBr->isConditionalBranch() && !FirstBr->isUnconditionalBranch()))
150 return;
151
152 assert(!FirstBr->isIndirectBranch() && "Unexpected indirect branch found.");
153
154 // Create a new MBB. Move instructions in MBB to the newly created MBB.
155 MachineBasicBlock *NewMBB =
156 MF->CreateMachineBasicBlock(MBB->getBasicBlock());
157
158 // Insert NewMBB and fix control flow.
159 MachineBasicBlock *Tgt = getTargetMBB(*FirstBr);
160 NewMBB->transferSuccessors(MBB);
Cong Houc1069892015-12-13 09:26:17 +0000161 NewMBB->removeSuccessor(Tgt, true);
Akira Hatanakaa2159292012-06-14 01:22:24 +0000162 MBB->addSuccessor(NewMBB);
163 MBB->addSuccessor(Tgt);
Benjamin Kramerb6d0bd42014-03-02 12:27:27 +0000164 MF->insert(std::next(MachineFunction::iterator(MBB)), NewMBB);
Akira Hatanakaa2159292012-06-14 01:22:24 +0000165
Duncan P. N. Exon Smith18720962016-09-11 18:51:28 +0000166 NewMBB->splice(NewMBB->end(), MBB, LastBr.getReverse(), MBB->end());
Akira Hatanakaa2159292012-06-14 01:22:24 +0000167}
168
169// Fill MBBInfos.
170void MipsLongBranch::initMBBInfo() {
171 // Split the MBBs if they have two branches. Each basic block should have at
172 // most one branch after this loop is executed.
Vasileios Kalintiris5a971a42016-04-15 20:43:17 +0000173 for (auto &MBB : *MF)
174 splitMBB(&MBB);
Akira Hatanakaa2159292012-06-14 01:22:24 +0000175
176 MF->RenumberBlocks();
177 MBBInfos.clear();
178 MBBInfos.resize(MF->size());
179
Bill Wendlingead89ef2013-06-07 07:04:14 +0000180 const MipsInstrInfo *TII =
Eric Christopher96e72c62015-01-29 23:27:36 +0000181 static_cast<const MipsInstrInfo *>(MF->getSubtarget().getInstrInfo());
Akira Hatanakaa2159292012-06-14 01:22:24 +0000182 for (unsigned I = 0, E = MBBInfos.size(); I < E; ++I) {
183 MachineBasicBlock *MBB = MF->getBlockNumbered(I);
184
185 // Compute size of MBB.
186 for (MachineBasicBlock::instr_iterator MI = MBB->instr_begin();
187 MI != MBB->instr_end(); ++MI)
Sjoerd Meijer89217f82016-07-28 16:32:22 +0000188 MBBInfos[I].Size += TII->getInstSizeInBytes(*MI);
Akira Hatanakaa2159292012-06-14 01:22:24 +0000189
190 // Search for MBB's branch instruction.
191 ReverseIter End = MBB->rend();
192 ReverseIter Br = getNonDebugInstr(MBB->rbegin(), End);
193
194 if ((Br != End) && !Br->isIndirectBranch() &&
Rafael Espindolab30e66b2016-06-28 14:33:28 +0000195 (Br->isConditionalBranch() || (Br->isUnconditionalBranch() && IsPIC)))
Duncan P. N. Exon Smith18720962016-09-11 18:51:28 +0000196 MBBInfos[I].Br = &*Br;
Akira Hatanakaa2159292012-06-14 01:22:24 +0000197 }
198}
199
200// Compute offset of branch in number of bytes.
201int64_t MipsLongBranch::computeOffset(const MachineInstr *Br) {
202 int64_t Offset = 0;
203 int ThisMBB = Br->getParent()->getNumber();
204 int TargetMBB = getTargetMBB(*Br)->getNumber();
205
206 // Compute offset of a forward branch.
207 if (ThisMBB < TargetMBB) {
208 for (int N = ThisMBB + 1; N < TargetMBB; ++N)
209 Offset += MBBInfos[N].Size;
210
211 return Offset + 4;
212 }
213
214 // Compute offset of a backward branch.
215 for (int N = ThisMBB; N >= TargetMBB; --N)
216 Offset += MBBInfos[N].Size;
217
218 return -Offset + 4;
219}
220
Akira Hatanakaa2159292012-06-14 01:22:24 +0000221// Replace Br with a branch which has the opposite condition code and a
222// MachineBasicBlock operand MBBOpnd.
223void MipsLongBranch::replaceBranch(MachineBasicBlock &MBB, Iter Br,
Benjamin Kramerbdc49562016-06-12 15:39:02 +0000224 const DebugLoc &DL,
225 MachineBasicBlock *MBBOpnd) {
Eric Christopher96e72c62015-01-29 23:27:36 +0000226 const MipsInstrInfo *TII = static_cast<const MipsInstrInfo *>(
227 MBB.getParent()->getSubtarget().getInstrInfo());
Akira Hatanaka067d8152013-05-13 17:43:19 +0000228 unsigned NewOpc = TII->getOppositeBranchOpc(Br->getOpcode());
Akira Hatanakaa2159292012-06-14 01:22:24 +0000229 const MCInstrDesc &NewDesc = TII->get(NewOpc);
230
231 MachineInstrBuilder MIB = BuildMI(MBB, Br, DL, NewDesc);
232
233 for (unsigned I = 0, E = Br->getDesc().getNumOperands(); I < E; ++I) {
234 MachineOperand &MO = Br->getOperand(I);
235
236 if (!MO.isReg()) {
237 assert(MO.isMBB() && "MBB operand expected.");
238 break;
239 }
240
241 MIB.addReg(MO.getReg());
242 }
243
244 MIB.addMBB(MBBOpnd);
245
Jozef Kolek3b8ddb62014-11-21 22:04:35 +0000246 if (Br->hasDelaySlot()) {
247 // Bundle the instruction in the delay slot to the newly created branch
248 // and erase the original branch.
249 assert(Br->isBundledWithSucc());
Duncan P. N. Exon Smith670900b2016-07-15 23:09:47 +0000250 MachineBasicBlock::instr_iterator II = Br.getInstrIterator();
Jozef Kolek3b8ddb62014-11-21 22:04:35 +0000251 MIBundleBuilder(&*MIB).append((++II)->removeFromBundle());
252 }
Akira Hatanakaa2159292012-06-14 01:22:24 +0000253 Br->eraseFromParent();
254}
255
256// Expand branch instructions to long branches.
Jozef Kolek9761e962015-01-12 12:03:34 +0000257// TODO: This function has to be fixed for beqz16 and bnez16, because it
258// currently assumes that all branches have 16-bit offsets, and will produce
259// wrong code if branches whose allowed offsets are [-128, -126, ..., 126]
260// are present.
Akira Hatanakaa2159292012-06-14 01:22:24 +0000261void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
Akira Hatanakaf72efdb2012-07-21 03:30:44 +0000262 MachineBasicBlock::iterator Pos;
263 MachineBasicBlock *MBB = I.Br->getParent(), *TgtMBB = getTargetMBB(*I.Br);
Akira Hatanakaa2159292012-06-14 01:22:24 +0000264 DebugLoc DL = I.Br->getDebugLoc();
Akira Hatanakaf72efdb2012-07-21 03:30:44 +0000265 const BasicBlock *BB = MBB->getBasicBlock();
266 MachineFunction::iterator FallThroughMBB = ++MachineFunction::iterator(MBB);
267 MachineBasicBlock *LongBrMBB = MF->CreateMachineBasicBlock(BB);
Eric Christopher96e72c62015-01-29 23:27:36 +0000268 const MipsSubtarget &Subtarget =
269 static_cast<const MipsSubtarget &>(MF->getSubtarget());
Bill Wendlingead89ef2013-06-07 07:04:14 +0000270 const MipsInstrInfo *TII =
Eric Christopher96e72c62015-01-29 23:27:36 +0000271 static_cast<const MipsInstrInfo *>(Subtarget.getInstrInfo());
Bill Wendlingead89ef2013-06-07 07:04:14 +0000272
Akira Hatanakaf72efdb2012-07-21 03:30:44 +0000273 MF->insert(FallThroughMBB, LongBrMBB);
Cong Houd97c1002015-12-01 05:29:22 +0000274 MBB->replaceSuccessor(TgtMBB, LongBrMBB);
Akira Hatanakaf72efdb2012-07-21 03:30:44 +0000275
276 if (IsPIC) {
Akira Hatanakaf72efdb2012-07-21 03:30:44 +0000277 MachineBasicBlock *BalTgtMBB = MF->CreateMachineBasicBlock(BB);
278 MF->insert(FallThroughMBB, BalTgtMBB);
Nico Weber4c5c02a2017-06-19 19:48:59 +0000279 LongBrMBB->addSuccessor(BalTgtMBB);
280 BalTgtMBB->addSuccessor(TgtMBB);
Akira Hatanakaa2159292012-06-14 01:22:24 +0000281
Daniel Sanders86cb3982014-06-13 13:02:52 +0000282 // We must select between the MIPS32r6/MIPS64r6 BAL (which is a normal
283 // instruction) and the pre-MIPS32r6/MIPS64r6 definition (which is an
284 // pseudo-instruction wrapping BGEZAL).
Daniel Sanders86cb3982014-06-13 13:02:52 +0000285 unsigned BalOp = Subtarget.hasMips32r6() ? Mips::BAL : Mips::BAL_BR;
286
Daniel Sanderse2e25da2014-10-24 16:15:27 +0000287 if (!ABI.IsN64()) {
Akira Hatanakab5af7122012-08-28 03:03:05 +0000288 // $longbr:
289 // addiu $sp, $sp, -8
290 // sw $ra, 0($sp)
Akira Hatanakab5af7122012-08-28 03:03:05 +0000291 // lui $at, %hi($tgt - $baltgt)
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000292 // bal $baltgt
Akira Hatanakab5af7122012-08-28 03:03:05 +0000293 // addiu $at, $at, %lo($tgt - $baltgt)
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000294 // $baltgt:
Akira Hatanakab5af7122012-08-28 03:03:05 +0000295 // addu $at, $ra, $at
296 // lw $ra, 0($sp)
297 // jr $at
298 // addiu $sp, $sp, 8
299 // $fallthrough:
300 //
Akira Hatanakaf72efdb2012-07-21 03:30:44 +0000301
Akira Hatanakab5af7122012-08-28 03:03:05 +0000302 Pos = LongBrMBB->begin();
Akira Hatanakaf72efdb2012-07-21 03:30:44 +0000303
Akira Hatanakab5af7122012-08-28 03:03:05 +0000304 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
305 .addReg(Mips::SP).addImm(-8);
306 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SW)).addReg(Mips::RA)
307 .addReg(Mips::SP).addImm(0);
Jakob Stoklund Olesen97030e02012-12-07 04:23:40 +0000308
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000309 // LUi and ADDiu instructions create 32-bit offset of the target basic
310 // block from the target of BAL instruction. We cannot use immediate
311 // value for this offset because it cannot be determined accurately when
312 // the program has inline assembly statements. We therefore use the
313 // relocation expressions %hi($tgt-$baltgt) and %lo($tgt-$baltgt) which
314 // are resolved during the fixup, so the values will always be correct.
315 //
316 // Since we cannot create %hi($tgt-$baltgt) and %lo($tgt-$baltgt)
317 // expressions at this point (it is possible only at the MC layer),
318 // we replace LUi and ADDiu with pseudo instructions
319 // LONG_BRANCH_LUi and LONG_BRANCH_ADDiu, and add both basic
320 // blocks as operands to these instructions. When lowering these pseudo
321 // instructions to LUi and ADDiu in the MC layer, we will create
322 // %hi($tgt-$baltgt) and %lo($tgt-$baltgt) expressions and add them as
323 // operands to lowered instructions.
324
325 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi), Mips::AT)
326 .addMBB(TgtMBB).addMBB(BalTgtMBB);
Jakob Stoklund Olesen97030e02012-12-07 04:23:40 +0000327 MIBundleBuilder(*LongBrMBB, Pos)
Daniel Sanders86cb3982014-06-13 13:02:52 +0000328 .append(BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB))
329 .append(BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_ADDiu), Mips::AT)
330 .addReg(Mips::AT)
331 .addMBB(TgtMBB)
332 .addMBB(BalTgtMBB));
Akira Hatanakaf72efdb2012-07-21 03:30:44 +0000333
Akira Hatanakab5af7122012-08-28 03:03:05 +0000334 Pos = BalTgtMBB->begin();
Akira Hatanakaf72efdb2012-07-21 03:30:44 +0000335
Akira Hatanakab5af7122012-08-28 03:03:05 +0000336 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT)
337 .addReg(Mips::RA).addReg(Mips::AT);
338 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA)
339 .addReg(Mips::SP).addImm(0);
Jakob Stoklund Olesen97030e02012-12-07 04:23:40 +0000340
Vasileios Kalintiris0cf68df2016-06-18 15:39:43 +0000341 // In NaCl, modifying the sp is not allowed in branch delay slot.
342 if (Subtarget.isTargetNaCl())
Sasa Stankovic67814262014-06-05 13:52:08 +0000343 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
344 .addReg(Mips::SP).addImm(8);
345
Vasileios Kalintiris0cf68df2016-06-18 15:39:43 +0000346 if (Subtarget.hasMips32r6())
Nico Weber4c5c02a2017-06-19 19:48:59 +0000347 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JALR))
348 .addReg(Mips::ZERO).addReg(Mips::AT);
Vasileios Kalintiris0cf68df2016-06-18 15:39:43 +0000349 else
350 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JR)).addReg(Mips::AT);
Sasa Stankovic67814262014-06-05 13:52:08 +0000351
Vasileios Kalintiris0cf68df2016-06-18 15:39:43 +0000352 if (Subtarget.isTargetNaCl()) {
353 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::NOP));
Sasa Stankovic67814262014-06-05 13:52:08 +0000354 // Bundle-align the target of indirect branch JR.
355 TgtMBB->setAlignment(MIPS_NACL_BUNDLE_ALIGN);
Vasileios Kalintiris0cf68df2016-06-18 15:39:43 +0000356 } else
357 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
358 .addReg(Mips::SP).addImm(8);
359
360 BalTgtMBB->rbegin()->bundleWithPred();
Akira Hatanakab5af7122012-08-28 03:03:05 +0000361 } else {
362 // $longbr:
363 // daddiu $sp, $sp, -16
364 // sd $ra, 0($sp)
Sasa Stankovice41db2f2014-05-27 18:53:06 +0000365 // daddiu $at, $zero, %hi($tgt - $baltgt)
Akira Hatanakab5af7122012-08-28 03:03:05 +0000366 // dsll $at, $at, 16
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000367 // bal $baltgt
Akira Hatanakab5af7122012-08-28 03:03:05 +0000368 // daddiu $at, $at, %lo($tgt - $baltgt)
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000369 // $baltgt:
Akira Hatanakab5af7122012-08-28 03:03:05 +0000370 // daddu $at, $ra, $at
371 // ld $ra, 0($sp)
372 // jr64 $at
373 // daddiu $sp, $sp, 16
374 // $fallthrough:
375 //
376
Sasa Stankovice41db2f2014-05-27 18:53:06 +0000377 // We assume the branch is within-function, and that offset is within
378 // +/- 2GB. High 32 bits will therefore always be zero.
379
380 // Note that this will work even if the offset is negative, because
381 // of the +1 modification that's added in that case. For example, if the
382 // offset is -1MB (0xFFFFFFFFFFF00000), the computation for %higher is
383 //
384 // 0xFFFFFFFFFFF00000 + 0x80008000 = 0x000000007FF08000
385 //
386 // and the bits [47:32] are zero. For %highest
387 //
388 // 0xFFFFFFFFFFF00000 + 0x800080008000 = 0x000080007FF08000
389 //
390 // and the bits [63:48] are zero.
Akira Hatanakab5af7122012-08-28 03:03:05 +0000391
392 Pos = LongBrMBB->begin();
393
394 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)
395 .addReg(Mips::SP_64).addImm(-16);
396 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SD)).addReg(Mips::RA_64)
397 .addReg(Mips::SP_64).addImm(0);
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000398 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu),
Sasa Stankovice41db2f2014-05-27 18:53:06 +0000399 Mips::AT_64).addReg(Mips::ZERO_64)
400 .addMBB(TgtMBB, MipsII::MO_ABS_HI).addMBB(BalTgtMBB);
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000401 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64)
402 .addReg(Mips::AT_64).addImm(16);
Jakob Stoklund Olesen97030e02012-12-07 04:23:40 +0000403
404 MIBundleBuilder(*LongBrMBB, Pos)
Daniel Sanders86cb3982014-06-13 13:02:52 +0000405 .append(BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB))
406 .append(
407 BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64)
408 .addReg(Mips::AT_64)
409 .addMBB(TgtMBB, MipsII::MO_ABS_LO)
410 .addMBB(BalTgtMBB));
Akira Hatanakab5af7122012-08-28 03:03:05 +0000411
412 Pos = BalTgtMBB->begin();
413
Akira Hatanakab5af7122012-08-28 03:03:05 +0000414 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDu), Mips::AT_64)
415 .addReg(Mips::RA_64).addReg(Mips::AT_64);
416 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LD), Mips::RA_64)
417 .addReg(Mips::SP_64).addImm(0);
Jakob Stoklund Olesen97030e02012-12-07 04:23:40 +0000418
Vasileios Kalintiris0cf68df2016-06-18 15:39:43 +0000419 if (Subtarget.hasMips64r6())
Nico Weber4c5c02a2017-06-19 19:48:59 +0000420 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JALR64))
421 .addReg(Mips::ZERO_64).addReg(Mips::AT_64);
Vasileios Kalintiris0cf68df2016-06-18 15:39:43 +0000422 else
423 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JR64)).addReg(Mips::AT_64);
424
425 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)
426 .addReg(Mips::SP_64).addImm(16);
427 BalTgtMBB->rbegin()->bundleWithPred();
Akira Hatanakaf72efdb2012-07-21 03:30:44 +0000428 }
Akira Hatanaka5fdeac32012-11-15 20:05:11 +0000429
Sasa Stankovic7b061a42014-04-30 15:06:25 +0000430 assert(LongBrMBB->size() + BalTgtMBB->size() == LongBranchSeqSize);
Akira Hatanakaf72efdb2012-07-21 03:30:44 +0000431 } else {
432 // $longbr:
433 // j $tgt
434 // nop
435 // $fallthrough:
436 //
437 Pos = LongBrMBB->begin();
438 LongBrMBB->addSuccessor(TgtMBB);
Jakob Stoklund Olesen97030e02012-12-07 04:23:40 +0000439 MIBundleBuilder(*LongBrMBB, Pos)
440 .append(BuildMI(*MF, DL, TII->get(Mips::J)).addMBB(TgtMBB))
441 .append(BuildMI(*MF, DL, TII->get(Mips::NOP)));
Akira Hatanaka5fdeac32012-11-15 20:05:11 +0000442
443 assert(LongBrMBB->size() == LongBranchSeqSize);
Akira Hatanakaa2159292012-06-14 01:22:24 +0000444 }
445
Akira Hatanakaf72efdb2012-07-21 03:30:44 +0000446 if (I.Br->isUnconditionalBranch()) {
447 // Change branch destination.
448 assert(I.Br->getDesc().getNumOperands() == 1);
449 I.Br->RemoveOperand(0);
450 I.Br->addOperand(MachineOperand::CreateMBB(LongBrMBB));
451 } else
452 // Change branch destination and reverse condition.
Duncan P. N. Exon Smith78691482015-10-20 00:15:20 +0000453 replaceBranch(*MBB, I.Br, DL, &*FallThroughMBB);
Akira Hatanakaa2159292012-06-14 01:22:24 +0000454}
455
456static void emitGPDisp(MachineFunction &F, const MipsInstrInfo *TII) {
457 MachineBasicBlock &MBB = F.front();
458 MachineBasicBlock::iterator I = MBB.begin();
459 DebugLoc DL = MBB.findDebugLoc(MBB.begin());
460 BuildMI(MBB, I, DL, TII->get(Mips::LUi), Mips::V0)
461 .addExternalSymbol("_gp_disp", MipsII::MO_ABS_HI);
462 BuildMI(MBB, I, DL, TII->get(Mips::ADDiu), Mips::V0)
463 .addReg(Mips::V0).addExternalSymbol("_gp_disp", MipsII::MO_ABS_LO);
464 MBB.removeLiveIn(Mips::V0);
465}
466
467bool MipsLongBranch::runOnMachineFunction(MachineFunction &F) {
Eric Christopher96e72c62015-01-29 23:27:36 +0000468 const MipsSubtarget &STI =
469 static_cast<const MipsSubtarget &>(F.getSubtarget());
Bill Wendlingead89ef2013-06-07 07:04:14 +0000470 const MipsInstrInfo *TII =
Eric Christopher96e72c62015-01-29 23:27:36 +0000471 static_cast<const MipsInstrInfo *>(STI.getInstrInfo());
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +0000472
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +0000473 const TargetMachine& TM = F.getTarget();
474 IsPIC = TM.isPositionIndependent();
475 ABI = static_cast<const MipsTargetMachine &>(TM).getABI();
476
Eric Christopher96e72c62015-01-29 23:27:36 +0000477 LongBranchSeqSize =
478 !IsPIC ? 2 : (ABI.IsN64() ? 10 : (!STI.isTargetNaCl() ? 9 : 10));
Bill Wendlingead89ef2013-06-07 07:04:14 +0000479
Eric Christophera08db01b2014-07-18 20:29:02 +0000480 if (STI.inMips16Mode() || !STI.enableLongBranchPass())
Reed Kotler1595f362013-04-09 19:46:01 +0000481 return false;
Rafael Espindolab30e66b2016-06-28 14:33:28 +0000482 if (IsPIC && static_cast<const MipsTargetMachine &>(TM).getABI().IsO32() &&
Akira Hatanakaa2159292012-06-14 01:22:24 +0000483 F.getInfo<MipsFunctionInfo>()->globalBaseRegSet())
484 emitGPDisp(F, TII);
485
486 if (SkipLongBranch)
Akira Hatanaka9f96bb82012-06-19 03:45:29 +0000487 return true;
Akira Hatanakaa2159292012-06-14 01:22:24 +0000488
489 MF = &F;
490 initMBBInfo();
491
Craig Topperaf0dea12013-07-04 01:31:24 +0000492 SmallVectorImpl<MBBInfo>::iterator I, E = MBBInfos.end();
Akira Hatanakaa2159292012-06-14 01:22:24 +0000493 bool EverMadeChange = false, MadeChange = true;
494
495 while (MadeChange) {
496 MadeChange = false;
497
498 for (I = MBBInfos.begin(); I != E; ++I) {
499 // Skip if this MBB doesn't have a branch or the branch has already been
500 // converted to a long branch.
501 if (!I->Br || I->HasLongBranch)
502 continue;
503
Eric Christopher96e72c62015-01-29 23:27:36 +0000504 int ShVal = STI.inMicroMipsMode() ? 2 : 4;
Sasa Stankovic67814262014-06-05 13:52:08 +0000505 int64_t Offset = computeOffset(I->Br) / ShVal;
506
Eric Christopher96e72c62015-01-29 23:27:36 +0000507 if (STI.isTargetNaCl()) {
Sasa Stankovic67814262014-06-05 13:52:08 +0000508 // The offset calculation does not include sandboxing instructions
509 // that will be added later in the MC layer. Since at this point we
510 // don't know the exact amount of code that "sandboxing" will add, we
511 // conservatively estimate that code will not grow more than 100%.
512 Offset *= 2;
513 }
Zoran Jovanovic9d86e262013-11-30 19:12:28 +0000514
Akira Hatanakab5af7122012-08-28 03:03:05 +0000515 // Check if offset fits into 16-bit immediate field of branches.
Sasa Stankovic67814262014-06-05 13:52:08 +0000516 if (!ForceLongBranch && isInt<16>(Offset))
Akira Hatanakab5af7122012-08-28 03:03:05 +0000517 continue;
Akira Hatanakaa2159292012-06-14 01:22:24 +0000518
Akira Hatanakab5af7122012-08-28 03:03:05 +0000519 I->HasLongBranch = true;
Akira Hatanaka206cefe2012-08-28 18:58:57 +0000520 I->Size += LongBranchSeqSize * 4;
Akira Hatanakaa2159292012-06-14 01:22:24 +0000521 ++LongBranches;
522 EverMadeChange = MadeChange = true;
523 }
524 }
525
Akira Hatanakab5af7122012-08-28 03:03:05 +0000526 if (!EverMadeChange)
527 return true;
528
529 // Compute basic block addresses.
Rafael Espindolab30e66b2016-06-28 14:33:28 +0000530 if (IsPIC) {
Akira Hatanakab5af7122012-08-28 03:03:05 +0000531 uint64_t Address = 0;
532
Akira Hatanaka206cefe2012-08-28 18:58:57 +0000533 for (I = MBBInfos.begin(); I != E; Address += I->Size, ++I)
Akira Hatanakab5af7122012-08-28 03:03:05 +0000534 I->Address = Address;
535 }
536
537 // Do the expansion.
538 for (I = MBBInfos.begin(); I != E; ++I)
539 if (I->HasLongBranch)
540 expandToLongBranch(*I);
541
542 MF->RenumberBlocks();
Akira Hatanakaa2159292012-06-14 01:22:24 +0000543
Akira Hatanaka9f96bb82012-06-19 03:45:29 +0000544 return true;
Akira Hatanakaa2159292012-06-14 01:22:24 +0000545}
Eugene Zelenko926883e2017-02-01 01:22:51 +0000546
547/// createMipsLongBranchPass - Returns a pass that converts branches to long
548/// branches.
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +0000549FunctionPass *llvm::createMipsLongBranchPass() { return new MipsLongBranch(); }