Switch PPC return lower to use an autogenerated CC description.
authorChris Lattner <sabre@nondot.org>
Tue, 6 Mar 2007 00:59:59 +0000 (00:59 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 6 Mar 2007 00:59:59 +0000 (00:59 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34940 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/Makefile
lib/Target/PowerPC/PPC.td
lib/Target/PowerPC/PPCCallingConv.td [new file with mode: 0644]
lib/Target/PowerPC/PPCISelLowering.cpp

index a5edc157c840688ed83129c4c6b0160a06f7d68a..77288ed03e790c5185b9796e9d68d457e84b7782 100644 (file)
@@ -14,6 +14,7 @@ TARGET = PPC
 BUILT_SOURCES = PPCGenInstrNames.inc PPCGenRegisterNames.inc \
                 PPCGenAsmWriter.inc  PPCGenCodeEmitter.inc \
                 PPCGenRegisterInfo.h.inc PPCGenRegisterInfo.inc \
-                PPCGenInstrInfo.inc PPCGenDAGISel.inc PPCGenSubtarget.inc
+                PPCGenInstrInfo.inc PPCGenDAGISel.inc \
+                PPCGenSubtarget.inc PPCGenCallingConv.inc
 
 include $(LEVEL)/Makefile.common
index 4a837a08352c0cb1c5204cf69855948902cc9f24..76f8ac4806053aace23828a81699972882a61b25 100644 (file)
@@ -89,6 +89,12 @@ def : Processor<"ppc64", G5Itineraries,
                    Feature64Bit /*, Feature64BitRegs */]>;
 
 
+//===----------------------------------------------------------------------===//
+// Calling Conventions
+//===----------------------------------------------------------------------===//
+
+include "PPCCallingConv.td"
+
 def PPCInstrInfo : InstrInfo {
   // Define how we want to layout our TargetSpecific information field... This
   // should be kept up-to-date with the fields in the PPCInstrInfo.h file.
diff --git a/lib/Target/PowerPC/PPCCallingConv.td b/lib/Target/PowerPC/PPCCallingConv.td
new file mode 100644 (file)
index 0000000..2b69d46
--- /dev/null
@@ -0,0 +1,65 @@
+//===- PPCCallingConv.td - Calling Conventions for PowerPC ------*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This describes the calling conventions for the PowerPC 32- and 64-bit
+// architectures.
+//
+//===----------------------------------------------------------------------===//
+
+/// CCIfSubtarget - Match if the current subtarget has a feature F.
+class CCIfSubtarget<string F, CCAction A>
+ : CCIf<!strconcat("State.getTarget().getSubtarget<PPCSubtarget>().", F), A>;
+
+//===----------------------------------------------------------------------===//
+// Return Value Calling Convention
+//===----------------------------------------------------------------------===//
+
+// Return-value convention for PowerPC
+def RetCC_PPC : CallingConv<[
+  CCIfType<[i32], CCAssignToReg<[R3, R4]>>,
+  CCIfType<[i64], CCAssignToReg<[X3, X4]>>,
+  
+  CCIfType<[f32, f64], CCAssignToReg<[F1]>>,
+  
+  // Vector types are always returned in V2.
+  CCIfType<[v16i8, v8i16, v4i32, v4f32], CCAssignToReg<[V2]>>
+]>;
+
+
+//===----------------------------------------------------------------------===//
+// PowerPC Argument Calling Conventions
+//===----------------------------------------------------------------------===//
+/*
+def CC_PPC : CallingConv<[
+  // The first 8 integer arguments are passed in integer registers.
+  CCIfType<[i32], CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10]>>,
+  CCIfType<[i64], CCAssignToReg<[X3, X4, X5, X6, X7, X8, X9, X10]>>,
+  
+  // Darwin passes FP values in F1 - F13
+  CCIfType<[f32, f64], CCIfSubtarget<"isMachoABI()",
+           CCAssignToReg<[F1, F2, F3, F4, F5, F6, F7, F8,F9,F10,F11,F12,F13]>>>,
+  // Other sub-targets pass FP values in F1-10.
+  CCIfType<[f32, f64], CCAssignToReg<[F1, F2, F3, F4, F5, F6, F7, F8, F9,F10]>>,
+           
+  // The first 12 Vector arguments are passed in altivec registers.
+  CCIfType<[v16i8, v8i16, v4i32, v4f32],
+              CCAssignToReg<[V2, V3, V4, V5, V6, V7, V8, V9, V10,V11,V12,V13]>>
+
+/*
+  // Integer/FP values get stored in stack slots that are 8 bytes in size and
+  // 8-byte aligned if there are no more registers to hold them.
+  CCIfType<[i32, i64, f32, f64], CCAssignToStack<8, 8>>,
+  
+  // Vectors get 16-byte stack slots that are 16-byte aligned.
+  CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
+              CCAssignToStack<16, 16>>*/
+]>;
+
+*/
+
index 38f3974d9a4a600aa8095fc9fa93d6f6eab9f0b5..b11b1f79b4e3169e2ee1ed415cbf973d3b4a178d 100644 (file)
@@ -18,6 +18,7 @@
 #include "PPCPerfectShuffle.h"
 #include "llvm/ADT/VectorExtras.h"
 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/CodeGen/CallingConvLower.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -1096,6 +1097,8 @@ static SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG,
                       SV->getOffset());
 }
 
