[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp PPCFrameInfo.h PPCHazardRecognizers.cpp PPCISelLowering.cpp PPCISelLowering.h PPCInstr64Bit.td PPCInstrInfo.td PPCRegisterInfo.cpp

Chris Lattner sabre at nondot.org
Sat Feb 24 21:34:49 PST 2007



Changes in directory llvm/lib/Target/PowerPC:

PPCCodeEmitter.cpp updated: 1.74 -> 1.75
PPCFrameInfo.h updated: 1.12 -> 1.13
PPCHazardRecognizers.cpp updated: 1.18 -> 1.19
PPCISelLowering.cpp updated: 1.253 -> 1.254
PPCISelLowering.h updated: 1.58 -> 1.59
PPCInstr64Bit.td updated: 1.38 -> 1.39
PPCInstrInfo.td updated: 1.272 -> 1.273
PPCRegisterInfo.cpp updated: 1.111 -> 1.112
---
Log message:

implement support for the linux/ppc function call ABI.  Patch by
Nicolas Geoffray!



---
Diffs of the changes:  (+343 -102)

 PPCCodeEmitter.cpp       |    7 +-
 PPCFrameInfo.h           |   50 +++++++++++----
 PPCHazardRecognizers.cpp |    2 
 PPCISelLowering.cpp      |  149 ++++++++++++++++++++++++++++++-----------------
 PPCISelLowering.h        |    2 
 PPCInstr64Bit.td         |   44 +++++++++++--
 PPCInstrInfo.td          |   64 ++++++++++++++++----
 PPCRegisterInfo.cpp      |  127 ++++++++++++++++++++++++++++++++++++----
 8 files changed, 343 insertions(+), 102 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp
diff -u llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.74 llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.75
--- llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.74	Fri Dec 15 10:44:10 2006
+++ llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp	Sat Feb 24 23:34:32 2007
@@ -133,7 +133,8 @@
   } else if (MO.isGlobalAddress() || MO.isExternalSymbol() ||
              MO.isConstantPoolIndex() || MO.isJumpTableIndex()) {
     unsigned Reloc = 0;
-    if (MI.getOpcode() == PPC::BL || MI.getOpcode() == PPC::BL8)
+    if (MI.getOpcode() == PPC::BL_Macho || MI.getOpcode() == PPC::BL8_Macho ||
+        MI.getOpcode() == PPC::BL_ELF || MI.getOpcode() == PPC::BL8_ELF)
       Reloc = PPC::reloc_pcrel_bx;
     else {
       if (TM.getRelocationModel() == Reloc::PIC_) {
@@ -213,7 +214,9 @@
   } else if (MO.isMachineBasicBlock()) {
     unsigned Reloc = 0;
     unsigned Opcode = MI.getOpcode();
-    if (Opcode == PPC::B || Opcode == PPC::BL || Opcode == PPC::BLA)
+    if (Opcode == PPC::B || Opcode == PPC::BL_Macho ||
+        Opcode == PPC::BLA_Macho || Opcode == PPC::BL_ELF || 
+        Opcode == PPC::BLA_ELF)
       Reloc = PPC::reloc_pcrel_bx;
     else // BCC instruction
       Reloc = PPC::reloc_pcrel_bcx;


Index: llvm/lib/Target/PowerPC/PPCFrameInfo.h
diff -u llvm/lib/Target/PowerPC/PPCFrameInfo.h:1.12 llvm/lib/Target/PowerPC/PPCFrameInfo.h:1.13
--- llvm/lib/Target/PowerPC/PPCFrameInfo.h:1.12	Wed Dec  6 11:42:06 2006
+++ llvm/lib/Target/PowerPC/PPCFrameInfo.h	Sat Feb 24 23:34:32 2007
@@ -29,41 +29,61 @@
 
   /// getReturnSaveOffset - Return the previous frame offset to save the
   /// return address.
-  static unsigned getReturnSaveOffset(bool LP64) {
-    return LP64 ? 16 : 8;
+  static unsigned getReturnSaveOffset(bool LP64, bool isMacho) {
+    if (isMacho)
+      return LP64 ? 16 : 8;
+    // For ELF ABI:
+    return LP64 ? 8 : 4;
   }
 
   /// getFramePointerSaveOffset - Return the previous frame offset to save the
   /// frame pointer.
-  static unsigned getFramePointerSaveOffset(bool LP64) {
+  static unsigned getFramePointerSaveOffset(bool LP64, bool isMacho) {
+    // For MachO ABI:
     // Use the TOC save slot in the PowerPC linkage area for saving the frame
     // pointer (if needed.)  LLVM does not generate code that uses the TOC (R2
     // is treated as a caller saved register.)
-    return LP64 ? 40 : 20;
+    if (isMacho)
+      return LP64 ? 40 : 20;
+    
+    // For ELF ABI:
+    // Save it right before the link register
+    return LP64 ? -8 : -4;
   }
   
   /// getLinkageSize - Return the size of the PowerPC ABI linkage area.
   ///
-  static unsigned getLinkageSize(bool LP64) {
-    return 6 * (LP64 ? 8 : 4);
+  static unsigned getLinkageSize(bool LP64, bool isMacho) {
+    if (isMacho)
+      return 6 * (LP64 ? 8 : 4);
+    
+    // For ELF ABI:
+    return LP64 ? 16 : 8;
   }
 
   /// getMinCallArgumentsSize - Return the size of the minium PowerPC ABI
   /// argument area.
-  static unsigned getMinCallArgumentsSize(bool LP64) {
-   // The prolog code of the callee may store up to 8 GPR argument registers to
-   // the stack, allowing va_start to index over them in memory if its varargs.
-   // Because we cannot tell if this is needed on the caller side, we have to
-   // conservatively assume that it is needed.  As such, make sure we have at
-   // least enough stack space for the caller to store the 8 GPRs.
-    return 8 * (LP64 ? 8 : 4);
+  static unsigned getMinCallArgumentsSize(bool LP64, bool isMacho) {
+    // For Macho ABI:
+    // The prolog code of the callee may store up to 8 GPR argument registers to
+    // the stack, allowing va_start to index over them in memory if its varargs.
+    // Because we cannot tell if this is needed on the caller side, we have to
+    // conservatively assume that it is needed.  As such, make sure we have at
+    // least enough stack space for the caller to store the 8 GPRs.
+    if (isMacho)
+      return 8 * (LP64 ? 8 : 4);
+    
+    // For Linux ABI:
+    // There is no default stack allocated for the 8 first GPR arguments.
+    return 0;
   }
 
   /// getMinCallFrameSize - Return the minimum size a call frame can be using
   /// the PowerPC ABI.
-  static unsigned getMinCallFrameSize(bool LP64) {
+  static unsigned getMinCallFrameSize(bool LP64, bool isMacho) {
     // The call frame needs to be at least big enough for linkage and 8 args.
-    return getLinkageSize(LP64) + getMinCallArgumentsSize(LP64);
+    return getLinkageSize(LP64, isMacho) +
+           getMinCallArgumentsSize(LP64, isMacho);
   }
   
 };


Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp
diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.18 llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.19
--- llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.18	Thu Dec  7 16:21:48 2006
+++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp	Sat Feb 24 23:34:32 2007
@@ -157,7 +157,7 @@
   }
   
   // Do not allow MTCTR and BCTRL to be in the same dispatch group.
-  if (HasCTRSet && Opcode == PPC::BCTRL)
+  if (HasCTRSet && Opcode == PPC::BCTRL_Macho || Opcode == PPC::BCTRL_ELF)
     return NoopHazard;
   
   // If this is a load following a store, make sure it's not to the same or


Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.253 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.254
--- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.253	Thu Feb 22 08:56:36 2007
+++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp	Sat Feb 24 23:34:32 2007
@@ -328,7 +328,8 @@
   case PPCISD::STD_32:        return "PPCISD::STD_32";
   case PPCISD::CALL:          return "PPCISD::CALL";
   case PPCISD::MTCTR:         return "PPCISD::MTCTR";
-  case PPCISD::BCTRL:         return "PPCISD::BCTRL";
+  case PPCISD::BCTRL_Macho:   return "PPCISD::BCTRL_Macho";
+  case PPCISD::BCTRL_ELF:     return "PPCISD::BCTRL_ELF";
   case PPCISD::RET_FLAG:      return "PPCISD::RET_FLAG";
   case PPCISD::MFCR:          return "PPCISD::MFCR";
   case PPCISD::VCMP:          return "PPCISD::VCMP";
@@ -1094,8 +1095,28 @@
                       SV->getOffset());
 }
 
+/// GetFPR - Get the set of FP registers that should be allocated for arguments,
+/// depending on which subtarget is selected.
+static const unsigned *GetFPR(const PPCSubtarget &Subtarget) {
+  if (Subtarget.isMachoABI()) {
+    static const unsigned FPR[] = {
+      PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
+      PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13
+    };
+    return FPR;
+  }
+  
+  
+  static const unsigned FPR[] = {
+    PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
+    PPC::F8, PPC::F9, PPC::F10
+  };
+  return FPR;
+}
+
 static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
-                                       int &VarArgsFrameIndex) {
+                                       int &VarArgsFrameIndex,
+                                       const PPCSubtarget &Subtarget) {
   // TODO: add description of PPC stack frame format, or at least some docs.
   //
   MachineFunction &MF = DAG.getMachineFunction();
@@ -1106,9 +1127,10 @@
   
   MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
   bool isPPC64 = PtrVT == MVT::i64;
+  bool isMachoABI = Subtarget.isMachoABI();
   unsigned PtrByteSize = isPPC64 ? 8 : 4;
 
-  unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64);
+  unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI);
   
   static const unsigned GPR_32[] = {           // 32-bit registers.
     PPC::R3, PPC::R4, PPC::R5, PPC::R6,
@@ -1118,17 +1140,16 @@
     PPC::X3, PPC::X4, PPC::X5, PPC::X6,
     PPC::X7, PPC::X8, PPC::X9, PPC::X10,
   };
-  static const unsigned FPR[] = {
-    PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
-    PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13
-  };
+  
+  static const unsigned *FPR = GetFPR(Subtarget);
+  
   static const unsigned VR[] = {
     PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
     PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
   };
 
   const unsigned Num_GPR_Regs = sizeof(GPR_32)/sizeof(GPR_32[0]);
-  const unsigned Num_FPR_Regs = sizeof(FPR)/sizeof(FPR[0]);
+  const unsigned Num_FPR_Regs = isMachoABI ? 13 : 10;
   const unsigned Num_VR_Regs  = sizeof( VR)/sizeof( VR[0]);
 
   unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
@@ -1149,9 +1170,6 @@
     switch (ObjectVT) {
     default: assert(0 && "Unhandled argument type!");
     case MVT::i32:
-      // All int arguments reserve stack space.
-      ArgOffset += PtrByteSize;
-
       if (GPR_idx != Num_GPR_Regs) {
         unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
         MF.addLiveIn(GPR[GPR_idx], VReg);
@@ -1161,11 +1179,11 @@
         needsLoad = true;
         ArgSize = PtrByteSize;
       }
+      // All int arguments reserve stack space in Macho ABI.
+      if (isMachoABI || needsLoad) ArgOffset += PtrByteSize;
       break;
-    case MVT::i64:  // PPC64
-      // All int arguments reserve stack space.
-      ArgOffset += 8;
       
+    case MVT::i64:  // PPC64
       if (GPR_idx != Num_GPR_Regs) {
         unsigned VReg = RegMap->createVirtualRegister(&PPC::G8RCRegClass);
         MF.addLiveIn(GPR[GPR_idx], VReg);
@@ -1174,12 +1192,12 @@
       } else {
         needsLoad = true;
       }
+      // All int arguments reserve stack space in Macho ABI.
+      if (isMachoABI || needsLoad) ArgOffset += 8;
       break;
+      
     case MVT::f32:
     case MVT::f64:
-      // All FP arguments reserve stack space.
-      ArgOffset += isPPC64 ? 8 : ObjSize;
-
       // Every 4 bytes of argument space consumes one of the GPRs available for
       // argument passing.
       if (GPR_idx != Num_GPR_Regs) {
@@ -1199,6 +1217,9 @@
       } else {
         needsLoad = true;
       }
+      
+      // All FP arguments reserve stack space in Macho ABI.
+      if (isMachoABI || needsLoad) ArgOffset += isPPC64 ? 8 : ObjSize;
       break;
     case MVT::v4f32:
     case MVT::v4i32:
@@ -1290,11 +1311,15 @@
   return DAG.getConstant((int)C->getValue() >> 2, MVT::i32).Val;
 }
 
-static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
-  SDOperand Chain = Op.getOperand(0);
-  bool isVarArg       = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
-  SDOperand Callee    = Op.getOperand(4);
-  unsigned NumOps     = (Op.getNumOperands() - 5) / 2;
+
+static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG,
+                           const PPCSubtarget &Subtarget) {
+  SDOperand Chain  = Op.getOperand(0);
+  bool isVarArg    = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
+  SDOperand Callee = Op.getOperand(4);
+  unsigned NumOps  = (Op.getNumOperands() - 5) / 2;
+  
+  bool isMachoABI = Subtarget.isMachoABI();
 
   MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
   bool isPPC64 = PtrVT == MVT::i64;
@@ -1307,7 +1332,7 @@
   // Count how many bytes are to be pushed on the stack, including the linkage
   // area, and parameter passing area.  We start with 24/48 bytes, which is
   // prereserved space for [SP][CR][LR][3 x unused].
-  unsigned NumBytes = PPCFrameInfo::getLinkageSize(isPPC64);
+  unsigned NumBytes = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI);
   
   // Add up all the space actually used.
   for (unsigned i = 0; i != NumOps; ++i) {
@@ -1321,7 +1346,8 @@
   // Because we cannot tell if this is needed on the caller side, we have to
   // conservatively assume that it is needed.  As such, make sure we have at
   // least enough stack space for the caller to store the 8 GPRs.
-  NumBytes = std::max(NumBytes, PPCFrameInfo::getMinCallFrameSize(isPPC64));
+  NumBytes = std::max(NumBytes,
+                      PPCFrameInfo::getMinCallFrameSize(isPPC64, isMachoABI));
   
   // Adjust the stack pointer for the new arguments...
   // These operations are automatically eliminated by the prolog/epilog pass
@@ -1341,7 +1367,7 @@
   // memory.  Also, if this is a vararg function, floating point operations
   // must be stored to our stack, and loaded into integer regs as well, if
   // any integer regs are available for argument passing.
-  unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64);
+  unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI);
   unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
   
   static const unsigned GPR_32[] = {           // 32-bit registers.
@@ -1352,16 +1378,14 @@
     PPC::X3, PPC::X4, PPC::X5, PPC::X6,
     PPC::X7, PPC::X8, PPC::X9, PPC::X10,
   };
