Patch to clean up function call pseudos and support the BLA instruction,
which branches to an absolute address.  This is required to support objc
direct dispatch.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24370 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index 64161b5..ad0a0a0 100644
--- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -735,6 +735,14 @@
   return SDOperand(N, 0);
 }
 
+/// isCallCompatibleAddress - Return true if the specified 32-bit value is
+/// representable in the immediate field of a Bx instruction.
+static bool isCallCompatibleAddress(ConstantSDNode *C) {
+  int Addr = C->getValue();
+  if (Addr & 3) return false;  // Low 2 bits are implicitly zero.
+  return (Addr << 6 >> 6) == Addr;  // Top 6 bits have to be sext of immediate.
+}
+
 SDOperand PPCDAGToDAGISel::SelectCALL(SDOperand Op) {
   SDNode *N = Op.Val;
   SDOperand Chain = Select(N->getOperand(0));
@@ -744,13 +752,18 @@
   
   if (GlobalAddressSDNode *GASD =
       dyn_cast<GlobalAddressSDNode>(N->getOperand(1))) {
-    CallOpcode = PPC::CALLpcrel;
+    CallOpcode = PPC::BL;
     CallOperands.push_back(CurDAG->getTargetGlobalAddress(GASD->getGlobal(),
                                                           MVT::i32));
   } else if (ExternalSymbolSDNode *ESSDN =
              dyn_cast<ExternalSymbolSDNode>(N->getOperand(1))) {
-    CallOpcode = PPC::CALLpcrel;
+    CallOpcode = PPC::BL;
     CallOperands.push_back(N->getOperand(1));
+  } else if (isa<ConstantSDNode>(N->getOperand(1)) &&
+             isCallCompatibleAddress(cast<ConstantSDNode>(N->getOperand(1)))) {
+    ConstantSDNode *C = cast<ConstantSDNode>(N->getOperand(1));
+    CallOpcode = PPC::BLA;
+    CallOperands.push_back(getI32Imm((int)C->getValue() >> 2));
   } else {
     // Copy the callee address into the CTR register.
     SDOperand Callee = Select(N->getOperand(1));
@@ -759,11 +772,9 @@
     // Copy the callee address into R12 on darwin.
     SDOperand R12 = CurDAG->getRegister(PPC::R12, MVT::i32);
     Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, R12, Callee);
-    
-    CallOperands.push_back(getI32Imm(20));  // Information to encode indcall
-    CallOperands.push_back(getI32Imm(0));   // Information to encode indcall
+
     CallOperands.push_back(R12);
-    CallOpcode = PPC::CALLindirect;
+    CallOpcode = PPC::BCTRL;
   }
   
   unsigned GPR_idx = 0, FPR_idx = 0;