+#include "PPCGenCallingConv.inc"
+
 /// 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) {
@@ -1626,47 +1629,34 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG,
   return Res.getValue(Op.ResNo);
 }
 
-static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) {
-  SDOperand Chain = Op.getOperand(0);
-  switch(Op.getNumOperands()) {
-  default:
-    assert(0 && "Do not know how to return this many arguments!");
-    abort();
-  case 1: 
-    return DAG.getNode(PPCISD::RET_FLAG, MVT::Other, Chain);
-  case 3: {
-    MVT::ValueType ArgVT = Op.getOperand(1).getValueType();
-    unsigned ArgReg;
-    if (ArgVT == MVT::i32) {
-      ArgReg = PPC::R3;
-    } else if (ArgVT == MVT::i64) {
-      ArgReg = PPC::X3;
-    } else if (MVT::isVector(ArgVT)) {
-      ArgReg = PPC::V2;
-    } else {
-      assert(MVT::isFloatingPoint(ArgVT));
-      ArgReg = PPC::F1;
-    }
-    
-    Chain = DAG.getCopyToReg(Chain, ArgReg, Op.getOperand(1), SDOperand());
-    
-    // If we haven't noted the R3/F1 are live out, do so now.
-    if (DAG.getMachineFunction().liveout_empty())
-      DAG.getMachineFunction().addLiveOut(ArgReg);
-    break;
+static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG, TargetMachine &TM) {
+  SmallVector<CCValAssign, 16> RVLocs;
+  unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
+  CCState CCInfo(CC, TM, RVLocs);
+  CCInfo.AnalyzeReturn(Op.Val, RetCC_PPC);
+  
+  // If this is the first return lowered for this function, add the regs to the
+  // liveout set for the function.
+  if (DAG.getMachineFunction().liveout_empty()) {
+    for (unsigned i = 0; i != RVLocs.size(); ++i)
+      DAG.getMachineFunction().addLiveOut(RVLocs[i].getLocReg());
   }
-  case 5:
-    Chain = DAG.getCopyToReg(Chain, PPC::R3, Op.getOperand(3), SDOperand());
-    Chain = DAG.getCopyToReg(Chain, PPC::R4, Op.getOperand(1),
-                             Chain.getValue(1));
-    // If we haven't noted the R3+R4 are live out, do so now.
-    if (DAG.getMachineFunction().liveout_empty()) {
-      DAG.getMachineFunction().addLiveOut(PPC::R3);
-      DAG.getMachineFunction().addLiveOut(PPC::R4);
-    }
-    break;
+
+  SDOperand Chain = Op.getOperand(0);
+  SDOperand Flag;
+  
+  // Copy the result values into the output registers.
+  for (unsigned i = 0; i != RVLocs.size(); ++i) {
+    CCValAssign &VA = RVLocs[i];
+    assert(VA.isRegLoc() && "Can only return in registers!");
+    Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1), Flag);
+    Flag = Chain.getValue(1);
   }
-  return DAG.getNode(PPCISD::RET_FLAG, MVT::Other, Chain, Chain.getValue(1));
+
+  if (Flag.Val)
+    return DAG.getNode(PPCISD::RET_FLAG, MVT::Other, Chain, Flag);
+  else
+    return DAG.getNode(PPCISD::RET_FLAG, MVT::Other, Chain);
 }
 
 static SDOperand LowerSTACKRESTORE(SDOperand Op, SelectionDAG &DAG,
@@ -2677,7 +2667,7 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
   case ISD::FORMAL_ARGUMENTS:
     return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex, PPCSubTarget);
   case ISD::CALL:               return LowerCALL(Op, DAG, PPCSubTarget);
-  case ISD::RET:                return LowerRET(Op, DAG);
+  case ISD::RET:                return LowerRET(Op, DAG, getTargetMachine());
   case ISD::STACKRESTORE:       return LowerSTACKRESTORE(Op, DAG, PPCSubTarget);
   case ISD::DYNAMIC_STACKALLOC:
     return LowerDYNAMIC_STACKALLOC(Op, DAG, PPCSubTarget);