-  static const unsigned FPR[] = {
-    PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
-    PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13
-  };
+  static const unsigned *FPR = GetFPR(Subtarget);
+  
   static const unsigned VR[] = {
     PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
     PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
   };
   const unsigned NumGPRs = sizeof(GPR_32)/sizeof(GPR_32[0]);
-  const unsigned NumFPRs = sizeof(FPR)/sizeof(FPR[0]);
+  const unsigned NumFPRs = isMachoABI ? 13 : 10;
   const unsigned NumVRs  = sizeof( VR)/sizeof( VR[0]);
   
   const unsigned *GPR = isPPC64 ? GPR_64 : GPR_32;
@@ -1369,6 +1393,7 @@
   std::vector<std::pair<unsigned, SDOperand> > RegsToPass;
   SmallVector<SDOperand, 8> MemOpChains;
   for (unsigned i = 0; i != NumOps; ++i) {
+    bool inMem = false;
     SDOperand Arg = Op.getOperand(5+2*i);
     
     // PtrOff will be used to store the current argument to the stack if a
@@ -1392,8 +1417,9 @@
         RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Arg));
       } else {
         MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
+        inMem = true;
       }
-      ArgOffset += PtrByteSize;
+      if (inMem || isMachoABI) ArgOffset += PtrByteSize;
       break;
     case MVT::f32:
     case MVT::f64:
