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