summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2010-09-22 17:39:48 +0000
committerJim Grosbach <grosbach@apple.com>2010-09-22 17:39:48 +0000
commita2244cb38781e596110023399c7902b5ee5087fe (patch)
tree85f07be297f3545cfe9407921cadcf1c69b1b304 /lib
parenteafca4e2b27d5b63d4375291b6db20d66e663c31 (diff)
downloadllvm-a2244cb38781e596110023399c7902b5ee5087fe.tar.gz
llvm-a2244cb38781e596110023399c7902b5ee5087fe.tar.bz2
llvm-a2244cb38781e596110023399c7902b5ee5087fe.tar.xz
Add MC instruction printer support for ARM and Thumb1 jump tables.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114555 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/ARM/ARMAsmPrinter.cpp52
1 files changed, 49 insertions, 3 deletions
diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp
index d2c98b6efe..2577d666cf 100644
--- a/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -1385,6 +1385,47 @@ static MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber,
return Label;
}
+void ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) {
+ unsigned Opcode = MI->getOpcode();
+ int OpNum = 1;
+ if (Opcode == ARM::BR_JTadd)
+ OpNum = 2;
+ else if (Opcode == ARM::BR_JTm)
+ OpNum = 3;
+
+ const MachineOperand &MO1 = MI->getOperand(OpNum);
+ const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
+ unsigned JTI = MO1.getIndex();
+
+ // Emit a label for the jump table.
+ MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
+ OutStreamer.EmitLabel(JTISymbol);
+
+ // Emit each entry of the table.
+ const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
+ const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
+ const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
+
+ for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
+ MachineBasicBlock *MBB = JTBBs[i];
+ // Construct an MCExpr for the entry. We want a value of the form:
+ // (BasicBlockAddr - TableBeginAddr)
+ //
+ // For example, a table with entries jumping to basic blocks BB0 and BB1
+ // would look like:
+ // LJTI_0_0:
+ // .word (LBB0 - LJTI_0_0)
+ // .word (LBB1 - LJTI_0_0)
+ const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext);
+
+ if (TM.getRelocationModel() == Reloc::PIC_)
+ Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol,
+ OutContext),
+ OutContext);
+ OutStreamer.EmitValue(Expr, 4);
+ }
+}
+
void ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) {
unsigned Opcode = MI->getOpcode();
int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1;
@@ -1664,9 +1705,14 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
case ARM::tBR_JTr:
case ARM::BR_JTr:
case ARM::BR_JTm:
- case ARM::BR_JTadd:
- abort();
- break;
+ case ARM::BR_JTadd: {
+ // Lower and emit the instruction itself, then the jump table following it.
+ MCInst TmpInst;
+ MCInstLowering.Lower(MI, TmpInst);
+ OutStreamer.EmitInstruction(TmpInst);
+ EmitJumpTable(MI);
+ return;
+ }
}
MCInst TmpInst;