@@ -1414,31 +1440,39 @@
           if (GPR_idx != NumGPRs) {
             SDOperand Load = DAG.getLoad(PtrVT, Store, PtrOff, NULL, 0);
             MemOpChains.push_back(Load.getValue(1));
-            RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));
+            if (isMachoABI) RegsToPass.push_back(std::make_pair(GPR[GPR_idx++],
+                                                                Load));
           }
           if (GPR_idx != NumGPRs && Arg.getValueType() == MVT::f64 && !isPPC64){
             SDOperand ConstFour = DAG.getConstant(4, PtrOff.getValueType());
             PtrOff = DAG.getNode(ISD::ADD, PtrVT, PtrOff, ConstFour);
             SDOperand Load = DAG.getLoad(PtrVT, Store, PtrOff, NULL, 0);
             MemOpChains.push_back(Load.getValue(1));
-            RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));
+            if (isMachoABI) RegsToPass.push_back(std::make_pair(GPR[GPR_idx++],
+                                                                Load));
           }
         } else {
           // If we have any FPRs remaining, we may also have GPRs remaining.
           // Args passed in FPRs consume either 1 (f32) or 2 (f64) available
           // GPRs.
-          if (GPR_idx != NumGPRs)
-            ++GPR_idx;
-          if (GPR_idx != NumGPRs && Arg.getValueType() == MVT::f64 && !isPPC64)
-            ++GPR_idx;
+          if (isMachoABI) {
+            if (GPR_idx != NumGPRs)
+              ++GPR_idx;
+            if (GPR_idx != NumGPRs && Arg.getValueType() == MVT::f64 &&
+                !isPPC64)  // PPC64 has 64-bit GPR's obviously :)
+              ++GPR_idx;
+          }
         }
       } else {
         MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
+        inMem = true;
+      }
+      if (inMem || isMachoABI) {
+        if (isPPC64)
+          ArgOffset += 8;
+        else
+          ArgOffset += Arg.getValueType() == MVT::f32 ? 4 : 8;
       }
