[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp PPCCodeEmitter.cpp PPCISelDAGToDAG.cpp PPCISelPattern.cpp PPCInstrInfo.td

Nate Begeman natebegeman at mac.com
Tue Nov 15 16:48:20 PST 2005



Changes in directory llvm/lib/Target/PowerPC:

PPCAsmPrinter.cpp updated: 1.109 -> 1.110
PPCCodeEmitter.cpp updated: 1.40 -> 1.41
PPCISelDAGToDAG.cpp updated: 1.125 -> 1.126
PPCISelPattern.cpp updated: 1.191 -> 1.192
PPCInstrInfo.td updated: 1.138 -> 1.139
---
Log message:

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.


---
Diffs of the changes:  (+31 -20)

 PPCAsmPrinter.cpp   |    4 ++++
 PPCCodeEmitter.cpp  |    2 +-
 PPCISelDAGToDAG.cpp |   23 +++++++++++++++++------
 PPCISelPattern.cpp  |    9 +++------
 PPCInstrInfo.td     |   13 ++++++-------
 5 files changed, 31 insertions(+), 20 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.109 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.110
--- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.109	Mon Nov 14 19:45:01 2005
+++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp	Tue Nov 15 18:48:01 2005
@@ -152,6 +152,10 @@
                 TM.getInstrInfo()->isCall(MI->getOpcode()));
       }
     }
+    void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo,
+                             MVT::ValueType VT) {
+     O << (int)MI->getOperand(OpNo).getImmedValue()*4;
+    }
     void printPICLabel(const MachineInstr *MI, unsigned OpNo,
                        MVT::ValueType VT) {
       // FIXME: should probably be converted to cout.width and cout.fill


Index: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp
diff -u llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.40 llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.41
--- llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.40	Sun Oct 16 00:39:50 2005
+++ llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp	Tue Nov 15 18:48:01 2005
@@ -196,7 +196,7 @@
                       MO.getGlobal()->hasWeakLinkage() ||
                       MO.getGlobal()->isExternal();
     unsigned Reloc = 0;
-    if (MI.getOpcode() == PPC::CALLpcrel)
+    if (MI.getOpcode() == PPC::BL)
       Reloc = PPC::reloc_pcrel_bx;
     else {
       switch (MI.getOpcode()) {


Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.125 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.126
--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.125	Fri Oct 28 17:58:07 2005
+++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp	Tue Nov 15 18:48:01 2005
@@ -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;


Index: llvm/lib/Target/PowerPC/PPCISelPattern.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.191 llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.192
--- llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.191	Wed Oct 19 21:15:44 2005
+++ llvm/lib/Target/PowerPC/PPCISelPattern.cpp	Tue Nov 15 18:48:01 2005
@@ -842,18 +842,15 @@
     // Emit the correct call instruction based on the type of symbol called.
     if (GlobalAddressSDNode *GASD =
         dyn_cast<GlobalAddressSDNode>(N.getOperand(1))) {
-      CallMI = BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(GASD->getGlobal(),
-                                                           true);
+      CallMI = BuildMI(PPC::BL, 1).addGlobalAddress(GASD->getGlobal(), true);
     } else if (ExternalSymbolSDNode *ESSDN =
                dyn_cast<ExternalSymbolSDNode>(N.getOperand(1))) {
-      CallMI = BuildMI(PPC::CALLpcrel, 1).addExternalSymbol(ESSDN->getSymbol(),
-                                                            true);
+      CallMI = BuildMI(PPC::BL, 1).addExternalSymbol(ESSDN->getSymbol(), true);
     } else {
       Tmp1 = SelectExpr(N.getOperand(1));
       BuildMI(BB, PPC::MTCTR, 1).addReg(Tmp1);
       BuildMI(BB, PPC::OR4, 2, PPC::R12).addReg(Tmp1).addReg(Tmp1);
-      CallMI = BuildMI(PPC::CALLindirect, 3).addImm(20).addImm(0)
-        .addReg(PPC::R12);
+      CallMI = BuildMI(PPC::BCTRL, 1).addReg(PPC::R12);
     }
 
     // Load the register args to virtual regs


Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.138 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.139
--- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.138	Fri Oct 28 15:32:44 2005
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.td	Tue Nov 15 18:48:01 2005
@@ -128,6 +128,9 @@
 def target : Operand<i32> {
   let PrintMethod = "printBranchOperand";
 }
+def aaddr : Operand<i32> {
+  let PrintMethod = "printAbsAddrOperand";
+}
 def piclabel: Operand<i32> {
   let PrintMethod = "printPICLabel";
 }
@@ -186,9 +189,6 @@
                                 target:$true, target:$false),
                            "; COND_BRANCH", []>;
   def B   : IForm<18, 0, 0, (ops target:$func), "b $func", BrB>;
-//def BA  : IForm<18, 1, 0, (ops target:$func), "ba $func", BrB>;
-  def BL  : IForm<18, 0, 1, (ops target:$func), "bl $func", BrB>;
-//def BLA : IForm<18, 1, 1, (ops target:$func), "bla $func", BrB>;
 
   // FIXME: 4*CR# needs to be added to the BI field!
   // This will only work for CR0 as it stands now
@@ -217,10 +217,9 @@
           LR,CTR,
           CR0,CR1,CR5,CR6,CR7] in {
   // Convenient aliases for call instructions
-  def CALLpcrel : IForm<18, 0, 1, (ops target:$func, variable_ops),
-                        "bl $func", BrB>;
-  def CALLindirect : XLForm_2_ext<19, 528, 20, 0, 1,
-                                  (ops variable_ops), "bctrl", BrB>;
+  def BL  : IForm<18, 0, 1, (ops target:$func, variable_ops), "bl $func", BrB>;
+  def BLA : IForm<18, 1, 1, (ops aaddr:$func, variable_ops), "bla $func", BrB>;
+  def BCTRL : XLForm_2_ext<19, 528, 20, 0, 1, (ops variable_ops), "bctrl", BrB>;
 }
 
 // D-Form instructions.  Most instructions that perform an operation on a






More information about the llvm-commits mailing list