diff options
-rw-r--r-- | include/llvm/CodeGen/SelectionDAGNodes.h | 3 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 24 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 1 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCISelPattern.cpp | 108 |
4 files changed, 95 insertions, 41 deletions
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 67ceda1161..e9b54fb92c 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -74,6 +74,9 @@ namespace ISD { // out. ImplicitDef, + // UNDEF - An undefined node + UNDEF, + // EXTRACT_ELEMENT - This is used to get the first or second (determined by // a Constant, which is required to be operand #1), element of the aggregate // value specified as operand #0. This is only for use before legalization, diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 5f8a21aca0..52449ef376 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -219,6 +219,23 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { if (Tmp1 != Node->getOperand(0)) Result = DAG.getImplicitDef(Tmp1, cast<RegSDNode>(Node)->getReg()); break; + case ISD::UNDEF: { + MVT::ValueType VT = Op.getValueType(); + switch (TLI.getOperationAction(ISD::UNDEF, VT)) { + case Expand: + case Promote: + if (MVT::isInteger(VT)) + Result = DAG.getConstant(0, VT); + else if (MVT::isFloatingPoint(VT)) + Result = DAG.getConstantFP(0, VT); + else + assert(0 && "Unknown value type!"); + break; + case Legal: + break; + } + break; + } case ISD::Constant: // We know we don't need to expand constants here, constants only have one // value and we check that it is fine above. @@ -1018,6 +1035,9 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) { std::cerr << "NODE: "; Node->dump(); std::cerr << "\n"; assert(0 && "Do not know how to promote this operator!"); abort(); + case ISD::UNDEF: + Result = DAG.getNode(ISD::UNDEF, NVT); + break; case ISD::Constant: Result = DAG.getNode(ISD::ZERO_EXTEND, NVT, Op); assert(isa<ConstantSDNode>(Result) && "Didn't constant fold zext?"); @@ -1574,6 +1594,10 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ std::cerr << "NODE: "; Node->dump(); std::cerr << "\n"; assert(0 && "Do not know how to expand this operator!"); abort(); + case ISD::UNDEF: + Lo = DAG.getNode(ISD::UNDEF, NVT); + Hi = DAG.getNode(ISD::UNDEF, NVT); + break; case ISD::Constant: { uint64_t Cst = cast<ConstantSDNode>(Node)->getValue(); Lo = DAG.getConstant(Cst, NVT); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index edc5b8c6f5..023848a9f9 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1112,6 +1112,7 @@ const char *SDNode::getOperationName() const { case ISD::CopyToReg: return "CopyToReg"; case ISD::CopyFromReg: return "CopyFromReg"; case ISD::ImplicitDef: return "ImplicitDef"; + case ISD::UNDEF: return "undef"; case ISD::ADD: return "add"; case ISD::SUB: return "sub"; diff --git a/lib/Target/PowerPC/PPCISelPattern.cpp b/lib/Target/PowerPC/PPCISelPattern.cpp index 8ea2086787..db56384a38 100644 --- a/lib/Target/PowerPC/PPCISelPattern.cpp +++ b/lib/Target/PowerPC/PPCISelPattern.cpp @@ -53,7 +53,7 @@ namespace { // PowerPC has an i16 but no i8 (or i1) SEXTLOAD setOperationAction(ISD::SEXTLOAD, MVT::i1, Expand); setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand); - + addLegalFPImmediate(+0.0); // Necessary for FSEL addLegalFPImmediate(-0.0); // @@ -251,15 +251,6 @@ PPC32TargetLowering::LowerCallTo(SDOperand Chain, unsigned ArgOffset = 24; unsigned GPR_remaining = 8; unsigned FPR_remaining = 13; - unsigned GPR_idx = 0, FPR_idx = 0; - static const unsigned GPR[] = { - PPC::R3, PPC::R4, PPC::R5, PPC::R6, - PPC::R7, PPC::R8, PPC::R9, PPC::R10, - }; - 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 - }; std::vector<SDOperand> MemOps; for (unsigned i = 0, e = Args.size(); i != e; ++i) { @@ -283,10 +274,8 @@ PPC32TargetLowering::LowerCallTo(SDOperand Chain, // FALL THROUGH case MVT::i32: if (GPR_remaining > 0) { - args_to_use.push_back(DAG.getCopyToReg(Chain, Args[i].first, - GPR[GPR_idx])); + args_to_use.push_back(Args[i].first); --GPR_remaining; - ++GPR_idx; } else { MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, Args[i].first, PtrOff)); @@ -302,13 +291,11 @@ PPC32TargetLowering::LowerCallTo(SDOperand Chain, Args[i].first, DAG.getConstant(1, MVT::i32)); SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Args[i].first, DAG.getConstant(0, MVT::i32)); - args_to_use.push_back(DAG.getCopyToReg(Chain, Hi, GPR[GPR_idx])); + args_to_use.push_back(Hi); --GPR_remaining; - ++GPR_idx; if (GPR_remaining > 0) { - args_to_use.push_back(DAG.getCopyToReg(Chain, Lo, GPR[GPR_idx])); + args_to_use.push_back(Lo); --GPR_remaining; - ++GPR_idx; } else { SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); @@ -324,6 +311,8 @@ PPC32TargetLowering::LowerCallTo(SDOperand Chain, case MVT::f32: case MVT::f64: if (FPR_remaining > 0) { + args_to_use.push_back(Args[i].first); + --FPR_remaining; if (isVarArg) { SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Chain, Args[i].first, PtrOff); @@ -332,32 +321,29 @@ PPC32TargetLowering::LowerCallTo(SDOperand Chain, if (GPR_remaining > 0) { SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff); MemOps.push_back(Load); - args_to_use.push_back(DAG.getCopyToReg(Load, Load, - GPR[GPR_idx])); + args_to_use.push_back(Load); + --GPR_remaining; } - if (GPR_remaining > 1 && MVT::f64 == ArgVT) { + if (GPR_remaining > 0 && MVT::f64 == ArgVT) { SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff); MemOps.push_back(Load); - args_to_use.push_back(DAG.getCopyToReg(Load, Load, - GPR[GPR_idx+1])); + args_to_use.push_back(Load); + --GPR_remaining; + } + } 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_remaining > 0) { + args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32)); + --GPR_remaining; + } + if (GPR_remaining > 0 && MVT::f64 == ArgVT) { + args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32)); + --GPR_remaining; } - } - args_to_use.push_back(DAG.getCopyToReg(Chain, Args[i].first, - FPR[FPR_idx])); - --FPR_remaining; - ++FPR_idx; - // 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_remaining > 0) { - --GPR_remaining; - ++GPR_idx; - } - if (GPR_remaining > 0 && MVT::f64 == ArgVT) { - --GPR_remaining; - ++GPR_idx; } } else { MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, @@ -909,14 +895,20 @@ unsigned ISel::SelectExpr(SDOperand N) { } if (DestType == MVT::f64 || DestType == MVT::f32) - if (ISD::LOAD != opcode && ISD::EXTLOAD != opcode) + if (ISD::LOAD != opcode && ISD::EXTLOAD != opcode && ISD::UNDEF != opcode) return SelectExprFP(N, Result); switch (opcode) { default: Node->dump(); assert(0 && "Node not handled!\n"); - + case ISD::UNDEF: + if (Result != 1) + ExprMap[N.getValue(1)] = 1; + else + Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType()); + BuildMI(BB, PPC::IMPLICIT_DEF, 0, Result); + return Result; case ISD::DYNAMIC_STACKALLOC: // Generate both result values. FIXME: Need a better commment here? if (Result != 1) @@ -1020,13 +1012,47 @@ unsigned ISel::SelectExpr(SDOperand N) { } case ISD::CALL: { + unsigned GPR_idx = 0, FPR_idx = 0; + static const unsigned GPR[] = { + PPC::R3, PPC::R4, PPC::R5, PPC::R6, + PPC::R7, PPC::R8, PPC::R9, PPC::R10, + }; + 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 + }; + // Lower the chain for this call. Select(N.getOperand(0)); ExprMap[N.getValue(Node->getNumValues()-1)] = 1; + // Load the register args to virtual regs + std::vector<unsigned> ArgVR; for(int i = 2, e = Node->getNumOperands(); i < e; ++i) - Select(N.getOperand(i)); - + ArgVR.push_back(SelectExpr(N.getOperand(i))); + + // Copy the virtual registers into the appropriate argument register + for(int i = 0, e = ArgVR.size(); i < e; ++i) { + switch(N.getOperand(i+2).getValueType()) { + default: Node->dump(); assert(0 && "Unknown value type for call"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + assert(GPR_idx < 8 && "Too many int args"); + if (N.getOperand(i+2).getOpcode() != ISD::UNDEF) + BuildMI(BB, PPC::OR,2,GPR[GPR_idx]).addReg(ArgVR[i]).addReg(ArgVR[i]); + ++GPR_idx; + break; + case MVT::f64: + case MVT::f32: + assert(FPR_idx < 13 && "Too many fp args"); + BuildMI(BB, PPC::FMR, 1, FPR[FPR_idx]).addReg(ArgVR[i]); + ++FPR_idx; + break; + } + } + // Emit the correct call instruction based on the type of symbol called. if (GlobalAddressSDNode *GASD = dyn_cast<GlobalAddressSDNode>(N.getOperand(1))) { |