-      if (isPPC64)
-        ArgOffset += 8;
-      else
-        ArgOffset += Arg.getValueType() == MVT::f32 ? 4 : 8;
       break;
     case MVT::v4f32:
     case MVT::v4i32:
@@ -1463,7 +1497,14 @@
                              InFlag);
     InFlag = Chain.getValue(1);
   }
-  
+ 
+  // With the ELF ABI, set CR6 to true if this is a vararg call.
+  if (isVarArg && !isMachoABI) {
+    SDOperand SetCR(DAG.getTargetNode(PPC::SETCR, MVT::i32), 0);
+    Chain = DAG.getCopyToReg(Chain, PPC::CR6, SetCR, InFlag);
+    InFlag = Chain.getValue(1);
+  }
+
   std::vector<MVT::ValueType> NodeTys;
   NodeTys.push_back(MVT::Other);   // Returns a chain
   NodeTys.push_back(MVT::Flag);    // Returns a flag for retval copy to use.
@@ -1489,14 +1530,16 @@
     InFlag = Chain.getValue(1);
     
     // Copy the callee address into R12 on darwin.
-    Chain = DAG.getCopyToReg(Chain, PPC::R12, Callee, InFlag);
-    InFlag = Chain.getValue(1);
+    if (isMachoABI) {
+      Chain = DAG.getCopyToReg(Chain, PPC::R12, Callee, InFlag);
+      InFlag = Chain.getValue(1);
+    }
 
     NodeTys.clear();
     NodeTys.push_back(MVT::Other);
     NodeTys.push_back(MVT::Flag);
     Ops.push_back(Chain);
-    CallOpc = PPCISD::BCTRL;
+    CallOpc = isMachoABI ? PPCISD::BCTRL_Macho : PPCISD::BCTRL_ELF;
     Callee.Val = 0;
   }
 
