1*9880d681SAndroid Build Coastguard Worker //===-- MipsInstrInfo.cpp - Mips Instruction Information ------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains the Mips implementation of the TargetInstrInfo class.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "MipsInstrInfo.h"
15*9880d681SAndroid Build Coastguard Worker #include "InstPrinter/MipsInstPrinter.h"
16*9880d681SAndroid Build Coastguard Worker #include "MipsMachineFunction.h"
17*9880d681SAndroid Build Coastguard Worker #include "MipsSubtarget.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Worker using namespace llvm;
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker #define GET_INSTRINFO_CTOR_DTOR
27*9880d681SAndroid Build Coastguard Worker #include "MipsGenInstrInfo.inc"
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard Worker // Pin the vtable to this file.
anchor()30*9880d681SAndroid Build Coastguard Worker void MipsInstrInfo::anchor() {}
31*9880d681SAndroid Build Coastguard Worker
MipsInstrInfo(const MipsSubtarget & STI,unsigned UncondBr)32*9880d681SAndroid Build Coastguard Worker MipsInstrInfo::MipsInstrInfo(const MipsSubtarget &STI, unsigned UncondBr)
33*9880d681SAndroid Build Coastguard Worker : MipsGenInstrInfo(Mips::ADJCALLSTACKDOWN, Mips::ADJCALLSTACKUP),
34*9880d681SAndroid Build Coastguard Worker Subtarget(STI), UncondBrOpc(UncondBr) {}
35*9880d681SAndroid Build Coastguard Worker
create(MipsSubtarget & STI)36*9880d681SAndroid Build Coastguard Worker const MipsInstrInfo *MipsInstrInfo::create(MipsSubtarget &STI) {
37*9880d681SAndroid Build Coastguard Worker if (STI.inMips16Mode())
38*9880d681SAndroid Build Coastguard Worker return llvm::createMips16InstrInfo(STI);
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Worker return llvm::createMipsSEInstrInfo(STI);
41*9880d681SAndroid Build Coastguard Worker }
42*9880d681SAndroid Build Coastguard Worker
isZeroImm(const MachineOperand & op) const43*9880d681SAndroid Build Coastguard Worker bool MipsInstrInfo::isZeroImm(const MachineOperand &op) const {
44*9880d681SAndroid Build Coastguard Worker return op.isImm() && op.getImm() == 0;
45*9880d681SAndroid Build Coastguard Worker }
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Worker /// insertNoop - If data hazard condition is found insert the target nop
48*9880d681SAndroid Build Coastguard Worker /// instruction.
49*9880d681SAndroid Build Coastguard Worker // FIXME: This appears to be dead code.
50*9880d681SAndroid Build Coastguard Worker void MipsInstrInfo::
insertNoop(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI) const51*9880d681SAndroid Build Coastguard Worker insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const
52*9880d681SAndroid Build Coastguard Worker {
53*9880d681SAndroid Build Coastguard Worker DebugLoc DL;
54*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MI, DL, get(Mips::NOP));
55*9880d681SAndroid Build Coastguard Worker }
56*9880d681SAndroid Build Coastguard Worker
GetMemOperand(MachineBasicBlock & MBB,int FI,unsigned Flag) const57*9880d681SAndroid Build Coastguard Worker MachineMemOperand *MipsInstrInfo::GetMemOperand(MachineBasicBlock &MBB, int FI,
58*9880d681SAndroid Build Coastguard Worker unsigned Flag) const {
59*9880d681SAndroid Build Coastguard Worker MachineFunction &MF = *MBB.getParent();
60*9880d681SAndroid Build Coastguard Worker MachineFrameInfo &MFI = *MF.getFrameInfo();
61*9880d681SAndroid Build Coastguard Worker unsigned Align = MFI.getObjectAlignment(FI);
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Worker return MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(MF, FI),
64*9880d681SAndroid Build Coastguard Worker Flag, MFI.getObjectSize(FI), Align);
65*9880d681SAndroid Build Coastguard Worker }
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
68*9880d681SAndroid Build Coastguard Worker // Branch Analysis
69*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
70*9880d681SAndroid Build Coastguard Worker
AnalyzeCondBr(const MachineInstr * Inst,unsigned Opc,MachineBasicBlock * & BB,SmallVectorImpl<MachineOperand> & Cond) const71*9880d681SAndroid Build Coastguard Worker void MipsInstrInfo::AnalyzeCondBr(const MachineInstr *Inst, unsigned Opc,
72*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *&BB,
73*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MachineOperand> &Cond) const {
74*9880d681SAndroid Build Coastguard Worker assert(getAnalyzableBrOpc(Opc) && "Not an analyzable branch");
75*9880d681SAndroid Build Coastguard Worker int NumOp = Inst->getNumExplicitOperands();
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Worker // for both int and fp branches, the last explicit operand is the
78*9880d681SAndroid Build Coastguard Worker // MBB.
79*9880d681SAndroid Build Coastguard Worker BB = Inst->getOperand(NumOp-1).getMBB();
80*9880d681SAndroid Build Coastguard Worker Cond.push_back(MachineOperand::CreateImm(Opc));
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Worker for (int i=0; i<NumOp-1; i++)
83*9880d681SAndroid Build Coastguard Worker Cond.push_back(Inst->getOperand(i));
84*9880d681SAndroid Build Coastguard Worker }
85*9880d681SAndroid Build Coastguard Worker
analyzeBranch(MachineBasicBlock & MBB,MachineBasicBlock * & TBB,MachineBasicBlock * & FBB,SmallVectorImpl<MachineOperand> & Cond,bool AllowModify) const86*9880d681SAndroid Build Coastguard Worker bool MipsInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
87*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *&TBB,
88*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *&FBB,
89*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MachineOperand> &Cond,
90*9880d681SAndroid Build Coastguard Worker bool AllowModify) const {
91*9880d681SAndroid Build Coastguard Worker SmallVector<MachineInstr*, 2> BranchInstrs;
92*9880d681SAndroid Build Coastguard Worker BranchType BT = analyzeBranch(MBB, TBB, FBB, Cond, AllowModify, BranchInstrs);
93*9880d681SAndroid Build Coastguard Worker
94*9880d681SAndroid Build Coastguard Worker return (BT == BT_None) || (BT == BT_Indirect);
95*9880d681SAndroid Build Coastguard Worker }
96*9880d681SAndroid Build Coastguard Worker
BuildCondBr(MachineBasicBlock & MBB,MachineBasicBlock * TBB,const DebugLoc & DL,ArrayRef<MachineOperand> Cond) const97*9880d681SAndroid Build Coastguard Worker void MipsInstrInfo::BuildCondBr(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
98*9880d681SAndroid Build Coastguard Worker const DebugLoc &DL,
99*9880d681SAndroid Build Coastguard Worker ArrayRef<MachineOperand> Cond) const {
100*9880d681SAndroid Build Coastguard Worker unsigned Opc = Cond[0].getImm();
101*9880d681SAndroid Build Coastguard Worker const MCInstrDesc &MCID = get(Opc);
102*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder MIB = BuildMI(&MBB, DL, MCID);
103*9880d681SAndroid Build Coastguard Worker
104*9880d681SAndroid Build Coastguard Worker for (unsigned i = 1; i < Cond.size(); ++i) {
105*9880d681SAndroid Build Coastguard Worker if (Cond[i].isReg())
106*9880d681SAndroid Build Coastguard Worker MIB.addReg(Cond[i].getReg());
107*9880d681SAndroid Build Coastguard Worker else if (Cond[i].isImm())
108*9880d681SAndroid Build Coastguard Worker MIB.addImm(Cond[i].getImm());
109*9880d681SAndroid Build Coastguard Worker else
110*9880d681SAndroid Build Coastguard Worker assert(false && "Cannot copy operand");
111*9880d681SAndroid Build Coastguard Worker }
112*9880d681SAndroid Build Coastguard Worker MIB.addMBB(TBB);
113*9880d681SAndroid Build Coastguard Worker }
114*9880d681SAndroid Build Coastguard Worker
InsertBranch(MachineBasicBlock & MBB,MachineBasicBlock * TBB,MachineBasicBlock * FBB,ArrayRef<MachineOperand> Cond,const DebugLoc & DL) const115*9880d681SAndroid Build Coastguard Worker unsigned MipsInstrInfo::InsertBranch(MachineBasicBlock &MBB,
116*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *TBB,
117*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *FBB,
118*9880d681SAndroid Build Coastguard Worker ArrayRef<MachineOperand> Cond,
119*9880d681SAndroid Build Coastguard Worker const DebugLoc &DL) const {
120*9880d681SAndroid Build Coastguard Worker // Shouldn't be a fall through.
121*9880d681SAndroid Build Coastguard Worker assert(TBB && "InsertBranch must not be told to insert a fallthrough");
122*9880d681SAndroid Build Coastguard Worker
123*9880d681SAndroid Build Coastguard Worker // # of condition operands:
124*9880d681SAndroid Build Coastguard Worker // Unconditional branches: 0
125*9880d681SAndroid Build Coastguard Worker // Floating point branches: 1 (opc)
126*9880d681SAndroid Build Coastguard Worker // Int BranchZero: 2 (opc, reg)
127*9880d681SAndroid Build Coastguard Worker // Int Branch: 3 (opc, reg0, reg1)
128*9880d681SAndroid Build Coastguard Worker assert((Cond.size() <= 3) &&
129*9880d681SAndroid Build Coastguard Worker "# of Mips branch conditions must be <= 3!");
130*9880d681SAndroid Build Coastguard Worker
131*9880d681SAndroid Build Coastguard Worker // Two-way Conditional branch.
132*9880d681SAndroid Build Coastguard Worker if (FBB) {
133*9880d681SAndroid Build Coastguard Worker BuildCondBr(MBB, TBB, DL, Cond);
134*9880d681SAndroid Build Coastguard Worker BuildMI(&MBB, DL, get(UncondBrOpc)).addMBB(FBB);
135*9880d681SAndroid Build Coastguard Worker return 2;
136*9880d681SAndroid Build Coastguard Worker }
137*9880d681SAndroid Build Coastguard Worker
138*9880d681SAndroid Build Coastguard Worker // One way branch.
139*9880d681SAndroid Build Coastguard Worker // Unconditional branch.
140*9880d681SAndroid Build Coastguard Worker if (Cond.empty())
141*9880d681SAndroid Build Coastguard Worker BuildMI(&MBB, DL, get(UncondBrOpc)).addMBB(TBB);
142*9880d681SAndroid Build Coastguard Worker else // Conditional branch.
143*9880d681SAndroid Build Coastguard Worker BuildCondBr(MBB, TBB, DL, Cond);
144*9880d681SAndroid Build Coastguard Worker return 1;
145*9880d681SAndroid Build Coastguard Worker }
146*9880d681SAndroid Build Coastguard Worker
RemoveBranch(MachineBasicBlock & MBB) const147*9880d681SAndroid Build Coastguard Worker unsigned MipsInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
148*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();
149*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::reverse_iterator FirstBr;
150*9880d681SAndroid Build Coastguard Worker unsigned removed;
151*9880d681SAndroid Build Coastguard Worker
152*9880d681SAndroid Build Coastguard Worker // Skip all the debug instructions.
153*9880d681SAndroid Build Coastguard Worker while (I != REnd && I->isDebugValue())
154*9880d681SAndroid Build Coastguard Worker ++I;
155*9880d681SAndroid Build Coastguard Worker
156*9880d681SAndroid Build Coastguard Worker FirstBr = I;
157*9880d681SAndroid Build Coastguard Worker
158*9880d681SAndroid Build Coastguard Worker // Up to 2 branches are removed.
159*9880d681SAndroid Build Coastguard Worker // Note that indirect branches are not removed.
160*9880d681SAndroid Build Coastguard Worker for (removed = 0; I != REnd && removed < 2; ++I, ++removed)
161*9880d681SAndroid Build Coastguard Worker if (!getAnalyzableBrOpc(I->getOpcode()))
162*9880d681SAndroid Build Coastguard Worker break;
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Worker MBB.erase(I.base(), FirstBr.base());
165*9880d681SAndroid Build Coastguard Worker
166*9880d681SAndroid Build Coastguard Worker return removed;
167*9880d681SAndroid Build Coastguard Worker }
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Worker /// ReverseBranchCondition - Return the inverse opcode of the
170*9880d681SAndroid Build Coastguard Worker /// specified Branch instruction.
ReverseBranchCondition(SmallVectorImpl<MachineOperand> & Cond) const171*9880d681SAndroid Build Coastguard Worker bool MipsInstrInfo::ReverseBranchCondition(
172*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MachineOperand> &Cond) const {
173*9880d681SAndroid Build Coastguard Worker assert( (Cond.size() && Cond.size() <= 3) &&
174*9880d681SAndroid Build Coastguard Worker "Invalid Mips branch condition!");
175*9880d681SAndroid Build Coastguard Worker Cond[0].setImm(getOppositeBranchOpc(Cond[0].getImm()));
176*9880d681SAndroid Build Coastguard Worker return false;
177*9880d681SAndroid Build Coastguard Worker }
178*9880d681SAndroid Build Coastguard Worker
analyzeBranch(MachineBasicBlock & MBB,MachineBasicBlock * & TBB,MachineBasicBlock * & FBB,SmallVectorImpl<MachineOperand> & Cond,bool AllowModify,SmallVectorImpl<MachineInstr * > & BranchInstrs) const179*9880d681SAndroid Build Coastguard Worker MipsInstrInfo::BranchType MipsInstrInfo::analyzeBranch(
180*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB,
181*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MachineOperand> &Cond, bool AllowModify,
182*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MachineInstr *> &BranchInstrs) const {
183*9880d681SAndroid Build Coastguard Worker
184*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();
185*9880d681SAndroid Build Coastguard Worker
186*9880d681SAndroid Build Coastguard Worker // Skip all the debug instructions.
187*9880d681SAndroid Build Coastguard Worker while (I != REnd && I->isDebugValue())
188*9880d681SAndroid Build Coastguard Worker ++I;
189*9880d681SAndroid Build Coastguard Worker
190*9880d681SAndroid Build Coastguard Worker if (I == REnd || !isUnpredicatedTerminator(*I)) {
191*9880d681SAndroid Build Coastguard Worker // This block ends with no branches (it just falls through to its succ).
192*9880d681SAndroid Build Coastguard Worker // Leave TBB/FBB null.
193*9880d681SAndroid Build Coastguard Worker TBB = FBB = nullptr;
194*9880d681SAndroid Build Coastguard Worker return BT_NoBranch;
195*9880d681SAndroid Build Coastguard Worker }
196*9880d681SAndroid Build Coastguard Worker
197*9880d681SAndroid Build Coastguard Worker MachineInstr *LastInst = &*I;
198*9880d681SAndroid Build Coastguard Worker unsigned LastOpc = LastInst->getOpcode();
199*9880d681SAndroid Build Coastguard Worker BranchInstrs.push_back(LastInst);
200*9880d681SAndroid Build Coastguard Worker
201*9880d681SAndroid Build Coastguard Worker // Not an analyzable branch (e.g., indirect jump).
202*9880d681SAndroid Build Coastguard Worker if (!getAnalyzableBrOpc(LastOpc))
203*9880d681SAndroid Build Coastguard Worker return LastInst->isIndirectBranch() ? BT_Indirect : BT_None;
204*9880d681SAndroid Build Coastguard Worker
205*9880d681SAndroid Build Coastguard Worker // Get the second to last instruction in the block.
206*9880d681SAndroid Build Coastguard Worker unsigned SecondLastOpc = 0;
207*9880d681SAndroid Build Coastguard Worker MachineInstr *SecondLastInst = nullptr;
208*9880d681SAndroid Build Coastguard Worker
209*9880d681SAndroid Build Coastguard Worker if (++I != REnd) {
210*9880d681SAndroid Build Coastguard Worker SecondLastInst = &*I;
211*9880d681SAndroid Build Coastguard Worker SecondLastOpc = getAnalyzableBrOpc(SecondLastInst->getOpcode());
212*9880d681SAndroid Build Coastguard Worker
213*9880d681SAndroid Build Coastguard Worker // Not an analyzable branch (must be an indirect jump).
214*9880d681SAndroid Build Coastguard Worker if (isUnpredicatedTerminator(*SecondLastInst) && !SecondLastOpc)
215*9880d681SAndroid Build Coastguard Worker return BT_None;
216*9880d681SAndroid Build Coastguard Worker }
217*9880d681SAndroid Build Coastguard Worker
218*9880d681SAndroid Build Coastguard Worker // If there is only one terminator instruction, process it.
219*9880d681SAndroid Build Coastguard Worker if (!SecondLastOpc) {
220*9880d681SAndroid Build Coastguard Worker // Unconditional branch.
221*9880d681SAndroid Build Coastguard Worker if (LastInst->isUnconditionalBranch()) {
222*9880d681SAndroid Build Coastguard Worker TBB = LastInst->getOperand(0).getMBB();
223*9880d681SAndroid Build Coastguard Worker return BT_Uncond;
224*9880d681SAndroid Build Coastguard Worker }
225*9880d681SAndroid Build Coastguard Worker
226*9880d681SAndroid Build Coastguard Worker // Conditional branch
227*9880d681SAndroid Build Coastguard Worker AnalyzeCondBr(LastInst, LastOpc, TBB, Cond);
228*9880d681SAndroid Build Coastguard Worker return BT_Cond;
229*9880d681SAndroid Build Coastguard Worker }
230*9880d681SAndroid Build Coastguard Worker
231*9880d681SAndroid Build Coastguard Worker // If we reached here, there are two branches.
232*9880d681SAndroid Build Coastguard Worker // If there are three terminators, we don't know what sort of block this is.
233*9880d681SAndroid Build Coastguard Worker if (++I != REnd && isUnpredicatedTerminator(*I))
234*9880d681SAndroid Build Coastguard Worker return BT_None;
235*9880d681SAndroid Build Coastguard Worker
236*9880d681SAndroid Build Coastguard Worker BranchInstrs.insert(BranchInstrs.begin(), SecondLastInst);
237*9880d681SAndroid Build Coastguard Worker
238*9880d681SAndroid Build Coastguard Worker // If second to last instruction is an unconditional branch,
239*9880d681SAndroid Build Coastguard Worker // analyze it and remove the last instruction.
240*9880d681SAndroid Build Coastguard Worker if (SecondLastInst->isUnconditionalBranch()) {
241*9880d681SAndroid Build Coastguard Worker // Return if the last instruction cannot be removed.
242*9880d681SAndroid Build Coastguard Worker if (!AllowModify)
243*9880d681SAndroid Build Coastguard Worker return BT_None;
244*9880d681SAndroid Build Coastguard Worker
245*9880d681SAndroid Build Coastguard Worker TBB = SecondLastInst->getOperand(0).getMBB();
246*9880d681SAndroid Build Coastguard Worker LastInst->eraseFromParent();
247*9880d681SAndroid Build Coastguard Worker BranchInstrs.pop_back();
248*9880d681SAndroid Build Coastguard Worker return BT_Uncond;
249*9880d681SAndroid Build Coastguard Worker }
250*9880d681SAndroid Build Coastguard Worker
251*9880d681SAndroid Build Coastguard Worker // Conditional branch followed by an unconditional branch.
252*9880d681SAndroid Build Coastguard Worker // The last one must be unconditional.
253*9880d681SAndroid Build Coastguard Worker if (!LastInst->isUnconditionalBranch())
254*9880d681SAndroid Build Coastguard Worker return BT_None;
255*9880d681SAndroid Build Coastguard Worker
256*9880d681SAndroid Build Coastguard Worker AnalyzeCondBr(SecondLastInst, SecondLastOpc, TBB, Cond);
257*9880d681SAndroid Build Coastguard Worker FBB = LastInst->getOperand(0).getMBB();
258*9880d681SAndroid Build Coastguard Worker
259*9880d681SAndroid Build Coastguard Worker return BT_CondUncond;
260*9880d681SAndroid Build Coastguard Worker }
261*9880d681SAndroid Build Coastguard Worker
262*9880d681SAndroid Build Coastguard Worker /// Return the corresponding compact (no delay slot) form of a branch.
getEquivalentCompactForm(const MachineBasicBlock::iterator I) const263*9880d681SAndroid Build Coastguard Worker unsigned MipsInstrInfo::getEquivalentCompactForm(
264*9880d681SAndroid Build Coastguard Worker const MachineBasicBlock::iterator I) const {
265*9880d681SAndroid Build Coastguard Worker unsigned Opcode = I->getOpcode();
266*9880d681SAndroid Build Coastguard Worker bool canUseShortMicroMipsCTI = false;
267*9880d681SAndroid Build Coastguard Worker
268*9880d681SAndroid Build Coastguard Worker if (Subtarget.inMicroMipsMode()) {
269*9880d681SAndroid Build Coastguard Worker switch (Opcode) {
270*9880d681SAndroid Build Coastguard Worker case Mips::BNE:
271*9880d681SAndroid Build Coastguard Worker case Mips::BEQ:
272*9880d681SAndroid Build Coastguard Worker // microMIPS has NE,EQ branches that do not have delay slots provided one
273*9880d681SAndroid Build Coastguard Worker // of the operands is zero.
274*9880d681SAndroid Build Coastguard Worker if (I->getOperand(1).getReg() == Subtarget.getABI().GetZeroReg())
275*9880d681SAndroid Build Coastguard Worker canUseShortMicroMipsCTI = true;
276*9880d681SAndroid Build Coastguard Worker break;
277*9880d681SAndroid Build Coastguard Worker // For microMIPS the PseudoReturn and PseudoIndirectBranch are always
278*9880d681SAndroid Build Coastguard Worker // expanded to JR_MM, so they can be replaced with JRC16_MM.
279*9880d681SAndroid Build Coastguard Worker case Mips::JR:
280*9880d681SAndroid Build Coastguard Worker case Mips::PseudoReturn:
281*9880d681SAndroid Build Coastguard Worker case Mips::PseudoIndirectBranch:
282*9880d681SAndroid Build Coastguard Worker canUseShortMicroMipsCTI = true;
283*9880d681SAndroid Build Coastguard Worker break;
284*9880d681SAndroid Build Coastguard Worker }
285*9880d681SAndroid Build Coastguard Worker }
286*9880d681SAndroid Build Coastguard Worker
287*9880d681SAndroid Build Coastguard Worker // MIPSR6 forbids both operands being the zero register.
288*9880d681SAndroid Build Coastguard Worker if (Subtarget.hasMips32r6() && (I->getNumOperands() > 1) &&
289*9880d681SAndroid Build Coastguard Worker (I->getOperand(0).isReg() &&
290*9880d681SAndroid Build Coastguard Worker (I->getOperand(0).getReg() == Mips::ZERO ||
291*9880d681SAndroid Build Coastguard Worker I->getOperand(0).getReg() == Mips::ZERO_64)) &&
292*9880d681SAndroid Build Coastguard Worker (I->getOperand(1).isReg() &&
293*9880d681SAndroid Build Coastguard Worker (I->getOperand(1).getReg() == Mips::ZERO ||
294*9880d681SAndroid Build Coastguard Worker I->getOperand(1).getReg() == Mips::ZERO_64)))
295*9880d681SAndroid Build Coastguard Worker return 0;
296*9880d681SAndroid Build Coastguard Worker
297*9880d681SAndroid Build Coastguard Worker if (Subtarget.hasMips32r6() || canUseShortMicroMipsCTI) {
298*9880d681SAndroid Build Coastguard Worker switch (Opcode) {
299*9880d681SAndroid Build Coastguard Worker case Mips::B:
300*9880d681SAndroid Build Coastguard Worker return Mips::BC;
301*9880d681SAndroid Build Coastguard Worker case Mips::BAL:
302*9880d681SAndroid Build Coastguard Worker return Mips::BALC;
303*9880d681SAndroid Build Coastguard Worker case Mips::BEQ:
304*9880d681SAndroid Build Coastguard Worker if (canUseShortMicroMipsCTI)
305*9880d681SAndroid Build Coastguard Worker return Mips::BEQZC_MM;
306*9880d681SAndroid Build Coastguard Worker else if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
307*9880d681SAndroid Build Coastguard Worker return 0;
308*9880d681SAndroid Build Coastguard Worker return Mips::BEQC;
309*9880d681SAndroid Build Coastguard Worker case Mips::BNE:
310*9880d681SAndroid Build Coastguard Worker if (canUseShortMicroMipsCTI)
311*9880d681SAndroid Build Coastguard Worker return Mips::BNEZC_MM;
312*9880d681SAndroid Build Coastguard Worker else if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
313*9880d681SAndroid Build Coastguard Worker return 0;
314*9880d681SAndroid Build Coastguard Worker return Mips::BNEC;
315*9880d681SAndroid Build Coastguard Worker case Mips::BGE:
316*9880d681SAndroid Build Coastguard Worker if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
317*9880d681SAndroid Build Coastguard Worker return 0;
318*9880d681SAndroid Build Coastguard Worker return Mips::BGEC;
319*9880d681SAndroid Build Coastguard Worker case Mips::BGEU:
320*9880d681SAndroid Build Coastguard Worker if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
321*9880d681SAndroid Build Coastguard Worker return 0;
322*9880d681SAndroid Build Coastguard Worker return Mips::BGEUC;
323*9880d681SAndroid Build Coastguard Worker case Mips::BGEZ:
324*9880d681SAndroid Build Coastguard Worker return Mips::BGEZC;
325*9880d681SAndroid Build Coastguard Worker case Mips::BGTZ:
326*9880d681SAndroid Build Coastguard Worker return Mips::BGTZC;
327*9880d681SAndroid Build Coastguard Worker case Mips::BLEZ:
328*9880d681SAndroid Build Coastguard Worker return Mips::BLEZC;
329*9880d681SAndroid Build Coastguard Worker case Mips::BLT:
330*9880d681SAndroid Build Coastguard Worker if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
331*9880d681SAndroid Build Coastguard Worker return 0;
332*9880d681SAndroid Build Coastguard Worker return Mips::BLTC;
333*9880d681SAndroid Build Coastguard Worker case Mips::BLTU:
334*9880d681SAndroid Build Coastguard Worker if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
335*9880d681SAndroid Build Coastguard Worker return 0;
336*9880d681SAndroid Build Coastguard Worker return Mips::BLTUC;
337*9880d681SAndroid Build Coastguard Worker case Mips::BLTZ:
338*9880d681SAndroid Build Coastguard Worker return Mips::BLTZC;
339*9880d681SAndroid Build Coastguard Worker // For MIPSR6, the instruction 'jic' can be used for these cases. Some
340*9880d681SAndroid Build Coastguard Worker // tools will accept 'jrc reg' as an alias for 'jic 0, $reg'.
341*9880d681SAndroid Build Coastguard Worker case Mips::JR:
342*9880d681SAndroid Build Coastguard Worker case Mips::PseudoReturn:
343*9880d681SAndroid Build Coastguard Worker case Mips::PseudoIndirectBranch:
344*9880d681SAndroid Build Coastguard Worker if (canUseShortMicroMipsCTI)
345*9880d681SAndroid Build Coastguard Worker return Mips::JRC16_MM;
346*9880d681SAndroid Build Coastguard Worker return Mips::JIC;
347*9880d681SAndroid Build Coastguard Worker case Mips::JALRPseudo:
348*9880d681SAndroid Build Coastguard Worker return Mips::JIALC;
349*9880d681SAndroid Build Coastguard Worker case Mips::JR64:
350*9880d681SAndroid Build Coastguard Worker case Mips::PseudoReturn64:
351*9880d681SAndroid Build Coastguard Worker case Mips::PseudoIndirectBranch64:
352*9880d681SAndroid Build Coastguard Worker return Mips::JIC64;
353*9880d681SAndroid Build Coastguard Worker case Mips::JALR64Pseudo:
354*9880d681SAndroid Build Coastguard Worker return Mips::JIALC64;
355*9880d681SAndroid Build Coastguard Worker default:
356*9880d681SAndroid Build Coastguard Worker return 0;
357*9880d681SAndroid Build Coastguard Worker }
358*9880d681SAndroid Build Coastguard Worker }
359*9880d681SAndroid Build Coastguard Worker
360*9880d681SAndroid Build Coastguard Worker return 0;
361*9880d681SAndroid Build Coastguard Worker }
362*9880d681SAndroid Build Coastguard Worker
363*9880d681SAndroid Build Coastguard Worker /// Predicate for distingushing between control transfer instructions and all
364*9880d681SAndroid Build Coastguard Worker /// other instructions for handling forbidden slots. Consider inline assembly
365*9880d681SAndroid Build Coastguard Worker /// as unsafe as well.
SafeInForbiddenSlot(const MachineInstr & MI) const366*9880d681SAndroid Build Coastguard Worker bool MipsInstrInfo::SafeInForbiddenSlot(const MachineInstr &MI) const {
367*9880d681SAndroid Build Coastguard Worker if (MI.isInlineAsm())
368*9880d681SAndroid Build Coastguard Worker return false;
369*9880d681SAndroid Build Coastguard Worker
370*9880d681SAndroid Build Coastguard Worker return (MI.getDesc().TSFlags & MipsII::IsCTI) == 0;
371*9880d681SAndroid Build Coastguard Worker
372*9880d681SAndroid Build Coastguard Worker }
373*9880d681SAndroid Build Coastguard Worker
374*9880d681SAndroid Build Coastguard Worker /// Predicate for distingushing instructions that have forbidden slots.
HasForbiddenSlot(const MachineInstr & MI) const375*9880d681SAndroid Build Coastguard Worker bool MipsInstrInfo::HasForbiddenSlot(const MachineInstr &MI) const {
376*9880d681SAndroid Build Coastguard Worker return (MI.getDesc().TSFlags & MipsII::HasForbiddenSlot) != 0;
377*9880d681SAndroid Build Coastguard Worker }
378*9880d681SAndroid Build Coastguard Worker
379*9880d681SAndroid Build Coastguard Worker /// Return the number of bytes of code the specified instruction may be.
GetInstSizeInBytes(const MachineInstr & MI) const380*9880d681SAndroid Build Coastguard Worker unsigned MipsInstrInfo::GetInstSizeInBytes(const MachineInstr &MI) const {
381*9880d681SAndroid Build Coastguard Worker switch (MI.getOpcode()) {
382*9880d681SAndroid Build Coastguard Worker default:
383*9880d681SAndroid Build Coastguard Worker return MI.getDesc().getSize();
384*9880d681SAndroid Build Coastguard Worker case TargetOpcode::INLINEASM: { // Inline Asm: Variable size.
385*9880d681SAndroid Build Coastguard Worker const MachineFunction *MF = MI.getParent()->getParent();
386*9880d681SAndroid Build Coastguard Worker const char *AsmStr = MI.getOperand(0).getSymbolName();
387*9880d681SAndroid Build Coastguard Worker return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
388*9880d681SAndroid Build Coastguard Worker }
389*9880d681SAndroid Build Coastguard Worker case Mips::CONSTPOOL_ENTRY:
390*9880d681SAndroid Build Coastguard Worker // If this machine instr is a constant pool entry, its size is recorded as
391*9880d681SAndroid Build Coastguard Worker // operand #2.
392*9880d681SAndroid Build Coastguard Worker return MI.getOperand(2).getImm();
393*9880d681SAndroid Build Coastguard Worker }
394*9880d681SAndroid Build Coastguard Worker }
395*9880d681SAndroid Build Coastguard Worker
396*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder
genInstrWithNewOpc(unsigned NewOpc,MachineBasicBlock::iterator I) const397*9880d681SAndroid Build Coastguard Worker MipsInstrInfo::genInstrWithNewOpc(unsigned NewOpc,
398*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator I) const {
399*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder MIB;
400*9880d681SAndroid Build Coastguard Worker
401*9880d681SAndroid Build Coastguard Worker // Certain branches have two forms: e.g beq $1, $zero, dst vs beqz $1, dest
402*9880d681SAndroid Build Coastguard Worker // Pick the zero form of the branch for readable assembly and for greater
403*9880d681SAndroid Build Coastguard Worker // branch distance in non-microMIPS mode.
404*9880d681SAndroid Build Coastguard Worker // FIXME: Certain atomic sequences on mips64 generate 32bit references to
405*9880d681SAndroid Build Coastguard Worker // Mips::ZERO, which is incorrect. This test should be updated to use
406*9880d681SAndroid Build Coastguard Worker // Subtarget.getABI().GetZeroReg() when those atomic sequences and others
407*9880d681SAndroid Build Coastguard Worker // are fixed.
408*9880d681SAndroid Build Coastguard Worker bool BranchWithZeroOperand =
409*9880d681SAndroid Build Coastguard Worker (I->isBranch() && !I->isPseudo() && I->getOperand(1).isReg() &&
410*9880d681SAndroid Build Coastguard Worker (I->getOperand(1).getReg() == Mips::ZERO ||
411*9880d681SAndroid Build Coastguard Worker I->getOperand(1).getReg() == Mips::ZERO_64));
412*9880d681SAndroid Build Coastguard Worker
413*9880d681SAndroid Build Coastguard Worker if (BranchWithZeroOperand) {
414*9880d681SAndroid Build Coastguard Worker switch (NewOpc) {
415*9880d681SAndroid Build Coastguard Worker case Mips::BEQC:
416*9880d681SAndroid Build Coastguard Worker NewOpc = Mips::BEQZC;
417*9880d681SAndroid Build Coastguard Worker break;
418*9880d681SAndroid Build Coastguard Worker case Mips::BNEC:
419*9880d681SAndroid Build Coastguard Worker NewOpc = Mips::BNEZC;
420*9880d681SAndroid Build Coastguard Worker break;
421*9880d681SAndroid Build Coastguard Worker case Mips::BGEC:
422*9880d681SAndroid Build Coastguard Worker NewOpc = Mips::BGEZC;
423*9880d681SAndroid Build Coastguard Worker break;
424*9880d681SAndroid Build Coastguard Worker case Mips::BLTC:
425*9880d681SAndroid Build Coastguard Worker NewOpc = Mips::BLTZC;
426*9880d681SAndroid Build Coastguard Worker break;
427*9880d681SAndroid Build Coastguard Worker }
428*9880d681SAndroid Build Coastguard Worker }
429*9880d681SAndroid Build Coastguard Worker
430*9880d681SAndroid Build Coastguard Worker MIB = BuildMI(*I->getParent(), I, I->getDebugLoc(), get(NewOpc));
431*9880d681SAndroid Build Coastguard Worker
432*9880d681SAndroid Build Coastguard Worker // For MIPSR6 JI*C requires an immediate 0 as an operand, JIALC(64) an
433*9880d681SAndroid Build Coastguard Worker // immediate 0 as an operand and requires the removal of it's %RA<imp-def>
434*9880d681SAndroid Build Coastguard Worker // implicit operand as copying the implicit operations of the instructio we're
435*9880d681SAndroid Build Coastguard Worker // looking at will give us the correct flags.
436*9880d681SAndroid Build Coastguard Worker if (NewOpc == Mips::JIC || NewOpc == Mips::JIALC || NewOpc == Mips::JIC64 ||
437*9880d681SAndroid Build Coastguard Worker NewOpc == Mips::JIALC64) {
438*9880d681SAndroid Build Coastguard Worker
439*9880d681SAndroid Build Coastguard Worker if (NewOpc == Mips::JIALC || NewOpc == Mips::JIALC64)
440*9880d681SAndroid Build Coastguard Worker MIB->RemoveOperand(0);
441*9880d681SAndroid Build Coastguard Worker
442*9880d681SAndroid Build Coastguard Worker for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J) {
443*9880d681SAndroid Build Coastguard Worker MIB.addOperand(I->getOperand(J));
444*9880d681SAndroid Build Coastguard Worker }
445*9880d681SAndroid Build Coastguard Worker
446*9880d681SAndroid Build Coastguard Worker MIB.addImm(0);
447*9880d681SAndroid Build Coastguard Worker
448*9880d681SAndroid Build Coastguard Worker } else if (BranchWithZeroOperand) {
449*9880d681SAndroid Build Coastguard Worker // For MIPSR6 and microMIPS branches with an explicit zero operand, copy
450*9880d681SAndroid Build Coastguard Worker // everything after the zero.
451*9880d681SAndroid Build Coastguard Worker MIB.addOperand(I->getOperand(0));
452*9880d681SAndroid Build Coastguard Worker
453*9880d681SAndroid Build Coastguard Worker for (unsigned J = 2, E = I->getDesc().getNumOperands(); J < E; ++J) {
454*9880d681SAndroid Build Coastguard Worker MIB.addOperand(I->getOperand(J));
455*9880d681SAndroid Build Coastguard Worker }
456*9880d681SAndroid Build Coastguard Worker } else {
457*9880d681SAndroid Build Coastguard Worker // All other cases copy all other operands.
458*9880d681SAndroid Build Coastguard Worker for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J) {
459*9880d681SAndroid Build Coastguard Worker MIB.addOperand(I->getOperand(J));
460*9880d681SAndroid Build Coastguard Worker }
461*9880d681SAndroid Build Coastguard Worker }
462*9880d681SAndroid Build Coastguard Worker
463*9880d681SAndroid Build Coastguard Worker MIB.copyImplicitOps(*I);
464*9880d681SAndroid Build Coastguard Worker
465*9880d681SAndroid Build Coastguard Worker MIB.setMemRefs(I->memoperands_begin(), I->memoperands_end());
466*9880d681SAndroid Build Coastguard Worker return MIB;
467*9880d681SAndroid Build Coastguard Worker }
468