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