summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/ARM/ARMAsmPrinter.cpp')
-rw-r--r--llvm/lib/Target/ARM/ARMAsmPrinter.cpp77
1 files changed, 77 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
index ad8a6ed0b6d..836dbc5d985 100644
--- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -1711,6 +1711,83 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
.addReg(0));
return;
}
+ case ARM::tTBB_JT:
+ case ARM::tTBH_JT: {
+
+ bool Is8Bit = MI->getOpcode() == ARM::tTBB_JT;
+ unsigned Base = MI->getOperand(0).getReg();
+ unsigned Idx = MI->getOperand(1).getReg();
+ assert(MI->getOperand(1).isKill() && "We need the index register as scratch!");
+
+ // Multiply up idx if necessary.
+ if (!Is8Bit)
+ EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tLSLri)
+ .addReg(Idx)
+ .addReg(ARM::CPSR)
+ .addReg(Idx)
+ .addImm(1)
+ // Add predicate operands.
+ .addImm(ARMCC::AL)
+ .addReg(0));
+
+ if (Base == ARM::PC) {
+ // TBB [base, idx] =
+ // ADDS idx, idx, base
+ // LDRB idx, [idx, #4] ; or LDRH if TBH
+ // LSLS idx, #1
+ // ADDS pc, pc, idx
+
+ EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tADDhirr)
+ .addReg(Idx)
+ .addReg(Idx)
+ .addReg(Base)
+ // Add predicate operands.
+ .addImm(ARMCC::AL)
+ .addReg(0));
+
+ unsigned Opc = Is8Bit ? ARM::tLDRBi : ARM::tLDRHi;
+ EmitToStreamer(*OutStreamer, MCInstBuilder(Opc)
+ .addReg(Idx)
+ .addReg(Idx)
+ .addImm(Is8Bit ? 4 : 2)
+ // Add predicate operands.
+ .addImm(ARMCC::AL)
+ .addReg(0));
+ } else {
+ // TBB [base, idx] =
+ // LDRB idx, [base, idx] ; or LDRH if TBH
+ // LSLS idx, #1
+ // ADDS pc, pc, idx
+
+ unsigned Opc = Is8Bit ? ARM::tLDRBr : ARM::tLDRHr;
+ EmitToStreamer(*OutStreamer, MCInstBuilder(Opc)
+ .addReg(Idx)
+ .addReg(Base)
+ .addReg(Idx)
+ // Add predicate operands.
+ .addImm(ARMCC::AL)
+ .addReg(0));
+ }
+
+ EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tLSLri)
+ .addReg(Idx)
+ .addReg(ARM::CPSR)
+ .addReg(Idx)
+ .addImm(1)
+ // Add predicate operands.
+ .addImm(ARMCC::AL)
+ .addReg(0));
+
+ OutStreamer->EmitLabel(GetCPISymbol(MI->getOperand(3).getImm()));
+ EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::tADDhirr)
+ .addReg(ARM::PC)
+ .addReg(ARM::PC)
+ .addReg(Idx)
+ // Add predicate operands.
+ .addImm(ARMCC::AL)
+ .addReg(0));
+ return;
+ }
case ARM::tBR_JTr:
case ARM::BR_JTr: {
// Lower and emit the instruction itself, then the jump table following it.
OpenPOWER on IntegriCloud