ARMv4 JIT forgets to set the lr register when making a indirect function call. Fixes...
authorXerxes Ranby <xerxes@zafena.se>
Thu, 22 Jul 2010 17:28:34 +0000 (17:28 +0000)
committerXerxes Ranby <xerxes@zafena.se>
Thu, 22 Jul 2010 17:28:34 +0000 (17:28 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@109125 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMCodeEmitter.cpp
lib/Target/ARM/ARMInstrFormats.td

index d5896a3f7cdc0cfeba27332926c346f081045a8e..93f617db64fdd02d634709e15d489033fe9cbf96 100644 (file)
@@ -654,6 +654,19 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
   switch (Opcode) {
   default:
     llvm_unreachable("ARMCodeEmitter::emitPseudoInstruction");
+  case ARM::BX:
+  case ARM::BMOVPCRX:
+  case ARM::BXr9:
+  case ARM::BMOVPCRXr9: {
+    // First emit mov lr, pc
+    unsigned Binary = 0x01a0e00f;
+    Binary |= II->getPredicate(&MI) << ARMII::CondShift;
+    emitWordLE(Binary);
+
+    // and then emit the branch.
+    emitMiscBranchInstruction(MI);
+    break;
+  }
   case TargetOpcode::INLINEASM: {
     // We allow inline assembler nodes with empty bodies - they can
     // implicitly define registers, which is ok for JIT.
index ac568e75ccc466d712c2ba0bf2f03e00b2f10fb1..74cdd9071e880863f36ccb8ac2de406e8d058357 100644 (file)
@@ -313,7 +313,7 @@ class ABXI<bits<4> opcod, dag oops, dag iops, InstrItinClass itin,
 }
 class ABXIx2<dag oops, dag iops, InstrItinClass itin,
              string asm, list<dag> pattern>
-  : XI<oops, iops, AddrModeNone, Size8Bytes, IndexModeNone, BrMiscFrm, itin,
+  : XI<oops, iops, AddrModeNone, Size8Bytes, IndexModeNone, Pseudo, itin,
        asm, "", pattern>;
 
 // BR_JT instructions