LLVM API Documentation
00001 //===- ARMInstrInfo.cpp - ARM Instruction Information -----------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains the ARM implementation of the TargetInstrInfo class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "ARMInstrInfo.h" 00015 #include "ARM.h" 00016 #include "ARMAddressingModes.h" 00017 #include "ARMGenInstrInfo.inc" 00018 #include "ARMMachineFunctionInfo.h" 00019 #include "llvm/ADT/STLExtras.h" 00020 #include "llvm/CodeGen/LiveVariables.h" 00021 #include "llvm/CodeGen/MachineFrameInfo.h" 00022 #include "llvm/CodeGen/MachineInstrBuilder.h" 00023 #include "llvm/CodeGen/MachineJumpTableInfo.h" 00024 #include "llvm/Target/TargetAsmInfo.h" 00025 #include "llvm/Support/CommandLine.h" 00026 using namespace llvm; 00027 00028 static cl::opt<bool> EnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden, 00029 cl::desc("Enable ARM 2-addr to 3-addr conv")); 00030 00031 static inline 00032 const MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) { 00033 return MIB.addImm((int64_t)ARMCC::AL).addReg(0); 00034 } 00035 00036 static inline 00037 const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) { 00038 return MIB.addReg(0); 00039 } 00040 00041 ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI) 00042 : TargetInstrInfoImpl(ARMInsts, array_lengthof(ARMInsts)), 00043 RI(*this, STI) { 00044 } 00045 00046 const TargetRegisterClass *ARMInstrInfo::getPointerRegClass() const { 00047 return &ARM::GPRRegClass; 00048 } 00049 00050 /// Return true if the instruction is a register to register move and 00051 /// leave the source and dest operands in the passed parameters. 00052 /// 00053 bool ARMInstrInfo::isMoveInstr(const MachineInstr &MI, 00054 unsigned &SrcReg, unsigned &DstReg) const { 00055 unsigned oc = MI.getOpcode(); 00056 switch (oc) { 00057 default: 00058 return false; 00059 case ARM::FCPYS: 00060 case ARM::FCPYD: 00061 SrcReg = MI.getOperand(1).getReg(); 00062 DstReg = MI.getOperand(0).getReg(); 00063 return true; 00064 case ARM::MOVr: 00065 case ARM::tMOVr: 00066 assert(MI.getDesc().getNumOperands() >= 2 && 00067 MI.getOperand(0).isReg() && 00068 MI.getOperand(1).isReg() && 00069 "Invalid ARM MOV instruction"); 00070 SrcReg = MI.getOperand(1).getReg(); 00071 DstReg = MI.getOperand(0).getReg(); 00072 return true; 00073 } 00074 } 00075 00076 unsigned ARMInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 00077 int &FrameIndex) const { 00078 switch (MI->getOpcode()) { 00079 default: break; 00080 case ARM::LDR: 00081 if (MI->getOperand(1).isFI() && 00082 MI->getOperand(2).isReg() && 00083 MI->getOperand(3).isImm() && 00084 MI->getOperand(2).getReg() == 0 && 00085 MI->getOperand(3).getImm() == 0) { 00086 FrameIndex = MI->getOperand(1).getIndex(); 00087 return MI->getOperand(0).getReg(); 00088 } 00089 break; 00090 case ARM::FLDD: 00091 case ARM::FLDS: 00092 if (MI->getOperand(1).isFI() && 00093 MI->getOperand(2).isImm() && 00094 MI->getOperand(2).getImm() == 0) { 00095 FrameIndex = MI->getOperand(1).getIndex(); 00096 return MI->getOperand(0).getReg(); 00097 } 00098 break; 00099 case ARM::tRestore: 00100 if (MI->getOperand(1).isFI() && 00101 MI->getOperand(2).isImm() && 00102 MI->getOperand(2).getImm() == 0) { 00103 FrameIndex = MI->getOperand(1).getIndex(); 00104 return MI->getOperand(0).getReg(); 00105 } 00106 break; 00107 } 00108 return 0; 00109 } 00110 00111 unsigned ARMInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 00112 int &FrameIndex) const { 00113 switch (MI->getOpcode()) { 00114 default: break; 00115 case ARM::STR: 00116 if (MI->getOperand(1).isFI() && 00117 MI->getOperand(2).isReg() && 00118 MI->getOperand(3).isImm() && 00119 MI->getOperand(2).getReg() == 0 && 00120 MI->getOperand(3).getImm() == 0) { 00121 FrameIndex = MI->getOperand(1).getIndex(); 00122 return MI->getOperand(0).getReg(); 00123 } 00124 break; 00125 case ARM::FSTD: 00126 case ARM::FSTS: 00127 if (MI->getOperand(1).isFI() && 00128 MI->getOperand(2).isImm() && 00129 MI->getOperand(2).getImm() == 0) { 00130 FrameIndex = MI->getOperand(1).getIndex(); 00131 return MI->getOperand(0).getReg(); 00132 } 00133 break; 00134 case ARM::tSpill: 00135 if (MI->getOperand(1).isFI() && 00136 MI->getOperand(2).isImm() && 00137 MI->getOperand(2).getImm() == 0) { 00138 FrameIndex = MI->getOperand(1).getIndex(); 00139 return MI->getOperand(0).getReg(); 00140 } 00141 break; 00142 } 00143 return 0; 00144 } 00145 00146 void ARMInstrInfo::reMaterialize(MachineBasicBlock &MBB, 00147 MachineBasicBlock::iterator I, 00148 unsigned DestReg, 00149 const MachineInstr *Orig) const { 00150 if (Orig->getOpcode() == ARM::MOVi2pieces) { 00151 RI.emitLoadConstPool(MBB, I, DestReg, Orig->getOperand(1).getImm(), 00152 Orig->getOperand(2).getImm(), 00153 Orig->getOperand(3).getReg(), this, false); 00154 return; 00155 } 00156 00157 MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig); 00158 MI->getOperand(0).setReg(DestReg); 00159 MBB.insert(I, MI); 00160 } 00161 00162 static unsigned getUnindexedOpcode(unsigned Opc) { 00163 switch (Opc) { 00164 default: break; 00165 case ARM::LDR_PRE: 00166 case ARM::LDR_POST: 00167 return ARM::LDR; 00168 case ARM::LDRH_PRE: 00169 case ARM::LDRH_POST: 00170 return ARM::LDRH; 00171 case ARM::LDRB_PRE: 00172 case ARM::LDRB_POST: 00173 return ARM::LDRB; 00174 case ARM::LDRSH_PRE: 00175 case ARM::LDRSH_POST: 00176 return ARM::LDRSH; 00177 case ARM::LDRSB_PRE: 00178 case ARM::LDRSB_POST: 00179 return ARM::LDRSB; 00180 case ARM::STR_PRE: 00181 case ARM::STR_POST: 00182 return ARM::STR; 00183 case ARM::STRH_PRE: 00184 case ARM::STRH_POST: 00185 return ARM::STRH; 00186 case ARM::STRB_PRE: 00187 case ARM::STRB_POST: 00188 return ARM::STRB; 00189 } 00190 return 0; 00191 } 00192 00193 MachineInstr * 00194 ARMInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, 00195 MachineBasicBlock::iterator &MBBI, 00196 LiveVariables *LV) const { 00197 if (!EnableARM3Addr) 00198 return NULL; 00199 00200 MachineInstr *MI = MBBI; 00201 MachineFunction &MF = *MI->getParent()->getParent(); 00202 unsigned TSFlags = MI->getDesc().TSFlags; 00203 bool isPre = false; 00204 switch ((TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift) { 00205 default: return NULL; 00206 case ARMII::IndexModePre: 00207 isPre = true; 00208 break; 00209 case ARMII::IndexModePost: 00210 break; 00211 } 00212 00213 // Try spliting an indexed load / store to a un-indexed one plus an add/sub 00214 // operation. 00215 unsigned MemOpc = getUnindexedOpcode(MI->getOpcode()); 00216 if (MemOpc == 0) 00217 return NULL; 00218 00219 MachineInstr *UpdateMI = NULL; 00220 MachineInstr *MemMI = NULL; 00221 unsigned AddrMode = (TSFlags & ARMII::AddrModeMask); 00222 const TargetInstrDesc &TID = MI->getDesc(); 00223 unsigned NumOps = TID.getNumOperands(); 00224 bool isLoad = !TID.mayStore(); 00225 const MachineOperand &WB = isLoad ? MI->getOperand(1) : MI->getOperand(0); 00226 const MachineOperand &Base = MI->getOperand(2); 00227 const MachineOperand &Offset = MI->getOperand(NumOps-3); 00228 unsigned WBReg = WB.getReg(); 00229 unsigned BaseReg = Base.getReg(); 00230 unsigned OffReg = Offset.getReg(); 00231 unsigned OffImm = MI->getOperand(NumOps-2).getImm(); 00232 ARMCC::CondCodes Pred = (ARMCC::CondCodes)MI->getOperand(NumOps-1).getImm(); 00233 switch (AddrMode) { 00234 default: 00235 assert(false && "Unknown indexed op!"); 00236 return NULL; 00237 case ARMII::AddrMode2: { 00238 bool isSub = ARM_AM::getAM2Op(OffImm) == ARM_AM::sub; 00239 unsigned Amt = ARM_AM::getAM2Offset(OffImm); 00240 if (OffReg == 0) { 00241 int SOImmVal = ARM_AM::getSOImmVal(Amt); 00242 if (SOImmVal == -1) 00243 // Can't encode it in a so_imm operand. This transformation will 00244 // add more than 1 instruction. Abandon! 00245 return NULL; 00246 UpdateMI = BuildMI(MF, get(isSub ? ARM::SUBri : ARM::ADDri), WBReg) 00247 .addReg(BaseReg).addImm(SOImmVal) 00248 .addImm(Pred).addReg(0).addReg(0); 00249 } else if (Amt != 0) { 00250 ARM_AM::ShiftOpc ShOpc = ARM_AM::getAM2ShiftOpc(OffImm); 00251 unsigned SOOpc = ARM_AM::getSORegOpc(ShOpc, Amt); 00252 UpdateMI = BuildMI(MF, get(isSub ? ARM::SUBrs : ARM::ADDrs), WBReg) 00253 .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc) 00254 .addImm(Pred).addReg(0).addReg(0); 00255 } else 00256 UpdateMI = BuildMI(MF, get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg) 00257 .addReg(BaseReg).addReg(OffReg) 00258 .addImm(Pred).addReg(0).addReg(0); 00259 break; 00260 } 00261 case ARMII::AddrMode3 : { 00262 bool isSub = ARM_AM::getAM3Op(OffImm) == ARM_AM::sub; 00263 unsigned Amt = ARM_AM::getAM3Offset(OffImm); 00264 if (OffReg == 0) 00265 // Immediate is 8-bits. It's guaranteed to fit in a so_imm operand. 00266 UpdateMI = BuildMI(MF, get(isSub ? ARM::SUBri : ARM::ADDri), WBReg) 00267 .addReg(BaseReg).addImm(Amt) 00268 .addImm(Pred).addReg(0).addReg(0); 00269 else 00270 UpdateMI = BuildMI(MF, get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg) 00271 .addReg(BaseReg).addReg(OffReg) 00272 .addImm(Pred).addReg(0).addReg(0); 00273 break; 00274 } 00275 } 00276 00277 std::vector<MachineInstr*> NewMIs; 00278 if (isPre) { 00279 if (isLoad) 00280 MemMI = BuildMI(MF, get(MemOpc), MI->getOperand(0).getReg()) 00281 .addReg(WBReg).addReg(0).addImm(0).addImm(Pred); 00282 else 00283 MemMI = BuildMI(MF, get(MemOpc)).addReg(MI->getOperand(1).getReg()) 00284 .addReg(WBReg).addReg(0).addImm(0).addImm(Pred); 00285 NewMIs.push_back(MemMI); 00286 NewMIs.push_back(UpdateMI); 00287 } else { 00288 if (isLoad) 00289 MemMI = BuildMI(MF, get(MemOpc), MI->getOperand(0).getReg()) 00290 .addReg(BaseReg).addReg(0).addImm(0).addImm(Pred); 00291 else 00292 MemMI = BuildMI(MF, get(MemOpc)).addReg(MI->getOperand(1).getReg()) 00293 .addReg(BaseReg).addReg(0).addImm(0).addImm(Pred); 00294 if (WB.isDead()) 00295 UpdateMI->getOperand(0).setIsDead(); 00296 NewMIs.push_back(UpdateMI); 00297 NewMIs.push_back(MemMI); 00298 } 00299 00300 // Transfer LiveVariables states, kill / dead info. 00301 if (LV) { 00302 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 00303 MachineOperand &MO = MI->getOperand(i); 00304 if (MO.isReg() && MO.getReg() && 00305 TargetRegisterInfo::isVirtualRegister(MO.getReg())) { 00306 unsigned Reg = MO.getReg(); 00307 00308 LiveVariables::VarInfo &VI = LV->getVarInfo(Reg); 00309 if (MO.isDef()) { 00310 MachineInstr *NewMI = (Reg == WBReg) ? UpdateMI : MemMI; 00311 if (MO.isDead()) 00312 LV->addVirtualRegisterDead(Reg, NewMI); 00313 } 00314 if (MO.isUse() && MO.isKill()) { 00315 for (unsigned j = 0; j < 2; ++j) { 00316 // Look at the two new MI's in reverse order. 00317 MachineInstr *NewMI = NewMIs[j]; 00318 if (!NewMI->readsRegister(Reg)) 00319 continue; 00320 LV->addVirtualRegisterKilled(Reg, NewMI); 00321 if (VI.removeKill(MI)) 00322 VI.Kills.push_back(NewMI); 00323 break; 00324 } 00325 } 00326 } 00327 } 00328 } 00329 00330 MFI->insert(MBBI, NewMIs[1]); 00331 MFI->insert(MBBI, NewMIs[0]); 00332 return NewMIs[0]; 00333 } 00334 00335 // Branch analysis. 00336 bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB, 00337 MachineBasicBlock *&FBB, 00338 SmallVectorImpl<MachineOperand> &Cond) const { 00339 // If the block has no terminators, it just falls into the block after it. 00340 MachineBasicBlock::iterator I = MBB.end(); 00341 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) 00342 return false; 00343 00344 // Get the last instruction in the block. 00345 MachineInstr *LastInst = I; 00346 00347 // If there is only one terminator instruction, process it. 00348 unsigned LastOpc = LastInst->getOpcode(); 00349 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 00350 if (LastOpc == ARM::B || LastOpc == ARM::tB) { 00351 TBB = LastInst->getOperand(0).getMBB(); 00352 return false; 00353 } 00354 if (LastOpc == ARM::Bcc || LastOpc == ARM::tBcc) { 00355 // Block ends with fall-through condbranch. 00356 TBB = LastInst->getOperand(0).getMBB(); 00357 Cond.push_back(LastInst->getOperand(1)); 00358 Cond.push_back(LastInst->getOperand(2)); 00359 return false; 00360 } 00361 return true; // Can't handle indirect branch. 00362 } 00363 00364 // Get the instruction before it if it is a terminator. 00365 MachineInstr *SecondLastInst = I; 00366 00367 // If there are three terminators, we don't know what sort of block this is. 00368 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I)) 00369 return true; 00370 00371 // If the block ends with ARM::B/ARM::tB and a ARM::Bcc/ARM::tBcc, handle it. 00372 unsigned SecondLastOpc = SecondLastInst->getOpcode(); 00373 if ((SecondLastOpc == ARM::Bcc && LastOpc == ARM::B) || 00374 (SecondLastOpc == ARM::tBcc && LastOpc == ARM::tB)) { 00375 TBB = SecondLastInst->getOperand(0).getMBB(); 00376 Cond.push_back(SecondLastInst->getOperand(1)); 00377 Cond.push_back(SecondLastInst->getOperand(2)); 00378 FBB = LastInst->getOperand(0).getMBB(); 00379 return false; 00380 } 00381 00382 // If the block ends with two unconditional branches, handle it. The second 00383 // one is not executed, so remove it. 00384 if ((SecondLastOpc == ARM::B || SecondLastOpc==ARM::tB) && 00385 (LastOpc == ARM::B || LastOpc == ARM::tB)) { 00386 TBB = SecondLastInst->getOperand(0).getMBB(); 00387 I = LastInst; 00388 I->eraseFromParent(); 00389 return false; 00390 } 00391 00392 // Likewise if it ends with a branch table followed by an unconditional branch. 00393 // The branch folder can create these, and we must get rid of them for 00394 // correctness of Thumb constant islands. 00395 if ((SecondLastOpc == ARM::BR_JTr || SecondLastOpc==ARM::BR_JTm || 00396 SecondLastOpc == ARM::BR_JTadd || SecondLastOpc==ARM::tBR_JTr) && 00397 (LastOpc == ARM::B || LastOpc == ARM::tB)) { 00398 I = LastInst; 00399 I->eraseFromParent(); 00400 return true; 00401 } 00402 00403 // Otherwise, can't handle this. 00404 return true; 00405 } 00406 00407 00408 unsigned ARMInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 00409 MachineFunction &MF = *MBB.getParent(); 00410 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 00411 int BOpc = AFI->isThumbFunction() ? ARM::tB : ARM::B; 00412 int BccOpc = AFI->isThumbFunction() ? ARM::tBcc : ARM::Bcc; 00413 00414 MachineBasicBlock::iterator I = MBB.end(); 00415 if (I == MBB.begin()) return 0; 00416 --I; 00417 if (I->getOpcode() != BOpc && I->getOpcode() != BccOpc) 00418 return 0; 00419 00420 // Remove the branch. 00421 I->eraseFromParent(); 00422 00423 I = MBB.end(); 00424 00425 if (I == MBB.begin()) return 1; 00426 --I; 00427 if (I->getOpcode() != BccOpc) 00428 return 1; 00429 00430 // Remove the branch. 00431 I->eraseFromParent(); 00432 return 2; 00433 } 00434 00435 unsigned ARMInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 00436 MachineBasicBlock *FBB, 00437 const SmallVectorImpl<MachineOperand> &Cond) const { 00438 MachineFunction &MF = *MBB.getParent(); 00439 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 00440 int BOpc = AFI->isThumbFunction() ? ARM::tB : ARM::B; 00441 int BccOpc = AFI->isThumbFunction() ? ARM::tBcc : ARM::Bcc; 00442 00443 // Shouldn't be a fall through. 00444 assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 00445 assert((Cond.size() == 2 || Cond.size() == 0) && 00446 "ARM branch conditions have two components!"); 00447 00448 if (FBB == 0) { 00449 if (Cond.empty()) // Unconditional branch? 00450 BuildMI(&MBB, get(BOpc)).addMBB(TBB); 00451 else 00452 BuildMI(&MBB, get(BccOpc)).addMBB(TBB) 00453 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()); 00454 return 1; 00455 } 00456 00457 // Two-way conditional branch. 00458 BuildMI(&MBB, get(BccOpc)).addMBB(TBB) 00459 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()); 00460 BuildMI(&MBB, get(BOpc)).addMBB(FBB); 00461 return 2; 00462 } 00463 00464 bool ARMInstrInfo::copyRegToReg(MachineBasicBlock &MBB, 00465 MachineBasicBlock::iterator I, 00466 unsigned DestReg, unsigned SrcReg, 00467 const TargetRegisterClass *DestRC, 00468 const TargetRegisterClass *SrcRC) const { 00469 if (DestRC != SrcRC) { 00470 // Not yet supported! 00471 return false; 00472 } 00473 00474 if (DestRC == ARM::GPRRegisterClass) { 00475 MachineFunction &MF = *MBB.getParent(); 00476 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 00477 if (AFI->isThumbFunction()) 00478 BuildMI(MBB, I, get(ARM::tMOVr), DestReg).addReg(SrcReg); 00479 else 00480 AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, get(ARM::MOVr), DestReg) 00481 .addReg(SrcReg))); 00482 } else if (DestRC == ARM::SPRRegisterClass) 00483 AddDefaultPred(BuildMI(MBB, I, get(ARM::FCPYS), DestReg) 00484 .addReg(SrcReg)); 00485 else if (DestRC == ARM::DPRRegisterClass) 00486 AddDefaultPred(BuildMI(MBB, I, get(ARM::FCPYD), DestReg) 00487 .addReg(SrcReg)); 00488 else 00489 return false; 00490 00491 return true; 00492 } 00493 00494 static const MachineInstrBuilder &ARMInstrAddOperand(MachineInstrBuilder &MIB, 00495 MachineOperand &MO) { 00496 if (MO.isReg()) 00497 MIB = MIB.addReg(MO.getReg(), MO.isDef(), MO.isImplicit()); 00498 else if (MO.isImm()) 00499 MIB = MIB.addImm(MO.getImm()); 00500 else if (MO.isFI()) 00501 MIB = MIB.addFrameIndex(MO.getIndex()); 00502 else 00503 assert(0 && "Unknown operand for ARMInstrAddOperand!"); 00504 00505 return MIB; 00506 } 00507 00508 void ARMInstrInfo:: 00509 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 00510 unsigned SrcReg, bool isKill, int FI, 00511 const TargetRegisterClass *RC) const { 00512 if (RC == ARM::GPRRegisterClass) { 00513 MachineFunction &MF = *MBB.getParent(); 00514 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 00515 if (AFI->isThumbFunction()) 00516 BuildMI(MBB, I, get(ARM::tSpill)).addReg(SrcReg, false, false, isKill) 00517 .addFrameIndex(FI).addImm(0); 00518 else 00519 AddDefaultPred(BuildMI(MBB, I, get(ARM::STR)) 00520 .addReg(SrcReg, false, false, isKill) 00521 .addFrameIndex(FI).addReg(0).addImm(0)); 00522 } else if (RC == ARM::DPRRegisterClass) { 00523 AddDefaultPred(BuildMI(MBB, I, get(ARM::FSTD)) 00524 .addReg(SrcReg, false, false, isKill) 00525 .addFrameIndex(FI).addImm(0)); 00526 } else { 00527 assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); 00528 AddDefaultPred(BuildMI(MBB, I, get(ARM::FSTS)) 00529 .addReg(SrcReg, false, false, isKill) 00530 .addFrameIndex(FI).addImm(0)); 00531 } 00532 } 00533 00534 void ARMInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, 00535 bool isKill, 00536 SmallVectorImpl<MachineOperand> &Addr, 00537 const TargetRegisterClass *RC, 00538 SmallVectorImpl<MachineInstr*> &NewMIs) const { 00539 unsigned Opc = 0; 00540 if (RC == ARM::GPRRegisterClass) { 00541 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 00542 if (AFI->isThumbFunction()) { 00543 Opc = Addr[0].isFI() ? ARM::tSpill : ARM::tSTR; 00544 MachineInstrBuilder MIB = 00545 BuildMI(MF, get(Opc)).addReg(SrcReg, false, false, isKill); 00546 for (unsigned i = 0, e = Addr.size(); i != e; ++i) 00547 MIB = ARMInstrAddOperand(MIB, Addr[i]); 00548 NewMIs.push_back(MIB); 00549 return; 00550 } 00551 Opc = ARM::STR; 00552 } else if (RC == ARM::DPRRegisterClass) { 00553 Opc = ARM::FSTD; 00554 } else { 00555 assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); 00556 Opc = ARM::FSTS; 00557 } 00558 00559 MachineInstrBuilder MIB = 00560 BuildMI(MF, get(Opc)).addReg(SrcReg, false, false, isKill); 00561 for (unsigned i = 0, e = Addr.size(); i != e; ++i) 00562 MIB = ARMInstrAddOperand(MIB, Addr[i]); 00563 AddDefaultPred(MIB); 00564 NewMIs.push_back(MIB); 00565 return; 00566 } 00567 00568 void ARMInstrInfo:: 00569 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 00570 unsigned DestReg, int FI, 00571 const TargetRegisterClass *RC) const { 00572 if (RC == ARM::GPRRegisterClass) { 00573 MachineFunction &MF = *MBB.getParent(); 00574 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 00575 if (AFI->isThumbFunction()) 00576 BuildMI(MBB, I, get(ARM::tRestore), DestReg) 00577 .addFrameIndex(FI).addImm(0); 00578 else 00579 AddDefaultPred(BuildMI(MBB, I, get(ARM::LDR), DestReg) 00580 .addFrameIndex(FI).addReg(0).addImm(0)); 00581 } else if (RC == ARM::DPRRegisterClass) { 00582 AddDefaultPred(BuildMI(MBB, I, get(ARM::FLDD), DestReg) 00583 .addFrameIndex(FI).addImm(0)); 00584 } else { 00585 assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); 00586 AddDefaultPred(BuildMI(MBB, I, get(ARM::FLDS), DestReg) 00587 .addFrameIndex(FI).addImm(0)); 00588 } 00589 } 00590 00591 void ARMInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, 00592 SmallVectorImpl<MachineOperand> &Addr, 00593 const TargetRegisterClass *RC, 00594 SmallVectorImpl<MachineInstr*> &NewMIs) const { 00595 unsigned Opc = 0; 00596 if (RC == ARM::GPRRegisterClass) { 00597 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 00598 if (AFI->isThumbFunction()) { 00599 Opc = Addr[0].isFI() ? ARM::tRestore : ARM::tLDR; 00600 MachineInstrBuilder MIB = BuildMI(MF, get(Opc), DestReg); 00601 for (unsigned i = 0, e = Addr.size(); i != e; ++i) 00602 MIB = ARMInstrAddOperand(MIB, Addr[i]); 00603 NewMIs.push_back(MIB); 00604 return; 00605 } 00606 Opc = ARM::LDR; 00607 } else if (RC == ARM::DPRRegisterClass) { 00608 Opc = ARM::FLDD; 00609 } else { 00610 assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); 00611 Opc = ARM::FLDS; 00612 } 00613 00614 MachineInstrBuilder MIB = BuildMI(MF, get(Opc), DestReg); 00615 for (unsigned i = 0, e = Addr.size(); i != e; ++i) 00616 MIB = ARMInstrAddOperand(MIB, Addr[i]); 00617 AddDefaultPred(MIB); 00618 NewMIs.push_back(MIB); 00619 return; 00620 } 00621 00622 bool ARMInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB, 00623 MachineBasicBlock::iterator MI, 00624 const std::vector<CalleeSavedInfo> &CSI) const { 00625 MachineFunction &MF = *MBB.getParent(); 00626 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 00627 if (!AFI->isThumbFunction() || CSI.empty()) 00628 return false; 00629 00630 MachineInstrBuilder MIB = BuildMI(MBB, MI, get(ARM::tPUSH)); 00631 for (unsigned i = CSI.size(); i != 0; --i) { 00632 unsigned Reg = CSI[i-1].getReg(); 00633 // Add the callee-saved register as live-in. It's killed at the spill. 00634 MBB.addLiveIn(Reg); 00635 MIB.addReg(Reg, false/*isDef*/,false/*isImp*/,true/*isKill*/); 00636 } 00637 return true; 00638 } 00639 00640 bool ARMInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 00641 MachineBasicBlock::iterator MI, 00642 const std::vector<CalleeSavedInfo> &CSI) const { 00643 MachineFunction &MF = *MBB.getParent(); 00644 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 00645 if (!AFI->isThumbFunction() || CSI.empty()) 00646 return false; 00647 00648 bool isVarArg = AFI->getVarArgsRegSaveSize() > 0; 00649 MachineInstr *PopMI = MF.CreateMachineInstr(get(ARM::tPOP)); 00650 MBB.insert(MI, PopMI); 00651 for (unsigned i = CSI.size(); i != 0; --i) { 00652 unsigned Reg = CSI[i-1].getReg(); 00653 if (Reg == ARM::LR) { 00654 // Special epilogue for vararg functions. See emitEpilogue 00655 if (isVarArg) 00656 continue; 00657 Reg = ARM::PC; 00658 PopMI->setDesc(get(ARM::tPOP_RET)); 00659 MBB.erase(MI); 00660 } 00661 PopMI->addOperand(MachineOperand::CreateReg(Reg, true)); 00662 } 00663 return true; 00664 } 00665 00666 MachineInstr *ARMInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, 00667 MachineInstr *MI, 00668 const SmallVectorImpl<unsigned> &Ops, 00669 int FI) const { 00670 if (Ops.size() != 1) return NULL; 00671 00672 unsigned OpNum = Ops[0]; 00673 unsigned Opc = MI->getOpcode(); 00674 MachineInstr *NewMI = NULL; 00675 switch (Opc) { 00676 default: break; 00677 case ARM::MOVr: { 00678 if (MI->getOperand(4).getReg() == ARM::CPSR) 00679 // If it is updating CPSR, then it cannot be foled. 00680 break; 00681 unsigned Pred = MI->getOperand(2).getImm(); 00682 unsigned PredReg = MI->getOperand(3).getReg(); 00683 if (OpNum == 0) { // move -> store 00684 unsigned SrcReg = MI->getOperand(1).getReg(); 00685 bool isKill = MI->getOperand(1).isKill(); 00686 NewMI = BuildMI(MF, get(ARM::STR)).addReg(SrcReg, false, false, isKill) 00687 .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg); 00688 } else { // move -> load 00689 unsigned DstReg = MI->getOperand(0).getReg(); 00690 bool isDead = MI->getOperand(0).isDead(); 00691 NewMI = BuildMI(MF, get(ARM::LDR)).addReg(DstReg, true, false, false, isDead) 00692 .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg); 00693 } 00694 break; 00695 } 00696 case ARM::tMOVr: { 00697 if (OpNum == 0) { // move -> store 00698 unsigned SrcReg = MI->getOperand(1).getReg(); 00699 bool isKill = MI->getOperand(1).isKill(); 00700 if (RI.isPhysicalRegister(SrcReg) && !RI.isLowRegister(SrcReg)) 00701 // tSpill cannot take a high register operand. 00702 break; 00703 NewMI = BuildMI(MF, get(ARM::tSpill)).addReg(SrcReg, false, false, isKill) 00704 .addFrameIndex(FI).addImm(0); 00705 } else { // move -> load 00706 unsigned DstReg = MI->getOperand(0).getReg(); 00707 if (RI.isPhysicalRegister(DstReg) && !RI.isLowRegister(DstReg)) 00708 // tRestore cannot target a high register operand. 00709 break; 00710 bool isDead = MI->getOperand(0).isDead(); 00711 NewMI = BuildMI(MF, get(ARM::tRestore)) 00712 .addReg(DstReg, true, false, false, isDead) 00713 .addFrameIndex(FI).addImm(0); 00714 } 00715 break; 00716 } 00717 case ARM::FCPYS: { 00718 unsigned Pred = MI->getOperand(2).getImm(); 00719 unsigned PredReg = MI->getOperand(3).getReg(); 00720 if (OpNum == 0) { // move -> store 00721 unsigned SrcReg = MI->getOperand(1).getReg(); 00722 NewMI = BuildMI(MF, get(ARM::FSTS)).addReg(SrcReg).addFrameIndex(FI) 00723 .addImm(0).addImm(Pred).addReg(PredReg); 00724 } else { // move -> load 00725 unsigned DstReg = MI->getOperand(0).getReg(); 00726 NewMI = BuildMI(MF, get(ARM::FLDS), DstReg).addFrameIndex(FI) 00727 .addImm(0).addImm(Pred).addReg(PredReg); 00728 } 00729 break; 00730 } 00731 case ARM::FCPYD: { 00732 unsigned Pred = MI->getOperand(2).getImm(); 00733 unsigned PredReg = MI->getOperand(3).getReg(); 00734 if (OpNum == 0) { // move -> store 00735 unsigned SrcReg = MI->getOperand(1).getReg(); 00736 bool isKill = MI->getOperand(1).isKill(); 00737 NewMI = BuildMI(MF, get(ARM::FSTD)).addReg(SrcReg, false, false, isKill) 00738 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); 00739 } else { // move -> load 00740 unsigned DstReg = MI->getOperand(0).getReg(); 00741 bool isDead = MI->getOperand(0).isDead(); 00742 NewMI = BuildMI(MF, get(ARM::FLDD)).addReg(DstReg, true, false, false, isDead) 00743 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); 00744 } 00745 break; 00746 } 00747 } 00748 00749 return NewMI; 00750 } 00751 00752 bool ARMInstrInfo::canFoldMemoryOperand(const MachineInstr *MI, 00753 const SmallVectorImpl<unsigned> &Ops) const { 00754 if (Ops.size() != 1) return false; 00755 00756 unsigned OpNum = Ops[0]; 00757 unsigned Opc = MI->getOpcode(); 00758 switch (Opc) { 00759 default: break; 00760 case ARM::MOVr: 00761 // If it is updating CPSR, then it cannot be foled. 00762 return MI->getOpera