bool HasFarJump;
const TargetInstrInfo *TII;
+ const ARMSubtarget *STI;
ARMFunctionInfo *AFI;
bool isThumb;
bool isThumb1;
TII = MF.getTarget().getInstrInfo();
AFI = MF.getInfo<ARMFunctionInfo>();
+ STI = &MF.getTarget().getSubtarget<ARMSubtarget>();
+
isThumb = AFI->isThumbFunction();
isThumb1 = AFI->isThumb1OnlyFunction();
isThumb2 = AFI->isThumb2Function();
MadeChange = true;
}
+ // Let's see if we can use tbb / tbh to do jump tables.
+ MadeChange |= OptimizeThumb2JumpTables(MF);
+
// After a while, this might be made debug-only, but it is not expensive.
verify(MF);
if (isThumb && !HasFarJump && AFI->isLRSpilledForFarJump())
MadeChange |= UndoLRSpillRestore();
- // Let's see if we can use tbb / tbh to do jump tables.
- MadeChange |= OptimizeThumb2JumpTables(MF);
-
BBSizes.clear();
BBOffsets.clear();
WaterList.clear();
bool NegOk = false;
bool IsSoImm = false;
+ // FIXME: Temporary workaround until I can figure out what's going on.
+ unsigned Slack = T2JumpTables.empty() ? 0 : 4;
switch (Opc) {
default:
llvm_unreachable("Unknown addressing mode for CP reference!");
// Remember that this is a user of a CP entry.
unsigned CPI = I->getOperand(op).getIndex();
MachineInstr *CPEMI = CPEMIs[CPI];
- unsigned MaxOffs = ((1 << Bits)-1) * Scale;
+ unsigned MaxOffs = ((1 << Bits)-1) * Scale - Slack;
CPUsers.push_back(CPUser(I, CPEMI, MaxOffs, NegOk, IsSoImm));
// Increment corresponding CPEntry reference count.
// We removed instructions from UserMBB, subtract that off from its size.
// Add 2 or 4 to the block to count the unconditional branch we added to it.
- unsigned delta = isThumb1 ? 2 : 4;
+ int delta = isThumb1 ? 2 : 4;
BBSizes[OrigBBI] -= NewBBSize - delta;
// ...and adjust BBOffsets for NewBB accordingly.
// sure all the branches are forward.
if (ByteOk && (DstOffset - JTOffset) > ((1<<8)-1)*2)
ByteOk = false;
- if (HalfWordOk && (DstOffset - JTOffset) > ((1<<16)-1)*2)
+ unsigned TBHLimit = ((1<<16)-1)*2;
+ if (STI->isTargetDarwin())
+ TBHLimit >>= 1; // FIXME: Work around an assembler bug.
+ if (HalfWordOk && (DstOffset - JTOffset) > TBHLimit)
HalfWordOk = false;
if (!ByteOk && !HalfWordOk)
break;
MachineInstr *LeaMI = --PrevI;
if (LeaMI->getOpcode() != ARM::t2LEApcrelJT ||
LeaMI->getOperand(0).getReg() != BaseReg)
- LeaMI = 0;
-
- if (OptOk) {
- unsigned Opc = ByteOk ? ARM::t2TBB : ARM::t2TBH;
- AddDefaultPred(BuildMI(MBB, MI->getDebugLoc(), TII->get(Opc))
- .addReg(IdxReg, getKillRegState(IdxRegKill))
- .addJumpTableIndex(JTI, JTOP.getTargetFlags())
- .addImm(MI->getOperand(JTOpIdx+1).getImm()));
- // FIXME: Insert an "ALIGN" instruction to ensure the next instruction
- // is 2-byte aligned. For now, asm printer will fix it up.
- AddrMI->eraseFromParent();
- if (LeaMI)
- LeaMI->eraseFromParent();
- MI->eraseFromParent();
- ++NumTBs;
- MadeChange = true;
- }
+ OptOk = false;
+
+ if (!OptOk)
+ continue;
+
+ unsigned Opc = ByteOk ? ARM::t2TBB : ARM::t2TBH;
+ MachineInstr *NewJTMI = BuildMI(MBB, MI->getDebugLoc(), TII->get(Opc))
+ .addReg(IdxReg, getKillRegState(IdxRegKill))
+ .addJumpTableIndex(JTI, JTOP.getTargetFlags())
+ .addImm(MI->getOperand(JTOpIdx+1).getImm());
+ // FIXME: Insert an "ALIGN" instruction to ensure the next instruction
+ // is 2-byte aligned. For now, asm printer will fix it up.
+ unsigned NewSize = TII->GetInstSizeInBytes(NewJTMI);
+ unsigned OrigSize = TII->GetInstSizeInBytes(AddrMI);
+ OrigSize += TII->GetInstSizeInBytes(LeaMI);
+ OrigSize += TII->GetInstSizeInBytes(MI);
+
+ AddrMI->eraseFromParent();
+ LeaMI->eraseFromParent();
+ MI->eraseFromParent();
+
+ int delta = OrigSize - NewSize;
+ BBSizes[MBB->getNumber()] -= delta;
+ AdjustBBOffsetsAfter(MBB, -delta);
+
+ ++NumTBs;
+ MadeChange = true;
}
}
// FIXME: A8.6.18 BFI - Bitfield insert (Encoding T1)
+/*
defm t2ORN : T2I_bin_irs<"orn", BinOpFrag<(or node:$LHS, (not node:$RHS))>>;
+*/
+// FIXME: Disable this pattern on Darwin to workaround an assembler bug.
+def t2ORNri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
+ "orn", " $dst, $lhs, $rhs",
+ [(set GPR:$dst, (or GPR:$lhs, (not t2_so_imm:$rhs)))]>,
+ Requires<[IsThumb2, IsNotDarwin]>;
+
+def t2ORNrr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
+ "orn", " $dst, $lhs, $rhs",
+ [(set GPR:$dst, (or GPR:$lhs, (not GPR:$rhs)))]>;
+def t2ORNrs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
+ "orn", " $dst, $lhs, $rhs",
+ [(set GPR:$dst, (or GPR:$lhs, (not t2_so_reg:$rhs)))]>;
// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
let AddedComplexity = 1 in
def : T2Pat<(and GPR:$src, t2_so_imm_not:$imm),
(t2BICri GPR:$src, t2_so_imm_not:$imm)>;
+// FIXME: Disable this pattern on Darwin to workaround an assembler bug.
def : T2Pat<(or GPR:$src, t2_so_imm_not:$imm),
- (t2ORNri GPR:$src, t2_so_imm_not:$imm)>;
+ (t2ORNri GPR:$src, t2_so_imm_not:$imm)>,
+ Requires<[IsThumb2, IsNotDarwin]>;
def : T2Pat<(t2_so_imm_not:$src),
(t2MVNi t2_so_imm_not:$src)>;
"mov pc, $target\n$jt",
[(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]>;
+// FIXME: Add a non-pc based case that can be predicated.
def t2TBB :
- T2I<(outs),
+ T2JTI<(outs),
(ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
- "tbb", " $index\n$jt", []>;
+ "tbb $index\n$jt", []>;
def t2TBH :
- T2I<(outs),
+ T2JTI<(outs),
(ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
- "tbh", " $index\n$jt", []>;
+ "tbh $index\n$jt", []>;
} // isNotDuplicable, isIndirectBranch
} // isBranch, isTerminator, isBarrier