diff options
| author | Chris Lattner <sabre@nondot.org> | 2005-07-16 00:19:57 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2005-07-16 00:19:57 +0000 | 
| commit | e3e847bfd7bde44a81632c5af297f1817d22abbd (patch) | |
| tree | 6c20603f9c3158bf0f6785781d7d13f88addf0f8 /llvm/lib/CodeGen | |
| parent | b47f5e6d54e1dc35c95196112aeee6114036b6dd (diff) | |
| download | bcm5719-llvm-e3e847bfd7bde44a81632c5af297f1817d22abbd.tar.gz bcm5719-llvm-e3e847bfd7bde44a81632c5af297f1817d22abbd.zip | |
Break the code for expanding UINT_TO_FP operations out into its own
SelectionDAGLegalize::ExpandLegalUINT_TO_FP method.
Add a new method, PromoteLegalUINT_TO_FP, which allows targets to request
that UINT_TO_FP operations be promoted to a larger input type.  This is
useful for targets that have some UINT_TO_FP or SINT_TO_FP operations but
not all of them (like X86).
The same should be done with SINT_TO_FP, but this patch does not do that
yet.
llvm-svn: 22447
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 151 | 
1 files changed, 116 insertions, 35 deletions
| diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 16d4eeb9414..ee515fd3900 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -124,6 +124,10 @@ private:                            SDOperand &Hi);    SDOperand ExpandIntToFP(bool isSigned, MVT::ValueType DestTy,                            SDOperand Source); + +  SDOperand ExpandLegalUINT_TO_FP(SDOperand LegalOp, MVT::ValueType DestVT); +  SDOperand PromoteLegalUINT_TO_FP(SDOperand LegalOp, MVT::ValueType DestVT); +     bool ExpandShift(unsigned Opc, SDOperand Op, SDOperand Amt,                     SDOperand &Lo, SDOperand &Hi);    void ExpandShiftParts(unsigned NodeOp, SDOperand Op, SDOperand Amt, @@ -147,6 +151,102 @@ SelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag)           "Too many value types for ValueTypeActions to hold!");  } +/// ExpandLegalUINT_TO_FP - This function is responsible for legalizing a  +/// UINT_TO_FP operation of the specified operand when the target requests that +/// we expand it.  At this point, we know that the result and operand types are +/// legal for the target. +SDOperand SelectionDAGLegalize::ExpandLegalUINT_TO_FP(SDOperand Op0, +                                                      MVT::ValueType DestVT) { +  assert(Op0.getValueType() == MVT::i32 && +         "This code only works for i32 input: extend in the future"); +  SDOperand Tmp1 = DAG.getNode(ISD::SINT_TO_FP, DestVT, Op0); +   +  SDOperand SignSet = DAG.getSetCC(ISD::SETLT, TLI.getSetCCResultTy(),  +                                   Op0, +                                   DAG.getConstant(0,  +                                                   Op0.getValueType())); +  SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4); +  SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(), +                                    SignSet, Four, Zero); +   +  uint64_t FF = 0x5f800000ULL; +  if (TLI.isLittleEndian()) FF <<= 32; +  static Constant *FudgeFactor = ConstantUInt::get(Type::ULongTy, FF); +   +  MachineConstantPool *CP = DAG.getMachineFunction().getConstantPool(); +  SDOperand CPIdx = DAG.getConstantPool(CP->getConstantPoolIndex(FudgeFactor), +                                        TLI.getPointerTy()); +  CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset); +  SDOperand FudgeInReg; +  if (DestVT == MVT::f32) +    FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx, +                             DAG.getSrcValue(NULL)); +  else { +    assert(DestVT == MVT::f64 && "Unexpected conversion"); +    FudgeInReg = LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, MVT::f64, +                                           DAG.getEntryNode(), CPIdx, +                                           DAG.getSrcValue(NULL), MVT::f32)); +  } +   +  NeedsAnotherIteration = true; +  return DAG.getNode(ISD::ADD, DestVT, Tmp1, FudgeInReg); +} + +/// PromoteLegalUINT_TO_FP - This function is responsible for legalizing a  +/// UINT_TO_FP operation of the specified operand when the target requests that +/// we promote it.  At this point, we know that the result and operand types are +/// legal for the target, and that there is a legal UINT_TO_FP or SINT_TO_FP +/// operation that takes a larger input. +SDOperand SelectionDAGLegalize::PromoteLegalUINT_TO_FP(SDOperand LegalOp, +                                                       MVT::ValueType DestVT) { +  // First step, figure out the appropriate *INT_TO_FP operation to use. +  MVT::ValueType NewInTy = LegalOp.getValueType(); +   +  unsigned OpToUse = 0; +   +  // Scan for the appropriate larger type to use. +  while (1) { +    NewInTy = (MVT::ValueType)(NewInTy+1); +    assert(MVT::isInteger(NewInTy) && "Ran out of possibilities!"); +     +    // If the target supports SINT_TO_FP of this type, use it. +    switch (TLI.getOperationAction(ISD::SINT_TO_FP, NewInTy)) { +      default: break; +      case TargetLowering::Legal: +        if (!TLI.hasNativeSupportFor(NewInTy)) +          break;  // Can't use this datatype. +        // FALL THROUGH. +      case TargetLowering::Custom: +        OpToUse = ISD::SINT_TO_FP; +        break; +    } +    if (OpToUse) break; +     +    // If the target supports UINT_TO_FP of this type, use it. +    switch (TLI.getOperationAction(ISD::UINT_TO_FP, NewInTy)) { +      default: break; +      case TargetLowering::Legal: +        if (!TLI.hasNativeSupportFor(NewInTy)) +          break;  // Can't use this datatype. +        // FALL THROUGH. +      case TargetLowering::Custom: +        OpToUse = ISD::UINT_TO_FP; +        break; +    } +    if (OpToUse) break; +     +    // Otherwise, try a larger type. +  } + +  // Make sure to legalize any nodes we create here in the next pass. +  NeedsAnotherIteration = true; +   +  // Okay, we found the operation and type to use.  Zero extend our input to the +  // desired type then run the operation on it. +  return DAG.getNode(OpToUse, DestVT, +                     DAG.getNode(ISD::ZERO_EXTEND, NewInTy, LegalOp)); +} +  void SelectionDAGLegalize::LegalizeDAG() {    SDOperand OldRoot = DAG.getRoot();    SDOperand NewRoot = LegalizeOp(OldRoot); @@ -1338,42 +1438,23 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {      switch (getTypeAction(Node->getOperand(0).getValueType())) {      case Legal:        //still made need to expand if the op is illegal, but the types are legal -      if (Node->getOpcode() == ISD::UINT_TO_FP && -          TLI.getOperationAction(Node->getOpcode(),  -                                 Node->getOperand(0).getValueType())  -          == TargetLowering::Expand) { -        SDOperand Op0 = LegalizeOp(Node->getOperand(0)); -        Tmp1 = DAG.getNode(ISD::SINT_TO_FP, Node->getValueType(0),  -                           Op0); -         -        SDOperand SignSet = DAG.getSetCC(ISD::SETLT, TLI.getSetCCResultTy(),  -                                         Op0, -                                         DAG.getConstant(0,  -                                         Op0.getValueType())); -        SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4); -        SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(), -                                          SignSet, Four, Zero); -        uint64_t FF = 0x5f800000ULL; -        if (TLI.isLittleEndian()) FF <<= 32; -        static Constant *FudgeFactor = ConstantUInt::get(Type::ULongTy, FF); - -        MachineConstantPool *CP = DAG.getMachineFunction().getConstantPool(); -        SDOperand CPIdx = DAG.getConstantPool(CP->getConstantPoolIndex(FudgeFactor), -                                              TLI.getPointerTy()); -        CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset); -        SDOperand FudgeInReg; -        if (Node->getValueType(0) == MVT::f32) -          FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx, -                                   DAG.getSrcValue(NULL)); -        else { -          assert(Node->getValueType(0) == MVT::f64 && "Unexpected conversion"); -          FudgeInReg =  -            LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, MVT::f64, -                                      DAG.getEntryNode(), CPIdx, -                                      DAG.getSrcValue(NULL), MVT::f32)); +      if (Node->getOpcode() == ISD::UINT_TO_FP) { +        switch (TLI.getOperationAction(Node->getOpcode(),  +                                       Node->getOperand(0).getValueType())) { +        default: assert(0 && "Unknown operation action!"); +        case TargetLowering::Expand: +          Result = ExpandLegalUINT_TO_FP(LegalizeOp(Node->getOperand(0)), +                                         Node->getValueType(0)); +          AddLegalizedOperand(Op, Result); +          return Result; +        case TargetLowering::Promote: +          Result = PromoteLegalUINT_TO_FP(LegalizeOp(Node->getOperand(0)), +                                          Node->getValueType(0)); +          AddLegalizedOperand(Op, Result); +          return Result; +        case TargetLowering::Legal: +          break;          } -        Result = DAG.getNode(ISD::ADD, Node->getValueType(0), Tmp1, FudgeInReg); -        break;        }        Tmp1 = LegalizeOp(Node->getOperand(0));        if (Tmp1 != Node->getOperand(0)) | 

