1//===-- MipsISelLowering.cpp - Mips DAG Lowering Implementation -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
--- 605 unchanged lines hidden (view full) ---
614 SetCC.getOperand(1), ISD::getSetCCInverse(CC, true));
615 return DAG.getNode(ISD::ADD, DL, SetCC.getValueType(), SetCC, True);
616 }
617
618 // Couldn't optimize.
619 return SDValue();
620}
621
622static SDValue performCMovFPCombine(SDNode *N, SelectionDAG &DAG,
623 TargetLowering::DAGCombinerInfo &DCI,
624 const MipsSubtarget &Subtarget) {
625 if (DCI.isBeforeLegalizeOps())
626 return SDValue();
627
628 SDValue ValueIfTrue = N->getOperand(0), ValueIfFalse = N->getOperand(2);
629
630 ConstantSDNode *FalseC = dyn_cast<ConstantSDNode>(ValueIfFalse);
631 if (!FalseC || FalseC->getZExtValue())
632 return SDValue();
633
634 // Since RHS (False) is 0, we swap the order of the True/False operands
635 // (obviously also inverting the condition) so that we can
636 // take advantage of conditional moves using the $0 register.
637 // Example:
638 // return (a != 0) ? x : 0;
639 // load $reg, x
640 // movz $reg, $0, a
641 unsigned Opc = (N->getOpcode() == MipsISD::CMovFP_T) ? MipsISD::CMovFP_F :
642 MipsISD::CMovFP_T;
643
644 SDValue FCC = N->getOperand(1), Glue = N->getOperand(3);
645 return DAG.getNode(Opc, SDLoc(N), ValueIfFalse.getValueType(),
646 ValueIfFalse, FCC, ValueIfTrue, Glue);
647}
648
649static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG,
650 TargetLowering::DAGCombinerInfo &DCI,
651 const MipsSubtarget &Subtarget) {
652 // Pattern match EXT.
653 // $dst = and ((sra or srl) $src , pos), (2**size - 1)
654 // => ext $dst, $src, size, pos
655 if (DCI.isBeforeLegalizeOps() || !Subtarget.hasExtractInsert())
656 return SDValue();
--- 117 unchanged lines hidden (view full) ---
774
775 switch (Opc) {
776 default: break;
777 case ISD::SDIVREM:
778 case ISD::UDIVREM:
779 return performDivRemCombine(N, DAG, DCI, Subtarget);
780 case ISD::SELECT:
781 return performSELECTCombine(N, DAG, DCI, Subtarget);
782 case MipsISD::CMovFP_F:
783 case MipsISD::CMovFP_T:
784 return performCMovFPCombine(N, DAG, DCI, Subtarget);
785 case ISD::AND:
786 return performANDCombine(N, DAG, DCI, Subtarget);
787 case ISD::OR:
788 return performORCombine(N, DAG, DCI, Subtarget);
789 case ISD::ADD:
790 return performADDCombine(N, DAG, DCI, Subtarget);
791 }
792
--- 1271 unchanged lines hidden (view full) ---
2064 DAG.getConstant(-1, MVT::i32));
2065 SDValue ShiftRight1Lo = DAG.getNode(ISD::SRL, DL, VT, Lo,
2066 DAG.getConstant(1, VT));
2067 SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, VT, ShiftRight1Lo, Not);
2068 SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, VT, Hi, Shamt);
2069 SDValue Or = DAG.getNode(ISD::OR, DL, VT, ShiftLeftHi, ShiftRightLo);
2070 SDValue ShiftLeftLo = DAG.getNode(ISD::SHL, DL, VT, Lo, Shamt);
2071 SDValue Cond = DAG.getNode(ISD::AND, DL, MVT::i32, Shamt,
2072 DAG.getConstant(VT.getSizeInBits(), MVT::i32));
2073 Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond,
2074 DAG.getConstant(0, VT), ShiftLeftLo);
2075 Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond, ShiftLeftLo, Or);
2076
2077 SDValue Ops[2] = {Lo, Hi};
2078 return DAG.getMergeValues(Ops, DL);
2079}
2080
--- 22 unchanged lines hidden (view full) ---
2103 SDValue ShiftLeft1Hi = DAG.getNode(ISD::SHL, DL, VT, Hi,
2104 DAG.getConstant(1, VT));
2105 SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, VT, ShiftLeft1Hi, Not);
2106 SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, VT, Lo, Shamt);
2107 SDValue Or = DAG.getNode(ISD::OR, DL, VT, ShiftLeftHi, ShiftRightLo);
2108 SDValue ShiftRightHi = DAG.getNode(IsSRA ? ISD::SRA : ISD::SRL,
2109 DL, VT, Hi, Shamt);
2110 SDValue Cond = DAG.getNode(ISD::AND, DL, MVT::i32, Shamt,
2111 DAG.getConstant(VT.getSizeInBits(), MVT::i32));
2112 SDValue Ext = DAG.getNode(ISD::SRA, DL, VT, Hi,
2113 DAG.getConstant(VT.getSizeInBits() - 1, VT));
2114 Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, ShiftRightHi, Or);
2115 Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond,
2116 IsSRA ? Ext : DAG.getConstant(0, VT), ShiftRightHi);
2117
2118 SDValue Ops[2] = {Lo, Hi};
2119 return DAG.getMergeValues(Ops, DL);
2120}
2121
2122static SDValue createLoadLR(unsigned Opc, SelectionDAG &DAG, LoadSDNode *LD,
2123 SDValue Chain, SDValue Src, unsigned Offset) {
2124 SDValue Ptr = LD->getBasePtr();
--- 803 unchanged lines hidden (view full) ---
2928 MipsFI->setFormalArgInfo(CCInfo.getNextStackOffset(),
2929 CCInfo.getInRegsParamsCount() > 0);
2930
2931 unsigned CurArgIdx = 0;
2932 CCInfo.rewindByValRegsInfo();
2933
2934 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
2935 CCValAssign &VA = ArgLocs[i];
2936 if (Ins[i].isOrigArg()) {
2937 std::advance(FuncArg, Ins[i].getOrigArgIndex() - CurArgIdx);
2938 CurArgIdx = Ins[i].getOrigArgIndex();
2939 }
2940 EVT ValVT = VA.getValVT();
2941 ISD::ArgFlagsTy Flags = Ins[i].Flags;
2942 bool IsRegLoc = VA.isRegLoc();
2943
2944 if (Flags.isByVal()) {
2945 assert(Ins[i].isOrigArg() && "Byval arguments cannot be implicit");
2946 unsigned FirstByValReg, LastByValReg;
2947 unsigned ByValIdx = CCInfo.getInRegsParamsProcessed();
2948 CCInfo.getInRegsParamInfo(ByValIdx, FirstByValReg, LastByValReg);
2949
2950 assert(Flags.getByValSize() &&
2951 "ByVal args of size 0 should have been ignored by front-end.");
2952 assert(ByValIdx < CCInfo.getInRegsParamsCount());
2953 copyByValRegs(Chain, DL, OutChains, DAG, Flags, InVals, &*FuncArg,
--- 104 unchanged lines hidden (view full) ---
3058 MachineFunction &MF, bool IsVarArg,
3059 const SmallVectorImpl<ISD::OutputArg> &Outs,
3060 LLVMContext &Context) const {
3061 SmallVector<CCValAssign, 16> RVLocs;
3062 MipsCCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
3063 return CCInfo.CheckReturn(Outs, RetCC_Mips);
3064}
3065
3066bool
3067MipsTargetLowering::shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const {
3068 if (Subtarget.hasMips3() && Subtarget.abiUsesSoftFloat()) {
3069 if (Type == MVT::i32)
3070 return true;
3071 }
3072 return IsSigned;
3073}
3074
3075SDValue
3076MipsTargetLowering::LowerReturn(SDValue Chain,
3077 CallingConv::ID CallConv, bool IsVarArg,
3078 const SmallVectorImpl<ISD::OutputArg> &Outs,
3079 const SmallVectorImpl<SDValue> &OutVals,
3080 SDLoc DL, SelectionDAG &DAG) const {
3081 // CCValAssign - represent the assignment of
3082 // the return value to a location
--- 826 unchanged lines hidden ---
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
--- 605 unchanged lines hidden (view full) ---
614 SetCC.getOperand(1), ISD::getSetCCInverse(CC, true));
615 return DAG.getNode(ISD::ADD, DL, SetCC.getValueType(), SetCC, True);
616 }
617
618 // Couldn't optimize.
619 return SDValue();
620}
621
622static SDValue performCMovFPCombine(SDNode *N, SelectionDAG &DAG,
623 TargetLowering::DAGCombinerInfo &DCI,
624 const MipsSubtarget &Subtarget) {
625 if (DCI.isBeforeLegalizeOps())
626 return SDValue();
627
628 SDValue ValueIfTrue = N->getOperand(0), ValueIfFalse = N->getOperand(2);
629
630 ConstantSDNode *FalseC = dyn_cast<ConstantSDNode>(ValueIfFalse);
631 if (!FalseC || FalseC->getZExtValue())
632 return SDValue();
633
634 // Since RHS (False) is 0, we swap the order of the True/False operands
635 // (obviously also inverting the condition) so that we can
636 // take advantage of conditional moves using the $0 register.
637 // Example:
638 // return (a != 0) ? x : 0;
639 // load $reg, x
640 // movz $reg, $0, a
641 unsigned Opc = (N->getOpcode() == MipsISD::CMovFP_T) ? MipsISD::CMovFP_F :
642 MipsISD::CMovFP_T;
643
644 SDValue FCC = N->getOperand(1), Glue = N->getOperand(3);
645 return DAG.getNode(Opc, SDLoc(N), ValueIfFalse.getValueType(),
646 ValueIfFalse, FCC, ValueIfTrue, Glue);
647}
648
649static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG,
650 TargetLowering::DAGCombinerInfo &DCI,
651 const MipsSubtarget &Subtarget) {
652 // Pattern match EXT.
653 // $dst = and ((sra or srl) $src , pos), (2**size - 1)
654 // => ext $dst, $src, size, pos
655 if (DCI.isBeforeLegalizeOps() || !Subtarget.hasExtractInsert())
656 return SDValue();
--- 117 unchanged lines hidden (view full) ---
774
775 switch (Opc) {
776 default: break;
777 case ISD::SDIVREM:
778 case ISD::UDIVREM:
779 return performDivRemCombine(N, DAG, DCI, Subtarget);
780 case ISD::SELECT:
781 return performSELECTCombine(N, DAG, DCI, Subtarget);
782 case MipsISD::CMovFP_F:
783 case MipsISD::CMovFP_T:
784 return performCMovFPCombine(N, DAG, DCI, Subtarget);
785 case ISD::AND:
786 return performANDCombine(N, DAG, DCI, Subtarget);
787 case ISD::OR:
788 return performORCombine(N, DAG, DCI, Subtarget);
789 case ISD::ADD:
790 return performADDCombine(N, DAG, DCI, Subtarget);
791 }
792
--- 1271 unchanged lines hidden (view full) ---
2064 DAG.getConstant(-1, MVT::i32));
2065 SDValue ShiftRight1Lo = DAG.getNode(ISD::SRL, DL, VT, Lo,
2066 DAG.getConstant(1, VT));
2067 SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, VT, ShiftRight1Lo, Not);
2068 SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, VT, Hi, Shamt);
2069 SDValue Or = DAG.getNode(ISD::OR, DL, VT, ShiftLeftHi, ShiftRightLo);
2070 SDValue ShiftLeftLo = DAG.getNode(ISD::SHL, DL, VT, Lo, Shamt);
2071 SDValue Cond = DAG.getNode(ISD::AND, DL, MVT::i32, Shamt,
2072 DAG.getConstant(VT.getSizeInBits(), MVT::i32));
2073 Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond,
2074 DAG.getConstant(0, VT), ShiftLeftLo);
2075 Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond, ShiftLeftLo, Or);
2076
2077 SDValue Ops[2] = {Lo, Hi};
2078 return DAG.getMergeValues(Ops, DL);
2079}
2080
--- 22 unchanged lines hidden (view full) ---
2103 SDValue ShiftLeft1Hi = DAG.getNode(ISD::SHL, DL, VT, Hi,
2104 DAG.getConstant(1, VT));
2105 SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, VT, ShiftLeft1Hi, Not);
2106 SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, VT, Lo, Shamt);
2107 SDValue Or = DAG.getNode(ISD::OR, DL, VT, ShiftLeftHi, ShiftRightLo);
2108 SDValue ShiftRightHi = DAG.getNode(IsSRA ? ISD::SRA : ISD::SRL,
2109 DL, VT, Hi, Shamt);
2110 SDValue Cond = DAG.getNode(ISD::AND, DL, MVT::i32, Shamt,
2111 DAG.getConstant(VT.getSizeInBits(), MVT::i32));
2112 SDValue Ext = DAG.getNode(ISD::SRA, DL, VT, Hi,
2113 DAG.getConstant(VT.getSizeInBits() - 1, VT));
2114 Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, ShiftRightHi, Or);
2115 Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond,
2116 IsSRA ? Ext : DAG.getConstant(0, VT), ShiftRightHi);
2117
2118 SDValue Ops[2] = {Lo, Hi};
2119 return DAG.getMergeValues(Ops, DL);
2120}
2121
2122static SDValue createLoadLR(unsigned Opc, SelectionDAG &DAG, LoadSDNode *LD,
2123 SDValue Chain, SDValue Src, unsigned Offset) {
2124 SDValue Ptr = LD->getBasePtr();
--- 803 unchanged lines hidden (view full) ---
2928 MipsFI->setFormalArgInfo(CCInfo.getNextStackOffset(),
2929 CCInfo.getInRegsParamsCount() > 0);
2930
2931 unsigned CurArgIdx = 0;
2932 CCInfo.rewindByValRegsInfo();
2933
2934 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
2935 CCValAssign &VA = ArgLocs[i];
2936 if (Ins[i].isOrigArg()) {
2937 std::advance(FuncArg, Ins[i].getOrigArgIndex() - CurArgIdx);
2938 CurArgIdx = Ins[i].getOrigArgIndex();
2939 }
2940 EVT ValVT = VA.getValVT();
2941 ISD::ArgFlagsTy Flags = Ins[i].Flags;
2942 bool IsRegLoc = VA.isRegLoc();
2943
2944 if (Flags.isByVal()) {
2945 assert(Ins[i].isOrigArg() && "Byval arguments cannot be implicit");
2946 unsigned FirstByValReg, LastByValReg;
2947 unsigned ByValIdx = CCInfo.getInRegsParamsProcessed();
2948 CCInfo.getInRegsParamInfo(ByValIdx, FirstByValReg, LastByValReg);
2949
2950 assert(Flags.getByValSize() &&
2951 "ByVal args of size 0 should have been ignored by front-end.");
2952 assert(ByValIdx < CCInfo.getInRegsParamsCount());
2953 copyByValRegs(Chain, DL, OutChains, DAG, Flags, InVals, &*FuncArg,
--- 104 unchanged lines hidden (view full) ---
3058 MachineFunction &MF, bool IsVarArg,
3059 const SmallVectorImpl<ISD::OutputArg> &Outs,
3060 LLVMContext &Context) const {
3061 SmallVector<CCValAssign, 16> RVLocs;
3062 MipsCCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
3063 return CCInfo.CheckReturn(Outs, RetCC_Mips);
3064}
3065
3066bool
3067MipsTargetLowering::shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const {
3068 if (Subtarget.hasMips3() && Subtarget.abiUsesSoftFloat()) {
3069 if (Type == MVT::i32)
3070 return true;
3071 }
3072 return IsSigned;
3073}
3074
3075SDValue
3076MipsTargetLowering::LowerReturn(SDValue Chain,
3077 CallingConv::ID CallConv, bool IsVarArg,
3078 const SmallVectorImpl<ISD::OutputArg> &Outs,
3079 const SmallVectorImpl<SDValue> &OutVals,
3080 SDLoc DL, SelectionDAG &DAG) const {
3081 // CCValAssign - represent the assignment of
3082 // the return value to a location
--- 826 unchanged lines hidden ---