@@ -1656,18 +1699,20 @@
                                          const PPCSubtarget &Subtarget) {
   MachineFunction &MF = DAG.getMachineFunction();
   bool IsPPC64 = Subtarget.isPPC64();
+  bool isMachoABI = Subtarget.isMachoABI();
 
   // Get current frame pointer save index.  The users of this index will be
   // primarily DYNALLOC instructions.
   PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
   int FPSI = FI->getFramePointerSaveIndex();
-  
+   
   // If the frame pointer save index hasn't been defined yet.
   if (!FPSI) {
     // Find out what the fix offset of the frame pointer save area.
-    int Offset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64);
+    int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64, isMachoABI);
+    
     // Allocate the frame index for frame pointer save area.
-    FPSI = MF.getFrameInfo()->CreateFixedObject(IsPPC64? 8 : 4, Offset); 
+    FPSI = MF.getFrameInfo()->CreateFixedObject(IsPPC64? 8 : 4, FPOffset); 
     // Save the result.
     FI->setFramePointerSaveIndex(FPSI);                      
   }
@@ -2630,12 +2675,12 @@
   case ISD::SETCC:              return LowerSETCC(Op, DAG);
   case ISD::VASTART:            return LowerVASTART(Op, DAG, VarArgsFrameIndex);
   case ISD::FORMAL_ARGUMENTS:
-      return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
-  case ISD::CALL:               return LowerCALL(Op, DAG);
+    return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex, PPCSubTarget);
+  case ISD::CALL:               return LowerCALL(Op, DAG, PPCSubTarget);
   case ISD::RET:                return LowerRET(Op, DAG);
   case ISD::STACKRESTORE:       return LowerSTACKRESTORE(Op, DAG, PPCSubTarget);
-  case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG,
-                                                               PPCSubTarget);
+  case ISD::DYNAMIC_STACKALLOC:
+    return LowerDYNAMIC_STACKALLOC(Op, DAG, PPCSubTarget);
     
   case ISD::SELECT_CC:          return LowerSELECT_CC(Op, DAG);
   case ISD::FP_TO_SINT:         return LowerFP_TO_SINT(Op, DAG);


Index: llvm/lib/Target/PowerPC/PPCISelLowering.h
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.58 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.59
--- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.58	Fri Jan 26 16:40:50 2007
+++ llvm/lib/Target/PowerPC/PPCISelLowering.h	Sat Feb 24 23:34:32 2007
@@ -90,7 +90,7 @@
       
       /// CHAIN,FLAG = BCTRL(CHAIN, INFLAG) - Directly corresponds to a
       /// BCTRL instruction.
-      BCTRL,
+      BCTRL_Macho, BCTRL_ELF,
       
       /// Return with a flag operand, matched by 'blr'
       RET_FLAG,


Index: llvm/lib/Target/PowerPC/PPCInstr64Bit.td
diff -u llvm/lib/Target/PowerPC/PPCInstr64Bit.td:1.38 llvm/lib/Target/PowerPC/PPCInstr64Bit.td:1.39
--- llvm/lib/Target/PowerPC/PPCInstr64Bit.td:1.38	Fri Dec 15 15:39:31 2006
+++ llvm/lib/Target/PowerPC/PPCInstr64Bit.td	Sat Feb 24 23:34:32 2007
@@ -69,6 +69,7 @@
   def MovePCtoLR8 : Pseudo<(ops piclabel:$label), "bl $label", []>,
                     PPC970_Unit_BRU;
 
+// Macho ABI Calls.
 let isCall = 1, noResults = 1, PPC970_Unit = 7, 
   // All calls clobber the PPC64 non-callee saved registers.
   Defs = [X0,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12,
@@ -77,18 +78,45 @@
           LR8,CTR8,
           CR0,CR1,CR5,CR6,CR7] in {
   // Convenient aliases for call instructions
-  def BL8  : IForm<18, 0, 1, (ops calltarget:$func, variable_ops), 
-                            "bl $func", BrB, []>;  // See Pat patterns below.
+  def BL8_Macho  : IForm<18, 0, 1,
+                         (ops calltarget:$func, variable_ops), 
+                         "bl $func", BrB, []>;  // See Pat patterns below.
                             
-  def BLA8 : IForm<18, 1, 1, (ops aaddr:$func, variable_ops),
-                   "bla $func", BrB, [(PPCcall (i64 imm:$func))]>;
+  def BLA8_Macho : IForm<18, 1, 1,
+                         (ops aaddr:$func, variable_ops),
+                         "bla $func", BrB, [(PPCcall_Macho (i64 imm:$func))]>;
 }
 
+// ELF ABI Calls.
+let isCall = 1, noResults = 1, PPC970_Unit = 7, 
+  // All calls clobber the PPC64 non-callee saved registers.
+  Defs = [X0,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12,
+          F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,
+          V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16,V17,V18,V19,
+          LR8,CTR8,
+          CR0,CR1,CR5,CR6,CR7] in {
+  // Convenient aliases for call instructions
+  def BL8_ELF  : IForm<18, 0, 1,
+                       (ops calltarget:$func, variable_ops), 
+                       "bl $func", BrB, []>;  // See Pat patterns below.
+                            
+  def BLA8_ELF : IForm<18, 1, 1,
+                       (ops aaddr:$func, variable_ops),
+                       "bla $func", BrB, [(PPCcall_ELF (i64 imm:$func))]>;
+}
+
+
 // Calls
