ARMBaseInstrInfo.cpp revision 83e0e36be8390fee1235783731f6c64aa604b7ee
1//===- ARMBaseInstrInfo.cpp - ARM Instruction Information -----------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains the Base ARM implementation of the TargetInstrInfo class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "ARMBaseInstrInfo.h" 15#include "ARM.h" 16#include "ARMAddressingModes.h" 17#include "ARMGenInstrInfo.inc" 18#include "ARMMachineFunctionInfo.h" 19#include "llvm/ADT/STLExtras.h" 20#include "llvm/CodeGen/LiveVariables.h" 21#include "llvm/CodeGen/MachineFrameInfo.h" 22#include "llvm/CodeGen/MachineInstrBuilder.h" 23#include "llvm/CodeGen/MachineJumpTableInfo.h" 24#include "llvm/Target/TargetAsmInfo.h" 25#include "llvm/Support/CommandLine.h" 26#include "llvm/Support/ErrorHandling.h" 27using namespace llvm; 28 29static cl::opt<bool> 30EnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden, 31 cl::desc("Enable ARM 2-addr to 3-addr conv")); 32 33ARMBaseInstrInfo::ARMBaseInstrInfo(const ARMSubtarget &sti) 34 : TargetInstrInfoImpl(ARMInsts, array_lengthof(ARMInsts)), 35 STI(sti) { 36} 37 38MachineInstr * 39ARMBaseInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, 40 MachineBasicBlock::iterator &MBBI, 41 LiveVariables *LV) const { 42 if (!EnableARM3Addr) 43 return NULL; 44 45 MachineInstr *MI = MBBI; 46 MachineFunction &MF = *MI->getParent()->getParent(); 47 unsigned TSFlags = MI->getDesc().TSFlags; 48 bool isPre = false; 49 switch ((TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift) { 50 default: return NULL; 51 case ARMII::IndexModePre: 52 isPre = true; 53 break; 54 case ARMII::IndexModePost: 55 break; 56 } 57 58 // Try splitting an indexed load/store to an un-indexed one plus an add/sub 59 // operation. 60 unsigned MemOpc = getUnindexedOpcode(MI->getOpcode()); 61 if (MemOpc == 0) 62 return NULL; 63 64 MachineInstr *UpdateMI = NULL; 65 MachineInstr *MemMI = NULL; 66 unsigned AddrMode = (TSFlags & ARMII::AddrModeMask); 67 const TargetInstrDesc &TID = MI->getDesc(); 68 unsigned NumOps = TID.getNumOperands(); 69 bool isLoad = !TID.mayStore(); 70 const MachineOperand &WB = isLoad ? MI->getOperand(1) : MI->getOperand(0); 71 const MachineOperand &Base = MI->getOperand(2); 72 const MachineOperand &Offset = MI->getOperand(NumOps-3); 73 unsigned WBReg = WB.getReg(); 74 unsigned BaseReg = Base.getReg(); 75 unsigned OffReg = Offset.getReg(); 76 unsigned OffImm = MI->getOperand(NumOps-2).getImm(); 77 ARMCC::CondCodes Pred = (ARMCC::CondCodes)MI->getOperand(NumOps-1).getImm(); 78 switch (AddrMode) { 79 default: 80 assert(false && "Unknown indexed op!"); 81 return NULL; 82 case ARMII::AddrMode2: { 83 bool isSub = ARM_AM::getAM2Op(OffImm) == ARM_AM::sub; 84 unsigned Amt = ARM_AM::getAM2Offset(OffImm); 85 if (OffReg == 0) { 86 if (ARM_AM::getSOImmVal(Amt) == -1) 87 // Can't encode it in a so_imm operand. This transformation will 88 // add more than 1 instruction. Abandon! 89 return NULL; 90 UpdateMI = BuildMI(MF, MI->getDebugLoc(), 91 get(isSub ? getOpcode(ARMII::SUBri) : 92 getOpcode(ARMII::ADDri)), WBReg) 93 .addReg(BaseReg).addImm(Amt) 94 .addImm(Pred).addReg(0).addReg(0); 95 } else if (Amt != 0) { 96 ARM_AM::ShiftOpc ShOpc = ARM_AM::getAM2ShiftOpc(OffImm); 97 unsigned SOOpc = ARM_AM::getSORegOpc(ShOpc, Amt); 98 UpdateMI = BuildMI(MF, MI->getDebugLoc(), 99 get(isSub ? getOpcode(ARMII::SUBrs) : 100 getOpcode(ARMII::ADDrs)), WBReg) 101 .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc) 102 .addImm(Pred).addReg(0).addReg(0); 103 } else 104 UpdateMI = BuildMI(MF, MI->getDebugLoc(), 105 get(isSub ? getOpcode(ARMII::SUBrr) : 106 getOpcode(ARMII::ADDrr)), WBReg) 107 .addReg(BaseReg).addReg(OffReg) 108 .addImm(Pred).addReg(0).addReg(0); 109 break; 110 } 111 case ARMII::AddrMode3 : { 112 bool isSub = ARM_AM::getAM3Op(OffImm) == ARM_AM::sub; 113 unsigned Amt = ARM_AM::getAM3Offset(OffImm); 114 if (OffReg == 0) 115 // Immediate is 8-bits. It's guaranteed to fit in a so_imm operand. 116 UpdateMI = BuildMI(MF, MI->getDebugLoc(), 117 get(isSub ? getOpcode(ARMII::SUBri) : 118 getOpcode(ARMII::ADDri)), WBReg) 119 .addReg(BaseReg).addImm(Amt) 120 .addImm(Pred).addReg(0).addReg(0); 121 else 122 UpdateMI = BuildMI(MF, MI->getDebugLoc(), 123 get(isSub ? getOpcode(ARMII::SUBrr) : 124 getOpcode(ARMII::ADDrr)), WBReg) 125 .addReg(BaseReg).addReg(OffReg) 126 .addImm(Pred).addReg(0).addReg(0); 127 break; 128 } 129 } 130 131 std::vector<MachineInstr*> NewMIs; 132 if (isPre) { 133 if (isLoad) 134 MemMI = BuildMI(MF, MI->getDebugLoc(), 135 get(MemOpc), MI->getOperand(0).getReg()) 136 .addReg(WBReg).addReg(0).addImm(0).addImm(Pred); 137 else 138 MemMI = BuildMI(MF, MI->getDebugLoc(), 139 get(MemOpc)).addReg(MI->getOperand(1).getReg()) 140 .addReg(WBReg).addReg(0).addImm(0).addImm(Pred); 141 NewMIs.push_back(MemMI); 142 NewMIs.push_back(UpdateMI); 143 } else { 144 if (isLoad) 145 MemMI = BuildMI(MF, MI->getDebugLoc(), 146 get(MemOpc), MI->getOperand(0).getReg()) 147 .addReg(BaseReg).addReg(0).addImm(0).addImm(Pred); 148 else 149 MemMI = BuildMI(MF, MI->getDebugLoc(), 150 get(MemOpc)).addReg(MI->getOperand(1).getReg()) 151 .addReg(BaseReg).addReg(0).addImm(0).addImm(Pred); 152 if (WB.isDead()) 153 UpdateMI->getOperand(0).setIsDead(); 154 NewMIs.push_back(UpdateMI); 155 NewMIs.push_back(MemMI); 156 } 157 158 // Transfer LiveVariables states, kill / dead info. 159 if (LV) { 160 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 161 MachineOperand &MO = MI->getOperand(i); 162 if (MO.isReg() && MO.getReg() && 163 TargetRegisterInfo::isVirtualRegister(MO.getReg())) { 164 unsigned Reg = MO.getReg(); 165 166 LiveVariables::VarInfo &VI = LV->getVarInfo(Reg); 167 if (MO.isDef()) { 168 MachineInstr *NewMI = (Reg == WBReg) ? UpdateMI : MemMI; 169 if (MO.isDead()) 170 LV->addVirtualRegisterDead(Reg, NewMI); 171 } 172 if (MO.isUse() && MO.isKill()) { 173 for (unsigned j = 0; j < 2; ++j) { 174 // Look at the two new MI's in reverse order. 175 MachineInstr *NewMI = NewMIs[j]; 176 if (!NewMI->readsRegister(Reg)) 177 continue; 178 LV->addVirtualRegisterKilled(Reg, NewMI); 179 if (VI.removeKill(MI)) 180 VI.Kills.push_back(NewMI); 181 break; 182 } 183 } 184 } 185 } 186 } 187 188 MFI->insert(MBBI, NewMIs[1]); 189 MFI->insert(MBBI, NewMIs[0]); 190 return NewMIs[0]; 191} 192 193// Branch analysis. 194bool 195ARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB, 196 MachineBasicBlock *&FBB, 197 SmallVectorImpl<MachineOperand> &Cond, 198 bool AllowModify) const { 199 // If the block has no terminators, it just falls into the block after it. 200 MachineBasicBlock::iterator I = MBB.end(); 201 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) 202 return false; 203 204 // Get the last instruction in the block. 205 MachineInstr *LastInst = I; 206 207 // If there is only one terminator instruction, process it. 208 unsigned LastOpc = LastInst->getOpcode(); 209 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 210 if (isUncondBranchOpcode(LastOpc)) { 211 TBB = LastInst->getOperand(0).getMBB(); 212 return false; 213 } 214 if (isCondBranchOpcode(LastOpc)) { 215 // Block ends with fall-through condbranch. 216 TBB = LastInst->getOperand(0).getMBB(); 217 Cond.push_back(LastInst->getOperand(1)); 218 Cond.push_back(LastInst->getOperand(2)); 219 return false; 220 } 221 return true; // Can't handle indirect branch. 222 } 223 224 // Get the instruction before it if it is a terminator. 225 MachineInstr *SecondLastInst = I; 226 227 // If there are three terminators, we don't know what sort of block this is. 228 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I)) 229 return true; 230 231 // If the block ends with a B and a Bcc, handle it. 232 unsigned SecondLastOpc = SecondLastInst->getOpcode(); 233 if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 234 TBB = SecondLastInst->getOperand(0).getMBB(); 235 Cond.push_back(SecondLastInst->getOperand(1)); 236 Cond.push_back(SecondLastInst->getOperand(2)); 237 FBB = LastInst->getOperand(0).getMBB(); 238 return false; 239 } 240 241 // If the block ends with two unconditional branches, handle it. The second 242 // one is not executed, so remove it. 243 if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 244 TBB = SecondLastInst->getOperand(0).getMBB(); 245 I = LastInst; 246 if (AllowModify) 247 I->eraseFromParent(); 248 return false; 249 } 250 251 // ...likewise if it ends with a branch table followed by an unconditional 252 // branch. The branch folder can create these, and we must get rid of them for 253 // correctness of Thumb constant islands. 254 if (isJumpTableBranchOpcode(SecondLastOpc) && 255 isUncondBranchOpcode(LastOpc)) { 256 I = LastInst; 257 if (AllowModify) 258 I->eraseFromParent(); 259 return true; 260 } 261 262 // Otherwise, can't handle this. 263 return true; 264} 265 266 267unsigned ARMBaseInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 268 MachineBasicBlock::iterator I = MBB.end(); 269 if (I == MBB.begin()) return 0; 270 --I; 271 if (!isUncondBranchOpcode(I->getOpcode()) && 272 !isCondBranchOpcode(I->getOpcode())) 273 return 0; 274 275 // Remove the branch. 276 I->eraseFromParent(); 277 278 I = MBB.end(); 279 280 if (I == MBB.begin()) return 1; 281 --I; 282 if (!isCondBranchOpcode(I->getOpcode())) 283 return 1; 284 285 // Remove the branch. 286 I->eraseFromParent(); 287 return 2; 288} 289 290unsigned 291ARMBaseInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 292 MachineBasicBlock *FBB, 293 const SmallVectorImpl<MachineOperand> &Cond) const { 294 // FIXME this should probably have a DebugLoc argument 295 DebugLoc dl = DebugLoc::getUnknownLoc(); 296 int BOpc = !STI.isThumb() 297 ? ARM::B : (STI.isThumb2() ? ARM::t2B : ARM::tB); 298 int BccOpc = !STI.isThumb() 299 ? ARM::Bcc : (STI.isThumb2() ? ARM::t2Bcc : ARM::tBcc); 300 301 // Shouldn't be a fall through. 302 assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 303 assert((Cond.size() == 2 || Cond.size() == 0) && 304 "ARM branch conditions have two components!"); 305 306 if (FBB == 0) { 307 if (Cond.empty()) // Unconditional branch? 308 BuildMI(&MBB, dl, get(BOpc)).addMBB(TBB); 309 else 310 BuildMI(&MBB, dl, get(BccOpc)).addMBB(TBB) 311 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()); 312 return 1; 313 } 314 315 // Two-way conditional branch. 316 BuildMI(&MBB, dl, get(BccOpc)).addMBB(TBB) 317 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()); 318 BuildMI(&MBB, dl, get(BOpc)).addMBB(FBB); 319 return 2; 320} 321 322bool ARMBaseInstrInfo:: 323ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 324 ARMCC::CondCodes CC = (ARMCC::CondCodes)(int)Cond[0].getImm(); 325 Cond[0].setImm(ARMCC::getOppositeCondition(CC)); 326 return false; 327} 328 329bool ARMBaseInstrInfo:: 330PredicateInstruction(MachineInstr *MI, 331 const SmallVectorImpl<MachineOperand> &Pred) const { 332 unsigned Opc = MI->getOpcode(); 333 if (isUncondBranchOpcode(Opc)) { 334 MI->setDesc(get(getMatchingCondBranchOpcode(Opc))); 335 MI->addOperand(MachineOperand::CreateImm(Pred[0].getImm())); 336 MI->addOperand(MachineOperand::CreateReg(Pred[1].getReg(), false)); 337 return true; 338 } 339 340 int PIdx = MI->findFirstPredOperandIdx(); 341 if (PIdx != -1) { 342 MachineOperand &PMO = MI->getOperand(PIdx); 343 PMO.setImm(Pred[0].getImm()); 344 MI->getOperand(PIdx+1).setReg(Pred[1].getReg()); 345 return true; 346 } 347 return false; 348} 349 350bool ARMBaseInstrInfo:: 351SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1, 352 const SmallVectorImpl<MachineOperand> &Pred2) const { 353 if (Pred1.size() > 2 || Pred2.size() > 2) 354 return false; 355 356 ARMCC::CondCodes CC1 = (ARMCC::CondCodes)Pred1[0].getImm(); 357 ARMCC::CondCodes CC2 = (ARMCC::CondCodes)Pred2[0].getImm(); 358 if (CC1 == CC2) 359 return true; 360 361 switch (CC1) { 362 default: 363 return false; 364 case ARMCC::AL: 365 return true; 366 case ARMCC::HS: 367 return CC2 == ARMCC::HI; 368 case ARMCC::LS: 369 return CC2 == ARMCC::LO || CC2 == ARMCC::EQ; 370 case ARMCC::GE: 371 return CC2 == ARMCC::GT; 372 case ARMCC::LE: 373 return CC2 == ARMCC::LT; 374 } 375} 376 377bool ARMBaseInstrInfo::DefinesPredicate(MachineInstr *MI, 378 std::vector<MachineOperand> &Pred) const { 379 const TargetInstrDesc &TID = MI->getDesc(); 380 if (!TID.getImplicitDefs() && !TID.hasOptionalDef()) 381 return false; 382 383 bool Found = false; 384 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 385 const MachineOperand &MO = MI->getOperand(i); 386 if (MO.isReg() && MO.getReg() == ARM::CPSR) { 387 Pred.push_back(MO); 388 Found = true; 389 } 390 } 391 392 return Found; 393} 394 395 396/// FIXME: Works around a gcc miscompilation with -fstrict-aliasing 397static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT, 398 unsigned JTI) DISABLE_INLINE; 399static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT, 400 unsigned JTI) { 401 return JT[JTI].MBBs.size(); 402} 403 404/// GetInstSize - Return the size of the specified MachineInstr. 405/// 406unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { 407 const MachineBasicBlock &MBB = *MI->getParent(); 408 const MachineFunction *MF = MBB.getParent(); 409 const TargetAsmInfo *TAI = MF->getTarget().getTargetAsmInfo(); 410 411 // Basic size info comes from the TSFlags field. 412 const TargetInstrDesc &TID = MI->getDesc(); 413 unsigned TSFlags = TID.TSFlags; 414 415 switch ((TSFlags & ARMII::SizeMask) >> ARMII::SizeShift) { 416 default: { 417 // If this machine instr is an inline asm, measure it. 418 if (MI->getOpcode() == ARM::INLINEASM) 419 return TAI->getInlineAsmLength(MI->getOperand(0).getSymbolName()); 420 if (MI->isLabel()) 421 return 0; 422 switch (MI->getOpcode()) { 423 default: 424 llvm_unreachable("Unknown or unset size field for instr!"); 425 case TargetInstrInfo::IMPLICIT_DEF: 426 case TargetInstrInfo::DECLARE: 427 case TargetInstrInfo::DBG_LABEL: 428 case TargetInstrInfo::EH_LABEL: 429 return 0; 430 } 431 break; 432 } 433 case ARMII::Size8Bytes: return 8; // ARM instruction x 2. 434 case ARMII::Size4Bytes: return 4; // ARM / Thumb2 instruction. 435 case ARMII::Size2Bytes: return 2; // Thumb1 instruction. 436 case ARMII::SizeSpecial: { 437 bool IsThumb1JT = false; 438 switch (MI->getOpcode()) { 439 case ARM::CONSTPOOL_ENTRY: 440 // If this machine instr is a constant pool entry, its size is recorded as 441 // operand #2. 442 return MI->getOperand(2).getImm(); 443 case ARM::Int_eh_sjlj_setjmp: 444 return 12; 445 case ARM::tBR_JTr: 446 IsThumb1JT = true; 447 // Fallthrough 448 case ARM::BR_JTr: 449 case ARM::BR_JTm: 450 case ARM::BR_JTadd: 451 case ARM::t2BR_JT: { 452 // These are jumptable branches, i.e. a branch followed by an inlined 453 // jumptable. The size is 4 + 4 * number of entries. 454 unsigned NumOps = TID.getNumOperands(); 455 MachineOperand JTOP = 456 MI->getOperand(NumOps - (TID.isPredicable() ? 3 : 2)); 457 unsigned JTI = JTOP.getIndex(); 458 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 459 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 460 assert(JTI < JT.size()); 461 // Thumb instructions are 2 byte aligned, but JT entries are 4 byte 462 // 4 aligned. The assembler / linker may add 2 byte padding just before 463 // the JT entries. The size does not include this padding; the 464 // constant islands pass does separate bookkeeping for it. 465 // FIXME: If we know the size of the function is less than (1 << 16) *2 466 // bytes, we can use 16-bit entries instead. Then there won't be an 467 // alignment issue. 468 return getNumJTEntries(JT, JTI) * 4 + (IsThumb1JT ? 2 : 4); 469 } 470 default: 471 // Otherwise, pseudo-instruction sizes are zero. 472 return 0; 473 } 474 } 475 } 476 return 0; // Not reached 477} 478 479/// Return true if the instruction is a register to register move and 480/// leave the source and dest operands in the passed parameters. 481/// 482bool 483ARMBaseInstrInfo::isMoveInstr(const MachineInstr &MI, 484 unsigned &SrcReg, unsigned &DstReg, 485 unsigned& SrcSubIdx, unsigned& DstSubIdx) const { 486 SrcSubIdx = DstSubIdx = 0; // No sub-registers. 487 488 switch (MI.getOpcode()) { 489 default: break; 490 case ARM::FCPYS: 491 case ARM::FCPYD: 492 case ARM::VMOVD: 493 case ARM::VMOVQ: { 494 SrcReg = MI.getOperand(1).getReg(); 495 DstReg = MI.getOperand(0).getReg(); 496 return true; 497 } 498 case ARM::MOVr: 499 case ARM::tMOVr: 500 case ARM::tMOVgpr2tgpr: 501 case ARM::tMOVtgpr2gpr: 502 case ARM::tMOVgpr2gpr: 503 case ARM::t2MOVr: { 504 assert(MI.getDesc().getNumOperands() >= 2 && 505 MI.getOperand(0).isReg() && 506 MI.getOperand(1).isReg() && 507 "Invalid ARM MOV instruction"); 508 SrcReg = MI.getOperand(1).getReg(); 509 DstReg = MI.getOperand(0).getReg(); 510 return true; 511 } 512 } 513 514 return false; 515} 516 517unsigned 518ARMBaseInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 519 int &FrameIndex) const { 520 switch (MI->getOpcode()) { 521 default: break; 522 case ARM::LDR: 523 case ARM::t2LDRs: // FIXME: don't use t2LDRs to access frame. 524 if (MI->getOperand(1).isFI() && 525 MI->getOperand(2).isReg() && 526 MI->getOperand(3).isImm() && 527 MI->getOperand(2).getReg() == 0 && 528 MI->getOperand(3).getImm() == 0) { 529 FrameIndex = MI->getOperand(1).getIndex(); 530 return MI->getOperand(0).getReg(); 531 } 532 break; 533 case ARM::t2LDRi12: 534 case ARM::tRestore: 535 if (MI->getOperand(1).isFI() && 536 MI->getOperand(2).isImm() && 537 MI->getOperand(2).getImm() == 0) { 538 FrameIndex = MI->getOperand(1).getIndex(); 539 return MI->getOperand(0).getReg(); 540 } 541 break; 542 case ARM::FLDD: 543 case ARM::FLDS: 544 if (MI->getOperand(1).isFI() && 545 MI->getOperand(2).isImm() && 546 MI->getOperand(2).getImm() == 0) { 547 FrameIndex = MI->getOperand(1).getIndex(); 548 return MI->getOperand(0).getReg(); 549 } 550 break; 551 } 552 553 return 0; 554} 555 556unsigned 557ARMBaseInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 558 int &FrameIndex) const { 559 switch (MI->getOpcode()) { 560 default: break; 561 case ARM::STR: 562 case ARM::t2STRs: // FIXME: don't use t2STRs to access frame. 563 if (MI->getOperand(1).isFI() && 564 MI->getOperand(2).isReg() && 565 MI->getOperand(3).isImm() && 566 MI->getOperand(2).getReg() == 0 && 567 MI->getOperand(3).getImm() == 0) { 568 FrameIndex = MI->getOperand(1).getIndex(); 569 return MI->getOperand(0).getReg(); 570 } 571 break; 572 case ARM::t2STRi12: 573 case ARM::tSpill: 574 if (MI->getOperand(1).isFI() && 575 MI->getOperand(2).isImm() && 576 MI->getOperand(2).getImm() == 0) { 577 FrameIndex = MI->getOperand(1).getIndex(); 578 return MI->getOperand(0).getReg(); 579 } 580 break; 581 case ARM::FSTD: 582 case ARM::FSTS: 583 if (MI->getOperand(1).isFI() && 584 MI->getOperand(2).isImm() && 585 MI->getOperand(2).getImm() == 0) { 586 FrameIndex = MI->getOperand(1).getIndex(); 587 return MI->getOperand(0).getReg(); 588 } 589 break; 590 } 591 592 return 0; 593} 594 595bool 596ARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB, 597 MachineBasicBlock::iterator I, 598 unsigned DestReg, unsigned SrcReg, 599 const TargetRegisterClass *DestRC, 600 const TargetRegisterClass *SrcRC) const { 601 DebugLoc DL = DebugLoc::getUnknownLoc(); 602 if (I != MBB.end()) DL = I->getDebugLoc(); 603 604 if (DestRC != SrcRC) { 605 // Not yet supported! 606 return false; 607 } 608 609 if (DestRC == ARM::GPRRegisterClass) 610 AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr), 611 DestReg).addReg(SrcReg))); 612 else if (DestRC == ARM::SPRRegisterClass) 613 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYS), DestReg) 614 .addReg(SrcReg)); 615 else if (DestRC == ARM::DPRRegisterClass) 616 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYD), DestReg) 617 .addReg(SrcReg)); 618 else if (DestRC == ARM::QPRRegisterClass) 619 BuildMI(MBB, I, DL, get(ARM::VMOVQ), DestReg).addReg(SrcReg); 620 else 621 return false; 622 623 return true; 624} 625 626void ARMBaseInstrInfo:: 627storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 628 unsigned SrcReg, bool isKill, int FI, 629 const TargetRegisterClass *RC) const { 630 DebugLoc DL = DebugLoc::getUnknownLoc(); 631 if (I != MBB.end()) DL = I->getDebugLoc(); 632 633 if (RC == ARM::GPRRegisterClass) { 634 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR)) 635 .addReg(SrcReg, getKillRegState(isKill)) 636 .addFrameIndex(FI).addReg(0).addImm(0)); 637 } else if (RC == ARM::DPRRegisterClass) { 638 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTD)) 639 .addReg(SrcReg, getKillRegState(isKill)) 640 .addFrameIndex(FI).addImm(0)); 641 } else { 642 assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); 643 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTS)) 644 .addReg(SrcReg, getKillRegState(isKill)) 645 .addFrameIndex(FI).addImm(0)); 646 } 647} 648 649void ARMBaseInstrInfo:: 650loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 651 unsigned DestReg, int FI, 652 const TargetRegisterClass *RC) const { 653 DebugLoc DL = DebugLoc::getUnknownLoc(); 654 if (I != MBB.end()) DL = I->getDebugLoc(); 655 656 if (RC == ARM::GPRRegisterClass) { 657 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDR), DestReg) 658 .addFrameIndex(FI).addReg(0).addImm(0)); 659 } else if (RC == ARM::DPRRegisterClass) { 660 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDD), DestReg) 661 .addFrameIndex(FI).addImm(0)); 662 } else { 663 assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); 664 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDS), DestReg) 665 .addFrameIndex(FI).addImm(0)); 666 } 667} 668 669MachineInstr *ARMBaseInstrInfo:: 670foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, 671 const SmallVectorImpl<unsigned> &Ops, int FI) const { 672 if (Ops.size() != 1) return NULL; 673 674 unsigned OpNum = Ops[0]; 675 unsigned Opc = MI->getOpcode(); 676 MachineInstr *NewMI = NULL; 677 if (Opc == ARM::MOVr || Opc == ARM::t2MOVr) { 678 // If it is updating CPSR, then it cannot be folded. 679 if (MI->getOperand(4).getReg() != ARM::CPSR || MI->getOperand(4).isDead()) { 680 unsigned Pred = MI->getOperand(2).getImm(); 681 unsigned PredReg = MI->getOperand(3).getReg(); 682 if (OpNum == 0) { // move -> store 683 unsigned SrcReg = MI->getOperand(1).getReg(); 684 bool isKill = MI->getOperand(1).isKill(); 685 bool isUndef = MI->getOperand(1).isUndef(); 686 if (Opc == ARM::MOVr) 687 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::STR)) 688 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)) 689 .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg); 690 else // ARM::t2MOVr 691 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::t2STRi12)) 692 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)) 693 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); 694 } else { // move -> load 695 unsigned DstReg = MI->getOperand(0).getReg(); 696 bool isDead = MI->getOperand(0).isDead(); 697 bool isUndef = MI->getOperand(0).isUndef(); 698 if (Opc == ARM::MOVr) 699 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::LDR)) 700 .addReg(DstReg, 701 RegState::Define | 702 getDeadRegState(isDead) | 703 getUndefRegState(isUndef)) 704 .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg); 705 else // ARM::t2MOVr 706 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::t2LDRi12)) 707 .addReg(DstReg, 708 RegState::Define | 709 getDeadRegState(isDead) | 710 getUndefRegState(isUndef)) 711 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); 712 } 713 } 714 } 715 else if (Opc == ARM::FCPYS) { 716 unsigned Pred = MI->getOperand(2).getImm(); 717 unsigned PredReg = MI->getOperand(3).getReg(); 718 if (OpNum == 0) { // move -> store 719 unsigned SrcReg = MI->getOperand(1).getReg(); 720 bool isKill = MI->getOperand(1).isKill(); 721 bool isUndef = MI->getOperand(1).isUndef(); 722 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FSTS)) 723 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)) 724 .addFrameIndex(FI) 725 .addImm(0).addImm(Pred).addReg(PredReg); 726 } else { // move -> load 727 unsigned DstReg = MI->getOperand(0).getReg(); 728 bool isDead = MI->getOperand(0).isDead(); 729 bool isUndef = MI->getOperand(0).isUndef(); 730 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDS)) 731 .addReg(DstReg, 732 RegState::Define | 733 getDeadRegState(isDead) | 734 getUndefRegState(isUndef)) 735 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); 736 } 737 } 738 else if (Opc == ARM::FCPYD) { 739 unsigned Pred = MI->getOperand(2).getImm(); 740 unsigned PredReg = MI->getOperand(3).getReg(); 741 if (OpNum == 0) { // move -> store 742 unsigned SrcReg = MI->getOperand(1).getReg(); 743 bool isKill = MI->getOperand(1).isKill(); 744 bool isUndef = MI->getOperand(1).isUndef(); 745 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FSTD)) 746 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)) 747 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); 748 } else { // move -> load 749 unsigned DstReg = MI->getOperand(0).getReg(); 750 bool isDead = MI->getOperand(0).isDead(); 751 bool isUndef = MI->getOperand(0).isUndef(); 752 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDD)) 753 .addReg(DstReg, 754 RegState::Define | 755 getDeadRegState(isDead) | 756 getUndefRegState(isUndef)) 757 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); 758 } 759 } 760 761 return NewMI; 762} 763 764MachineInstr* 765ARMBaseInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, 766 MachineInstr* MI, 767 const SmallVectorImpl<unsigned> &Ops, 768 MachineInstr* LoadMI) const { 769 // FIXME 770 return 0; 771} 772 773bool 774ARMBaseInstrInfo::canFoldMemoryOperand(const MachineInstr *MI, 775 const SmallVectorImpl<unsigned> &Ops) const { 776 if (Ops.size() != 1) return false; 777 778 unsigned Opc = MI->getOpcode(); 779 if (Opc == ARM::MOVr || Opc == ARM::t2MOVr) { 780 // If it is updating CPSR, then it cannot be folded. 781 return MI->getOperand(4).getReg() != ARM::CPSR ||MI->getOperand(4).isDead(); 782 } else if (Opc == ARM::FCPYS || Opc == ARM::FCPYD) { 783 return true; 784 } else if (Opc == ARM::VMOVD || Opc == ARM::VMOVQ) { 785 return false; // FIXME 786 } 787 788 return false; 789} 790 791int ARMBaseInstrInfo::getMatchingCondBranchOpcode(int Opc) const { 792 if (Opc == ARM::B) 793 return ARM::Bcc; 794 else if (Opc == ARM::tB) 795 return ARM::tBcc; 796 else if (Opc == ARM::t2B) 797 return ARM::t2Bcc; 798 799 llvm_unreachable("Unknown unconditional branch opcode!"); 800 return 0; 801} 802 803