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