-def : Pat<(PPCcall (i64 tglobaladdr:$dst)),
-          (BL8 tglobaladdr:$dst)>;
-def : Pat<(PPCcall (i64 texternalsym:$dst)),
-          (BL8 texternalsym:$dst)>;
+def : Pat<(PPCcall_Macho (i64 tglobaladdr:$dst)),
+          (BL8_Macho tglobaladdr:$dst)>;
+def : Pat<(PPCcall_Macho (i64 texternalsym:$dst)),
+          (BL8_Macho texternalsym:$dst)>;
+
+def : Pat<(PPCcall_ELF (i64 tglobaladdr:$dst)),
+          (BL8_ELF tglobaladdr:$dst)>;
+def : Pat<(PPCcall_ELF (i64 texternalsym:$dst)),
+          (BL8_ELF texternalsym:$dst)>;
+
 
 //===----------------------------------------------------------------------===//
 // 64-bit SPR manipulation instrs.


Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.272 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.273
--- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.272	Fri Jan 26 08:34:51 2007
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.td	Sat Feb 24 23:34:32 2007
@@ -81,11 +81,16 @@
                            [SDNPHasChain, SDNPOutFlag]>;
 
 def SDT_PPCCall   : SDTypeProfile<0, -1, [SDTCisInt<0>]>;
