aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/ARM/ARMAsmPrinter.cpp
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2011-03-15 00:30:40 +0000
committerJim Grosbach <grosbach@apple.com>2011-03-15 00:30:40 +0000
commit5edf24efac40062766c643e08f11bc509d373370 (patch)
tree6408ba08b0b38782ac670466078b82f9db4ba4a9 /lib/Target/ARM/ARMAsmPrinter.cpp
parentb9b80c326847ccb1b0611e9b6dc4d372ecc158d3 (diff)
downloadexternal_llvm-5edf24efac40062766c643e08f11bc509d373370.zip
external_llvm-5edf24efac40062766c643e08f11bc509d373370.tar.gz
external_llvm-5edf24efac40062766c643e08f11bc509d373370.tar.bz2
Clean up ARM tail calls a bit. They're pseudo-instructions for normal branches.
Also more cleanly separate the ARM vs. Thumb functionality. Previously, the encoding would be incorrect for some Thumb instructions (the indirect calls). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127637 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/ARMAsmPrinter.cpp')
-rw-r--r--lib/Target/ARM/ARMAsmPrinter.cpp43
1 files changed, 43 insertions, 0 deletions
diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp
index 4c9ab3c..784a661 100644
--- a/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -1707,6 +1707,49 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
}
return;
}
+ // Tail jump branches are really just branch instructions with additional
+ // code-gen attributes. Convert them to the cannonical form here.
+ case ARM::TAILJMPd:
+ case ARM::TAILJMPdND: {
+ MCInst TmpInst, TmpInst2;
+ // Lower the instruction as-is to get the operands properly converted.
+ LowerARMMachineInstrToMCInst(MI, TmpInst2, *this);
+ TmpInst.setOpcode(ARM::Bcc);
+ TmpInst.addOperand(TmpInst2.getOperand(0));
+ // Add predicate operands.
+ TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
+ TmpInst.addOperand(MCOperand::CreateReg(0));
+ OutStreamer.AddComment("TAILCALL");
+ OutStreamer.EmitInstruction(TmpInst);
+ return;
+ }
+ case ARM::tTAILJMPd:
+ case ARM::tTAILJMPdND: {
+ MCInst TmpInst, TmpInst2;
+ LowerARMMachineInstrToMCInst(MI, TmpInst2, *this);
+ TmpInst.setOpcode(ARM::tB);
+ TmpInst.addOperand(TmpInst2.getOperand(0));
+ OutStreamer.AddComment("TAILCALL");
+ OutStreamer.EmitInstruction(TmpInst);
+ return;
+ }
+ case ARM::TAILJMPrND:
+ case ARM::tTAILJMPrND:
+ case ARM::TAILJMPr:
+ case ARM::tTAILJMPr: {
+ unsigned newOpc = (Opc == ARM::TAILJMPr || Opc == ARM::TAILJMPrND)
+ ? ARM::BX : ARM::tBX;
+ MCInst TmpInst;
+ TmpInst.setOpcode(newOpc);
+ TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
+ // Predicate.
+ TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
+ TmpInst.addOperand(MCOperand::CreateReg(0));
+ OutStreamer.AddComment("TAILCALL");
+ OutStreamer.EmitInstruction(TmpInst);
+ return;
+ }
+
// These are the pseudos created to comply with stricter operand restrictions
// on ARMv5. Lower them now to "normal" instructions, since all the
// restrictions are already satisfied.