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, RegState::Kill) 260 .addReg(DestReg, RegState::Kill) 261 .addImm((unsigned)Pred).addReg(PredReg).addReg(0) 262 .setMIFlags(MIFlags); 263 } else { 264 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2ADDrr), DestReg) 265 .addReg(DestReg, RegState::Kill) 266 .addReg(BaseReg, RegState::Kill) 267 .addImm((unsigned)Pred).addReg(PredReg).addReg(0) 268 .setMIFlags(MIFlags); 269 } 270 return; 271 } 272 } 273 274 while (NumBytes) { 275 unsigned ThisVal = NumBytes; 276 unsigned Opc = 0; 277 if (DestReg == ARM::SP && BaseReg != ARM::SP) { 278 // mov sp, rn. Note t2MOVr cannot be used. 279 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr),DestReg) 280 .addReg(BaseReg).setMIFlags(MIFlags)); 281 BaseReg = ARM::SP; 282 continue; 283 } 284 285 bool HasCCOut = true; 286 if (BaseReg == ARM::SP) { 287 // sub sp, sp, #imm7 288 if (DestReg == ARM::SP && (ThisVal < ((1 << 7)-1) * 4)) { 289 assert((ThisVal & 3) == 0 && "Stack update is not multiple of 4?"); 290 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi; 291 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) 292 .addReg(BaseReg).addImm(ThisVal/4).setMIFlags(MIFlags)); 293 NumBytes = 0; 294 continue; 295 } 296 297 // sub rd, sp, so_imm 298 Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri; 299 if (ARM_AM::getT2SOImmVal(NumBytes) != -1) { 300 NumBytes = 0; 301 } else { 302 // FIXME: Move this to ARMAddressingModes.h? 303 unsigned RotAmt = countLeadingZeros(ThisVal); 304 ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt); 305 NumBytes &= ~ThisVal; 306 assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 && 307 "Bit extraction didn't work?"); 308 } 309 } else { 310 assert(DestReg != ARM::SP && BaseReg != ARM::SP); 311 Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri; 312 if (ARM_AM::getT2SOImmVal(NumBytes) != -1) { 313 NumBytes = 0; 314 } else if (ThisVal < 4096) { 315 Opc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12; 316 HasCCOut = false; 317 NumBytes = 0; 318 } else { 319 // FIXME: Move this to ARMAddressingModes.h? 320 unsigned RotAmt = countLeadingZeros(ThisVal); 321 ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt); 322 NumBytes &= ~ThisVal; 323 assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 && 324 "Bit extraction didn't work?"); 325 } 326 } 327 328 // Build the new ADD / SUB. 329 MachineInstrBuilder MIB = 330 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) 331 .addReg(BaseReg, RegState::Kill) 332 .addImm(ThisVal)).setMIFlags(MIFlags); 333 if (HasCCOut) 334 AddDefaultCC(MIB); 335 336 BaseReg = DestReg; 337 } 338 } 339 340 static unsigned 341 negativeOffsetOpcode(unsigned opcode) 342 { 343 switch (opcode) { 344 case ARM::t2LDRi12: return ARM::t2LDRi8; 345 case ARM::t2LDRHi12: return ARM::t2LDRHi8; 346 case ARM::t2LDRBi12: return ARM::t2LDRBi8; 347 case ARM::t2LDRSHi12: return ARM::t2LDRSHi8; 348 case ARM::t2LDRSBi12: return ARM::t2LDRSBi8; 349 case ARM::t2STRi12: return ARM::t2STRi8; 350 case ARM::t2STRBi12: return ARM::t2STRBi8; 351 case ARM::t2STRHi12: return ARM::t2STRHi8; 352 case ARM::t2PLDi12: return ARM::t2PLDi8; 353 354 case ARM::t2LDRi8: 355 case ARM::t2LDRHi8: 356 case ARM::t2LDRBi8: 357 case ARM::t2LDRSHi8: 358 case ARM::t2LDRSBi8: 359 case ARM::t2STRi8: 360 case ARM::t2STRBi8: 361 case ARM::t2STRHi8: 362 case ARM::t2PLDi8: 363 return opcode; 364 365 default: 366 break; 367 } 368 369 return 0; 370 } 371 372 static unsigned 373 positiveOffsetOpcode(unsigned opcode) 374 { 375 switch (opcode) { 376 case ARM::t2LDRi8: return ARM::t2LDRi12; 377 case ARM::t2LDRHi8: return ARM::t2LDRHi12; 378 case ARM::t2LDRBi8: return ARM::t2LDRBi12; 379 case ARM::t2LDRSHi8: return ARM::t2LDRSHi12; 380 case ARM::t2LDRSBi8: return ARM::t2LDRSBi12; 381 case ARM::t2STRi8: return ARM::t2STRi12; 382 case ARM::t2STRBi8: return ARM::t2STRBi12; 383 case ARM::t2STRHi8: return ARM::t2STRHi12; 384 case ARM::t2PLDi8: return ARM::t2PLDi12; 385 386 case ARM::t2LDRi12: 387 case ARM::t2LDRHi12: 388 case ARM::t2LDRBi12: 389 case ARM::t2LDRSHi12: 390 case ARM::t2LDRSBi12: 391 case ARM::t2STRi12: 392 case ARM::t2STRBi12: 393 case ARM::t2STRHi12: 394 case ARM::t2PLDi12: 395 return opcode; 396 397 default: 398 break; 399 } 400 401 return 0; 402 } 403 404 static unsigned 405 immediateOffsetOpcode(unsigned opcode) 406 { 407 switch (opcode) { 408 case ARM::t2LDRs: return ARM::t2LDRi12; 409 case ARM::t2LDRHs: return ARM::t2LDRHi12; 410 case ARM::t2LDRBs: return ARM::t2LDRBi12; 411 case ARM::t2LDRSHs: return ARM::t2LDRSHi12; 412 case ARM::t2LDRSBs: return ARM::t2LDRSBi12; 413 case ARM::t2STRs: return ARM::t2STRi12; 414 case ARM::t2STRBs: return ARM::t2STRBi12; 415 case ARM::t2STRHs: return ARM::t2STRHi12; 416 case ARM::t2PLDs: return ARM::t2PLDi12; 417 418 case ARM::t2LDRi12: 419 case ARM::t2LDRHi12: 420 case ARM::t2LDRBi12: 421 case ARM::t2LDRSHi12: 422 case ARM::t2LDRSBi12: 423 case ARM::t2STRi12: 424 case ARM::t2STRBi12: 425 case ARM::t2STRHi12: 426 case ARM::t2PLDi12: 427 case ARM::t2LDRi8: 428 case ARM::t2LDRHi8: 429 case ARM::t2LDRBi8: 430 case ARM::t2LDRSHi8: 431 case ARM::t2LDRSBi8: 432 case ARM::t2STRi8: 433 case ARM::t2STRBi8: 434 case ARM::t2STRHi8: 435 case ARM::t2PLDi8: 436 return opcode; 437 438 default: 439 break; 440 } 441 442 return 0; 443 } 444 445 bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 446 unsigned FrameReg, int &Offset, 447 const ARMBaseInstrInfo &TII) { 448 unsigned Opcode = MI.getOpcode(); 449 const MCInstrDesc &Desc = MI.getDesc(); 450 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 451 bool isSub = false; 452 453 // Memory operands in inline assembly always use AddrModeT2_i12. 454 if (Opcode == ARM::INLINEASM) 455 AddrMode = ARMII::AddrModeT2_i12; // FIXME. mode for thumb2? 456 457 if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) { 458 Offset += MI.getOperand(FrameRegIdx+1).getImm(); 459 460 unsigned PredReg; 461 if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) { 462 // Turn it into a move. 463 MI.setDesc(TII.get(ARM::tMOVr)); 464 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 465 // Remove offset and remaining explicit predicate operands. 466 do MI.RemoveOperand(FrameRegIdx+1); 467 while (MI.getNumOperands() > FrameRegIdx+1); 468 MachineInstrBuilder MIB(*MI.getParent()->getParent(), &MI); 469 AddDefaultPred(MIB); 470 return true; 471 } 472 473 bool HasCCOut = Opcode != ARM::t2ADDri12; 474 475 if (Offset < 0) { 476 Offset = -Offset; 477 isSub = true; 478 MI.setDesc(TII.get(ARM::t2SUBri)); 479 } else { 480 MI.setDesc(TII.get(ARM::t2ADDri)); 481 } 482 483 // Common case: small offset, fits into instruction. 484 if (ARM_AM::getT2SOImmVal(Offset) != -1) { 485 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 486 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset); 487 // Add cc_out operand if the original instruction did not have one. 488 if (!HasCCOut) 489 MI.addOperand(MachineOperand::CreateReg(0, false)); 490 Offset = 0; 491 return true; 492 } 493 // Another common case: imm12. 494 if (Offset < 4096 && 495 (!HasCCOut || MI.getOperand(MI.getNumOperands()-1).getReg() == 0)) { 496 unsigned NewOpc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12; 497 MI.setDesc(TII.get(NewOpc)); 498 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 499 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset); 500 // Remove the cc_out operand. 501 if (HasCCOut) 502 MI.RemoveOperand(MI.getNumOperands()-1); 503 Offset = 0; 504 return true; 505 } 506 507 // Otherwise, extract 8 adjacent bits from the immediate into this 508 // t2ADDri/t2SUBri. 509 unsigned RotAmt = countLeadingZeros<unsigned>(Offset); 510 unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xff000000U, RotAmt); 511 512 // We will handle these bits from offset, clear them. 513 Offset &= ~ThisImmVal; 514 515 assert(ARM_AM::getT2SOImmVal(ThisImmVal) != -1 && 516 "Bit extraction didn't work?"); 517 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal); 518 // Add cc_out operand if the original instruction did not have one. 519 if (!HasCCOut) 520 MI.addOperand(MachineOperand::CreateReg(0, false)); 521 522 } else { 523 524 // AddrMode4 and AddrMode6 cannot handle any offset. 525 if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6) 526 return false; 527 528 // AddrModeT2_so cannot handle any offset. If there is no offset 529 // register then we change to an immediate version. 530 unsigned NewOpc = Opcode; 531 if (AddrMode == ARMII::AddrModeT2_so) { 532 unsigned OffsetReg = MI.getOperand(FrameRegIdx+1).getReg(); 533 if (OffsetReg != 0) { 534 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 535 return Offset == 0; 536 } 537 538 MI.RemoveOperand(FrameRegIdx+1); 539 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(0); 540 NewOpc = immediateOffsetOpcode(Opcode); 541 AddrMode = ARMII::AddrModeT2_i12; 542 } 543 544 unsigned NumBits = 0; 545 unsigned Scale = 1; 546 if (AddrMode == ARMII::AddrModeT2_i8 || AddrMode == ARMII::AddrModeT2_i12) { 547 // i8 supports only negative, and i12 supports only positive, so 548 // based on Offset sign convert Opcode to the appropriate 549 // instruction 550 Offset += MI.getOperand(FrameRegIdx+1).getImm(); 551 if (Offset < 0) { 552 NewOpc = negativeOffsetOpcode(Opcode); 553 NumBits = 8; 554 isSub = true; 555 Offset = -Offset; 556 } else { 557 NewOpc = positiveOffsetOpcode(Opcode); 558 NumBits = 12; 559 } 560 } else if (AddrMode == ARMII::AddrMode5) { 561 // VFP address mode. 562 const MachineOperand &OffOp = MI.getOperand(FrameRegIdx+1); 563 int InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm()); 564 if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub) 565 InstrOffs *= -1; 566 NumBits = 8; 567 Scale = 4; 568 Offset += InstrOffs * 4; 569 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!"); 570 if (Offset < 0) { 571 Offset = -Offset; 572 isSub = true; 573 } 574 } else if (AddrMode == ARMII::AddrModeT2_i8s4) { 575 Offset += MI.getOperand(FrameRegIdx + 1).getImm() * 4; 576 NumBits = 10; // 8 bits scaled by 4 577 // MCInst operand expects already scaled value. 578 Scale = 1; 579 assert((Offset & 3) == 0 && "Can't encode this offset!"); 580 } else { 581 llvm_unreachable("Unsupported addressing mode!"); 582 } 583 584 if (NewOpc != Opcode) 585 MI.setDesc(TII.get(NewOpc)); 586 587 MachineOperand &ImmOp = MI.getOperand(FrameRegIdx+1); 588 589 // Attempt to fold address computation 590 // Common case: small offset, fits into instruction. 591 int ImmedOffset = Offset / Scale; 592 unsigned Mask = (1 << NumBits) - 1; 593 if ((unsigned)Offset <= Mask * Scale) { 594 // Replace the FrameIndex with fp/sp 595 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 596 if (isSub) { 597 if (AddrMode == ARMII::AddrMode5) 598 // FIXME: Not consistent. 599 ImmedOffset |= 1 << NumBits; 600 else 601 ImmedOffset = -ImmedOffset; 602 } 603 ImmOp.ChangeToImmediate(ImmedOffset); 604 Offset = 0; 605 return true; 606 } 607 608 // Otherwise, offset doesn't fit. Pull in what we can to simplify 609 ImmedOffset = ImmedOffset & Mask; 610 if (isSub) { 611 if (AddrMode == ARMII::AddrMode5) 612 // FIXME: Not consistent. 613 ImmedOffset |= 1 << NumBits; 614 else { 615 ImmedOffset = -ImmedOffset; 616 if (ImmedOffset == 0) 617 // Change the opcode back if the encoded offset is zero. 618 MI.setDesc(TII.get(positiveOffsetOpcode(NewOpc))); 619 } 620 } 621 ImmOp.ChangeToImmediate(ImmedOffset); 622 Offset &= ~(Mask*Scale); 623 } 624 625 Offset = (isSub) ? -Offset : Offset; 626 return Offset == 0; 627 } 628 629 ARMCC::CondCodes 630 llvm::getITInstrPredicate(const MachineInstr *MI, unsigned &PredReg) { 631 unsigned Opc = MI->getOpcode(); 632 if (Opc == ARM::tBcc || Opc == ARM::t2Bcc) 633 return ARMCC::AL; 634 return getInstrPredicate(MI, PredReg); 635 } 636