From c04ba7a97d5ad599d92a1817de2d7c5fbb145810 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 16 May 2006 23:54:25 +0000 Subject: [PATCH] implement passing/returning vector regs to calls, at least non-varargs calls. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28341 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 70 +++++++++++++++----------- lib/Target/PowerPC/PPCISelLowering.cpp | 13 ++++- 2 files changed, 54 insertions(+), 29 deletions(-) diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 715fc420d78..a9bd05ed537 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -137,8 +137,8 @@ namespace { return "PowerPC DAG->DAG Pattern Instruction Selection"; } - /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for this - /// target when scheduling the DAG. + /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for + /// this target when scheduling the DAG. virtual HazardRecognizer *CreateTargetHazardRecognizer() { // Should use subtarget info to pick the right hazard recognizer. For // now, always return a PPC970 recognizer. @@ -813,8 +813,8 @@ SDOperand PPCDAGToDAGISel::SelectSETCC(SDOperand Op) { Op = SDOperand(CurDAG->getTargetNode(PPC::NOR, MVT::i32, Op, Op), 0); SDNode *AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag, Op, getI32Imm(~0U)); - return CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, SDOperand(AD, 0), Op, - SDOperand(AD, 1)); + return CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, SDOperand(AD, 0), + Op, SDOperand(AD, 1)); } case ISD::SETLT: { SDOperand AD = SDOperand(CurDAG->getTargetNode(PPC::ADDI, MVT::i32, Op, @@ -908,7 +908,7 @@ SDOperand PPCDAGToDAGISel::SelectCALL(SDOperand Op) { CallOpcode = PPC::BCTRL; } - unsigned GPR_idx = 0, FPR_idx = 0; + unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0; static const unsigned GPR[] = { PPC::R3, PPC::R4, PPC::R5, PPC::R6, PPC::R7, PPC::R8, PPC::R9, PPC::R10, @@ -917,6 +917,10 @@ SDOperand PPCDAGToDAGISel::SelectCALL(SDOperand Op) { 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 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 + }; SDOperand InFlag; // Null incoming flag value. @@ -926,11 +930,13 @@ SDOperand PPCDAGToDAGISel::SelectCALL(SDOperand Op) { if (RegTy == MVT::i32) { assert(GPR_idx < 8 && "Too many int args"); DestReg = GPR[GPR_idx++]; - } else { - assert(MVT::isFloatingPoint(N->getOperand(i).getValueType()) && - "Unpromoted integer arg?"); + } else if (MVT::isFloatingPoint(N->getOperand(i).getValueType())) { assert(FPR_idx < 13 && "Too many fp args"); DestReg = FPR[FPR_idx++]; + } else { + assert(MVT::isVector(N->getOperand(i).getValueType()) && "unknown arg!"); + assert(VR_idx < 12 && "Too many vector args"); + DestReg = VR[VR_idx++]; } if (N->getOperand(i).getOpcode() != ISD::UNDEF) { @@ -955,28 +961,36 @@ SDOperand PPCDAGToDAGISel::SelectCALL(SDOperand Op) { // If the call has results, copy the values out of the ret val registers. switch (N->getValueType(0)) { - default: assert(0 && "Unexpected ret value!"); - case MVT::Other: break; - case MVT::i32: - if (N->getValueType(1) == MVT::i32) { - Chain = CurDAG->getCopyFromReg(Chain, PPC::R4, MVT::i32, - Chain.getValue(1)).getValue(1); - CallResults.push_back(Chain.getValue(0)); - Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32, - Chain.getValue(2)).getValue(1); - CallResults.push_back(Chain.getValue(0)); - } else { - Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32, - Chain.getValue(1)).getValue(1); - CallResults.push_back(Chain.getValue(0)); - } - break; - case MVT::f32: - case MVT::f64: - Chain = CurDAG->getCopyFromReg(Chain, PPC::F1, N->getValueType(0), + default: assert(0 && "Unexpected ret value!"); + case MVT::Other: break; + case MVT::i32: + if (N->getValueType(1) == MVT::i32) { + Chain = CurDAG->getCopyFromReg(Chain, PPC::R4, MVT::i32, Chain.getValue(1)).getValue(1); CallResults.push_back(Chain.getValue(0)); - break; + Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32, + Chain.getValue(2)).getValue(1); + CallResults.push_back(Chain.getValue(0)); + } else { + Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32, + Chain.getValue(1)).getValue(1); + CallResults.push_back(Chain.getValue(0)); + } + break; + case MVT::f32: + case MVT::f64: + Chain = CurDAG->getCopyFromReg(Chain, PPC::F1, N->getValueType(0), + Chain.getValue(1)).getValue(1); + CallResults.push_back(Chain.getValue(0)); + break; + case MVT::v4f32: + case MVT::v4i32: + case MVT::v8i16: + case MVT::v16i8: + Chain = CurDAG->getCopyFromReg(Chain, PPC::V2, N->getValueType(0), + Chain.getValue(1)).getValue(1); + CallResults.push_back(Chain.getValue(0)); + break; } CallResults.push_back(Chain); diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index b22f081b430..b6a0e07280e 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -920,7 +920,8 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { unsigned ArgOffset = 24; unsigned GPR_remaining = 8; unsigned FPR_remaining = 13; - + unsigned VR_remaining = 12; + std::vector MemOps; for (unsigned i = 5, e = Op.getNumOperands(); i != e; ++i) { SDOperand Arg = Op.getOperand(i); @@ -987,6 +988,16 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { } ArgOffset += (Arg.getValueType() == MVT::f32) ? 4 : 8; break; + case MVT::v4f32: + case MVT::v4i32: + case MVT::v8i16: + case MVT::v16i8: + assert(!isVarArg && "Don't support passing vectors to varargs yet!"); + assert(VR_remaining && + "Don't support passing more than 12 vector args yet!"); + args_to_use.push_back(Arg); + --VR_remaining; + break; } } if (!MemOps.empty())