-def PPCcall       : SDNode<"PPCISD::CALL", SDT_PPCCall,
+def PPCcall_Macho : SDNode<"PPCISD::CALL", SDT_PPCCall,
+                           [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
+def PPCcall_ELF   : SDNode<"PPCISD::CALL", SDT_PPCCall,
                            [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
 def PPCmtctr      : SDNode<"PPCISD::MTCTR", SDT_PPCCall,
                            [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
-def PPCbctrl      : SDNode<"PPCISD::BCTRL", SDTRet,
+def PPCbctrl_Macho  : SDNode<"PPCISD::BCTRL_Macho", SDTRet,
+	                   [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
+
+def PPCbctrl_ELF  : SDNode<"PPCISD::BCTRL_ELF", SDTRet,
 	                   [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
 
 def retflag       : SDNode<"PPCISD::RET_FLAG", SDTRet,
@@ -366,6 +371,7 @@
                   /*[(PPCcondbranch CRRC:$crS, imm:$opc, bb:$dst)]*/>;
 }
 
+// Macho ABI Calls.
 let isCall = 1, noResults = 1, PPC970_Unit = 7, 
   // All calls clobber the non-callee saved registers...
   Defs = [R0,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,
@@ -374,12 +380,38 @@
           LR,CTR,
           CR0,CR1,CR5,CR6,CR7] in {
   // Convenient aliases for call instructions
-  def BL  : IForm<18, 0, 1, (ops calltarget:$func, variable_ops), 
-                            "bl $func", BrB, []>;  // See Pat patterns below.
-  def BLA : IForm<18, 1, 1, (ops aaddr:$func, variable_ops),
-                            "bla $func", BrB, [(PPCcall (i32 imm:$func))]>;
-  def BCTRL : XLForm_2_ext<19, 528, 20, 0, 1, (ops variable_ops), "bctrl", BrB,
-                           [(PPCbctrl)]>;
+  def BL_Macho  : IForm<18, 0, 1,
+                        (ops calltarget:$func, variable_ops), 
+                        "bl $func", BrB, []>;  // See Pat patterns below.
+  def BLA_Macho : IForm<18, 1, 1, 
+                        (ops aaddr:$func, variable_ops),
+                        "bla $func", BrB, [(PPCcall_Macho (i32 imm:$func))]>;
+  def BCTRL_Macho : XLForm_2_ext<19, 528, 20, 0, 1, 
+                                 (ops variable_ops),
+                                 "bctrl", BrB,
+                                 [(PPCbctrl_Macho)]>;
+}
+
+// ELF ABI Calls.
+let isCall = 1, noResults = 1, PPC970_Unit = 7, 
+  // All calls clobber the non-callee saved registers...
+  Defs = [R0,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,
+          F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,
+          V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16,V17,V18,V19,
+          LR,CTR,
+          CR0,CR1,CR5,CR6,CR7] in {
+  // Convenient aliases for call instructions
+  def BL_ELF  : IForm<18, 0, 1,
+                      (ops calltarget:$func, variable_ops), 
+                      "bl $func", BrB, []>;  // See Pat patterns below.
+  def BLA_ELF : IForm<18, 1, 1,
+                      (ops aaddr:$func, variable_ops),
+                      "bla $func", BrB,
+                      [(PPCcall_ELF (i32 imm:$func))]>;
+  def BCTRL_ELF : XLForm_2_ext<19, 528, 20, 0, 1,
+                               (ops variable_ops),
+                               "bctrl", BrB,
+                               [(PPCbctrl_ELF)]>;
 }
 
 // DCB* instructions.
@@ -791,6 +823,14 @@
                       "mcrf $BF, $BFA", BrMCR>,
              PPC970_DGroup_First, PPC970_Unit_CRU;
 
+def CREQV  : XLForm_1<19, 289, (ops CRRC:$CRD, CRRC:$CRA, CRRC:$CRB),
+                      "creqv $CRD, $CRA, $CRB", BrCR,
+                      []>;
+
+def SETCR  : XLForm_1_ext<19, 289, (ops CRRC:$dst),
+              "creqv $dst, $dst, $dst", BrCR,
+              []>;
+
 // XFX-Form instructions.  Instructions that deal with SPRs.
 //
 def MFCTR : XFXForm_1_ext<31, 339, 9, (ops GPRC:$rT), "mfctr $rT", SprMFSPR>,
@@ -1060,10 +1100,10 @@
           (RLWNM GPRC:$in, GPRC:$sh, (MB maskimm32:$imm), (ME maskimm32:$imm))>;
 
 // Calls
-def : Pat<(PPCcall (i32 tglobaladdr:$dst)),
-          (BL tglobaladdr:$dst)>;
-def : Pat<(PPCcall (i32 texternalsym:$dst)),
-          (BL texternalsym:$dst)>;
+def : Pat<(PPCcall_Macho (i32 tglobaladdr:$dst)),
+          (BL_Macho tglobaladdr:$dst)>;
+def : Pat<(PPCcall_ELF (i32 texternalsym:$dst)),
+          (BL_ELF texternalsym:$dst)>;
 
 // Hi and Lo for Darwin Global Addresses.
 def : Pat<(PPChi tglobaladdr:$in, 0), (LIS tglobaladdr:$in)>;


Index: llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
diff -u llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.111 llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.112
--- llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.111	Fri Feb 23 14:34:16 2007
+++ llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp	Sat Feb 24 23:34:32 2007
@@ -261,6 +261,28 @@
     
     PPC::LR,  0
   };
+  
+  static const unsigned ELF32_CalleeSavedRegs[] = {
+              PPC::R13, PPC::R14, PPC::R15,
+    PPC::R16, PPC::R17, PPC::R18, PPC::R19,
+    PPC::R20, PPC::R21, PPC::R22, PPC::R23,
+    PPC::R24, PPC::R25, PPC::R26, PPC::R27,
+    PPC::R28, PPC::R29, PPC::R30, PPC::R31,
+
+              PPC::F11, PPC::F12, PPC::F13,
+    PPC::F14, PPC::F15, PPC::F16, PPC::F17,
+    PPC::F18, PPC::F19, PPC::F20, PPC::F21,
+    PPC::F22, PPC::F23, PPC::F24, PPC::F25,
+    PPC::F26, PPC::F27, PPC::F28, PPC::F29,
+    PPC::F30, PPC::F31,
+    
+    PPC::CR2, PPC::CR3, PPC::CR4,
+    PPC::V20, PPC::V21, PPC::V22, PPC::V23,
+    PPC::V24, PPC::V25, PPC::V26, PPC::V27,
+    PPC::V28, PPC::V29, PPC::V30, PPC::V31,
+    
+    PPC::LR,  0
+  };
   // 64-bit Darwin calling convention. 
   static const unsigned Darwin64_CalleeSavedRegs[] = {
     PPC::X14, PPC::X15,
@@ -283,8 +305,34 @@
     PPC::LR8,  0
   };
   
-  return Subtarget.isPPC64() ? Darwin64_CalleeSavedRegs :
-                               Darwin32_CalleeSavedRegs;
+  static const unsigned ELF64_CalleeSavedRegs[] = {
+    PPC::X14, PPC::X15,
+    PPC::X16, PPC::X17, PPC::X18, PPC::X19,
+    PPC::X20, PPC::X21, PPC::X22, PPC::X23,
+    PPC::X24, PPC::X25, PPC::X26, PPC::X27,
+    PPC::X28, PPC::X29, PPC::X30, PPC::X31,
+    
+              PPC::F11, PPC::F12, PPC::F13,
+    PPC::F14, PPC::F15, PPC::F16, PPC::F17,
+    PPC::F18, PPC::F19, PPC::F20, PPC::F21,
+    PPC::F22, PPC::F23, PPC::F24, PPC::F25,
+    PPC::F26, PPC::F27, PPC::F28, PPC::F29,
+    PPC::F30, PPC::F31,
+    
+    PPC::CR2, PPC::CR3, PPC::CR4,
+    PPC::V20, PPC::V21, PPC::V22, PPC::V23,
+    PPC::V24, PPC::V25, PPC::V26, PPC::V27,
+    PPC::V28, PPC::V29, PPC::V30, PPC::V31,
+    
+    PPC::LR8,  0
+  };
+  
+  if (Subtarget.isMachoABI())
+    return Subtarget.isPPC64() ? Darwin64_CalleeSavedRegs :
+                                 Darwin32_CalleeSavedRegs;
+  
+  // ELF.
+  return Subtarget.isPPC64() ? ELF64_CalleeSavedRegs : ELF32_CalleeSavedRegs;
 }
 
 const TargetRegisterClass* const*
@@ -312,6 +360,29 @@
     &PPC::GPRCRegClass, 0
   };
   
+  static const TargetRegisterClass * const ELF32_CalleeSavedRegClasses[] = {
+                       &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,
+    &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,
+    &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,
+    &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,
+    &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,
+
+                       &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
+    &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
+    &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
+    &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
+    &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
+    &PPC::F8RCRegClass,&PPC::F8RCRegClass,
+    
+    &PPC::CRRCRegClass,&PPC::CRRCRegClass,&PPC::CRRCRegClass,
+    
+    &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
+    &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
+    &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
+    
+    &PPC::GPRCRegClass, 0
+  };
+  
   // 64-bit Darwin calling convention. 
   static const TargetRegisterClass * const Darwin64_CalleeSavedRegClasses[] = {
     &PPC::G8RCRegClass,&PPC::G8RCRegClass,
@@ -334,9 +405,37 @@
     
     &PPC::G8RCRegClass, 0
   };
+  
+  static const TargetRegisterClass * const ELF64_CalleeSavedRegClasses[] = {
+    &PPC::G8RCRegClass,&PPC::G8RCRegClass,
+    &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,
+    &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,
+    &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,
+    &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,
+    
+                       &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
+    &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
+    &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
+    &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
+    &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
+    &PPC::F8RCRegClass,&PPC::F8RCRegClass,
+    
+    &PPC::CRRCRegClass,&PPC::CRRCRegClass,&PPC::CRRCRegClass,
+    
+    &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
+    &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
+    &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
+    
+    &PPC::G8RCRegClass, 0
+  };
  
-  return Subtarget.isPPC64() ? Darwin64_CalleeSavedRegClasses :
-                               Darwin32_CalleeSavedRegClasses;
+  if (Subtarget.isMachoABI())
+    return Subtarget.isPPC64() ? Darwin64_CalleeSavedRegClasses :
+                                 Darwin32_CalleeSavedRegClasses;
+  
+  // ELF.
+  return Subtarget.isPPC64() ? ELF64_CalleeSavedRegClasses :
+                               ELF32_CalleeSavedRegClasses;
 }
 
 // needsFP - Return true if the specified function should have a dedicated frame
