1 //===-- Thumb2InstrInfo.cpp - Thumb-2 Instruction Information -------------===// 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 Thumb-2 implementation of the TargetInstrInfo class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "Thumb2InstrInfo.h" 15 #include "ARM.h" 16 #include "ARMConstantPoolValue.h" 17 #include "ARMMachineFunctionInfo.h" 18 #include "MCTargetDesc/ARMAddressingModes.h" 19 #include "llvm/CodeGen/MachineFrameInfo.h" 20 #include "llvm/CodeGen/MachineInstrBuilder.h" 21 #include "llvm/CodeGen/MachineMemOperand.h" 22 #include "llvm/MC/MCInst.h" 23 #include "llvm/Support/CommandLine.h" 24 25 using namespace llvm; 26 27 static cl::opt<bool> 28 OldT2IfCvt("old-thumb2-ifcvt", cl::Hidden, 29 cl::desc("Use old-style Thumb2 if-conversion heuristics"), 30 cl::init(false)); 31 32 Thumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget &STI) 33 : ARMBaseInstrInfo(STI), RI(*this, STI) { 34 } 35 36 /// getNoopForMachoTarget - Return the noop instruction to use for a noop. 37 void Thumb2InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const { 38 NopInst.setOpcode(ARM::tNOP); 39 NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 40 NopInst.addOperand(MCOperand::CreateReg(0)); 41 } 42 43 unsigned Thumb2InstrInfo::getUnindexedOpcode(unsigned Opc) const { 44 // FIXME 45 return 0; 46 } 47 48 void 49 Thumb2InstrInfo::ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail, 50 MachineBasicBlock *NewDest) const { 51 MachineBasicBlock *MBB = Tail->getParent(); 52 ARMFunctionInfo *AFI = MBB->getParent()->getInfo<ARMFunctionInfo>(); 53 if (!AFI->hasITBlocks()) { 54 TargetInstrInfoImpl::ReplaceTailWithBranchTo(Tail, NewDest); 55 return; 56 } 57 58 // If the first instruction of Tail is predicated, we may have to update 59 // the IT instruction. 60 unsigned PredReg = 0; 61 ARMCC::CondCodes CC = getInstrPredicate(Tail, PredReg); 62 MachineBasicBlock::iterator MBBI = Tail; 63 if (CC != ARMCC::AL) 64 // Expecting at least the t2IT instruction before it. 65 --MBBI; 66 67 // Actually replace the tail. 68 TargetInstrInfoImpl::ReplaceTailWithBranchTo(Tail, NewDest); 69 70 // Fix up IT. 71 if (CC != ARMCC::AL) { 72 MachineBasicBlock::iterator E = MBB->begin(); 73 unsigned Count = 4; // At most 4 instructions in an IT block. 74 while (Count && MBBI != E) { 75 if (MBBI->isDebugValue()) { 76 --MBBI; 77 continue; 78 } 79 if (MBBI->getOpcode() == ARM::t2IT) { 80 unsigned Mask = MBBI->getOperand(1).getImm(); 81 if (Count == 4) 82 MBBI->eraseFromParent(); 83 else { 84 unsigned MaskOn = 1 << Count; 85 unsigned MaskOff = ~(MaskOn - 1); 86 MBBI->getOperand(1).setImm((Mask & MaskOff) | MaskOn); 87 } 88 return; 89 } 90 --MBBI; 91 --Count; 92 } 93 94 // Ctrl flow can reach here if branch folding is run before IT block 95 // formation pass. 96 } 97 } 98 99 bool 100 Thumb2InstrInfo::isLegalToSplitMBBAt(MachineBasicBlock &MBB, 101 MachineBasicBlock::iterator MBBI) const { 102 while (MBBI->isDebugValue()) { 103 ++MBBI; 104 if (MBBI == MBB.end()) 105 return false; 106 } 107 108 unsigned PredReg = 0; 109 return getITInstrPredicate(MBBI, PredReg) == ARMCC::AL; 110 } 111 112 void Thumb2InstrInfo::copyPhysReg(MachineBasicBlock &MBB, 113 MachineBasicBlock::iterator I, DebugLoc DL, 114 unsigned DestReg, unsigned SrcReg, 115 bool KillSrc) const { 116 // Handle SPR, DPR, and QPR copies. 117 if (!ARM::GPRRegClass.contains(DestReg, SrcReg)) 118 return ARMBaseInstrInfo::copyPhysReg(MBB, I, DL, DestReg, SrcReg, KillSrc); 119 120 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg) 121 .addReg(SrcReg, getKillRegState(KillSrc))); 122 } 123 124 void Thumb2InstrInfo:: 125 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 126 unsigned SrcReg, bool isKill, int FI, 127 const TargetRegisterClass *RC, 128 const TargetRegisterInfo *TRI) const { 129 if (RC == ARM::GPRRegisterClass || RC == ARM::tGPRRegisterClass || 130 RC == ARM::tcGPRRegisterClass || RC == ARM::rGPRRegisterClass || 131 RC == ARM::GPRnopcRegisterClass) { 132 DebugLoc DL; 133 if (I != MBB.end()) DL = I->getDebugLoc(); 134 135 MachineFunction &MF = *MBB.getParent(); 136 MachineFrameInfo &MFI = *MF.getFrameInfo(); 137 MachineMemOperand *MMO = 138 MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI), 139 MachineMemOperand::MOStore, 140 MFI.getObjectSize(FI), 141 MFI.getObjectAlignment(FI)); 142 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::t2STRi12)) 143 .addReg(SrcReg, getKillRegState(isKill)) 144 .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); 145 return; 146 } 147 148 ARMBaseInstrInfo::storeRegToStackSlot(MBB, I, SrcReg, isKill, FI, RC, TRI); 149 } 150 151 void Thumb2InstrInfo:: 152 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 153 unsigned DestReg, int FI, 154 const TargetRegisterClass *RC, 155 const TargetRegisterInfo *TRI) const { 156 if (RC == ARM::GPRRegisterClass || RC == ARM::tGPRRegisterClass || 157 RC == ARM::tcGPRRegisterClass || RC == ARM::rGPRRegisterClass || 158 RC == ARM::GPRnopcRegisterClass) { 159 DebugLoc DL; 160 if (I != MBB.end()) DL = I->getDebugLoc(); 161 162 MachineFunction &MF = *MBB.getParent(); 163 MachineFrameInfo &MFI = *MF.getFrameInfo(); 164 MachineMemOperand *MMO = 165 MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI), 166 MachineMemOperand::MOLoad, 167 MFI.getObjectSize(FI), 168 MFI.getObjectAlignment(FI)); 169 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::t2LDRi12), DestReg) 170 .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); 171 return; 172 } 173 174 ARMBaseInstrInfo::loadRegFromStackSlot(MBB, I, DestReg, FI, RC, TRI); 175 } 176 177 void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB, 178 MachineBasicBlock::iterator &MBBI, DebugLoc dl, 179 unsigned DestReg, unsigned BaseReg, int NumBytes, 180 ARMCC::CondCodes Pred, unsigned PredReg, 181 const ARMBaseInstrInfo &TII, unsigned MIFlags) { 182 bool isSub = NumBytes < 0; 183 if (isSub) NumBytes = -NumBytes; 184 185 // If profitable, use a movw or movt to materialize the offset. 186 // FIXME: Use the scavenger to grab a scratch register. 187 if (DestReg != ARM::SP && DestReg != BaseReg && 188 NumBytes >= 4096 && 189 ARM_AM::getT2SOImmVal(NumBytes) == -1) { 190 bool Fits = false; 191 if (NumBytes < 65536) { 192 // Use a movw to materialize the 16-bit constant. 193 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi16), DestReg) 194 .addImm(NumBytes) 195 .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags); 196 Fits = true; 197 } else if ((NumBytes & 0xffff) == 0) { 198 // Use a movt to materialize the 32-bit constant. 199 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVTi16), DestReg) 200 .addReg(DestReg) 201 .addImm(NumBytes >> 16) 202 .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags); 203 Fits = true; 204 } 205 206 if (Fits) { 207 if (isSub) { 208 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2SUBrr), DestReg) 209 .addReg(BaseReg, RegState::Kill) 210 .addReg(DestReg, RegState::Kill) 211 .addImm((unsigned)Pred).addReg(PredReg).addReg(0) 212 .setMIFlags(MIFlags); 213 } else { 214 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2ADDrr), DestReg) 215 .addReg(DestReg, RegState::Kill) 216 .addReg(BaseReg, RegState::Kill) 217 .addImm((unsigned)Pred).addReg(PredReg).addReg(0) 218 .setMIFlags(MIFlags); 219 } 220 return; 221 } 222 } 223 224 while (NumBytes) { 225 unsigned ThisVal = NumBytes; 226 unsigned Opc = 0; 227 if (DestReg == ARM::SP && BaseReg != ARM::SP) { 228 // mov sp, rn. Note t2MOVr cannot be used. 229 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr),DestReg) 230 .addReg(BaseReg).setMIFlags(MIFlags)); 231 BaseReg = ARM::SP; 232 continue; 233 } 234 235 bool HasCCOut = true; 236 if (BaseReg == ARM::SP) { 237 // sub sp, sp, #imm7 238 if (DestReg == ARM::SP && (ThisVal < ((1 << 7)-1) * 4)) { 239 assert((ThisVal & 3) == 0 && "Stack update is not multiple of 4?"); 240 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi; 241 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) 242 .addReg(BaseReg).addImm(ThisVal/4).setMIFlags(MIFlags)); 243 NumBytes = 0; 244 continue; 245 } 246 247 // sub rd, sp, so_imm 248 Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri; 249 if (ARM_AM::getT2SOImmVal(NumBytes) != -1) { 250 NumBytes = 0; 251 } else { 252 // FIXME: Move this to ARMAddressingModes.h? 253 unsigned RotAmt = CountLeadingZeros_32(ThisVal); 254 ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt); 255 NumBytes &= ~ThisVal; 256 assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 && 257 "Bit extraction didn't work?"); 258 } 259 } else { 260 assert(DestReg != ARM::SP && BaseReg != ARM::SP); 261 Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri; 262 if (ARM_AM::getT2SOImmVal(NumBytes) != -1) { 263 NumBytes = 0; 264 } else if (ThisVal < 4096) { 265 Opc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12; 266 HasCCOut = false; 267 NumBytes = 0; 268 } else { 269 // FIXME: Move this to ARMAddressingModes.h? 270 unsigned RotAmt = CountLeadingZeros_32(ThisVal); 271 ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt); 272 NumBytes &= ~ThisVal; 273 assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 && 274 "Bit extraction didn't work?"); 275 } 276 } 277 278 // Build the new ADD / SUB. 279 MachineInstrBuilder MIB = 280 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) 281 .addReg(BaseReg, RegState::Kill) 282 .addImm(ThisVal)).setMIFlags(MIFlags); 283 if (HasCCOut) 284 AddDefaultCC(MIB); 285 286 BaseReg = DestReg; 287 } 288 } 289 290 static unsigned 291 negativeOffsetOpcode(unsigned opcode) 292 { 293 switch (opcode) { 294 case ARM::t2LDRi12: return ARM::t2LDRi8; 295 case ARM::t2LDRHi12: return ARM::t2LDRHi8; 296 case ARM::t2LDRBi12: return ARM::t2LDRBi8; 297 case ARM::t2LDRSHi12: return ARM::t2LDRSHi8; 298 case ARM::t2LDRSBi12: return ARM::t2LDRSBi8; 299 case ARM::t2STRi12: return ARM::t2STRi8; 300 case ARM::t2STRBi12: return ARM::t2STRBi8; 301 case ARM::t2STRHi12: return ARM::t2STRHi8; 302 303 case ARM::t2LDRi8: 304 case ARM::t2LDRHi8: 305 case ARM::t2LDRBi8: 306 case ARM::t2LDRSHi8: 307 case ARM::t2LDRSBi8: 308 case ARM::t2STRi8: 309 case ARM::t2STRBi8: 310 case ARM::t2STRHi8: 311 return opcode; 312 313 default: 314 break; 315 } 316 317 return 0; 318 } 319 320 static unsigned 321 positiveOffsetOpcode(unsigned opcode) 322 { 323 switch (opcode) { 324 case ARM::t2LDRi8: return ARM::t2LDRi12; 325 case ARM::t2LDRHi8: return ARM::t2LDRHi12; 326 case ARM::t2LDRBi8: return ARM::t2LDRBi12; 327 case ARM::t2LDRSHi8: return ARM::t2LDRSHi12; 328 case ARM::t2LDRSBi8: return ARM::t2LDRSBi12; 329 case ARM::t2STRi8: return ARM::t2STRi12; 330 case ARM::t2STRBi8: return ARM::t2STRBi12; 331 case ARM::t2STRHi8: return ARM::t2STRHi12; 332 333 case ARM::t2LDRi12: 334 case ARM::t2LDRHi12: 335 case ARM::t2LDRBi12: 336 case ARM::t2LDRSHi12: 337 case ARM::t2LDRSBi12: 338 case ARM::t2STRi12: 339 case ARM::t2STRBi12: 340 case ARM::t2STRHi12: 341 return opcode; 342 343 default: 344 break; 345 } 346 347 return 0; 348 } 349 350 static unsigned 351 immediateOffsetOpcode(unsigned opcode) 352 { 353 switch (opcode) { 354 case ARM::t2LDRs: return ARM::t2LDRi12; 355 case ARM::t2LDRHs: return ARM::t2LDRHi12; 356 case ARM::t2LDRBs: return ARM::t2LDRBi12; 357 case ARM::t2LDRSHs: return ARM::t2LDRSHi12; 358 case ARM::t2LDRSBs: return ARM::t2LDRSBi12; 359 case ARM::t2STRs: return ARM::t2STRi12; 360 case ARM::t2STRBs: return ARM::t2STRBi12; 361 case ARM::t2STRHs: return ARM::t2STRHi12; 362 363 case ARM::t2LDRi12: 364 case ARM::t2LDRHi12: 365 case ARM::t2LDRBi12: 366 case ARM::t2LDRSHi12: 367 case ARM::t2LDRSBi12: 368 case ARM::t2STRi12: 369 case ARM::t2STRBi12: 370 case ARM::t2STRHi12: 371 case ARM::t2LDRi8: 372 case ARM::t2LDRHi8: 373 case ARM::t2LDRBi8: 374 case ARM::t2LDRSHi8: 375 case ARM::t2LDRSBi8: 376 case ARM::t2STRi8: 377 case ARM::t2STRBi8: 378 case ARM::t2STRHi8: 379 return opcode; 380 381 default: 382 break; 383 } 384 385 return 0; 386 } 387 388 bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 389 unsigned FrameReg, int &Offset, 390 const ARMBaseInstrInfo &TII) { 391 unsigned Opcode = MI.getOpcode(); 392 const MCInstrDesc &Desc = MI.getDesc(); 393 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 394 bool isSub = false; 395 396 // Memory operands in inline assembly always use AddrModeT2_i12. 397 if (Opcode == ARM::INLINEASM) 398 AddrMode = ARMII::AddrModeT2_i12; // FIXME. mode for thumb2? 399 400 if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) { 401 Offset += MI.getOperand(FrameRegIdx+1).getImm(); 402 403 unsigned PredReg; 404 if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) { 405 // Turn it into a move. 406 MI.setDesc(TII.get(ARM::tMOVr)); 407 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 408 // Remove offset and remaining explicit predicate operands. 409 do MI.RemoveOperand(FrameRegIdx+1); 410 while (MI.getNumOperands() > FrameRegIdx+1); 411 MachineInstrBuilder MIB(&MI); 412 AddDefaultPred(MIB); 413 return true; 414 } 415 416 bool HasCCOut = Opcode != ARM::t2ADDri12; 417 418 if (Offset < 0) { 419 Offset = -Offset; 420 isSub = true; 421 MI.setDesc(TII.get(ARM::t2SUBri)); 422 } else { 423 MI.setDesc(TII.get(ARM::t2ADDri)); 424 } 425 426 // Common case: small offset, fits into instruction. 427 if (ARM_AM::getT2SOImmVal(Offset) != -1) { 428 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 429 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset); 430 // Add cc_out operand if the original instruction did not have one. 431 if (!HasCCOut) 432 MI.addOperand(MachineOperand::CreateReg(0, false)); 433 Offset = 0; 434 return true; 435 } 436 // Another common case: imm12. 437 if (Offset < 4096 && 438 (!HasCCOut || MI.getOperand(MI.getNumOperands()-1).getReg() == 0)) { 439 unsigned NewOpc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12; 440 MI.setDesc(TII.get(NewOpc)); 441 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 442 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset); 443 // Remove the cc_out operand. 444 if (HasCCOut) 445 MI.RemoveOperand(MI.getNumOperands()-1); 446 Offset = 0; 447 return true; 448 } 449 450 // Otherwise, extract 8 adjacent bits from the immediate into this 451 // t2ADDri/t2SUBri. 452 unsigned RotAmt = CountLeadingZeros_32(Offset); 453 unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xff000000U, RotAmt); 454 455 // We will handle these bits from offset, clear them. 456 Offset &= ~ThisImmVal; 457 458 assert(ARM_AM::getT2SOImmVal(ThisImmVal) != -1 && 459 "Bit extraction didn't work?"); 460 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal); 461 // Add cc_out operand if the original instruction did not have one. 462 if (!HasCCOut) 463 MI.addOperand(MachineOperand::CreateReg(0, false)); 464 465 } else { 466 467 // AddrMode4 and AddrMode6 cannot handle any offset. 468 if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6) 469 return false; 470 471 // AddrModeT2_so cannot handle any offset. If there is no offset 472 // register then we change to an immediate version. 473 unsigned NewOpc = Opcode; 474 if (AddrMode == ARMII::AddrModeT2_so) { 475 unsigned OffsetReg = MI.getOperand(FrameRegIdx+1).getReg(); 476 if (OffsetReg != 0) { 477 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 478 return Offset == 0; 479 } 480 481 MI.RemoveOperand(FrameRegIdx+1); 482 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(0); 483 NewOpc = immediateOffsetOpcode(Opcode); 484 AddrMode = ARMII::AddrModeT2_i12; 485 } 486 487 unsigned NumBits = 0; 488 unsigned Scale = 1; 489 if (AddrMode == ARMII::AddrModeT2_i8 || AddrMode == ARMII::AddrModeT2_i12) { 490 // i8 supports only negative, and i12 supports only positive, so 491 // based on Offset sign convert Opcode to the appropriate 492 // instruction 493 Offset += MI.getOperand(FrameRegIdx+1).getImm(); 494 if (Offset < 0) { 495 NewOpc = negativeOffsetOpcode(Opcode); 496 NumBits = 8; 497 isSub = true; 498 Offset = -Offset; 499 } else { 500 NewOpc = positiveOffsetOpcode(Opcode); 501 NumBits = 12; 502 } 503 } else if (AddrMode == ARMII::AddrMode5) { 504 // VFP address mode. 505 const MachineOperand &OffOp = MI.getOperand(FrameRegIdx+1); 506 int InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm()); 507 if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub) 508 InstrOffs *= -1; 509 NumBits = 8; 510 Scale = 4; 511 Offset += InstrOffs * 4; 512 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!"); 513 if (Offset < 0) { 514 Offset = -Offset; 515 isSub = true; 516 } 517 } else { 518 llvm_unreachable("Unsupported addressing mode!"); 519 } 520 521 if (NewOpc != Opcode) 522 MI.setDesc(TII.get(NewOpc)); 523 524 MachineOperand &ImmOp = MI.getOperand(FrameRegIdx+1); 525 526 // Attempt to fold address computation 527 // Common case: small offset, fits into instruction. 528 int ImmedOffset = Offset / Scale; 529 unsigned Mask = (1 << NumBits) - 1; 530 if ((unsigned)Offset <= Mask * Scale) { 531 // Replace the FrameIndex with fp/sp 532 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 533 if (isSub) { 534 if (AddrMode == ARMII::AddrMode5) 535 // FIXME: Not consistent. 536 ImmedOffset |= 1 << NumBits; 537 else 538 ImmedOffset = -ImmedOffset; 539 } 540 ImmOp.ChangeToImmediate(ImmedOffset); 541 Offset = 0; 542 return true; 543 } 544 545 // Otherwise, offset doesn't fit. Pull in what we can to simplify 546 ImmedOffset = ImmedOffset & Mask; 547 if (isSub) { 548 if (AddrMode == ARMII::AddrMode5) 549 // FIXME: Not consistent. 550 ImmedOffset |= 1 << NumBits; 551 else { 552 ImmedOffset = -ImmedOffset; 553 if (ImmedOffset == 0) 554 // Change the opcode back if the encoded offset is zero. 555 MI.setDesc(TII.get(positiveOffsetOpcode(NewOpc))); 556 } 557 } 558 ImmOp.ChangeToImmediate(ImmedOffset); 559 Offset &= ~(Mask*Scale); 560 } 561 562 Offset = (isSub) ? -Offset : Offset; 563 return Offset == 0; 564 } 565 566 /// scheduleTwoAddrSource - Schedule the copy / re-mat of the source of the 567 /// two-addrss instruction inserted by two-address pass. 568 void 569 Thumb2InstrInfo::scheduleTwoAddrSource(MachineInstr *SrcMI, 570 MachineInstr *UseMI, 571 const TargetRegisterInfo &TRI) const { 572 if (SrcMI->getOpcode() != ARM::tMOVr || SrcMI->getOperand(1).isKill()) 573 return; 574 575 unsigned PredReg = 0; 576 ARMCC::CondCodes CC = getInstrPredicate(UseMI, PredReg); 577 if (CC == ARMCC::AL || PredReg != ARM::CPSR) 578 return; 579 580 // Schedule the copy so it doesn't come between previous instructions 581 // and UseMI which can form an IT block. 582 unsigned SrcReg = SrcMI->getOperand(1).getReg(); 583 ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC); 584 MachineBasicBlock *MBB = UseMI->getParent(); 585 MachineBasicBlock::iterator MBBI = SrcMI; 586 unsigned NumInsts = 0; 587 while (--MBBI != MBB->begin()) { 588 if (MBBI->isDebugValue()) 589 continue; 590 591 MachineInstr *NMI = &*MBBI; 592 ARMCC::CondCodes NCC = getInstrPredicate(NMI, PredReg); 593 if (!(NCC == CC || NCC == OCC) || 594 NMI->modifiesRegister(SrcReg, &TRI) || 595 NMI->modifiesRegister(ARM::CPSR, &TRI)) 596 break; 597 if (++NumInsts == 4) 598 // Too many in a row! 599 return; 600 } 601 602 if (NumInsts) { 603 MBB->remove(SrcMI); 604 MBB->insert(++MBBI, SrcMI); 605 } 606 } 607 608 ARMCC::CondCodes 609 llvm::getITInstrPredicate(const MachineInstr *MI, unsigned &PredReg) { 610 unsigned Opc = MI->getOpcode(); 611 if (Opc == ARM::tBcc || Opc == ARM::t2Bcc) 612 return ARMCC::AL; 613 return getInstrPredicate(MI, PredReg); 614 } 615