forked from OSchip/llvm-project
parent
50475de6af
commit
28d6d87244
|
@ -1155,16 +1155,17 @@ void Emitter<CodeEmitter>::emitMiscBranchInstruction(const MachineInstr &MI) {
|
||||||
const TargetInstrDesc &TID = MI.getDesc();
|
const TargetInstrDesc &TID = MI.getDesc();
|
||||||
|
|
||||||
// Handle jump tables.
|
// Handle jump tables.
|
||||||
if (TID.Opcode == ARM::BR_JTr || TID.Opcode == ARM::BR_JTadd) {
|
if (TID.Opcode == ARM::BR_JTr || TID.Opcode == ARM::BR_JTadd ||
|
||||||
|
TID.Opcode == ARM::t2BR_JTr || TID.Opcode == ARM::t2BR_JTadd) {
|
||||||
// First emit a ldr pc, [] instruction.
|
// First emit a ldr pc, [] instruction.
|
||||||
emitDataProcessingInstruction(MI, ARM::PC);
|
emitDataProcessingInstruction(MI, ARM::PC);
|
||||||
|
|
||||||
// Then emit the inline jump table.
|
// Then emit the inline jump table.
|
||||||
unsigned JTIndex = (TID.Opcode == ARM::BR_JTr)
|
unsigned JTIndex = (TID.Opcode == ARM::BR_JTr || TID.Opcode == ARM::t2BR_JTr)
|
||||||
? MI.getOperand(1).getIndex() : MI.getOperand(2).getIndex();
|
? MI.getOperand(1).getIndex() : MI.getOperand(2).getIndex();
|
||||||
emitInlineJumpTable(JTIndex);
|
emitInlineJumpTable(JTIndex);
|
||||||
return;
|
return;
|
||||||
} else if (TID.Opcode == ARM::BR_JTm) {
|
} else if (TID.Opcode == ARM::BR_JTm || TID.Opcode == ARM::t2BR_JTm) {
|
||||||
// First emit a ldr pc, [] instruction.
|
// First emit a ldr pc, [] instruction.
|
||||||
emitLoadStoreInstruction(MI, ARM::PC);
|
emitLoadStoreInstruction(MI, ARM::PC);
|
||||||
|
|
||||||
|
|
|
@ -379,6 +379,8 @@ void ARMConstantIslands::InitialFunctionScan(MachineFunction &Fn,
|
||||||
switch (Opc) {
|
switch (Opc) {
|
||||||
case ARM::tBR_JTr:
|
case ARM::tBR_JTr:
|
||||||
case ARM::t2BR_JTr:
|
case ARM::t2BR_JTr:
|
||||||
|
case ARM::t2BR_JTm:
|
||||||
|
case ARM::t2BR_JTadd:
|
||||||
// A Thumb table jump may involve padding; for the offsets to
|
// A Thumb table jump may involve padding; for the offsets to
|
||||||
// be right, functions containing these must be 4-byte aligned.
|
// be right, functions containing these must be 4-byte aligned.
|
||||||
AFI->setAlign(2U);
|
AFI->setAlign(2U);
|
||||||
|
@ -766,7 +768,9 @@ void ARMConstantIslands::AdjustBBOffsetsAfter(MachineBasicBlock *BB,
|
||||||
// following unconditional branches are removed by AnalyzeBranch.
|
// following unconditional branches are removed by AnalyzeBranch.
|
||||||
MachineInstr *ThumbJTMI = NULL;
|
MachineInstr *ThumbJTMI = NULL;
|
||||||
if ((prior(MBB->end())->getOpcode() == ARM::tBR_JTr)
|
if ((prior(MBB->end())->getOpcode() == ARM::tBR_JTr)
|
||||||
|| (prior(MBB->end())->getOpcode() == ARM::t2BR_JTr))
|
|| (prior(MBB->end())->getOpcode() == ARM::t2BR_JTr)
|
||||||
|
|| (prior(MBB->end())->getOpcode() == ARM::t2BR_JTm)
|
||||||
|
|| (prior(MBB->end())->getOpcode() == ARM::t2BR_JTadd))
|
||||||
ThumbJTMI = prior(MBB->end());
|
ThumbJTMI = prior(MBB->end());
|
||||||
if (ThumbJTMI) {
|
if (ThumbJTMI) {
|
||||||
unsigned newMIOffset = GetOffsetOf(ThumbJTMI);
|
unsigned newMIOffset = GetOffsetOf(ThumbJTMI);
|
||||||
|
|
|
@ -401,7 +401,8 @@ bool
|
||||||
// correctness of Thumb constant islands.
|
// correctness of Thumb constant islands.
|
||||||
if ((SecondLastOpc == ARM::BR_JTr || SecondLastOpc==ARM::BR_JTm ||
|
if ((SecondLastOpc == ARM::BR_JTr || SecondLastOpc==ARM::BR_JTm ||
|
||||||
SecondLastOpc == ARM::BR_JTadd || SecondLastOpc==ARM::tBR_JTr ||
|
SecondLastOpc == ARM::BR_JTadd || SecondLastOpc==ARM::tBR_JTr ||
|
||||||
SecondLastOpc==ARM::t2BR_JTr) &&
|
SecondLastOpc == ARM::t2BR_JTr || SecondLastOpc==ARM::t2BR_JTm ||
|
||||||
|
SecondLastOpc == ARM::t2BR_JTadd) &&
|
||||||
(LastOpc == ARM::B || LastOpc == ARM::tB || LastOpc == ARM::t2B)) {
|
(LastOpc == ARM::B || LastOpc == ARM::tB || LastOpc == ARM::t2B)) {
|
||||||
I = LastInst;
|
I = LastInst;
|
||||||
if (AllowModify)
|
if (AllowModify)
|
||||||
|
@ -708,7 +709,9 @@ ARMBaseInstrInfo::BlockHasNoFallThrough(const MachineBasicBlock &MBB) const {
|
||||||
case ARM::tBR_JTr:
|
case ARM::tBR_JTr:
|
||||||
case ARM::t2BR_JTr:
|
case ARM::t2BR_JTr:
|
||||||
case ARM::BR_JTr: // Jumptable branch.
|
case ARM::BR_JTr: // Jumptable branch.
|
||||||
|
case ARM::t2BR_JTm:
|
||||||
case ARM::BR_JTm: // Jumptable branch through mem.
|
case ARM::BR_JTm: // Jumptable branch through mem.
|
||||||
|
case ARM::t2BR_JTadd:
|
||||||
case ARM::BR_JTadd: // Jumptable branch add to pc.
|
case ARM::BR_JTadd: // Jumptable branch add to pc.
|
||||||
return true;
|
return true;
|
||||||
default: return false;
|
default: return false;
|
||||||
|
@ -846,8 +849,10 @@ unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
|
||||||
case ARM::BR_JTr:
|
case ARM::BR_JTr:
|
||||||
case ARM::BR_JTm:
|
case ARM::BR_JTm:
|
||||||
case ARM::BR_JTadd:
|
case ARM::BR_JTadd:
|
||||||
case ARM::tBR_JTr:
|
case ARM::t2BR_JTr:
|
||||||
case ARM::t2BR_JTr: {
|
case ARM::t2BR_JTm:
|
||||||
|
case ARM::t2BR_JTadd:
|
||||||
|
case ARM::tBR_JTr: {
|
||||||
// These are jumptable branches, i.e. a branch followed by an inlined
|
// These are jumptable branches, i.e. a branch followed by an inlined
|
||||||
// jumptable. The size is 4 + 4 * number of entries.
|
// jumptable. The size is 4 + 4 * number of entries.
|
||||||
unsigned NumOps = TID.getNumOperands();
|
unsigned NumOps = TID.getNumOperands();
|
||||||
|
@ -865,8 +870,7 @@ unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
|
||||||
// bytes, we can use 16-bit entries instead. Then there won't be an
|
// bytes, we can use 16-bit entries instead. Then there won't be an
|
||||||
// alignment issue.
|
// alignment issue.
|
||||||
return getNumJTEntries(JT, JTI) * 4 +
|
return getNumJTEntries(JT, JTI) * 4 +
|
||||||
((MI->getOpcode()==ARM::tBR_JTr ||
|
((MI->getOpcode()==ARM::tBR_JTr) ? 2 : 4);
|
||||||
MI->getOpcode()==ARM::t2BR_JTr) ? 2 : 4);
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
// Otherwise, pseudo-instruction sizes are zero.
|
// Otherwise, pseudo-instruction sizes are zero.
|
||||||
|
|
|
@ -698,11 +698,25 @@ def t2B : T2XI<(outs), (ins brtarget:$target),
|
||||||
"b $target",
|
"b $target",
|
||||||
[(br bb:$target)]>;
|
[(br bb:$target)]>;
|
||||||
|
|
||||||
def t2BR_JTr : T2JTI<(outs),
|
let isNotDuplicable = 1, isIndirectBranch = 1 in {
|
||||||
(ins tGPR:$target, jtblock_operand:$jt, i32imm:$id),
|
def t2BR_JTr : T2JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
|
||||||
"cpy pc, $target \n\t.align\t2\n$jt",
|
"mov pc, $target \n$jt",
|
||||||
[(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>;
|
[(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>;
|
||||||
}
|
|
||||||
|
def t2BR_JTm :
|
||||||
|
T2JTI<(outs),
|
||||||
|
(ins t2addrmode_so_reg:$target, jtblock_operand:$jt, i32imm:$id),
|
||||||
|
"ldr pc, $target \n$jt",
|
||||||
|
[(ARMbrjt (i32 (load t2addrmode_so_reg:$target)), tjumptable:$jt,
|
||||||
|
imm:$id)]>;
|
||||||
|
|
||||||
|
def t2BR_JTadd :
|
||||||
|
T2JTI<(outs),
|
||||||
|
(ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
|
||||||
|
"add pc, $target, $idx \n$jt",
|
||||||
|
[(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt, imm:$id)]>;
|
||||||
|
} // isNotDuplicate, isIndirectBranch
|
||||||
|
} // isBranch, isTerminator, isBarrier
|
||||||
|
|
||||||
// FIXME: should be able to write a pattern for ARMBrcond, but can't use
|
// FIXME: should be able to write a pattern for ARMBrcond, but can't use
|
||||||
// a two-value operand where a dag node expects two operands. :(
|
// a two-value operand where a dag node expects two operands. :(
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep {ldr\\W*pc,} | count 1
|
||||||
|
|
||||||
|
define i32 @foo(i32 %a) nounwind {
|
||||||
|
entry:
|
||||||
|
switch i32 %a, label %bb4 [
|
||||||
|
i32 1, label %bb5
|
||||||
|
i32 2, label %bb1
|
||||||
|
i32 3, label %bb2
|
||||||
|
i32 5, label %bb3
|
||||||
|
]
|
||||||
|
|
||||||
|
bb1: ; preds = %entry
|
||||||
|
ret i32 1
|
||||||
|
|
||||||
|
bb2: ; preds = %entry
|
||||||
|
ret i32 1234
|
||||||
|
|
||||||
|
bb3: ; preds = %entry
|
||||||
|
ret i32 3456
|
||||||
|
|
||||||
|
bb4: ; preds = %entry
|
||||||
|
ret i32 0
|
||||||
|
|
||||||
|
bb5: ; preds = %entry
|
||||||
|
ret i32 12
|
||||||
|
}
|
Loading…
Reference in New Issue