@@ -753,7 +852,8 @@
   
   // Maximum call frame needs to be at least big enough for linkage and 8 args.
   unsigned minCallFrameSize =
-    PPCFrameInfo::getMinCallFrameSize(Subtarget.isPPC64());
+    PPCFrameInfo::getMinCallFrameSize(Subtarget.isPPC64(), 
+                                      Subtarget.isMachoABI());
   maxCallFrameSize = std::max(maxCallFrameSize, minCallFrameSize);
 
   // If we have dynamic alloca then maxCallFrameSize needs to be aligned so
@@ -766,7 +866,7 @@
   
   // Include call frame size in total.
   FrameSize += maxCallFrameSize;
-
+  
   // Make sure the frame is aligned.
   FrameSize = (FrameSize + AlignMask) & ~AlignMask;
 
@@ -815,13 +915,15 @@
   
   // Get processor type.
   bool IsPPC64 = Subtarget.isPPC64();
+  // Get operating system
+  bool IsMachoABI = Subtarget.isMachoABI();
   // Check if the link register (LR) has been used.
   bool UsesLR = MFI->hasCalls() || usesLR(MF);
   // Do we have a frame pointer for this function?
   bool HasFP = hasFP(MF);
   
-  int LROffset = PPCFrameInfo::getReturnSaveOffset(IsPPC64);
-  int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64);
+  int LROffset = PPCFrameInfo::getReturnSaveOffset(IsPPC64, IsMachoABI);
+  int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64, IsMachoABI);
   
   if (IsPPC64) {
     if (UsesLR)
@@ -976,11 +1078,16 @@
   
   // Get processor type.
   bool IsPPC64 = Subtarget.isPPC64();
+  // Get operating system
+  bool IsMachoABI = Subtarget.isMachoABI();
   // Check if the link register (LR) has been used.
   bool UsesLR = MFI->hasCalls() || usesLR(MF);
   // Do we have a frame pointer for this function?
   bool HasFP = hasFP(MF);
-
+  
+  int LROffset = PPCFrameInfo::getReturnSaveOffset(IsPPC64, IsMachoABI);
+  int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64, IsMachoABI);
+  
   // The loaded (or persistent) stack pointer value is offset by the 'stwu'
   // on entry to the function.  Add this offset back now.
   if (!Subtarget.isPPC64()) {
@@ -1001,8 +1108,6 @@
     }
   }
   
-  int LROffset = PPCFrameInfo::getReturnSaveOffset(IsPPC64);
-  int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64);
 
   if (IsPPC64) {
     if (UsesLR)






More information about the llvm-commits mailing list