LLVM API Documentation
00001 00002 //===-- Mips16InstrInfo.cpp - Mips16 Instruction Information --------------===// 00003 // 00004 // The LLVM Compiler Infrastructure 00005 // 00006 // This file is distributed under the University of Illinois Open Source 00007 // License. See LICENSE.TXT for details. 00008 // 00009 //===----------------------------------------------------------------------===// 00010 // 00011 // This file contains the Mips16 implementation of the TargetInstrInfo class. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 #include "Mips16InstrInfo.h" 00015 #include "InstPrinter/MipsInstPrinter.h" 00016 #include "MipsMachineFunction.h" 00017 #include "MipsTargetMachine.h" 00018 #include "llvm/ADT/STLExtras.h" 00019 #include "llvm/ADT/StringRef.h" 00020 #include "llvm/CodeGen/MachineInstrBuilder.h" 00021 #include "llvm/CodeGen/MachineRegisterInfo.h" 00022 #include "llvm/CodeGen/RegisterScavenging.h" 00023 #include "llvm/MC/MCAsmInfo.h" 00024 #include "llvm/Support/CommandLine.h" 00025 #include "llvm/Support/Debug.h" 00026 #include "llvm/Support/ErrorHandling.h" 00027 #include "llvm/Support/TargetRegistry.h" 00028 #include <cctype> 00029 00030 using namespace llvm; 00031 00032 #define DEBUG_TYPE "mips16-instrinfo" 00033 00034 Mips16InstrInfo::Mips16InstrInfo(const MipsSubtarget &STI) 00035 : MipsInstrInfo(STI, Mips::Bimm16), RI(STI) {} 00036 00037 const MipsRegisterInfo &Mips16InstrInfo::getRegisterInfo() const { 00038 return RI; 00039 } 00040 00041 /// isLoadFromStackSlot - If the specified machine instruction is a direct 00042 /// load from a stack slot, return the virtual or physical register number of 00043 /// the destination along with the FrameIndex of the loaded stack slot. If 00044 /// not, return 0. This predicate must return 0 if the instruction has 00045 /// any side effects other than loading from the stack slot. 00046 unsigned Mips16InstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 00047 int &FrameIndex) const { 00048 return 0; 00049 } 00050 00051 /// isStoreToStackSlot - If the specified machine instruction is a direct 00052 /// store to a stack slot, return the virtual or physical register number of 00053 /// the source reg along with the FrameIndex of the loaded stack slot. If 00054 /// not, return 0. This predicate must return 0 if the instruction has 00055 /// any side effects other than storing to the stack slot. 00056 unsigned Mips16InstrInfo::isStoreToStackSlot(const MachineInstr *MI, 00057 int &FrameIndex) const { 00058 return 0; 00059 } 00060 00061 void Mips16InstrInfo::copyPhysReg(MachineBasicBlock &MBB, 00062 MachineBasicBlock::iterator I, DebugLoc DL, 00063 unsigned DestReg, unsigned SrcReg, 00064 bool KillSrc) const { 00065 unsigned Opc = 0; 00066 00067 if (Mips::CPU16RegsRegClass.contains(DestReg) && 00068 Mips::GPR32RegClass.contains(SrcReg)) 00069 Opc = Mips::MoveR3216; 00070 else if (Mips::GPR32RegClass.contains(DestReg) && 00071 Mips::CPU16RegsRegClass.contains(SrcReg)) 00072 Opc = Mips::Move32R16; 00073 else if ((SrcReg == Mips::HI0) && 00074 (Mips::CPU16RegsRegClass.contains(DestReg))) 00075 Opc = Mips::Mfhi16, SrcReg = 0; 00076 00077 else if ((SrcReg == Mips::LO0) && 00078 (Mips::CPU16RegsRegClass.contains(DestReg))) 00079 Opc = Mips::Mflo16, SrcReg = 0; 00080 00081 00082 assert(Opc && "Cannot copy registers"); 00083 00084 MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc)); 00085 00086 if (DestReg) 00087 MIB.addReg(DestReg, RegState::Define); 00088 00089 if (SrcReg) 00090 MIB.addReg(SrcReg, getKillRegState(KillSrc)); 00091 } 00092 00093 void Mips16InstrInfo::storeRegToStack(MachineBasicBlock &MBB, 00094 MachineBasicBlock::iterator I, 00095 unsigned SrcReg, bool isKill, int FI, 00096 const TargetRegisterClass *RC, 00097 const TargetRegisterInfo *TRI, 00098 int64_t Offset) const { 00099 DebugLoc DL; 00100 if (I != MBB.end()) DL = I->getDebugLoc(); 00101 MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOStore); 00102 unsigned Opc = 0; 00103 if (Mips::CPU16RegsRegClass.hasSubClassEq(RC)) 00104 Opc = Mips::SwRxSpImmX16; 00105 assert(Opc && "Register class not handled!"); 00106 BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill)). 00107 addFrameIndex(FI).addImm(Offset) 00108 .addMemOperand(MMO); 00109 } 00110 00111 void Mips16InstrInfo::loadRegFromStack(MachineBasicBlock &MBB, 00112 MachineBasicBlock::iterator I, 00113 unsigned DestReg, int FI, 00114 const TargetRegisterClass *RC, 00115 const TargetRegisterInfo *TRI, 00116 int64_t Offset) const { 00117 DebugLoc DL; 00118 if (I != MBB.end()) DL = I->getDebugLoc(); 00119 MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad); 00120 unsigned Opc = 0; 00121 00122 if (Mips::CPU16RegsRegClass.hasSubClassEq(RC)) 00123 Opc = Mips::LwRxSpImmX16; 00124 assert(Opc && "Register class not handled!"); 00125 BuildMI(MBB, I, DL, get(Opc), DestReg).addFrameIndex(FI).addImm(Offset) 00126 .addMemOperand(MMO); 00127 } 00128 00129 bool Mips16InstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { 00130 MachineBasicBlock &MBB = *MI->getParent(); 00131 switch(MI->getDesc().getOpcode()) { 00132 default: 00133 return false; 00134 case Mips::RetRA16: 00135 ExpandRetRA16(MBB, MI, Mips::JrcRa16); 00136 break; 00137 } 00138 00139 MBB.erase(MI); 00140 return true; 00141 } 00142 00143 /// GetOppositeBranchOpc - Return the inverse of the specified 00144 /// opcode, e.g. turning BEQ to BNE. 00145 unsigned Mips16InstrInfo::getOppositeBranchOpc(unsigned Opc) const { 00146 switch (Opc) { 00147 default: llvm_unreachable("Illegal opcode!"); 00148 case Mips::BeqzRxImmX16: return Mips::BnezRxImmX16; 00149 case Mips::BnezRxImmX16: return Mips::BeqzRxImmX16; 00150 case Mips::BeqzRxImm16: return Mips::BnezRxImm16; 00151 case Mips::BnezRxImm16: return Mips::BeqzRxImm16; 00152 case Mips::BteqzT8CmpX16: return Mips::BtnezT8CmpX16; 00153 case Mips::BteqzT8SltX16: return Mips::BtnezT8SltX16; 00154 case Mips::BteqzT8SltiX16: return Mips::BtnezT8SltiX16; 00155 case Mips::Btnez16: return Mips::Bteqz16; 00156 case Mips::BtnezX16: return Mips::BteqzX16; 00157 case Mips::BtnezT8CmpiX16: return Mips::BteqzT8CmpiX16; 00158 case Mips::BtnezT8SltuX16: return Mips::BteqzT8SltuX16; 00159 case Mips::BtnezT8SltiuX16: return Mips::BteqzT8SltiuX16; 00160 case Mips::Bteqz16: return Mips::Btnez16; 00161 case Mips::BteqzX16: return Mips::BtnezX16; 00162 case Mips::BteqzT8CmpiX16: return Mips::BtnezT8CmpiX16; 00163 case Mips::BteqzT8SltuX16: return Mips::BtnezT8SltuX16; 00164 case Mips::BteqzT8SltiuX16: return Mips::BtnezT8SltiuX16; 00165 case Mips::BtnezT8CmpX16: return Mips::BteqzT8CmpX16; 00166 case Mips::BtnezT8SltX16: return Mips::BteqzT8SltX16; 00167 case Mips::BtnezT8SltiX16: return Mips::BteqzT8SltiX16; 00168 } 00169 assert(false && "Implement this function."); 00170 return 0; 00171 } 00172 00173 static void addSaveRestoreRegs(MachineInstrBuilder &MIB, 00174 const std::vector<CalleeSavedInfo> &CSI, 00175 unsigned Flags = 0) { 00176 for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 00177 // Add the callee-saved register as live-in. Do not add if the register is 00178 // RA and return address is taken, because it has already been added in 00179 // method MipsTargetLowering::LowerRETURNADDR. 00180 // It's killed at the spill, unless the register is RA and return address 00181 // is taken. 00182 unsigned Reg = CSI[e-i-1].getReg(); 00183 switch (Reg) { 00184 case Mips::RA: 00185 case Mips::S0: 00186 case Mips::S1: 00187 MIB.addReg(Reg, Flags); 00188 break; 00189 case Mips::S2: 00190 break; 00191 default: 00192 llvm_unreachable("unexpected mips16 callee saved register"); 00193 00194 } 00195 } 00196 } 00197 // Adjust SP by FrameSize bytes. Save RA, S0, S1 00198 void Mips16InstrInfo::makeFrame(unsigned SP, int64_t FrameSize, 00199 MachineBasicBlock &MBB, 00200 MachineBasicBlock::iterator I) const { 00201 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 00202 MachineFunction &MF = *MBB.getParent(); 00203 MachineFrameInfo *MFI = MF.getFrameInfo(); 00204 const BitVector Reserved = RI.getReservedRegs(MF); 00205 bool SaveS2 = Reserved[Mips::S2]; 00206 MachineInstrBuilder MIB; 00207 unsigned Opc = ((FrameSize <= 128) && !SaveS2)? Mips::Save16:Mips::SaveX16; 00208 MIB = BuildMI(MBB, I, DL, get(Opc)); 00209 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 00210 addSaveRestoreRegs(MIB, CSI); 00211 if (SaveS2) 00212 MIB.addReg(Mips::S2); 00213 if (isUInt<11>(FrameSize)) 00214 MIB.addImm(FrameSize); 00215 else { 00216 int Base = 2040; // should create template function like isUInt that 00217 // returns largest possible n bit unsigned integer 00218 int64_t Remainder = FrameSize - Base; 00219 MIB.addImm(Base); 00220 if (isInt<16>(-Remainder)) 00221 BuildAddiuSpImm(MBB, I, -Remainder); 00222 else 00223 adjustStackPtrBig(SP, -Remainder, MBB, I, Mips::V0, Mips::V1); 00224 } 00225 } 00226 00227 // Adjust SP by FrameSize bytes. Restore RA, S0, S1 00228 void Mips16InstrInfo::restoreFrame(unsigned SP, int64_t FrameSize, 00229 MachineBasicBlock &MBB, 00230 MachineBasicBlock::iterator I) const { 00231 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 00232 MachineFunction *MF = MBB.getParent(); 00233 MachineFrameInfo *MFI = MF->getFrameInfo(); 00234 const BitVector Reserved = RI.getReservedRegs(*MF); 00235 bool SaveS2 = Reserved[Mips::S2]; 00236 MachineInstrBuilder MIB; 00237 unsigned Opc = ((FrameSize <= 128) && !SaveS2)? 00238 Mips::Restore16:Mips::RestoreX16; 00239 00240 if (!isUInt<11>(FrameSize)) { 00241 unsigned Base = 2040; 00242 int64_t Remainder = FrameSize - Base; 00243 FrameSize = Base; // should create template function like isUInt that 00244 // returns largest possible n bit unsigned integer 00245 00246 if (isInt<16>(Remainder)) 00247 BuildAddiuSpImm(MBB, I, Remainder); 00248 else 00249 adjustStackPtrBig(SP, Remainder, MBB, I, Mips::A0, Mips::A1); 00250 } 00251 MIB = BuildMI(MBB, I, DL, get(Opc)); 00252 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 00253 addSaveRestoreRegs(MIB, CSI, RegState::Define); 00254 if (SaveS2) 00255 MIB.addReg(Mips::S2, RegState::Define); 00256 MIB.addImm(FrameSize); 00257 } 00258 00259 // Adjust SP by Amount bytes where bytes can be up to 32bit number. 00260 // This can only be called at times that we know that there is at least one free 00261 // register. 00262 // This is clearly safe at prologue and epilogue. 00263 // 00264 void Mips16InstrInfo::adjustStackPtrBig(unsigned SP, int64_t Amount, 00265 MachineBasicBlock &MBB, 00266 MachineBasicBlock::iterator I, 00267 unsigned Reg1, unsigned Reg2) const { 00268 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 00269 // 00270 // li reg1, constant 00271 // move reg2, sp 00272 // add reg1, reg1, reg2 00273 // move sp, reg1 00274 // 00275 // 00276 MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::LwConstant32), Reg1); 00277 MIB1.addImm(Amount).addImm(-1); 00278 MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::MoveR3216), Reg2); 00279 MIB2.addReg(Mips::SP, RegState::Kill); 00280 MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::AdduRxRyRz16), Reg1); 00281 MIB3.addReg(Reg1); 00282 MIB3.addReg(Reg2, RegState::Kill); 00283 MachineInstrBuilder MIB4 = BuildMI(MBB, I, DL, get(Mips::Move32R16), 00284 Mips::SP); 00285 MIB4.addReg(Reg1, RegState::Kill); 00286 } 00287 00288 void Mips16InstrInfo::adjustStackPtrBigUnrestricted( 00289 unsigned SP, int64_t Amount, MachineBasicBlock &MBB, 00290 MachineBasicBlock::iterator I) const { 00291 assert(false && "adjust stack pointer amount exceeded"); 00292 } 00293 00294 /// Adjust SP by Amount bytes. 00295 void Mips16InstrInfo::adjustStackPtr(unsigned SP, int64_t Amount, 00296 MachineBasicBlock &MBB, 00297 MachineBasicBlock::iterator I) const { 00298 if (isInt<16>(Amount)) // need to change to addiu sp, ....and isInt<16> 00299 BuildAddiuSpImm(MBB, I, Amount); 00300 else 00301 adjustStackPtrBigUnrestricted(SP, Amount, MBB, I); 00302 } 00303 00304 /// This function generates the sequence of instructions needed to get the 00305 /// result of adding register REG and immediate IMM. 00306 unsigned Mips16InstrInfo::loadImmediate(unsigned FrameReg, int64_t Imm, 00307 MachineBasicBlock &MBB, 00308 MachineBasicBlock::iterator II, 00309 DebugLoc DL, unsigned &NewImm) const { 00310 // 00311 // given original instruction is: 00312 // Instr rx, T[offset] where offset is too big. 00313 // 00314 // lo = offset & 0xFFFF 00315 // hi = ((offset >> 16) + (lo >> 15)) & 0xFFFF; 00316 // 00317 // let T = temporary register 00318 // li T, hi 00319 // shl T, 16 00320 // add T, Rx, T 00321 // 00322 RegScavenger rs; 00323 int32_t lo = Imm & 0xFFFF; 00324 NewImm = lo; 00325 int Reg =0; 00326 int SpReg = 0; 00327 00328 rs.enterBasicBlock(&MBB); 00329 rs.forward(II); 00330 // 00331 // We need to know which registers can be used, in the case where there 00332 // are not enough free registers. We exclude all registers that 00333 // are used in the instruction that we are helping. 00334 // // Consider all allocatable registers in the register class initially 00335 BitVector Candidates = 00336 RI.getAllocatableSet 00337 (*II->getParent()->getParent(), &Mips::CPU16RegsRegClass); 00338 // Exclude all the registers being used by the instruction. 00339 for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) { 00340 MachineOperand &MO = II->getOperand(i); 00341 if (MO.isReg() && MO.getReg() != 0 && !MO.isDef() && 00342 !TargetRegisterInfo::isVirtualRegister(MO.getReg())) 00343 Candidates.reset(MO.getReg()); 00344 } 00345 00346 // If the same register was used and defined in an instruction, then 00347 // it will not be in the list of candidates. 00348 // 00349 // we need to analyze the instruction that we are helping. 00350 // we need to know if it defines register x but register x is not 00351 // present as an operand of the instruction. this tells 00352 // whether the register is live before the instruction. if it's not 00353 // then we don't need to save it in case there are no free registers. 00354 int DefReg = 0; 00355 for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) { 00356 MachineOperand &MO = II->getOperand(i); 00357 if (MO.isReg() && MO.isDef()) { 00358 DefReg = MO.getReg(); 00359 break; 00360 } 00361 } 00362 00363 BitVector Available = rs.getRegsAvailable(&Mips::CPU16RegsRegClass); 00364 Available &= Candidates; 00365 // 00366 // we use T0 for the first register, if we need to save something away. 00367 // we use T1 for the second register, if we need to save something away. 00368 // 00369 unsigned FirstRegSaved =0, SecondRegSaved=0; 00370 unsigned FirstRegSavedTo = 0, SecondRegSavedTo = 0; 00371 00372 Reg = Available.find_first(); 00373 00374 if (Reg == -1) { 00375 Reg = Candidates.find_first(); 00376 Candidates.reset(Reg); 00377 if (DefReg != Reg) { 00378 FirstRegSaved = Reg; 00379 FirstRegSavedTo = Mips::T0; 00380 copyPhysReg(MBB, II, DL, FirstRegSavedTo, FirstRegSaved, true); 00381 } 00382 } 00383 else 00384 Available.reset(Reg); 00385 BuildMI(MBB, II, DL, get(Mips::LwConstant32), Reg).addImm(Imm).addImm(-1); 00386 NewImm = 0; 00387 if (FrameReg == Mips::SP) { 00388 SpReg = Available.find_first(); 00389 if (SpReg == -1) { 00390 SpReg = Candidates.find_first(); 00391 // Candidates.reset(SpReg); // not really needed 00392 if (DefReg!= SpReg) { 00393 SecondRegSaved = SpReg; 00394 SecondRegSavedTo = Mips::T1; 00395 } 00396 if (SecondRegSaved) 00397 copyPhysReg(MBB, II, DL, SecondRegSavedTo, SecondRegSaved, true); 00398 } 00399 else 00400 Available.reset(SpReg); 00401 copyPhysReg(MBB, II, DL, SpReg, Mips::SP, false); 00402 BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(SpReg, RegState::Kill) 00403 .addReg(Reg); 00404 } 00405 else 00406 BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(FrameReg) 00407 .addReg(Reg, RegState::Kill); 00408 if (FirstRegSaved || SecondRegSaved) { 00409 II = std::next(II); 00410 if (FirstRegSaved) 00411 copyPhysReg(MBB, II, DL, FirstRegSaved, FirstRegSavedTo, true); 00412 if (SecondRegSaved) 00413 copyPhysReg(MBB, II, DL, SecondRegSaved, SecondRegSavedTo, true); 00414 } 00415 return Reg; 00416 } 00417 00418 unsigned Mips16InstrInfo::getAnalyzableBrOpc(unsigned Opc) const { 00419 return (Opc == Mips::BeqzRxImmX16 || Opc == Mips::BimmX16 || 00420 Opc == Mips::Bimm16 || 00421 Opc == Mips::Bteqz16 || Opc == Mips::Btnez16 || 00422 Opc == Mips::BeqzRxImm16 || Opc == Mips::BnezRxImm16 || 00423 Opc == Mips::BnezRxImmX16 || Opc == Mips::BteqzX16 || 00424 Opc == Mips::BteqzT8CmpX16 || Opc == Mips::BteqzT8CmpiX16 || 00425 Opc == Mips::BteqzT8SltX16 || Opc == Mips::BteqzT8SltuX16 || 00426 Opc == Mips::BteqzT8SltiX16 || Opc == Mips::BteqzT8SltiuX16 || 00427 Opc == Mips::BtnezX16 || Opc == Mips::BtnezT8CmpX16 || 00428 Opc == Mips::BtnezT8CmpiX16 || Opc == Mips::BtnezT8SltX16 || 00429 Opc == Mips::BtnezT8SltuX16 || Opc == Mips::BtnezT8SltiX16 || 00430 Opc == Mips::BtnezT8SltiuX16 ) ? Opc : 0; 00431 } 00432 00433 void Mips16InstrInfo::ExpandRetRA16(MachineBasicBlock &MBB, 00434 MachineBasicBlock::iterator I, 00435 unsigned Opc) const { 00436 BuildMI(MBB, I, I->getDebugLoc(), get(Opc)); 00437 } 00438 00439 const MCInstrDesc &Mips16InstrInfo::AddiuSpImm(int64_t Imm) const { 00440 if (validSpImm8(Imm)) 00441 return get(Mips::AddiuSpImm16); 00442 else 00443 return get(Mips::AddiuSpImmX16); 00444 } 00445 00446 void Mips16InstrInfo::BuildAddiuSpImm 00447 (MachineBasicBlock &MBB, MachineBasicBlock::iterator I, int64_t Imm) const { 00448 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 00449 BuildMI(MBB, I, DL, AddiuSpImm(Imm)).addImm(Imm); 00450 } 00451 00452 const MipsInstrInfo *llvm::createMips16InstrInfo(const MipsSubtarget &STI) { 00453 return new Mips16InstrInfo(STI); 00454 } 00455 00456 bool Mips16InstrInfo::validImmediate(unsigned Opcode, unsigned Reg, 00457 int64_t Amount) { 00458 switch (Opcode) { 00459 case Mips::LbRxRyOffMemX16: 00460 case Mips::LbuRxRyOffMemX16: 00461 case Mips::LhRxRyOffMemX16: 00462 case Mips::LhuRxRyOffMemX16: 00463 case Mips::SbRxRyOffMemX16: 00464 case Mips::ShRxRyOffMemX16: 00465 case Mips::LwRxRyOffMemX16: 00466 case Mips::SwRxRyOffMemX16: 00467 case Mips::SwRxSpImmX16: 00468 case Mips::LwRxSpImmX16: 00469 return isInt<16>(Amount); 00470 case Mips::AddiuRxRyOffMemX16: 00471 if ((Reg == Mips::PC) || (Reg == Mips::SP)) 00472 return isInt<16>(Amount); 00473 return isInt<15>(Amount); 00474 } 00475 llvm_unreachable("unexpected Opcode in validImmediate"); 00476 } 00477 00478 /// Measure the specified inline asm to determine an approximation of its 00479 /// length. 00480 /// Comments (which run till the next SeparatorString or newline) do not 00481 /// count as an instruction. 00482 /// Any other non-whitespace text is considered an instruction, with 00483 /// multiple instructions separated by SeparatorString or newlines. 00484 /// Variable-length instructions are not handled here; this function 00485 /// may be overloaded in the target code to do that. 00486 /// We implement the special case of the .space directive taking only an 00487 /// integer argument, which is the size in bytes. This is used for creating 00488 /// inline code spacing for testing purposes using inline assembly. 00489 /// 00490 unsigned Mips16InstrInfo::getInlineAsmLength(const char *Str, 00491 const MCAsmInfo &MAI) const { 00492 00493 // Count the number of instructions in the asm. 00494 bool atInsnStart = true; 00495 unsigned Length = 0; 00496 for (; *Str; ++Str) { 00497 if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(), 00498 strlen(MAI.getSeparatorString())) == 0) 00499 atInsnStart = true; 00500 if (atInsnStart && !std::isspace(static_cast<unsigned char>(*Str))) { 00501 if (strncmp(Str, ".space", 6)==0) { 00502 char *EStr; int Sz; 00503 Sz = strtol(Str+6, &EStr, 10); 00504 while (isspace(*EStr)) ++EStr; 00505 if (*EStr=='\0') { 00506 DEBUG(dbgs() << "parsed .space " << Sz << '\n'); 00507 return Sz; 00508 } 00509 } 00510 Length += MAI.getMaxInstLength(); 00511 atInsnStart = false; 00512 } 00513 if (atInsnStart && strncmp(Str, MAI.getCommentString(), 00514 strlen(MAI.getCommentString())) == 0) 00515 atInsnStart = false; 00516 } 00517 00518 return Length; 00519 }