1 //===- Thumb2InstrInfo.cpp - Thumb-2 Instruction Information ----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the Thumb-2 implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
14 #include "Thumb2InstrInfo.h"
16 #include "ARMConstantPoolValue.h"
17 #include "ARMAddressingModes.h"
18 #include "ARMGenInstrInfo.inc"
19 #include "ARMMachineFunctionInfo.h"
20 #include "Thumb2HazardRecognizer.h"
21 #include "Thumb2InstrInfo.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineInstrBuilder.h"
24 #include "llvm/CodeGen/MachineMemOperand.h"
25 #include "llvm/CodeGen/PseudoSourceValue.h"
26 #include "llvm/ADT/SmallVector.h"
27 #include "llvm/Support/CommandLine.h"
31 static cl::opt<unsigned>
32 IfCvtLimit("thumb2-ifcvt-limit", cl::Hidden,
33 cl::desc("Thumb2 if-conversion limit (default 3)"),
36 static cl::opt<unsigned>
37 IfCvtDiamondLimit("thumb2-ifcvt-diamond-limit", cl::Hidden,
38 cl::desc("Thumb2 diamond if-conversion limit (default 3)"),
41 Thumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget &STI)
42 : ARMBaseInstrInfo(STI), RI(*this, STI) {
45 unsigned Thumb2InstrInfo::getUnindexedOpcode(unsigned Opc) const {
51 Thumb2InstrInfo::ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail,
52 MachineBasicBlock *NewDest) const {
53 MachineBasicBlock *MBB = Tail->getParent();
54 ARMFunctionInfo *AFI = MBB->getParent()->getInfo<ARMFunctionInfo>();
55 if (!AFI->hasITBlocks()) {
56 TargetInstrInfoImpl::ReplaceTailWithBranchTo(Tail, NewDest);
60 // If the first instruction of Tail is predicated, we may have to update
61 // the IT instruction.
63 ARMCC::CondCodes CC = llvm::getInstrPredicate(Tail, PredReg);
64 MachineBasicBlock::iterator MBBI = Tail;
66 // Expecting at least the t2IT instruction before it.
69 // Actually replace the tail.
70 TargetInstrInfoImpl::ReplaceTailWithBranchTo(Tail, NewDest);
73 if (CC != ARMCC::AL) {
74 MachineBasicBlock::iterator E = MBB->begin();
75 unsigned Count = 4; // At most 4 instructions in an IT block.
76 while (Count && MBBI != E) {
77 if (MBBI->isDebugValue()) {
81 if (MBBI->getOpcode() == ARM::t2IT) {
82 unsigned Mask = MBBI->getOperand(1).getImm();
84 MBBI->eraseFromParent();
86 unsigned MaskOn = 1 << Count;
87 unsigned MaskOff = ~(MaskOn - 1);
88 MBBI->getOperand(1).setImm((Mask & MaskOff) | MaskOn);
96 // Ctrl flow can reach here if branch folding is run before IT block
102 Thumb2InstrInfo::isLegalToSplitMBBAt(MachineBasicBlock &MBB,
103 MachineBasicBlock::iterator MBBI) const {
104 unsigned PredReg = 0;
105 return llvm::getITInstrPredicate(MBBI, PredReg) == ARMCC::AL;
108 bool Thumb2InstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB,
109 unsigned NumInstrs) const {
110 return NumInstrs && NumInstrs <= IfCvtLimit;
113 bool Thumb2InstrInfo::
114 isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumT,
115 MachineBasicBlock &FMBB, unsigned NumF) const {
116 // FIXME: Catch optimization such as:
119 return NumT && NumF &&
120 NumT <= (IfCvtDiamondLimit) && NumF <= (IfCvtDiamondLimit);
123 void Thumb2InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
124 MachineBasicBlock::iterator I, DebugLoc DL,
125 unsigned DestReg, unsigned SrcReg,
126 bool KillSrc) const {
127 // Handle SPR, DPR, and QPR copies.
128 if (!ARM::GPRRegClass.contains(DestReg, SrcReg))
129 return ARMBaseInstrInfo::copyPhysReg(MBB, I, DL, DestReg, SrcReg, KillSrc);
131 bool tDest = ARM::tGPRRegClass.contains(DestReg);
132 bool tSrc = ARM::tGPRRegClass.contains(SrcReg);
133 unsigned Opc = ARM::tMOVgpr2gpr;
137 Opc = ARM::tMOVtgpr2gpr;
139 Opc = ARM::tMOVgpr2tgpr;
141 BuildMI(MBB, I, DL, get(Opc), DestReg)
142 .addReg(SrcReg, getKillRegState(KillSrc));
145 void Thumb2InstrInfo::
146 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
147 unsigned SrcReg, bool isKill, int FI,
148 const TargetRegisterClass *RC,
149 const TargetRegisterInfo *TRI) const {
150 if (RC == ARM::GPRRegisterClass || RC == ARM::tGPRRegisterClass ||
151 RC == ARM::tcGPRRegisterClass || RC == ARM::rGPRRegisterClass) {
153 if (I != MBB.end()) DL = I->getDebugLoc();
155 MachineFunction &MF = *MBB.getParent();
156 MachineFrameInfo &MFI = *MF.getFrameInfo();
157 MachineMemOperand *MMO =
158 MF.getMachineMemOperand(PseudoSourceValue::getFixedStack(FI),
159 MachineMemOperand::MOStore, 0,
160 MFI.getObjectSize(FI),
161 MFI.getObjectAlignment(FI));
162 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::t2STRi12))
163 .addReg(SrcReg, getKillRegState(isKill))
164 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
168 ARMBaseInstrInfo::storeRegToStackSlot(MBB, I, SrcReg, isKill, FI, RC, TRI);
171 void Thumb2InstrInfo::
172 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
173 unsigned DestReg, int FI,
174 const TargetRegisterClass *RC,
175 const TargetRegisterInfo *TRI) const {
176 if (RC == ARM::GPRRegisterClass || RC == ARM::tGPRRegisterClass ||
177 RC == ARM::tcGPRRegisterClass || RC == ARM::rGPRRegisterClass) {
179 if (I != MBB.end()) DL = I->getDebugLoc();
181 MachineFunction &MF = *MBB.getParent();
182 MachineFrameInfo &MFI = *MF.getFrameInfo();
183 MachineMemOperand *MMO =
184 MF.getMachineMemOperand(PseudoSourceValue::getFixedStack(FI),
185 MachineMemOperand::MOLoad, 0,
186 MFI.getObjectSize(FI),
187 MFI.getObjectAlignment(FI));
188 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::t2LDRi12), DestReg)
189 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
193 ARMBaseInstrInfo::loadRegFromStackSlot(MBB, I, DestReg, FI, RC, TRI);
196 ScheduleHazardRecognizer *Thumb2InstrInfo::
197 CreateTargetPostRAHazardRecognizer(const InstrItineraryData &II) const {
198 return (ScheduleHazardRecognizer *)new Thumb2HazardRecognizer(II);
201 void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB,
202 MachineBasicBlock::iterator &MBBI, DebugLoc dl,
203 unsigned DestReg, unsigned BaseReg, int NumBytes,
204 ARMCC::CondCodes Pred, unsigned PredReg,
205 const ARMBaseInstrInfo &TII) {
206 bool isSub = NumBytes < 0;
207 if (isSub) NumBytes = -NumBytes;
209 // If profitable, use a movw or movt to materialize the offset.
210 // FIXME: Use the scavenger to grab a scratch register.
211 if (DestReg != ARM::SP && DestReg != BaseReg &&
213 ARM_AM::getT2SOImmVal(NumBytes) == -1) {
215 if (NumBytes < 65536) {
216 // Use a movw to materialize the 16-bit constant.
217 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi16), DestReg)
219 .addImm((unsigned)Pred).addReg(PredReg);
221 } else if ((NumBytes & 0xffff) == 0) {
222 // Use a movt to materialize the 32-bit constant.
223 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVTi16), DestReg)
225 .addImm(NumBytes >> 16)
226 .addImm((unsigned)Pred).addReg(PredReg);
232 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2SUBrr), DestReg)
233 .addReg(BaseReg, RegState::Kill)
234 .addReg(DestReg, RegState::Kill)
235 .addImm((unsigned)Pred).addReg(PredReg).addReg(0);
237 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2ADDrr), DestReg)
238 .addReg(DestReg, RegState::Kill)
239 .addReg(BaseReg, RegState::Kill)
240 .addImm((unsigned)Pred).addReg(PredReg).addReg(0);
247 unsigned ThisVal = NumBytes;
249 if (DestReg == ARM::SP && BaseReg != ARM::SP) {
250 // mov sp, rn. Note t2MOVr cannot be used.
251 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr),DestReg).addReg(BaseReg);
256 bool HasCCOut = true;
257 if (BaseReg == ARM::SP) {
259 if (DestReg == ARM::SP && (ThisVal < ((1 << 7)-1) * 4)) {
260 assert((ThisVal & 3) == 0 && "Stack update is not multiple of 4?");
261 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
262 // FIXME: Fix Thumb1 immediate encoding.
263 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
264 .addReg(BaseReg).addImm(ThisVal/4);
269 // sub rd, sp, so_imm
270 Opc = isSub ? ARM::t2SUBrSPi : ARM::t2ADDrSPi;
271 if (ARM_AM::getT2SOImmVal(NumBytes) != -1) {
274 // FIXME: Move this to ARMAddressingModes.h?
275 unsigned RotAmt = CountLeadingZeros_32(ThisVal);
276 ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt);
277 NumBytes &= ~ThisVal;
278 assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 &&
279 "Bit extraction didn't work?");
282 assert(DestReg != ARM::SP && BaseReg != ARM::SP);
283 Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri;
284 if (ARM_AM::getT2SOImmVal(NumBytes) != -1) {
286 } else if (ThisVal < 4096) {
287 Opc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
291 // FIXME: Move this to ARMAddressingModes.h?
292 unsigned RotAmt = CountLeadingZeros_32(ThisVal);
293 ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt);
294 NumBytes &= ~ThisVal;
295 assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 &&
296 "Bit extraction didn't work?");
300 // Build the new ADD / SUB.
301 MachineInstrBuilder MIB =
302 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
303 .addReg(BaseReg, RegState::Kill)
313 negativeOffsetOpcode(unsigned opcode)
316 case ARM::t2LDRi12: return ARM::t2LDRi8;
317 case ARM::t2LDRHi12: return ARM::t2LDRHi8;
318 case ARM::t2LDRBi12: return ARM::t2LDRBi8;
319 case ARM::t2LDRSHi12: return ARM::t2LDRSHi8;
320 case ARM::t2LDRSBi12: return ARM::t2LDRSBi8;
321 case ARM::t2STRi12: return ARM::t2STRi8;
322 case ARM::t2STRBi12: return ARM::t2STRBi8;
323 case ARM::t2STRHi12: return ARM::t2STRHi8;
343 positiveOffsetOpcode(unsigned opcode)
346 case ARM::t2LDRi8: return ARM::t2LDRi12;
347 case ARM::t2LDRHi8: return ARM::t2LDRHi12;
348 case ARM::t2LDRBi8: return ARM::t2LDRBi12;
349 case ARM::t2LDRSHi8: return ARM::t2LDRSHi12;
350 case ARM::t2LDRSBi8: return ARM::t2LDRSBi12;
351 case ARM::t2STRi8: return ARM::t2STRi12;
352 case ARM::t2STRBi8: return ARM::t2STRBi12;
353 case ARM::t2STRHi8: return ARM::t2STRHi12;
358 case ARM::t2LDRSHi12:
359 case ARM::t2LDRSBi12:
373 immediateOffsetOpcode(unsigned opcode)
376 case ARM::t2LDRs: return ARM::t2LDRi12;
377 case ARM::t2LDRHs: return ARM::t2LDRHi12;
378 case ARM::t2LDRBs: return ARM::t2LDRBi12;
379 case ARM::t2LDRSHs: return ARM::t2LDRSHi12;
380 case ARM::t2LDRSBs: return ARM::t2LDRSBi12;
381 case ARM::t2STRs: return ARM::t2STRi12;
382 case ARM::t2STRBs: return ARM::t2STRBi12;
383 case ARM::t2STRHs: return ARM::t2STRHi12;
388 case ARM::t2LDRSHi12:
389 case ARM::t2LDRSBi12:
410 bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
411 unsigned FrameReg, int &Offset,
412 const ARMBaseInstrInfo &TII) {
413 unsigned Opcode = MI.getOpcode();
414 const TargetInstrDesc &Desc = MI.getDesc();
415 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
418 // Memory operands in inline assembly always use AddrModeT2_i12.
419 if (Opcode == ARM::INLINEASM)
420 AddrMode = ARMII::AddrModeT2_i12; // FIXME. mode for thumb2?
422 if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) {
423 Offset += MI.getOperand(FrameRegIdx+1).getImm();
426 if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) {
427 // Turn it into a move.
428 MI.setDesc(TII.get(ARM::tMOVgpr2gpr));
429 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
430 // Remove offset and remaining explicit predicate operands.
431 do MI.RemoveOperand(FrameRegIdx+1);
432 while (MI.getNumOperands() > FrameRegIdx+1 &&
433 (!MI.getOperand(FrameRegIdx+1).isReg() ||
434 !MI.getOperand(FrameRegIdx+1).isImm()));
438 bool isSP = FrameReg == ARM::SP;
439 bool HasCCOut = Opcode != ARM::t2ADDri12;
444 MI.setDesc(TII.get(isSP ? ARM::t2SUBrSPi : ARM::t2SUBri));
446 MI.setDesc(TII.get(isSP ? ARM::t2ADDrSPi : ARM::t2ADDri));
449 // Common case: small offset, fits into instruction.
450 if (ARM_AM::getT2SOImmVal(Offset) != -1) {
451 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
452 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
453 // Add cc_out operand if the original instruction did not have one.
455 MI.addOperand(MachineOperand::CreateReg(0, false));
459 // Another common case: imm12.
461 (!HasCCOut || MI.getOperand(MI.getNumOperands()-1).getReg() == 0)) {
462 unsigned NewOpc = isSP
463 ? (isSub ? ARM::t2SUBrSPi12 : ARM::t2ADDrSPi12)
464 : (isSub ? ARM::t2SUBri12 : ARM::t2ADDri12);
465 MI.setDesc(TII.get(NewOpc));
466 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
467 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
468 // Remove the cc_out operand.
470 MI.RemoveOperand(MI.getNumOperands()-1);
475 // Otherwise, extract 8 adjacent bits from the immediate into this
477 unsigned RotAmt = CountLeadingZeros_32(Offset);
478 unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xff000000U, RotAmt);
480 // We will handle these bits from offset, clear them.
481 Offset &= ~ThisImmVal;
483 assert(ARM_AM::getT2SOImmVal(ThisImmVal) != -1 &&
484 "Bit extraction didn't work?");
485 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
486 // Add cc_out operand if the original instruction did not have one.
488 MI.addOperand(MachineOperand::CreateReg(0, false));
492 // AddrMode4 and AddrMode6 cannot handle any offset.
493 if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6)
496 // AddrModeT2_so cannot handle any offset. If there is no offset
497 // register then we change to an immediate version.
498 unsigned NewOpc = Opcode;
499 if (AddrMode == ARMII::AddrModeT2_so) {
500 unsigned OffsetReg = MI.getOperand(FrameRegIdx+1).getReg();
501 if (OffsetReg != 0) {
502 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
506 MI.RemoveOperand(FrameRegIdx+1);
507 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(0);
508 NewOpc = immediateOffsetOpcode(Opcode);
509 AddrMode = ARMII::AddrModeT2_i12;
512 unsigned NumBits = 0;
514 if (AddrMode == ARMII::AddrModeT2_i8 || AddrMode == ARMII::AddrModeT2_i12) {
515 // i8 supports only negative, and i12 supports only positive, so
516 // based on Offset sign convert Opcode to the appropriate
518 Offset += MI.getOperand(FrameRegIdx+1).getImm();
520 NewOpc = negativeOffsetOpcode(Opcode);
525 NewOpc = positiveOffsetOpcode(Opcode);
528 } else if (AddrMode == ARMII::AddrMode5) {
530 const MachineOperand &OffOp = MI.getOperand(FrameRegIdx+1);
531 int InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm());
532 if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub)
536 Offset += InstrOffs * 4;
537 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
543 llvm_unreachable("Unsupported addressing mode!");
546 if (NewOpc != Opcode)
547 MI.setDesc(TII.get(NewOpc));
549 MachineOperand &ImmOp = MI.getOperand(FrameRegIdx+1);
551 // Attempt to fold address computation
552 // Common case: small offset, fits into instruction.
553 int ImmedOffset = Offset / Scale;
554 unsigned Mask = (1 << NumBits) - 1;
555 if ((unsigned)Offset <= Mask * Scale) {
556 // Replace the FrameIndex with fp/sp
557 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
559 if (AddrMode == ARMII::AddrMode5)
560 // FIXME: Not consistent.
561 ImmedOffset |= 1 << NumBits;
563 ImmedOffset = -ImmedOffset;
565 ImmOp.ChangeToImmediate(ImmedOffset);
570 // Otherwise, offset doesn't fit. Pull in what we can to simplify
571 ImmedOffset = ImmedOffset & Mask;
573 if (AddrMode == ARMII::AddrMode5)
574 // FIXME: Not consistent.
575 ImmedOffset |= 1 << NumBits;
577 ImmedOffset = -ImmedOffset;
578 if (ImmedOffset == 0)
579 // Change the opcode back if the encoded offset is zero.
580 MI.setDesc(TII.get(positiveOffsetOpcode(NewOpc)));
583 ImmOp.ChangeToImmediate(ImmedOffset);
584 Offset &= ~(Mask*Scale);
587 Offset = (isSub) ? -Offset : Offset;
591 /// scheduleTwoAddrSource - Schedule the copy / re-mat of the source of the
592 /// two-addrss instruction inserted by two-address pass.
594 Thumb2InstrInfo::scheduleTwoAddrSource(MachineInstr *SrcMI,
596 const TargetRegisterInfo &TRI) const {
597 if (SrcMI->getOpcode() != ARM::tMOVgpr2gpr ||
598 SrcMI->getOperand(1).isKill())
601 unsigned PredReg = 0;
602 ARMCC::CondCodes CC = llvm::getInstrPredicate(UseMI, PredReg);
603 if (CC == ARMCC::AL || PredReg != ARM::CPSR)
606 // Schedule the copy so it doesn't come between previous instructions
607 // and UseMI which can form an IT block.
608 unsigned SrcReg = SrcMI->getOperand(1).getReg();
609 ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC);
610 MachineBasicBlock *MBB = UseMI->getParent();
611 MachineBasicBlock::iterator MBBI = SrcMI;
612 unsigned NumInsts = 0;
613 while (--MBBI != MBB->begin()) {
614 if (MBBI->isDebugValue())
617 MachineInstr *NMI = &*MBBI;
618 ARMCC::CondCodes NCC = llvm::getInstrPredicate(NMI, PredReg);
619 if (!(NCC == CC || NCC == OCC) ||
620 NMI->modifiesRegister(SrcReg, &TRI) ||
621 NMI->definesRegister(ARM::CPSR))
624 // Too many in a row!
630 MBB->insert(++MBBI, SrcMI);
635 llvm::getITInstrPredicate(const MachineInstr *MI, unsigned &PredReg) {
636 unsigned Opc = MI->getOpcode();
637 if (Opc == ARM::tBcc || Opc == ARM::t2Bcc)
639 return llvm::getInstrPredicate(MI, PredReg);