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 "ARMConstantPoolValue.h" 16 #include "ARMMachineFunctionInfo.h" 17 #include "MCTargetDesc/ARMAddressingModes.h" 18 #include "llvm/CodeGen/MachineFrameInfo.h" 19 #include "llvm/CodeGen/MachineInstrBuilder.h" 20 #include "llvm/CodeGen/MachineMemOperand.h" 21 #include "llvm/CodeGen/MachineRegisterInfo.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() {} 34 35 /// getNoopForMachoTarget - Return the noop instruction to use for a noop. 36 void Thumb2InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const { 37 NopInst.setOpcode(ARM::tHINT); 38 NopInst.addOperand(MCOperand::createImm(0)); 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 TargetInstrInfo::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 TargetInstrInfo::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 DebugLoc DL; 130 if (I != MBB.end()) DL = I->getDebugLoc(); 131 132 MachineFunction &MF = *MBB.getParent(); 133 MachineFrameInfo &MFI = *MF.getFrameInfo(); 134 MachineMemOperand *MMO = 135 MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI), 136 MachineMemOperand::MOStore, 137 MFI.getObjectSize(FI), 138 MFI.getObjectAlignment(FI)); 139 140 if (RC == &ARM::GPRRegClass || RC == &ARM::tGPRRegClass || 141 RC == &ARM::tcGPRRegClass || RC == &ARM::rGPRRegClass || 142 RC == &ARM::GPRnopcRegClass) { 143 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::t2STRi12)) 144 .addReg(SrcReg, getKillRegState(isKill)) 145 .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); 146 return; 147 } 148 149 if (ARM::GPRPairRegClass.hasSubClassEq(RC)) { 150 // Thumb2 STRD expects its dest-registers to be in rGPR. Not a problem for 151 // gsub_0, but needs an extra constraint for gsub_1 (which could be sp 152 // otherwise). 153 MachineRegisterInfo *MRI = &MF.getRegInfo(); 154 MRI->constrainRegClass(SrcReg, &ARM::GPRPair_with_gsub_1_in_rGPRRegClass); 155 156 MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::t2STRDi8)); 157 AddDReg(MIB, SrcReg, ARM::gsub_0, getKillRegState(isKill), TRI); 158 AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI); 159 MIB.addFrameIndex(FI).addImm(0).addMemOperand(MMO); 160 AddDefaultPred(MIB); 161 return; 162 } 163 164 ARMBaseInstrInfo::storeRegToStackSlot(MBB, I, SrcReg, isKill, FI, RC, TRI); 165 } 166 167 void Thumb2InstrInfo:: 168 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 169 unsigned DestReg, int FI, 170 const TargetRegisterClass *RC, 171 const TargetRegisterInfo *TRI) const { 172 MachineFunction &MF = *MBB.getParent(); 173 MachineFrameInfo &MFI = *MF.getFrameInfo(); 174 MachineMemOperand *MMO = 175 MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI), 176 MachineMemOperand::MOLoad, 177 MFI.getObjectSize(FI), 178 MFI.getObjectAlignment(FI)); 179 DebugLoc DL; 180 if (I != MBB.end()) DL = I->getDebugLoc(); 181 182 if (RC == &ARM::GPRRegClass || RC == &ARM::tGPRRegClass || 183 RC == &ARM::tcGPRRegClass || RC == &ARM::rGPRRegClass || 184 RC == &ARM::GPRnopcRegClass) { 185 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::t2LDRi12), DestReg) 186 .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); 187 return; 188 } 189 190 if (ARM::GPRPairRegClass.hasSubClassEq(RC)) { 191 // Thumb2 LDRD expects its dest-registers to be in rGPR. Not a problem for 192 // gsub_0, but needs an extra constraint for gsub_1 (which could be sp 193 // otherwise). 194 MachineRegisterInfo *MRI = &MF.getRegInfo(); 195 MRI->constrainRegClass(DestReg, &ARM::GPRPair_with_gsub_1_in_rGPRRegClass); 196 197 MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::t2LDRDi8)); 198 AddDReg(MIB, DestReg, ARM::gsub_0, RegState::DefineNoRead, TRI); 199 AddDReg(MIB, DestReg, ARM::gsub_1, RegState::DefineNoRead, TRI); 200 MIB.addFrameIndex(FI).addImm(0).addMemOperand(MMO); 201 AddDefaultPred(MIB); 202 203 if (TargetRegisterInfo::isPhysicalRegister(DestReg)) 204 MIB.addReg(DestReg, RegState::ImplicitDefine); 205 return; 206 } 207 208 ARMBaseInstrInfo::loadRegFromStackSlot(MBB, I, DestReg, FI, RC, TRI); 209 } 210 211 void 212 Thumb2InstrInfo::expandLoadStackGuard(MachineBasicBlock::iterator MI, 213 Reloc::Model RM) const { 214 if (RM == Reloc::PIC_) 215 expandLoadStackGuardBase(MI, ARM::t2MOV_ga_pcrel, ARM::t2LDRi12, RM); 216 else 217 expandLoadStackGuardBase(MI, ARM::t2MOVi32imm, ARM::t2LDRi12, RM); 218 } 219 220 void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB, 221 MachineBasicBlock::iterator &MBBI, DebugLoc dl, 222 unsigned DestReg, unsigned BaseReg, int NumBytes, 223 ARMCC::CondCodes Pred, unsigned PredReg, 224 const ARMBaseInstrInfo &TII, unsigned MIFlags) { 225 if (NumBytes == 0 && DestReg != BaseReg) { 226 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg) 227 .addReg(BaseReg, RegState::Kill) 228 .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags); 229 return; 230 } 231 232 bool isSub = NumBytes < 0; 233 if (isSub) NumBytes = -NumBytes; 234 235 // If profitable, use a movw or movt to materialize the offset. 236 // FIXME: Use the scavenger to grab a scratch register. 237 if (DestReg != ARM::SP && DestReg != BaseReg && 238 NumBytes >= 4096 && 239 ARM_AM::getT2SOImmVal(NumBytes) == -1) { 240 bool Fits = false; 241 if (NumBytes < 65536) { 242 // Use a movw to materialize the 16-bit constant. 243 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi16), DestReg) 244 .addImm(NumBytes) 245 .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags); 246 Fits = true; 247 } else if ((NumBytes & 0xffff) == 0) { 248 // Use a movt to materialize the 32-bit constant. 249 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVTi16), DestReg) 250 .addReg(DestReg) 251 .addImm(NumBytes >> 16) 252 .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags); 253 Fits = true; 254 } 255 256 if (Fits) { 257 if (isSub) { 258 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2SUBrr), DestReg) 259 .addReg(BaseReg) 260 .addReg(DestReg, RegState::Kill) 261 .addImm((unsigned)Pred).addReg(PredReg).addReg(0) 262 .setMIFlags(MIFlags); 263 } else { 264 // Here we know that DestReg is not SP but we do not 265 // know anything about BaseReg. t2ADDrr is an invalid 266 // instruction is SP is used as the second argument, but 267 // is fine if SP is the first argument. To be sure we 268 // do not generate invalid encoding, put BaseReg first. 269 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2ADDrr), DestReg) 270 .addReg(BaseReg) 271 .addReg(DestReg, RegState::Kill) 272 .addImm((unsigned)Pred).addReg(PredReg).addReg(0) 273 .setMIFlags(MIFlags); 274 } 275 return; 276 } 277 } 278 279 while (NumBytes) { 280 unsigned ThisVal = NumBytes; 281 unsigned Opc = 0; 282 if (DestReg == ARM::SP && BaseReg != ARM::SP) { 283 // mov sp, rn. Note t2MOVr cannot be used. 284 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr),DestReg) 285 .addReg(BaseReg).setMIFlags(MIFlags)); 286 BaseReg = ARM::SP; 287 continue; 288 } 289 290 bool HasCCOut = true; 291 if (BaseReg == ARM::SP) { 292 // sub sp, sp, #imm7 293 if (DestReg == ARM::SP && (ThisVal < ((1 << 7)-1) * 4)) { 294 assert((ThisVal & 3) == 0 && "Stack update is not multiple of 4?"); 295 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi; 296 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) 297 .addReg(BaseReg).addImm(ThisVal/4).setMIFlags(MIFlags)); 298 NumBytes = 0; 299 continue; 300 } 301 302 // sub rd, sp, so_imm 303 Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri; 304 if (ARM_AM::getT2SOImmVal(NumBytes) != -1) { 305 NumBytes = 0; 306 } else { 307 // FIXME: Move this to ARMAddressingModes.h? 308 unsigned RotAmt = countLeadingZeros(ThisVal); 309 ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt); 310 NumBytes &= ~ThisVal; 311 assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 && 312 "Bit extraction didn't work?"); 313 } 314 } else { 315 assert(DestReg != ARM::SP && BaseReg != ARM::SP); 316 Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri; 317 if (ARM_AM::getT2SOImmVal(NumBytes) != -1) { 318 NumBytes = 0; 319 } else if (ThisVal < 4096) { 320 Opc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12; 321 HasCCOut = false; 322 NumBytes = 0; 323 } else { 324 // FIXME: Move this to ARMAddressingModes.h? 325 unsigned RotAmt = countLeadingZeros(ThisVal); 326 ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt); 327 NumBytes &= ~ThisVal; 328 assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 && 329 "Bit extraction didn't work?"); 330 } 331 } 332 333 // Build the new ADD / SUB. 334 MachineInstrBuilder MIB = 335 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) 336 .addReg(BaseReg, RegState::Kill) 337 .addImm(ThisVal)).setMIFlags(MIFlags); 338 if (HasCCOut) 339 AddDefaultCC(MIB); 340 341 BaseReg = DestReg; 342 } 343 } 344 345 static unsigned 346 negativeOffsetOpcode(unsigned opcode) 347 { 348 switch (opcode) { 349 case ARM::t2LDRi12: return ARM::t2LDRi8; 350 case ARM::t2LDRHi12: return ARM::t2LDRHi8; 351 case ARM::t2LDRBi12: return ARM::t2LDRBi8; 352 case ARM::t2LDRSHi12: return ARM::t2LDRSHi8; 353 case ARM::t2LDRSBi12: return ARM::t2LDRSBi8; 354 case ARM::t2STRi12: return ARM::t2STRi8; 355 case ARM::t2STRBi12: return ARM::t2STRBi8; 356 case ARM::t2STRHi12: return ARM::t2STRHi8; 357 case ARM::t2PLDi12: return ARM::t2PLDi8; 358 359 case ARM::t2LDRi8: 360 case ARM::t2LDRHi8: 361 case ARM::t2LDRBi8: 362 case ARM::t2LDRSHi8: 363 case ARM::t2LDRSBi8: 364 case ARM::t2STRi8: 365 case ARM::t2STRBi8: 366 case ARM::t2STRHi8: 367 case ARM::t2PLDi8: 368 return opcode; 369 370 default: 371 break; 372 } 373 374 return 0; 375 } 376 377 static unsigned 378 positiveOffsetOpcode(unsigned opcode) 379 { 380 switch (opcode) { 381 case ARM::t2LDRi8: return ARM::t2LDRi12; 382 case ARM::t2LDRHi8: return ARM::t2LDRHi12; 383 case ARM::t2LDRBi8: return ARM::t2LDRBi12; 384 case ARM::t2LDRSHi8: return ARM::t2LDRSHi12; 385 case ARM::t2LDRSBi8: return ARM::t2LDRSBi12; 386 case ARM::t2STRi8: return ARM::t2STRi12; 387 case ARM::t2STRBi8: return ARM::t2STRBi12; 388 case ARM::t2STRHi8: return ARM::t2STRHi12; 389 case ARM::t2PLDi8: return ARM::t2PLDi12; 390 391 case ARM::t2LDRi12: 392 case ARM::t2LDRHi12: 393 case ARM::t2LDRBi12: 394 case ARM::t2LDRSHi12: 395 case ARM::t2LDRSBi12: 396 case ARM::t2STRi12: 397 case ARM::t2STRBi12: 398 case ARM::t2STRHi12: 399 case ARM::t2PLDi12: 400 return opcode; 401 402 default: 403 break; 404 } 405 406 return 0; 407 } 408 409 static unsigned 410 immediateOffsetOpcode(unsigned opcode) 411 { 412 switch (opcode) { 413 case ARM::t2LDRs: return ARM::t2LDRi12; 414 case ARM::t2LDRHs: return ARM::t2LDRHi12; 415 case ARM::t2LDRBs: return ARM::t2LDRBi12; 416 case ARM::t2LDRSHs: return ARM::t2LDRSHi12; 417 case ARM::t2LDRSBs: return ARM::t2LDRSBi12; 418 case ARM::t2STRs: return ARM::t2STRi12; 419 case ARM::t2STRBs: return ARM::t2STRBi12; 420 case ARM::t2STRHs: return ARM::t2STRHi12; 421 case ARM::t2PLDs: return ARM::t2PLDi12; 422 423 case ARM::t2LDRi12: 424 case ARM::t2LDRHi12: 425 case ARM::t2LDRBi12: 426 case ARM::t2LDRSHi12: 427 case ARM::t2LDRSBi12: 428 case ARM::t2STRi12: 429 case ARM::t2STRBi12: 430 case ARM::t2STRHi12: 431 case ARM::t2PLDi12: 432 case ARM::t2LDRi8: 433 case ARM::t2LDRHi8: 434 case ARM::t2LDRBi8: 435 case ARM::t2LDRSHi8: 436 case ARM::t2LDRSBi8: 437 case ARM::t2STRi8: 438 case ARM::t2STRBi8: 439 case ARM::t2STRHi8: 440 case ARM::t2PLDi8: 441 return opcode; 442 443 default: 444 break; 445 } 446 447 return 0; 448 } 449 450 bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 451 unsigned FrameReg, int &Offset, 452 const ARMBaseInstrInfo &TII) { 453 unsigned Opcode = MI.getOpcode(); 454 const MCInstrDesc &Desc = MI.getDesc(); 455 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 456 bool isSub = false; 457 458 // Memory operands in inline assembly always use AddrModeT2_i12. 459 if (Opcode == ARM::INLINEASM) 460 AddrMode = ARMII::AddrModeT2_i12; // FIXME. mode for thumb2? 461 462 if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) { 463 Offset += MI.getOperand(FrameRegIdx+1).getImm(); 464 465 unsigned PredReg; 466 if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) { 467 // Turn it into a move. 468 MI.setDesc(TII.get(ARM::tMOVr)); 469 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 470 // Remove offset and remaining explicit predicate operands. 471 do MI.RemoveOperand(FrameRegIdx+1); 472 while (MI.getNumOperands() > FrameRegIdx+1); 473 MachineInstrBuilder MIB(*MI.getParent()->getParent(), &MI); 474 AddDefaultPred(MIB); 475 return true; 476 } 477 478 bool HasCCOut = Opcode != ARM::t2ADDri12; 479 480 if (Offset < 0) { 481 Offset = -Offset; 482 isSub = true; 483 MI.setDesc(TII.get(ARM::t2SUBri)); 484 } else { 485 MI.setDesc(TII.get(ARM::t2ADDri)); 486 } 487 488 // Common case: small offset, fits into instruction. 489 if (ARM_AM::getT2SOImmVal(Offset) != -1) { 490 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 491 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset); 492 // Add cc_out operand if the original instruction did not have one. 493 if (!HasCCOut) 494 MI.addOperand(MachineOperand::CreateReg(0, false)); 495 Offset = 0; 496 return true; 497 } 498 // Another common case: imm12. 499 if (Offset < 4096 && 500 (!HasCCOut || MI.getOperand(MI.getNumOperands()-1).getReg() == 0)) { 501 unsigned NewOpc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12; 502 MI.setDesc(TII.get(NewOpc)); 503 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 504 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset); 505 // Remove the cc_out operand. 506 if (HasCCOut) 507 MI.RemoveOperand(MI.getNumOperands()-1); 508 Offset = 0; 509 return true; 510 } 511 512 // Otherwise, extract 8 adjacent bits from the immediate into this 513 // t2ADDri/t2SUBri. 514 unsigned RotAmt = countLeadingZeros<unsigned>(Offset); 515 unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xff000000U, RotAmt); 516 517 // We will handle these bits from offset, clear them. 518 Offset &= ~ThisImmVal; 519 520 assert(ARM_AM::getT2SOImmVal(ThisImmVal) != -1 && 521 "Bit extraction didn't work?"); 522 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal); 523 // Add cc_out operand if the original instruction did not have one. 524 if (!HasCCOut) 525 MI.addOperand(MachineOperand::CreateReg(0, false)); 526 527 } else { 528 529 // AddrMode4 and AddrMode6 cannot handle any offset. 530 if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6) 531 return false; 532 533 // AddrModeT2_so cannot handle any offset. If there is no offset 534 // register then we change to an immediate version. 535 unsigned NewOpc = Opcode; 536 if (AddrMode == ARMII::AddrModeT2_so) { 537 unsigned OffsetReg = MI.getOperand(FrameRegIdx+1).getReg(); 538 if (OffsetReg != 0) { 539 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 540 return Offset == 0; 541 } 542 543 MI.RemoveOperand(FrameRegIdx+1); 544 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(0); 545 NewOpc = immediateOffsetOpcode(Opcode); 546 AddrMode = ARMII::AddrModeT2_i12; 547 } 548 549 unsigned NumBits = 0; 550 unsigned Scale = 1; 551 if (AddrMode == ARMII::AddrModeT2_i8 || AddrMode == ARMII::AddrModeT2_i12) { 552 // i8 supports only negative, and i12 supports only positive, so 553 // based on Offset sign convert Opcode to the appropriate 554 // instruction 555 Offset += MI.getOperand(FrameRegIdx+1).getImm(); 556 if (Offset < 0) { 557 NewOpc = negativeOffsetOpcode(Opcode); 558 NumBits = 8; 559 isSub = true; 560 Offset = -Offset; 561 } else { 562 NewOpc = positiveOffsetOpcode(Opcode); 563 NumBits = 12; 564 } 565 } else if (AddrMode == ARMII::AddrMode5) { 566 // VFP address mode. 567 const MachineOperand &OffOp = MI.getOperand(FrameRegIdx+1); 568 int InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm()); 569 if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub) 570 InstrOffs *= -1; 571 NumBits = 8; 572 Scale = 4; 573 Offset += InstrOffs * 4; 574 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!"); 575 if (Offset < 0) { 576 Offset = -Offset; 577 isSub = true; 578 } 579 } else if (AddrMode == ARMII::AddrModeT2_i8s4) { 580 Offset += MI.getOperand(FrameRegIdx + 1).getImm() * 4; 581 NumBits = 10; // 8 bits scaled by 4 582 // MCInst operand expects already scaled value. 583 Scale = 1; 584 assert((Offset & 3) == 0 && "Can't encode this offset!"); 585 } else { 586 llvm_unreachable("Unsupported addressing mode!"); 587 } 588 589 if (NewOpc != Opcode) 590 MI.setDesc(TII.get(NewOpc)); 591 592 MachineOperand &ImmOp = MI.getOperand(FrameRegIdx+1); 593 594 // Attempt to fold address computation 595 // Common case: small offset, fits into instruction. 596 int ImmedOffset = Offset / Scale; 597 unsigned Mask = (1 << NumBits) - 1; 598 if ((unsigned)Offset <= Mask * Scale) { 599 // Replace the FrameIndex with fp/sp 600 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 601 if (isSub) { 602 if (AddrMode == ARMII::AddrMode5) 603 // FIXME: Not consistent. 604 ImmedOffset |= 1 << NumBits; 605 else 606 ImmedOffset = -ImmedOffset; 607 } 608 ImmOp.ChangeToImmediate(ImmedOffset); 609 Offset = 0; 610 return true; 611 } 612 613 // Otherwise, offset doesn't fit. Pull in what we can to simplify 614 ImmedOffset = ImmedOffset & Mask; 615 if (isSub) { 616 if (AddrMode == ARMII::AddrMode5) 617 // FIXME: Not consistent. 618 ImmedOffset |= 1 << NumBits; 619 else { 620 ImmedOffset = -ImmedOffset; 621 if (ImmedOffset == 0) 622 // Change the opcode back if the encoded offset is zero. 623 MI.setDesc(TII.get(positiveOffsetOpcode(NewOpc))); 624 } 625 } 626 ImmOp.ChangeToImmediate(ImmedOffset); 627 Offset &= ~(Mask*Scale); 628 } 629 630 Offset = (isSub) ? -Offset : Offset; 631 return Offset == 0; 632 } 633 634 ARMCC::CondCodes 635 llvm::getITInstrPredicate(const MachineInstr *MI, unsigned &PredReg) { 636 unsigned Opc = MI->getOpcode(); 637 if (Opc == ARM::tBcc || Opc == ARM::t2Bcc) 638 return ARMCC::AL; 639 return getInstrPredicate(MI, PredReg); 640 } 641