auto MJTI = MF->getJumpTableInfo();
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
+ // Only inline jump tables are placed in the function.
+ if (MJTI->getEntryKind() != MachineJumpTableInfo::EK_Inline)
+ return;
+
MachineBasicBlock *LastCorrectlyNumberedBB = nullptr;
for (MachineBasicBlock &MBB : *MF) {
auto MI = MBB.getLastNonDebugInstr();
// Compute block offsets and known bits.
BBUtils->adjustBBOffsetsAfter(&MF->front());
+ // We only care about jump table instructions when jump tables are inline.
+ MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
+ bool InlineJumpTables =
+ MJTI && MJTI->getEntryKind() == MachineJumpTableInfo::EK_Inline;
+
// Now go back through the instructions and build up our data structures.
for (MachineBasicBlock &MBB : *MF) {
// If this block doesn't fall through into the next MBB, then this is
continue; // Ignore other JT branches
case ARM::t2BR_JT:
case ARM::tBR_JTr:
- T2JumpTables.push_back(&I);
+ if (InlineJumpTables)
+ T2JumpTables.push_back(&I);
continue; // Does not get an entry in ImmBranches
case ARM::Bcc:
isCond = true;
// Scan the instructions for constant pool operands.
for (unsigned op = 0, e = I.getNumOperands(); op != e; ++op)
- if (I.getOperand(op).isCPI() || I.getOperand(op).isJTI()) {
+ if (I.getOperand(op).isCPI() ||
+ (I.getOperand(op).isJTI() && InlineJumpTables)) {
// We found one. The addressing mode tells us the max displacement
// from the PC that this instruction permits.
#include "llvm/CodeGen/LivePhysRegs.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Support/Debug.h"
Lower0_7 = Lower0_7.addExternalSymbol(ES, TF | ARMII::MO_LO_0_7);
break;
}
+ case MachineOperand::MO_JumpTableIndex: {
+ unsigned Idx = MO.getIndex();
+ unsigned TF = MO.getTargetFlags();
+ Upper8_15 = Upper8_15.addJumpTableIndex(Idx, TF | ARMII::MO_HI_8_15);
+ Upper0_7 = Upper0_7.addJumpTableIndex(Idx, TF | ARMII::MO_HI_0_7);
+ Lower8_15 = Lower8_15.addJumpTableIndex(Idx, TF | ARMII::MO_LO_8_15);
+ Lower0_7 = Lower0_7.addJumpTableIndex(Idx, TF | ARMII::MO_LO_0_7);
+ break;
+ }
default: {
const GlobalValue *GV = MO.getGlobal();
unsigned TF = MO.getTargetFlags();
ExpandTMOV32BitImm(MBB, MBBI);
return true;
+ case ARM::tLEApcrelJT:
+ // Inline jump tables are handled in ARMAsmPrinter.
+ if (MI.getMF()->getJumpTableInfo()->getEntryKind() ==
+ MachineJumpTableInfo::EK_Inline)
+ return false;
+
+ // Use a 32-bit immediate move to generate the address of the jump table.
+ assert(STI->isThumb() && "Non-inline jump tables expected only in thumb");
+ ExpandTMOV32BitImm(MBB, MBBI);
+ return true;
+
case ARM::SUBS_PC_LR: {
MachineInstrBuilder MIB =
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::SUBri), ARM::PC)
}
unsigned ARMTargetLowering::getJumpTableEncoding() const {
+ // If we don't have a 32-bit pc-relative branch instruction then the jump
+ // table consists of block addresses. Usually this is inline, but for
+ // execute-only it must be placed out-of-line.
+ if (Subtarget->genExecuteOnly() && !Subtarget->hasV8MBaselineOps())
+ return MachineJumpTableInfo::EK_BlockAddress;
return MachineJumpTableInfo::EK_Inline;
}
; CHECK-NEXT: b.w
; CHECK-NEXT: b.w
+; CHECK-T1-LABEL: jump_table:
+; CHECK-T1: lsls [[REG_OFFSET:r[0-9]+]], {{r[0-9]+}}, #2
+; CHECK-T1-NEXT: movs [[REG_JT:r[0-9]+]], :upper8_15:.LJTI1_0
+; CHECK-T1-NEXT: lsls [[REG_JT]], [[REG_JT]], #8
+; CHECK-T1-NEXT: adds [[REG_JT]], :upper0_7:.LJTI1_0
+; CHECK-T1-NEXT: lsls [[REG_JT]], [[REG_JT]], #8
+; CHECK-T1-NEXT: adds [[REG_JT]], :lower8_15:.LJTI1_0
+; CHECK-T1-NEXT: lsls [[REG_JT]], [[REG_JT]], #8
+; CHECK-T1-NEXT: adds [[REG_JT]], :lower0_7:.LJTI1_0
+; CHECK-T1-NEXT: ldr [[REG_ENTRY:r[0-9]+]], [[[REG_JT]], [[REG_OFFSET]]]
+; CHECK-T1-NEXT: mov pc, [[REG_ENTRY]]
+; CHECK-T1: .section .rodata,"a",%progbits
+; CHECK-T1-NEXT: .p2align 2, 0x0
+; CHECK-T1-NEXT: .LJTI1_0:
+; CHECK-T1-NEXT: .long
+; CHECK-T1-NEXT: .long
+; CHECK-T1-NEXT: .long
+; CHECK-T1-NEXT: .long
+; CHECK-T1-NEXT: .long
+; CHECK-T1-NEXT: .long
+
entry:
switch i32 %c, label %return [
i32 1, label %sw.bb