From 1a8f1fe676f1d83e0da7336e744ebcdcc14a88c4 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Sat, 9 Dec 2006 02:42:38 +0000 Subject: [PATCH] Preliminary soft float support. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32394 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 35 +++++++++++++-- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 15 +++++-- lib/CodeGen/SelectionDAG/TargetLowering.cpp | 43 +++++++++++++------ 3 files changed, 74 insertions(+), 19 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 0d8ca7bd2eb..fc5c59f36f9 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -4351,9 +4351,8 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); SDNode *Node = Op.Val; assert(getTypeAction(VT) == Expand && "Not an expanded type!"); - assert((MVT::isInteger(VT) || VT == MVT::Vector) && - "Cannot expand FP values!"); - assert(((MVT::isInteger(NVT) && NVT < VT) || VT == MVT::Vector) && + assert(((MVT::isInteger(NVT) && NVT < VT) || MVT::isFloatingPoint(VT) || + VT == MVT::Vector) && "Cannot expand to FP value or to larger int value!"); // See if we already expanded it. @@ -4583,9 +4582,18 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ Tmp = TLI.LowerOperation(DAG.getNode(ISD::BIT_CONVERT, VT, Tmp), DAG); } + MVT::ValueType NVT = Node->getValueType(0); + // f32 / f64 must be expanded to i32 / i64. + if (NVT == MVT::f32 || NVT == MVT::f64) { + Lo = DAG.getNode(ISD::BIT_CONVERT, TLI.getTypeToTransformTo(NVT), + Node->getOperand(0)); + Hi = DAG.getConstant(0, TLI.getTypeToTransformTo(NVT)); + break; + } + // Turn this into a load/store pair by default. if (Tmp.Val == 0) - Tmp = ExpandBIT_CONVERT(Node->getValueType(0), Node->getOperand(0)); + Tmp = ExpandBIT_CONVERT(NVT, Node->getOperand(0)); ExpandOp(Tmp, Lo, Hi); break; @@ -4858,6 +4866,25 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ case ISD::UDIV: Lo = ExpandLibCall("__udivdi3", Node, Hi); break; case ISD::SREM: Lo = ExpandLibCall("__moddi3" , Node, Hi); break; case ISD::UREM: Lo = ExpandLibCall("__umoddi3", Node, Hi); break; + + case ISD::FADD: + Lo = ExpandLibCall(((VT == MVT::f32) ? "__addsf3" : "__adddf3"), Node, Hi); + break; + case ISD::FSUB: + Lo = ExpandLibCall(((VT == MVT::f32) ? "__subsf3" : "__subdf3"), Node, Hi); + break; + case ISD::FMUL: + Lo = ExpandLibCall(((VT == MVT::f32) ? "__mulsf3" : "__muldf3"), Node, Hi); + break; + case ISD::FDIV: + Lo = ExpandLibCall(((VT == MVT::f32) ? "__divsf3" : "__divdf3"), Node, Hi); + break; + case ISD::FP_EXTEND: + Lo = ExpandLibCall("__extendsfdf2", Node, Hi); + break; + case ISD::FP_ROUND: + Lo = ExpandLibCall("__truncdfsf2", Node, Hi); + break; } // Make sure the resultant values have been legalized themselves, unless this diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index e43303538d7..cb408e18a3b 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -2954,7 +2954,10 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { // integers it is. MVT::ValueType NVT = getTypeToTransformTo(VT); unsigned NumVals = MVT::getSizeInBits(VT)/MVT::getSizeInBits(NVT); - if (NumVals == 2) { + if (NumVals == 1) { + SDOperand Tmp = SDOperand(Result, i++); + Ops.push_back(DAG.getNode(ISD::BIT_CONVERT, VT, Tmp)); + } else if (NumVals == 2) { SDOperand Lo = SDOperand(Result, i++); SDOperand Hi = SDOperand(Result, i++); @@ -3040,7 +3043,10 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, // integers it is. MVT::ValueType NVT = getTypeToTransformTo(VT); unsigned NumVals = MVT::getSizeInBits(VT)/MVT::getSizeInBits(NVT); - if (NumVals == 2) { + if (NumVals == 1) { + Ops.push_back(DAG.getNode(ISD::BIT_CONVERT, VT, Op)); + Ops.push_back(DAG.getConstant(isSigned, MVT::i32)); + } else if (NumVals == 2) { SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Op, DAG.getConstant(0, getPointerTy())); SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Op, @@ -3166,7 +3172,10 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, ResVal = DAG.getNode(ISD::TRUNCATE, VT, ResVal); } else { assert(MVT::isFloatingPoint(VT)); - ResVal = DAG.getNode(ISD::FP_ROUND, VT, ResVal); + if (getTypeAction(VT) == Expand) + ResVal = DAG.getNode(ISD::BIT_CONVERT, VT, ResVal); + else + ResVal = DAG.getNode(ISD::FP_ROUND, VT, ResVal); } } } else if (RetTys.size() == 3) { diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 41828b5ef7c..314941a3561 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -86,10 +86,17 @@ static void SetValueTypeAction(MVT::ValueType VT, assert(VT < PromoteTo && "Must promote to a larger type!"); TransformToType[VT] = PromoteTo; } else if (Action == TargetLowering::Expand) { - assert((VT == MVT::Vector || MVT::isInteger(VT)) && VT > MVT::i8 && - "Cannot expand this type: target must support SOME integer reg!"); - // Expand to the next smaller integer type! - TransformToType[VT] = (MVT::ValueType)(VT-1); + // f32 and f64 is each expanded to corresponding integer type of same size. + if (VT == MVT::f32) + TransformToType[VT] = MVT::i32; + else if (VT == MVT::f64) + TransformToType[VT] = MVT::i64; + else { + assert((VT == MVT::Vector || MVT::isInteger(VT)) && VT > MVT::i8 && + "Cannot expand this type: target must support SOME integer reg!"); + // Expand to the next smaller integer type! + TransformToType[VT] = (MVT::ValueType)(VT-1); + } } } @@ -129,12 +136,27 @@ void TargetLowering::computeRegisterProperties() { else TransformToType[(MVT::ValueType)IntReg] = (MVT::ValueType)IntReg; - // If the target does not have native support for F32, promote it to F64. - if (!isTypeLegal(MVT::f32)) - SetValueTypeAction(MVT::f32, Promote, *this, - TransformToType, ValueTypeActions); - else + // If the target does not have native F64 support, expand it to I64. We will + // be generating soft float library calls. If the target does not have native + // support for F32, promote it to F64 if it is legal. Otherwise, expand it to + // I32. + if (isTypeLegal(MVT::f64)) + TransformToType[MVT::f64] = MVT::f64; + else { + NumElementsForVT[MVT::f64] = NumElementsForVT[MVT::i64]; + SetValueTypeAction(MVT::f64, Expand, *this, TransformToType, + ValueTypeActions); + } + if (isTypeLegal(MVT::f32)) TransformToType[MVT::f32] = MVT::f32; + else if (isTypeLegal(MVT::f64)) + SetValueTypeAction(MVT::f32, Promote, *this, TransformToType, + ValueTypeActions); + else { + NumElementsForVT[MVT::f32] = NumElementsForVT[MVT::i32]; + SetValueTypeAction(MVT::f32, Expand, *this, TransformToType, + ValueTypeActions); + } // Set MVT::Vector to always be Expanded SetValueTypeAction(MVT::Vector, Expand, *this, TransformToType, @@ -147,9 +169,6 @@ void TargetLowering::computeRegisterProperties() { if (isTypeLegal((MVT::ValueType)i)) TransformToType[i] = (MVT::ValueType)i; } - - assert(isTypeLegal(MVT::f64) && "Target does not support FP?"); - TransformToType[MVT::f64] = MVT::f64; } const char *TargetLowering::getTargetNodeName(unsigned Opcode) const {