xref: /aosp_15_r20/external/llvm/lib/Target/Mips/Mips16InstrInfo.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- Mips16InstrInfo.cpp - Mips16 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 Mips16 implementation of the TargetInstrInfo class.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker #include "Mips16InstrInfo.h"
14*9880d681SAndroid Build Coastguard Worker #include "InstPrinter/MipsInstPrinter.h"
15*9880d681SAndroid Build Coastguard Worker #include "MipsMachineFunction.h"
16*9880d681SAndroid Build Coastguard Worker #include "MipsTargetMachine.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/RegisterScavenging.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
26*9880d681SAndroid Build Coastguard Worker #include <cctype>
27*9880d681SAndroid Build Coastguard Worker 
28*9880d681SAndroid Build Coastguard Worker using namespace llvm;
29*9880d681SAndroid Build Coastguard Worker 
30*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "mips16-instrinfo"
31*9880d681SAndroid Build Coastguard Worker 
Mips16InstrInfo(const MipsSubtarget & STI)32*9880d681SAndroid Build Coastguard Worker Mips16InstrInfo::Mips16InstrInfo(const MipsSubtarget &STI)
33*9880d681SAndroid Build Coastguard Worker     : MipsInstrInfo(STI, Mips::Bimm16), RI() {}
34*9880d681SAndroid Build Coastguard Worker 
getRegisterInfo() const35*9880d681SAndroid Build Coastguard Worker const MipsRegisterInfo &Mips16InstrInfo::getRegisterInfo() const {
36*9880d681SAndroid Build Coastguard Worker   return RI;
37*9880d681SAndroid Build Coastguard Worker }
38*9880d681SAndroid Build Coastguard Worker 
39*9880d681SAndroid Build Coastguard Worker /// isLoadFromStackSlot - If the specified machine instruction is a direct
40*9880d681SAndroid Build Coastguard Worker /// load from a stack slot, return the virtual or physical register number of
41*9880d681SAndroid Build Coastguard Worker /// the destination along with the FrameIndex of the loaded stack slot.  If
42*9880d681SAndroid Build Coastguard Worker /// not, return 0.  This predicate must return 0 if the instruction has
43*9880d681SAndroid Build Coastguard Worker /// any side effects other than loading from the stack slot.
isLoadFromStackSlot(const MachineInstr & MI,int & FrameIndex) const44*9880d681SAndroid Build Coastguard Worker unsigned Mips16InstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
45*9880d681SAndroid Build Coastguard Worker                                               int &FrameIndex) const {
46*9880d681SAndroid Build Coastguard Worker   return 0;
47*9880d681SAndroid Build Coastguard Worker }
48*9880d681SAndroid Build Coastguard Worker 
49*9880d681SAndroid Build Coastguard Worker /// isStoreToStackSlot - If the specified machine instruction is a direct
50*9880d681SAndroid Build Coastguard Worker /// store to a stack slot, return the virtual or physical register number of
51*9880d681SAndroid Build Coastguard Worker /// the source reg along with the FrameIndex of the loaded stack slot.  If
52*9880d681SAndroid Build Coastguard Worker /// not, return 0.  This predicate must return 0 if the instruction has
53*9880d681SAndroid Build Coastguard Worker /// any side effects other than storing to the stack slot.
isStoreToStackSlot(const MachineInstr & MI,int & FrameIndex) const54*9880d681SAndroid Build Coastguard Worker unsigned Mips16InstrInfo::isStoreToStackSlot(const MachineInstr &MI,
55*9880d681SAndroid Build Coastguard Worker                                              int &FrameIndex) const {
56*9880d681SAndroid Build Coastguard Worker   return 0;
57*9880d681SAndroid Build Coastguard Worker }
58*9880d681SAndroid Build Coastguard Worker 
copyPhysReg(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,const DebugLoc & DL,unsigned DestReg,unsigned SrcReg,bool KillSrc) const59*9880d681SAndroid Build Coastguard Worker void Mips16InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
60*9880d681SAndroid Build Coastguard Worker                                   MachineBasicBlock::iterator I,
61*9880d681SAndroid Build Coastguard Worker                                   const DebugLoc &DL, unsigned DestReg,
62*9880d681SAndroid Build Coastguard Worker                                   unsigned SrcReg, bool KillSrc) const {
63*9880d681SAndroid Build Coastguard Worker   unsigned Opc = 0;
64*9880d681SAndroid Build Coastguard Worker 
65*9880d681SAndroid Build Coastguard Worker   if (Mips::CPU16RegsRegClass.contains(DestReg) &&
66*9880d681SAndroid Build Coastguard Worker       Mips::GPR32RegClass.contains(SrcReg))
67*9880d681SAndroid Build Coastguard Worker     Opc = Mips::MoveR3216;
68*9880d681SAndroid Build Coastguard Worker   else if (Mips::GPR32RegClass.contains(DestReg) &&
69*9880d681SAndroid Build Coastguard Worker            Mips::CPU16RegsRegClass.contains(SrcReg))
70*9880d681SAndroid Build Coastguard Worker     Opc = Mips::Move32R16;
71*9880d681SAndroid Build Coastguard Worker   else if ((SrcReg == Mips::HI0) &&
72*9880d681SAndroid Build Coastguard Worker            (Mips::CPU16RegsRegClass.contains(DestReg)))
73*9880d681SAndroid Build Coastguard Worker     Opc = Mips::Mfhi16, SrcReg = 0;
74*9880d681SAndroid Build Coastguard Worker 
75*9880d681SAndroid Build Coastguard Worker   else if ((SrcReg == Mips::LO0) &&
76*9880d681SAndroid Build Coastguard Worker            (Mips::CPU16RegsRegClass.contains(DestReg)))
77*9880d681SAndroid Build Coastguard Worker     Opc = Mips::Mflo16, SrcReg = 0;
78*9880d681SAndroid Build Coastguard Worker 
79*9880d681SAndroid Build Coastguard Worker 
80*9880d681SAndroid Build Coastguard Worker   assert(Opc && "Cannot copy registers");
81*9880d681SAndroid Build Coastguard Worker 
82*9880d681SAndroid Build Coastguard Worker   MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc));
83*9880d681SAndroid Build Coastguard Worker 
84*9880d681SAndroid Build Coastguard Worker   if (DestReg)
85*9880d681SAndroid Build Coastguard Worker     MIB.addReg(DestReg, RegState::Define);
86*9880d681SAndroid Build Coastguard Worker 
87*9880d681SAndroid Build Coastguard Worker   if (SrcReg)
88*9880d681SAndroid Build Coastguard Worker     MIB.addReg(SrcReg, getKillRegState(KillSrc));
89*9880d681SAndroid Build Coastguard Worker }
90*9880d681SAndroid Build Coastguard Worker 
storeRegToStack(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,unsigned SrcReg,bool isKill,int FI,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI,int64_t Offset) const91*9880d681SAndroid Build Coastguard Worker void Mips16InstrInfo::storeRegToStack(MachineBasicBlock &MBB,
92*9880d681SAndroid Build Coastguard Worker                                       MachineBasicBlock::iterator I,
93*9880d681SAndroid Build Coastguard Worker                                       unsigned SrcReg, bool isKill, int FI,
94*9880d681SAndroid Build Coastguard Worker                                       const TargetRegisterClass *RC,
95*9880d681SAndroid Build Coastguard Worker                                       const TargetRegisterInfo *TRI,
96*9880d681SAndroid Build Coastguard Worker                                       int64_t Offset) const {
97*9880d681SAndroid Build Coastguard Worker   DebugLoc DL;
98*9880d681SAndroid Build Coastguard Worker   if (I != MBB.end()) DL = I->getDebugLoc();
99*9880d681SAndroid Build Coastguard Worker   MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOStore);
100*9880d681SAndroid Build Coastguard Worker   unsigned Opc = 0;
101*9880d681SAndroid Build Coastguard Worker   if (Mips::CPU16RegsRegClass.hasSubClassEq(RC))
102*9880d681SAndroid Build Coastguard Worker     Opc = Mips::SwRxSpImmX16;
103*9880d681SAndroid Build Coastguard Worker   assert(Opc && "Register class not handled!");
104*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill)).
105*9880d681SAndroid Build Coastguard Worker       addFrameIndex(FI).addImm(Offset)
106*9880d681SAndroid Build Coastguard Worker       .addMemOperand(MMO);
107*9880d681SAndroid Build Coastguard Worker }
108*9880d681SAndroid Build Coastguard Worker 
loadRegFromStack(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,unsigned DestReg,int FI,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI,int64_t Offset) const109*9880d681SAndroid Build Coastguard Worker void Mips16InstrInfo::loadRegFromStack(MachineBasicBlock &MBB,
110*9880d681SAndroid Build Coastguard Worker                                        MachineBasicBlock::iterator I,
111*9880d681SAndroid Build Coastguard Worker                                        unsigned DestReg, int FI,
112*9880d681SAndroid Build Coastguard Worker                                        const TargetRegisterClass *RC,
113*9880d681SAndroid Build Coastguard Worker                                        const TargetRegisterInfo *TRI,
114*9880d681SAndroid Build Coastguard Worker                                        int64_t Offset) const {
115*9880d681SAndroid Build Coastguard Worker   DebugLoc DL;
116*9880d681SAndroid Build Coastguard Worker   if (I != MBB.end()) DL = I->getDebugLoc();
117*9880d681SAndroid Build Coastguard Worker   MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad);
118*9880d681SAndroid Build Coastguard Worker   unsigned Opc = 0;
119*9880d681SAndroid Build Coastguard Worker 
120*9880d681SAndroid Build Coastguard Worker   if (Mips::CPU16RegsRegClass.hasSubClassEq(RC))
121*9880d681SAndroid Build Coastguard Worker     Opc = Mips::LwRxSpImmX16;
122*9880d681SAndroid Build Coastguard Worker   assert(Opc && "Register class not handled!");
123*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, I, DL, get(Opc), DestReg).addFrameIndex(FI).addImm(Offset)
124*9880d681SAndroid Build Coastguard Worker     .addMemOperand(MMO);
125*9880d681SAndroid Build Coastguard Worker }
126*9880d681SAndroid Build Coastguard Worker 
expandPostRAPseudo(MachineInstr & MI) const127*9880d681SAndroid Build Coastguard Worker bool Mips16InstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
128*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock &MBB = *MI.getParent();
129*9880d681SAndroid Build Coastguard Worker   switch (MI.getDesc().getOpcode()) {
130*9880d681SAndroid Build Coastguard Worker   default:
131*9880d681SAndroid Build Coastguard Worker     return false;
132*9880d681SAndroid Build Coastguard Worker   case Mips::RetRA16:
133*9880d681SAndroid Build Coastguard Worker     ExpandRetRA16(MBB, MI, Mips::JrcRa16);
134*9880d681SAndroid Build Coastguard Worker     break;
135*9880d681SAndroid Build Coastguard Worker   }
136*9880d681SAndroid Build Coastguard Worker 
137*9880d681SAndroid Build Coastguard Worker   MBB.erase(MI.getIterator());
138*9880d681SAndroid Build Coastguard Worker   return true;
139*9880d681SAndroid Build Coastguard Worker }
140*9880d681SAndroid Build Coastguard Worker 
141*9880d681SAndroid Build Coastguard Worker /// GetOppositeBranchOpc - Return the inverse of the specified
142*9880d681SAndroid Build Coastguard Worker /// opcode, e.g. turning BEQ to BNE.
getOppositeBranchOpc(unsigned Opc) const143*9880d681SAndroid Build Coastguard Worker unsigned Mips16InstrInfo::getOppositeBranchOpc(unsigned Opc) const {
144*9880d681SAndroid Build Coastguard Worker   switch (Opc) {
145*9880d681SAndroid Build Coastguard Worker   case Mips::BeqzRxImmX16: return Mips::BnezRxImmX16;
146*9880d681SAndroid Build Coastguard Worker   case Mips::BnezRxImmX16: return Mips::BeqzRxImmX16;
147*9880d681SAndroid Build Coastguard Worker   case Mips::BeqzRxImm16: return Mips::BnezRxImm16;
148*9880d681SAndroid Build Coastguard Worker   case Mips::BnezRxImm16: return Mips::BeqzRxImm16;
149*9880d681SAndroid Build Coastguard Worker   case Mips::BteqzT8CmpX16: return Mips::BtnezT8CmpX16;
150*9880d681SAndroid Build Coastguard Worker   case Mips::BteqzT8SltX16: return Mips::BtnezT8SltX16;
151*9880d681SAndroid Build Coastguard Worker   case Mips::BteqzT8SltiX16: return Mips::BtnezT8SltiX16;
152*9880d681SAndroid Build Coastguard Worker   case Mips::Btnez16: return Mips::Bteqz16;
153*9880d681SAndroid Build Coastguard Worker   case Mips::BtnezX16: return Mips::BteqzX16;
154*9880d681SAndroid Build Coastguard Worker   case Mips::BtnezT8CmpiX16: return Mips::BteqzT8CmpiX16;
155*9880d681SAndroid Build Coastguard Worker   case Mips::BtnezT8SltuX16: return Mips::BteqzT8SltuX16;
156*9880d681SAndroid Build Coastguard Worker   case Mips::BtnezT8SltiuX16: return Mips::BteqzT8SltiuX16;
157*9880d681SAndroid Build Coastguard Worker   case Mips::Bteqz16: return Mips::Btnez16;
158*9880d681SAndroid Build Coastguard Worker   case Mips::BteqzX16: return Mips::BtnezX16;
159*9880d681SAndroid Build Coastguard Worker   case Mips::BteqzT8CmpiX16: return Mips::BtnezT8CmpiX16;
160*9880d681SAndroid Build Coastguard Worker   case Mips::BteqzT8SltuX16: return Mips::BtnezT8SltuX16;
161*9880d681SAndroid Build Coastguard Worker   case Mips::BteqzT8SltiuX16: return Mips::BtnezT8SltiuX16;
162*9880d681SAndroid Build Coastguard Worker   case Mips::BtnezT8CmpX16: return Mips::BteqzT8CmpX16;
163*9880d681SAndroid Build Coastguard Worker   case Mips::BtnezT8SltX16: return Mips::BteqzT8SltX16;
164*9880d681SAndroid Build Coastguard Worker   case Mips::BtnezT8SltiX16: return Mips::BteqzT8SltiX16;
165*9880d681SAndroid Build Coastguard Worker   }
166*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("Illegal opcode!");
167*9880d681SAndroid Build Coastguard Worker }
168*9880d681SAndroid Build Coastguard Worker 
addSaveRestoreRegs(MachineInstrBuilder & MIB,const std::vector<CalleeSavedInfo> & CSI,unsigned Flags=0)169*9880d681SAndroid Build Coastguard Worker static void addSaveRestoreRegs(MachineInstrBuilder &MIB,
170*9880d681SAndroid Build Coastguard Worker                                const std::vector<CalleeSavedInfo> &CSI,
171*9880d681SAndroid Build Coastguard Worker                                unsigned Flags = 0) {
172*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
173*9880d681SAndroid Build Coastguard Worker     // Add the callee-saved register as live-in. Do not add if the register is
174*9880d681SAndroid Build Coastguard Worker     // RA and return address is taken, because it has already been added in
175*9880d681SAndroid Build Coastguard Worker     // method MipsTargetLowering::LowerRETURNADDR.
176*9880d681SAndroid Build Coastguard Worker     // It's killed at the spill, unless the register is RA and return address
177*9880d681SAndroid Build Coastguard Worker     // is taken.
178*9880d681SAndroid Build Coastguard Worker     unsigned Reg = CSI[e-i-1].getReg();
179*9880d681SAndroid Build Coastguard Worker     switch (Reg) {
180*9880d681SAndroid Build Coastguard Worker     case Mips::RA:
181*9880d681SAndroid Build Coastguard Worker     case Mips::S0:
182*9880d681SAndroid Build Coastguard Worker     case Mips::S1:
183*9880d681SAndroid Build Coastguard Worker       MIB.addReg(Reg, Flags);
184*9880d681SAndroid Build Coastguard Worker       break;
185*9880d681SAndroid Build Coastguard Worker     case Mips::S2:
186*9880d681SAndroid Build Coastguard Worker       break;
187*9880d681SAndroid Build Coastguard Worker     default:
188*9880d681SAndroid Build Coastguard Worker       llvm_unreachable("unexpected mips16 callee saved register");
189*9880d681SAndroid Build Coastguard Worker 
190*9880d681SAndroid Build Coastguard Worker     }
191*9880d681SAndroid Build Coastguard Worker   }
192*9880d681SAndroid Build Coastguard Worker }
193*9880d681SAndroid Build Coastguard Worker // Adjust SP by FrameSize bytes. Save RA, S0, S1
makeFrame(unsigned SP,int64_t FrameSize,MachineBasicBlock & MBB,MachineBasicBlock::iterator I) const194*9880d681SAndroid Build Coastguard Worker void Mips16InstrInfo::makeFrame(unsigned SP, int64_t FrameSize,
195*9880d681SAndroid Build Coastguard Worker                                 MachineBasicBlock &MBB,
196*9880d681SAndroid Build Coastguard Worker                                 MachineBasicBlock::iterator I) const {
197*9880d681SAndroid Build Coastguard Worker   DebugLoc DL;
198*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB.getParent();
199*9880d681SAndroid Build Coastguard Worker   MachineFrameInfo *MFI    = MF.getFrameInfo();
200*9880d681SAndroid Build Coastguard Worker   const BitVector Reserved = RI.getReservedRegs(MF);
201*9880d681SAndroid Build Coastguard Worker   bool SaveS2 = Reserved[Mips::S2];
202*9880d681SAndroid Build Coastguard Worker   MachineInstrBuilder MIB;
203*9880d681SAndroid Build Coastguard Worker   unsigned Opc = ((FrameSize <= 128) && !SaveS2)? Mips::Save16:Mips::SaveX16;
204*9880d681SAndroid Build Coastguard Worker   MIB = BuildMI(MBB, I, DL, get(Opc));
205*9880d681SAndroid Build Coastguard Worker   const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
206*9880d681SAndroid Build Coastguard Worker   addSaveRestoreRegs(MIB, CSI);
207*9880d681SAndroid Build Coastguard Worker   if (SaveS2)
208*9880d681SAndroid Build Coastguard Worker     MIB.addReg(Mips::S2);
209*9880d681SAndroid Build Coastguard Worker   if (isUInt<11>(FrameSize))
210*9880d681SAndroid Build Coastguard Worker     MIB.addImm(FrameSize);
211*9880d681SAndroid Build Coastguard Worker   else {
212*9880d681SAndroid Build Coastguard Worker     int Base = 2040; // should create template function like isUInt that
213*9880d681SAndroid Build Coastguard Worker                      // returns largest possible n bit unsigned integer
214*9880d681SAndroid Build Coastguard Worker     int64_t Remainder = FrameSize - Base;
215*9880d681SAndroid Build Coastguard Worker     MIB.addImm(Base);
216*9880d681SAndroid Build Coastguard Worker     if (isInt<16>(-Remainder))
217*9880d681SAndroid Build Coastguard Worker       BuildAddiuSpImm(MBB, I, -Remainder);
218*9880d681SAndroid Build Coastguard Worker     else
219*9880d681SAndroid Build Coastguard Worker       adjustStackPtrBig(SP, -Remainder, MBB, I, Mips::V0, Mips::V1);
220*9880d681SAndroid Build Coastguard Worker   }
221*9880d681SAndroid Build Coastguard Worker }
222*9880d681SAndroid Build Coastguard Worker 
223*9880d681SAndroid Build Coastguard Worker // Adjust SP by FrameSize bytes. Restore RA, S0, S1
restoreFrame(unsigned SP,int64_t FrameSize,MachineBasicBlock & MBB,MachineBasicBlock::iterator I) const224*9880d681SAndroid Build Coastguard Worker void Mips16InstrInfo::restoreFrame(unsigned SP, int64_t FrameSize,
225*9880d681SAndroid Build Coastguard Worker                                    MachineBasicBlock &MBB,
226*9880d681SAndroid Build Coastguard Worker                                    MachineBasicBlock::iterator I) const {
227*9880d681SAndroid Build Coastguard Worker   DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
228*9880d681SAndroid Build Coastguard Worker   MachineFunction *MF = MBB.getParent();
229*9880d681SAndroid Build Coastguard Worker   MachineFrameInfo *MFI    = MF->getFrameInfo();
230*9880d681SAndroid Build Coastguard Worker   const BitVector Reserved = RI.getReservedRegs(*MF);
231*9880d681SAndroid Build Coastguard Worker   bool SaveS2 = Reserved[Mips::S2];
232*9880d681SAndroid Build Coastguard Worker   MachineInstrBuilder MIB;
233*9880d681SAndroid Build Coastguard Worker   unsigned Opc = ((FrameSize <= 128) && !SaveS2)?
234*9880d681SAndroid Build Coastguard Worker     Mips::Restore16:Mips::RestoreX16;
235*9880d681SAndroid Build Coastguard Worker 
236*9880d681SAndroid Build Coastguard Worker   if (!isUInt<11>(FrameSize)) {
237*9880d681SAndroid Build Coastguard Worker     unsigned Base = 2040;
238*9880d681SAndroid Build Coastguard Worker     int64_t Remainder = FrameSize - Base;
239*9880d681SAndroid Build Coastguard Worker     FrameSize = Base; // should create template function like isUInt that
240*9880d681SAndroid Build Coastguard Worker                      // returns largest possible n bit unsigned integer
241*9880d681SAndroid Build Coastguard Worker 
242*9880d681SAndroid Build Coastguard Worker     if (isInt<16>(Remainder))
243*9880d681SAndroid Build Coastguard Worker       BuildAddiuSpImm(MBB, I, Remainder);
244*9880d681SAndroid Build Coastguard Worker     else
245*9880d681SAndroid Build Coastguard Worker       adjustStackPtrBig(SP, Remainder, MBB, I, Mips::A0, Mips::A1);
246*9880d681SAndroid Build Coastguard Worker   }
247*9880d681SAndroid Build Coastguard Worker   MIB = BuildMI(MBB, I, DL, get(Opc));
248*9880d681SAndroid Build Coastguard Worker   const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
249*9880d681SAndroid Build Coastguard Worker   addSaveRestoreRegs(MIB, CSI, RegState::Define);
250*9880d681SAndroid Build Coastguard Worker   if (SaveS2)
251*9880d681SAndroid Build Coastguard Worker     MIB.addReg(Mips::S2, RegState::Define);
252*9880d681SAndroid Build Coastguard Worker   MIB.addImm(FrameSize);
253*9880d681SAndroid Build Coastguard Worker }
254*9880d681SAndroid Build Coastguard Worker 
255*9880d681SAndroid Build Coastguard Worker // Adjust SP by Amount bytes where bytes can be up to 32bit number.
256*9880d681SAndroid Build Coastguard Worker // This can only be called at times that we know that there is at least one free
257*9880d681SAndroid Build Coastguard Worker // register.
258*9880d681SAndroid Build Coastguard Worker // This is clearly safe at prologue and epilogue.
259*9880d681SAndroid Build Coastguard Worker //
adjustStackPtrBig(unsigned SP,int64_t Amount,MachineBasicBlock & MBB,MachineBasicBlock::iterator I,unsigned Reg1,unsigned Reg2) const260*9880d681SAndroid Build Coastguard Worker void Mips16InstrInfo::adjustStackPtrBig(unsigned SP, int64_t Amount,
261*9880d681SAndroid Build Coastguard Worker                                         MachineBasicBlock &MBB,
262*9880d681SAndroid Build Coastguard Worker                                         MachineBasicBlock::iterator I,
263*9880d681SAndroid Build Coastguard Worker                                         unsigned Reg1, unsigned Reg2) const {
264*9880d681SAndroid Build Coastguard Worker   DebugLoc DL;
265*9880d681SAndroid Build Coastguard Worker   //
266*9880d681SAndroid Build Coastguard Worker   // li reg1, constant
267*9880d681SAndroid Build Coastguard Worker   // move reg2, sp
268*9880d681SAndroid Build Coastguard Worker   // add reg1, reg1, reg2
269*9880d681SAndroid Build Coastguard Worker   // move sp, reg1
270*9880d681SAndroid Build Coastguard Worker   //
271*9880d681SAndroid Build Coastguard Worker   //
272*9880d681SAndroid Build Coastguard Worker   MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::LwConstant32), Reg1);
273*9880d681SAndroid Build Coastguard Worker   MIB1.addImm(Amount).addImm(-1);
274*9880d681SAndroid Build Coastguard Worker   MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::MoveR3216), Reg2);
275*9880d681SAndroid Build Coastguard Worker   MIB2.addReg(Mips::SP, RegState::Kill);
276*9880d681SAndroid Build Coastguard Worker   MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::AdduRxRyRz16), Reg1);
277*9880d681SAndroid Build Coastguard Worker   MIB3.addReg(Reg1);
278*9880d681SAndroid Build Coastguard Worker   MIB3.addReg(Reg2, RegState::Kill);
279*9880d681SAndroid Build Coastguard Worker   MachineInstrBuilder MIB4 = BuildMI(MBB, I, DL, get(Mips::Move32R16),
280*9880d681SAndroid Build Coastguard Worker                                                      Mips::SP);
281*9880d681SAndroid Build Coastguard Worker   MIB4.addReg(Reg1, RegState::Kill);
282*9880d681SAndroid Build Coastguard Worker }
283*9880d681SAndroid Build Coastguard Worker 
adjustStackPtrBigUnrestricted(unsigned SP,int64_t Amount,MachineBasicBlock & MBB,MachineBasicBlock::iterator I) const284*9880d681SAndroid Build Coastguard Worker void Mips16InstrInfo::adjustStackPtrBigUnrestricted(
285*9880d681SAndroid Build Coastguard Worker     unsigned SP, int64_t Amount, MachineBasicBlock &MBB,
286*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock::iterator I) const {
287*9880d681SAndroid Build Coastguard Worker    llvm_unreachable("adjust stack pointer amount exceeded");
288*9880d681SAndroid Build Coastguard Worker }
289*9880d681SAndroid Build Coastguard Worker 
290*9880d681SAndroid Build Coastguard Worker /// Adjust SP by Amount bytes.
adjustStackPtr(unsigned SP,int64_t Amount,MachineBasicBlock & MBB,MachineBasicBlock::iterator I) const291*9880d681SAndroid Build Coastguard Worker void Mips16InstrInfo::adjustStackPtr(unsigned SP, int64_t Amount,
292*9880d681SAndroid Build Coastguard Worker                                      MachineBasicBlock &MBB,
293*9880d681SAndroid Build Coastguard Worker                                      MachineBasicBlock::iterator I) const {
294*9880d681SAndroid Build Coastguard Worker   if (Amount == 0)
295*9880d681SAndroid Build Coastguard Worker     return;
296*9880d681SAndroid Build Coastguard Worker 
297*9880d681SAndroid Build Coastguard Worker   if (isInt<16>(Amount))  // need to change to addiu sp, ....and isInt<16>
298*9880d681SAndroid Build Coastguard Worker     BuildAddiuSpImm(MBB, I, Amount);
299*9880d681SAndroid Build Coastguard Worker   else
300*9880d681SAndroid Build Coastguard Worker     adjustStackPtrBigUnrestricted(SP, Amount, MBB, I);
301*9880d681SAndroid Build Coastguard Worker }
302*9880d681SAndroid Build Coastguard Worker 
303*9880d681SAndroid Build Coastguard Worker /// This function generates the sequence of instructions needed to get the
304*9880d681SAndroid Build Coastguard Worker /// result of adding register REG and immediate IMM.
loadImmediate(unsigned FrameReg,int64_t Imm,MachineBasicBlock & MBB,MachineBasicBlock::iterator II,const DebugLoc & DL,unsigned & NewImm) const305*9880d681SAndroid Build Coastguard Worker unsigned Mips16InstrInfo::loadImmediate(unsigned FrameReg, int64_t Imm,
306*9880d681SAndroid Build Coastguard Worker                                         MachineBasicBlock &MBB,
307*9880d681SAndroid Build Coastguard Worker                                         MachineBasicBlock::iterator II,
308*9880d681SAndroid Build Coastguard Worker                                         const DebugLoc &DL,
309*9880d681SAndroid Build Coastguard Worker                                         unsigned &NewImm) const {
310*9880d681SAndroid Build Coastguard Worker   //
311*9880d681SAndroid Build Coastguard Worker   // given original instruction is:
312*9880d681SAndroid Build Coastguard Worker   // Instr rx, T[offset] where offset is too big.
313*9880d681SAndroid Build Coastguard Worker   //
314*9880d681SAndroid Build Coastguard Worker   // lo = offset & 0xFFFF
315*9880d681SAndroid Build Coastguard Worker   // hi = ((offset >> 16) + (lo >> 15)) & 0xFFFF;
316*9880d681SAndroid Build Coastguard Worker   //
317*9880d681SAndroid Build Coastguard Worker   // let T = temporary register
318*9880d681SAndroid Build Coastguard Worker   // li T, hi
319*9880d681SAndroid Build Coastguard Worker   // shl T, 16
320*9880d681SAndroid Build Coastguard Worker   // add T, Rx, T
321*9880d681SAndroid Build Coastguard Worker   //
322*9880d681SAndroid Build Coastguard Worker   RegScavenger rs;
323*9880d681SAndroid Build Coastguard Worker   int32_t lo = Imm & 0xFFFF;
324*9880d681SAndroid Build Coastguard Worker   NewImm = lo;
325*9880d681SAndroid Build Coastguard Worker   int Reg =0;
326*9880d681SAndroid Build Coastguard Worker   int SpReg = 0;
327*9880d681SAndroid Build Coastguard Worker 
328*9880d681SAndroid Build Coastguard Worker   rs.enterBasicBlock(MBB);
329*9880d681SAndroid Build Coastguard Worker   rs.forward(II);
330*9880d681SAndroid Build Coastguard Worker   //
331*9880d681SAndroid Build Coastguard Worker   // We need to know which registers can be used, in the case where there
332*9880d681SAndroid Build Coastguard Worker   // are not enough free registers. We exclude all registers that
333*9880d681SAndroid Build Coastguard Worker   // are used in the instruction that we are helping.
334*9880d681SAndroid Build Coastguard Worker   //  // Consider all allocatable registers in the register class initially
335*9880d681SAndroid Build Coastguard Worker   BitVector Candidates =
336*9880d681SAndroid Build Coastguard Worker       RI.getAllocatableSet
337*9880d681SAndroid Build Coastguard Worker       (*II->getParent()->getParent(), &Mips::CPU16RegsRegClass);
338*9880d681SAndroid Build Coastguard Worker   // Exclude all the registers being used by the instruction.
339*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) {
340*9880d681SAndroid Build Coastguard Worker     MachineOperand &MO = II->getOperand(i);
341*9880d681SAndroid Build Coastguard Worker     if (MO.isReg() && MO.getReg() != 0 && !MO.isDef() &&
342*9880d681SAndroid Build Coastguard Worker         !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
343*9880d681SAndroid Build Coastguard Worker       Candidates.reset(MO.getReg());
344*9880d681SAndroid Build Coastguard Worker   }
345*9880d681SAndroid Build Coastguard Worker 
346*9880d681SAndroid Build Coastguard Worker   // If the same register was used and defined in an instruction, then
347*9880d681SAndroid Build Coastguard Worker   // it will not be in the list of candidates.
348*9880d681SAndroid Build Coastguard Worker   //
349*9880d681SAndroid Build Coastguard Worker   // we need to analyze the instruction that we are helping.
350*9880d681SAndroid Build Coastguard Worker   // we need to know if it defines register x but register x is not
351*9880d681SAndroid Build Coastguard Worker   // present as an operand of the instruction. this tells
352*9880d681SAndroid Build Coastguard Worker   // whether the register is live before the instruction. if it's not
353*9880d681SAndroid Build Coastguard Worker   // then we don't need to save it in case there are no free registers.
354*9880d681SAndroid Build Coastguard Worker   int DefReg = 0;
355*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) {
356*9880d681SAndroid Build Coastguard Worker     MachineOperand &MO = II->getOperand(i);
357*9880d681SAndroid Build Coastguard Worker     if (MO.isReg() && MO.isDef()) {
358*9880d681SAndroid Build Coastguard Worker       DefReg = MO.getReg();
359*9880d681SAndroid Build Coastguard Worker       break;
360*9880d681SAndroid Build Coastguard Worker     }
361*9880d681SAndroid Build Coastguard Worker   }
362*9880d681SAndroid Build Coastguard Worker 
363*9880d681SAndroid Build Coastguard Worker   BitVector Available = rs.getRegsAvailable(&Mips::CPU16RegsRegClass);
364*9880d681SAndroid Build Coastguard Worker   Available &= Candidates;
365*9880d681SAndroid Build Coastguard Worker   //
366*9880d681SAndroid Build Coastguard Worker   // we use T0 for the first register, if we need to save something away.
367*9880d681SAndroid Build Coastguard Worker   // we use T1 for the second register, if we need to save something away.
368*9880d681SAndroid Build Coastguard Worker   //
369*9880d681SAndroid Build Coastguard Worker   unsigned FirstRegSaved =0, SecondRegSaved=0;
370*9880d681SAndroid Build Coastguard Worker   unsigned FirstRegSavedTo = 0, SecondRegSavedTo = 0;
371*9880d681SAndroid Build Coastguard Worker 
372*9880d681SAndroid Build Coastguard Worker   Reg = Available.find_first();
373*9880d681SAndroid Build Coastguard Worker 
374*9880d681SAndroid Build Coastguard Worker   if (Reg == -1) {
375*9880d681SAndroid Build Coastguard Worker     Reg = Candidates.find_first();
376*9880d681SAndroid Build Coastguard Worker     Candidates.reset(Reg);
377*9880d681SAndroid Build Coastguard Worker     if (DefReg != Reg) {
378*9880d681SAndroid Build Coastguard Worker       FirstRegSaved = Reg;
379*9880d681SAndroid Build Coastguard Worker       FirstRegSavedTo = Mips::T0;
380*9880d681SAndroid Build Coastguard Worker       copyPhysReg(MBB, II, DL, FirstRegSavedTo, FirstRegSaved, true);
381*9880d681SAndroid Build Coastguard Worker     }
382*9880d681SAndroid Build Coastguard Worker   }
383*9880d681SAndroid Build Coastguard Worker   else
384*9880d681SAndroid Build Coastguard Worker     Available.reset(Reg);
385*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, II, DL, get(Mips::LwConstant32), Reg).addImm(Imm).addImm(-1);
386*9880d681SAndroid Build Coastguard Worker   NewImm = 0;
387*9880d681SAndroid Build Coastguard Worker   if (FrameReg == Mips::SP) {
388*9880d681SAndroid Build Coastguard Worker     SpReg = Available.find_first();
389*9880d681SAndroid Build Coastguard Worker     if (SpReg == -1) {
390*9880d681SAndroid Build Coastguard Worker       SpReg = Candidates.find_first();
391*9880d681SAndroid Build Coastguard Worker       // Candidates.reset(SpReg); // not really needed
392*9880d681SAndroid Build Coastguard Worker       if (DefReg!= SpReg) {
393*9880d681SAndroid Build Coastguard Worker         SecondRegSaved = SpReg;
394*9880d681SAndroid Build Coastguard Worker         SecondRegSavedTo = Mips::T1;
395*9880d681SAndroid Build Coastguard Worker       }
396*9880d681SAndroid Build Coastguard Worker       if (SecondRegSaved)
397*9880d681SAndroid Build Coastguard Worker         copyPhysReg(MBB, II, DL, SecondRegSavedTo, SecondRegSaved, true);
398*9880d681SAndroid Build Coastguard Worker     }
399*9880d681SAndroid Build Coastguard Worker    else
400*9880d681SAndroid Build Coastguard Worker      Available.reset(SpReg);
401*9880d681SAndroid Build Coastguard Worker     copyPhysReg(MBB, II, DL, SpReg, Mips::SP, false);
402*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, II, DL, get(Mips::  AdduRxRyRz16), Reg).addReg(SpReg, RegState::Kill)
403*9880d681SAndroid Build Coastguard Worker       .addReg(Reg);
404*9880d681SAndroid Build Coastguard Worker   }
405*9880d681SAndroid Build Coastguard Worker   else
406*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, II, DL, get(Mips::  AdduRxRyRz16), Reg).addReg(FrameReg)
407*9880d681SAndroid Build Coastguard Worker       .addReg(Reg, RegState::Kill);
408*9880d681SAndroid Build Coastguard Worker   if (FirstRegSaved || SecondRegSaved) {
409*9880d681SAndroid Build Coastguard Worker     II = std::next(II);
410*9880d681SAndroid Build Coastguard Worker     if (FirstRegSaved)
411*9880d681SAndroid Build Coastguard Worker       copyPhysReg(MBB, II, DL, FirstRegSaved, FirstRegSavedTo, true);
412*9880d681SAndroid Build Coastguard Worker     if (SecondRegSaved)
413*9880d681SAndroid Build Coastguard Worker       copyPhysReg(MBB, II, DL, SecondRegSaved, SecondRegSavedTo, true);
414*9880d681SAndroid Build Coastguard Worker   }
415*9880d681SAndroid Build Coastguard Worker   return Reg;
416*9880d681SAndroid Build Coastguard Worker }
417*9880d681SAndroid Build Coastguard Worker 
getAnalyzableBrOpc(unsigned Opc) const418*9880d681SAndroid Build Coastguard Worker unsigned Mips16InstrInfo::getAnalyzableBrOpc(unsigned Opc) const {
419*9880d681SAndroid Build Coastguard Worker   return (Opc == Mips::BeqzRxImmX16   || Opc == Mips::BimmX16  ||
420*9880d681SAndroid Build Coastguard Worker           Opc == Mips::Bimm16  ||
421*9880d681SAndroid Build Coastguard Worker           Opc == Mips::Bteqz16        || Opc == Mips::Btnez16 ||
422*9880d681SAndroid Build Coastguard Worker           Opc == Mips::BeqzRxImm16    || Opc == Mips::BnezRxImm16   ||
423*9880d681SAndroid Build Coastguard Worker           Opc == Mips::BnezRxImmX16   || Opc == Mips::BteqzX16 ||
424*9880d681SAndroid Build Coastguard Worker           Opc == Mips::BteqzT8CmpX16  || Opc == Mips::BteqzT8CmpiX16 ||
425*9880d681SAndroid Build Coastguard Worker           Opc == Mips::BteqzT8SltX16  || Opc == Mips::BteqzT8SltuX16  ||
426*9880d681SAndroid Build Coastguard Worker           Opc == Mips::BteqzT8SltiX16 || Opc == Mips::BteqzT8SltiuX16 ||
427*9880d681SAndroid Build Coastguard Worker           Opc == Mips::BtnezX16       || Opc == Mips::BtnezT8CmpX16 ||
428*9880d681SAndroid Build Coastguard Worker           Opc == Mips::BtnezT8CmpiX16 || Opc == Mips::BtnezT8SltX16 ||
429*9880d681SAndroid Build Coastguard Worker           Opc == Mips::BtnezT8SltuX16 || Opc == Mips::BtnezT8SltiX16 ||
430*9880d681SAndroid Build Coastguard Worker           Opc == Mips::BtnezT8SltiuX16 ) ? Opc : 0;
431*9880d681SAndroid Build Coastguard Worker }
432*9880d681SAndroid Build Coastguard Worker 
ExpandRetRA16(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,unsigned Opc) const433*9880d681SAndroid Build Coastguard Worker void Mips16InstrInfo::ExpandRetRA16(MachineBasicBlock &MBB,
434*9880d681SAndroid Build Coastguard Worker                                   MachineBasicBlock::iterator I,
435*9880d681SAndroid Build Coastguard Worker                                   unsigned Opc) const {
436*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, I, I->getDebugLoc(), get(Opc));
437*9880d681SAndroid Build Coastguard Worker }
438*9880d681SAndroid Build Coastguard Worker 
AddiuSpImm(int64_t Imm) const439*9880d681SAndroid Build Coastguard Worker const MCInstrDesc &Mips16InstrInfo::AddiuSpImm(int64_t Imm) const {
440*9880d681SAndroid Build Coastguard Worker   if (validSpImm8(Imm))
441*9880d681SAndroid Build Coastguard Worker     return get(Mips::AddiuSpImm16);
442*9880d681SAndroid Build Coastguard Worker   else
443*9880d681SAndroid Build Coastguard Worker     return get(Mips::AddiuSpImmX16);
444*9880d681SAndroid Build Coastguard Worker }
445*9880d681SAndroid Build Coastguard Worker 
BuildAddiuSpImm(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,int64_t Imm) const446*9880d681SAndroid Build Coastguard Worker void Mips16InstrInfo::BuildAddiuSpImm
447*9880d681SAndroid Build Coastguard Worker   (MachineBasicBlock &MBB, MachineBasicBlock::iterator I, int64_t Imm) const {
448*9880d681SAndroid Build Coastguard Worker   DebugLoc DL;
449*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, I, DL, AddiuSpImm(Imm)).addImm(Imm);
450*9880d681SAndroid Build Coastguard Worker }
451*9880d681SAndroid Build Coastguard Worker 
createMips16InstrInfo(const MipsSubtarget & STI)452*9880d681SAndroid Build Coastguard Worker const MipsInstrInfo *llvm::createMips16InstrInfo(const MipsSubtarget &STI) {
453*9880d681SAndroid Build Coastguard Worker   return new Mips16InstrInfo(STI);
454*9880d681SAndroid Build Coastguard Worker }
455*9880d681SAndroid Build Coastguard Worker 
validImmediate(unsigned Opcode,unsigned Reg,int64_t Amount)456*9880d681SAndroid Build Coastguard Worker bool Mips16InstrInfo::validImmediate(unsigned Opcode, unsigned Reg,
457*9880d681SAndroid Build Coastguard Worker                                      int64_t Amount) {
458*9880d681SAndroid Build Coastguard Worker   switch (Opcode) {
459*9880d681SAndroid Build Coastguard Worker   case Mips::LbRxRyOffMemX16:
460*9880d681SAndroid Build Coastguard Worker   case Mips::LbuRxRyOffMemX16:
461*9880d681SAndroid Build Coastguard Worker   case Mips::LhRxRyOffMemX16:
462*9880d681SAndroid Build Coastguard Worker   case Mips::LhuRxRyOffMemX16:
463*9880d681SAndroid Build Coastguard Worker   case Mips::SbRxRyOffMemX16:
464*9880d681SAndroid Build Coastguard Worker   case Mips::ShRxRyOffMemX16:
465*9880d681SAndroid Build Coastguard Worker   case Mips::LwRxRyOffMemX16:
466*9880d681SAndroid Build Coastguard Worker   case Mips::SwRxRyOffMemX16:
467*9880d681SAndroid Build Coastguard Worker   case Mips::SwRxSpImmX16:
468*9880d681SAndroid Build Coastguard Worker   case Mips::LwRxSpImmX16:
469*9880d681SAndroid Build Coastguard Worker     return isInt<16>(Amount);
470*9880d681SAndroid Build Coastguard Worker   case Mips::AddiuRxRyOffMemX16:
471*9880d681SAndroid Build Coastguard Worker     if ((Reg == Mips::PC) || (Reg == Mips::SP))
472*9880d681SAndroid Build Coastguard Worker       return isInt<16>(Amount);
473*9880d681SAndroid Build Coastguard Worker     return isInt<15>(Amount);
474*9880d681SAndroid Build Coastguard Worker   }
475*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("unexpected Opcode in validImmediate");
476*9880d681SAndroid Build Coastguard Worker }
477*9880d681SAndroid Build Coastguard Worker 
478*9880d681SAndroid Build Coastguard Worker /// Measure the specified inline asm to determine an approximation of its
479*9880d681SAndroid Build Coastguard Worker /// length.
480*9880d681SAndroid Build Coastguard Worker /// Comments (which run till the next SeparatorString or newline) do not
481*9880d681SAndroid Build Coastguard Worker /// count as an instruction.
482*9880d681SAndroid Build Coastguard Worker /// Any other non-whitespace text is considered an instruction, with
483*9880d681SAndroid Build Coastguard Worker /// multiple instructions separated by SeparatorString or newlines.
484*9880d681SAndroid Build Coastguard Worker /// Variable-length instructions are not handled here; this function
485*9880d681SAndroid Build Coastguard Worker /// may be overloaded in the target code to do that.
486*9880d681SAndroid Build Coastguard Worker /// We implement the special case of the .space directive taking only an
487*9880d681SAndroid Build Coastguard Worker /// integer argument, which is the size in bytes. This is used for creating
488*9880d681SAndroid Build Coastguard Worker /// inline code spacing for testing purposes using inline assembly.
489*9880d681SAndroid Build Coastguard Worker ///
getInlineAsmLength(const char * Str,const MCAsmInfo & MAI) const490*9880d681SAndroid Build Coastguard Worker unsigned Mips16InstrInfo::getInlineAsmLength(const char *Str,
491*9880d681SAndroid Build Coastguard Worker                                              const MCAsmInfo &MAI) const {
492*9880d681SAndroid Build Coastguard Worker 
493*9880d681SAndroid Build Coastguard Worker   // Count the number of instructions in the asm.
494*9880d681SAndroid Build Coastguard Worker   bool atInsnStart = true;
495*9880d681SAndroid Build Coastguard Worker   unsigned Length = 0;
496*9880d681SAndroid Build Coastguard Worker   for (; *Str; ++Str) {
497*9880d681SAndroid Build Coastguard Worker     if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(),
498*9880d681SAndroid Build Coastguard Worker                                 strlen(MAI.getSeparatorString())) == 0)
499*9880d681SAndroid Build Coastguard Worker       atInsnStart = true;
500*9880d681SAndroid Build Coastguard Worker     if (atInsnStart && !std::isspace(static_cast<unsigned char>(*Str))) {
501*9880d681SAndroid Build Coastguard Worker       if (strncmp(Str, ".space", 6)==0) {
502*9880d681SAndroid Build Coastguard Worker         char *EStr; int Sz;
503*9880d681SAndroid Build Coastguard Worker         Sz = strtol(Str+6, &EStr, 10);
504*9880d681SAndroid Build Coastguard Worker         while (isspace(*EStr)) ++EStr;
505*9880d681SAndroid Build Coastguard Worker         if (*EStr=='\0') {
506*9880d681SAndroid Build Coastguard Worker           DEBUG(dbgs() << "parsed .space " << Sz << '\n');
507*9880d681SAndroid Build Coastguard Worker           return Sz;
508*9880d681SAndroid Build Coastguard Worker         }
509*9880d681SAndroid Build Coastguard Worker       }
510*9880d681SAndroid Build Coastguard Worker       Length += MAI.getMaxInstLength();
511*9880d681SAndroid Build Coastguard Worker       atInsnStart = false;
512*9880d681SAndroid Build Coastguard Worker     }
513*9880d681SAndroid Build Coastguard Worker     if (atInsnStart && strncmp(Str, MAI.getCommentString(),
514*9880d681SAndroid Build Coastguard Worker                                strlen(MAI.getCommentString())) == 0)
515*9880d681SAndroid Build Coastguard Worker       atInsnStart = false;
516*9880d681SAndroid Build Coastguard Worker   }
517*9880d681SAndroid Build Coastguard Worker 
518*9880d681SAndroid Build Coastguard Worker   return Length;
519*9880d681SAndroid Build Coastguard Worker }
520