Add the ability to lower return instructions to TargetLowering. This
authorNate Begeman <natebegeman@mac.com>
Tue, 18 Oct 2005 23:23:37 +0000 (23:23 +0000)
committerNate Begeman <natebegeman@mac.com>
Tue, 18 Oct 2005 23:23:37 +0000 (23:23 +0000)
allows us to lower legal return types to something else, to meet ABI
requirements (such as that i64 be returned in two i32 regs on Darwin/ppc).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23802 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetLowering.h
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
lib/Target/PowerPC/PPCISelDAGToDAG.cpp
lib/Target/PowerPC/PPCISelLowering.cpp
lib/Target/PowerPC/PPCISelLowering.h

index 734c8dc0297cd1af1ee3fdf8b0e7be2befda2e89..02278e9e422304ab9af6f6f1d15af7c0e7ccd419 100644 (file)
@@ -311,6 +311,12 @@ public:
               unsigned CallingConv, bool isTailCall, SDOperand Callee,
               ArgListTy &Args, SelectionDAG &DAG) = 0;
 
+  /// LowerReturnTo - This hook lowers a return instruction into the appropriate
+  /// legal ISD::RET node for the target's current ABI.  This method is optional
+  /// and is intended for targets that need non-standard behavior.
+  virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op, 
+                                  SelectionDAG &DAG);
+  
   /// LowerVAStart - This lowers the llvm.va_start intrinsic.  If not
   /// implemented, this method prints a message and aborts.  This method should
   /// return the modified chain value.  Note that VAListPtr* correspond to the
index 72ee7501082c499999cbb69b4772556fb82faf51..4a89578eaa03538b389f39a6ebbb0857951f39b6 100644 (file)
@@ -450,8 +450,8 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) {
   case MVT::f64:
     break; // No extension needed!
   }
-
-  DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other, getRoot(), Op1));
+  // Allow targets to lower this further to meet ABI requirements
+  DAG.setRoot(TLI.LowerReturnTo(getRoot(), Op1, DAG));
 }
 
 void SelectionDAGLowering::visitBr(BranchInst &I) {
@@ -898,6 +898,11 @@ MachineBasicBlock *TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
   return 0;  
 }
 
+SDOperand TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
+                                        SelectionDAG &DAG) {
+  return DAG.getNode(ISD::RET, MVT::Other, Chain, Op);
+}
+
 SDOperand TargetLowering::LowerVAStart(SDOperand Chain,
                                        SDOperand VAListP, Value *VAListV,
                                        SelectionDAG &DAG) {
index c55bd30a2dd18469a113d6f0b2c49875708e677c..754809303112fc6be9f22accbd8a7424c884b826 100644 (file)
@@ -1206,6 +1206,22 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
       
     // Other cases are autogenerated.
     break;
+  case ISD::ANY_EXTEND:
+    switch(N->getValueType(0)) {
+    default: assert(0 && "Unhandled type in ANY_EXTEND");
+    case MVT::i64:
+      CurDAG->SelectNodeTo(N, PPC::OR8, MVT::i64, Select(N->getOperand(0)), 
+                           Select(N->getOperand(0)));
+      break;
+    }
+    return SDOperand(N, 0);
+  case ISD::ZERO_EXTEND:
+    assert(N->getValueType(0) == MVT::i64 && 
+           N->getOperand(0).getValueType() == MVT::i32 &&
+           "ZERO_EXTEND only supported for i32 -> i64");
+    CurDAG->SelectNodeTo(N, PPC::RLDICL, MVT::i64, Select(N->getOperand(0)),
+                         getI32Imm(32));
+    return SDOperand(N, 0);
   case ISD::SHL: {
     unsigned Imm, SH, MB, ME;
     if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) &&
@@ -1393,11 +1409,6 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
       SDOperand Val = Select(N->getOperand(1));
       if (N->getOperand(1).getValueType() == MVT::i32) {
         Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Val);
-      } else if (N->getOperand(1).getValueType() == MVT::i64) {
-        SDOperand Srl = CurDAG->getTargetNode(PPC::RLDICL, MVT::i64, Val,
-                                              getI32Imm(32), getI32Imm(32));
-        Chain = CurDAG->getCopyToReg(Chain, PPC::R4, Val);
-        Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Srl);
       } else {
         assert(MVT::isFloatingPoint(N->getOperand(1).getValueType()));
         Chain = CurDAG->getCopyToReg(Chain, PPC::F1, Val);
index 8cc538df83afab6eaf94604ec4d7b62e98f14bf7..5256e4839d1a14e3ce90d7cf951581bd7dad9598 100644 (file)
@@ -693,6 +693,19 @@ PPCTargetLowering::LowerCallTo(SDOperand Chain,
   return std::make_pair(RetVal, Chain);
 }
 
+SDOperand PPCTargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
+                                           SelectionDAG &DAG) {
+  if (Op.getValueType() == MVT::i64) {
+    SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, 
+                               DAG.getConstant(1, MVT::i32));
+    SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
+                               DAG.getConstant(0, MVT::i32));
+    return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Hi);
+  } else {
+    return DAG.getNode(ISD::RET, MVT::Other, Chain, Op);
+  }
+}
+
 SDOperand PPCTargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP,
                                           Value *VAListV, SelectionDAG &DAG) {
   // vastart just stores the address of the VarArgsFrameIndex slot into the
index 0b3690ddf691c8c58540e1e5e5be0a2a023efb18..f44f192e6934855dbd5c438093734238b6299794 100644 (file)
@@ -63,6 +63,9 @@ namespace llvm {
                   unsigned CC,
                   bool isTailCall, SDOperand Callee, ArgListTy &Args,
                   SelectionDAG &DAG);
+
+    virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
+                                    SelectionDAG &DAG);
     
     virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP,
                                    Value *VAListV, SelectionDAG &DAG);