Index: lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- lib/Target/ARM/ARMISelLowering.cpp +++ lib/Target/ARM/ARMISelLowering.cpp @@ -951,31 +951,35 @@ setOperationAction(ISD::UDIV, MVT::i32, LibCall); } - if (Subtarget->isTargetWindows() && !Subtarget->hasDivide()) { - setOperationAction(ISD::SDIV, MVT::i32, Custom); - setOperationAction(ISD::UDIV, MVT::i32, Custom); - - setOperationAction(ISD::SDIV, MVT::i64, Custom); - setOperationAction(ISD::UDIV, MVT::i64, Custom); - } - setOperationAction(ISD::SREM, MVT::i32, Expand); setOperationAction(ISD::UREM, MVT::i32, Expand); // Register based DivRem for AEABI (RTABI 4.2) if (Subtarget->isTargetAEABI() || Subtarget->isTargetAndroid() || - Subtarget->isTargetGNUAEABI() || Subtarget->isTargetMuslAEABI()) { + Subtarget->isTargetGNUAEABI() || Subtarget->isTargetMuslAEABI() || + Subtarget->isTargetWindows()) { setOperationAction(ISD::SREM, MVT::i64, Custom); setOperationAction(ISD::UREM, MVT::i64, Custom); HasStandaloneRem = false; - setLibcallName(RTLIB::SDIVREM_I8, "__aeabi_idivmod"); - setLibcallName(RTLIB::SDIVREM_I16, "__aeabi_idivmod"); - setLibcallName(RTLIB::SDIVREM_I32, "__aeabi_idivmod"); - setLibcallName(RTLIB::SDIVREM_I64, "__aeabi_ldivmod"); - setLibcallName(RTLIB::UDIVREM_I8, "__aeabi_uidivmod"); - setLibcallName(RTLIB::UDIVREM_I16, "__aeabi_uidivmod"); - setLibcallName(RTLIB::UDIVREM_I32, "__aeabi_uidivmod"); - setLibcallName(RTLIB::UDIVREM_I64, "__aeabi_uldivmod"); + if (Subtarget->isTargetWindows()) { + setLibcallName(RTLIB::SDIVREM_I8, "__rt_sdiv"); + setLibcallName(RTLIB::SDIVREM_I16, "__rt_sdiv"); + setLibcallName(RTLIB::SDIVREM_I32, "__rt_sdiv"); + setLibcallName(RTLIB::SDIVREM_I64, "__rt_sdiv64"); + setLibcallName(RTLIB::UDIVREM_I8, "__rt_udiv"); + setLibcallName(RTLIB::UDIVREM_I16, "__rt_udiv"); + setLibcallName(RTLIB::UDIVREM_I32, "__rt_udiv"); + setLibcallName(RTLIB::UDIVREM_I64, "__rt_udiv64"); + } else { + setLibcallName(RTLIB::SDIVREM_I8, "__aeabi_idivmod"); + setLibcallName(RTLIB::SDIVREM_I16, "__aeabi_idivmod"); + setLibcallName(RTLIB::SDIVREM_I32, "__aeabi_idivmod"); + setLibcallName(RTLIB::SDIVREM_I64, "__aeabi_ldivmod"); + setLibcallName(RTLIB::UDIVREM_I8, "__aeabi_uidivmod"); + setLibcallName(RTLIB::UDIVREM_I16, "__aeabi_uidivmod"); + setLibcallName(RTLIB::UDIVREM_I32, "__aeabi_uidivmod"); + setLibcallName(RTLIB::UDIVREM_I64, "__aeabi_uldivmod"); + } setLibcallCallingConv(RTLIB::SDIVREM_I8, CallingConv::ARM_AAPCS); setLibcallCallingConv(RTLIB::SDIVREM_I16, CallingConv::ARM_AAPCS); @@ -7207,48 +7211,6 @@ return LowerCallTo(CLI).first; } -SDValue ARMTargetLowering::LowerDIV_Windows(SDValue Op, SelectionDAG &DAG, - bool Signed) const { - assert(Op.getValueType() == MVT::i32 && - "unexpected type for custom lowering DIV"); - SDLoc dl(Op); - - SDValue DBZCHK = DAG.getNode(ARMISD::WIN__DBZCHK, dl, MVT::Other, - DAG.getEntryNode(), Op.getOperand(1)); - - return LowerWindowsDIVLibCall(Op, DAG, Signed, DBZCHK); -} - -void ARMTargetLowering::ExpandDIV_Windows( - SDValue Op, SelectionDAG &DAG, bool Signed, - SmallVectorImpl &Results) const { - const auto &DL = DAG.getDataLayout(); - const auto &TLI = DAG.getTargetLoweringInfo(); - - assert(Op.getValueType() == MVT::i64 && - "unexpected type for custom lowering DIV"); - SDLoc dl(Op); - - SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Op.getOperand(1), - DAG.getConstant(0, dl, MVT::i32)); - SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Op.getOperand(1), - DAG.getConstant(1, dl, MVT::i32)); - SDValue Or = DAG.getNode(ISD::OR, dl, MVT::i32, Lo, Hi); - - SDValue DBZCHK = - DAG.getNode(ARMISD::WIN__DBZCHK, dl, MVT::Other, DAG.getEntryNode(), Or); - - SDValue Result = LowerWindowsDIVLibCall(Op, DAG, Signed, DBZCHK); - - SDValue Lower = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Result); - SDValue Upper = DAG.getNode(ISD::SRL, dl, MVT::i64, Result, - DAG.getConstant(32, dl, TLI.getPointerTy(DL))); - Upper = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Upper); - - Results.push_back(Lower); - Results.push_back(Upper); -} - static SDValue LowerAtomicLoadStore(SDValue Op, SelectionDAG &DAG) { if (isStrongerThanMonotonic(cast(Op)->getOrdering())) // Acquire/Release load/store is not legal for targets without a dmb or @@ -7381,12 +7343,8 @@ case ISD::FLT_ROUNDS_: return LowerFLT_ROUNDS_(Op, DAG); case ISD::MUL: return LowerMUL(Op, DAG); case ISD::SDIV: - if (Subtarget->isTargetWindows()) - return LowerDIV_Windows(Op, DAG, /* Signed */ true); return LowerSDIV(Op, DAG); case ISD::UDIV: - if (Subtarget->isTargetWindows()) - return LowerDIV_Windows(Op, DAG, /* Signed */ false); return LowerUDIV(Op, DAG); case ISD::ADDC: case ISD::ADDE: @@ -7447,9 +7405,8 @@ return; case ISD::UDIV: case ISD::SDIV: - assert(Subtarget->isTargetWindows() && "can only expand DIV on Windows"); - return ExpandDIV_Windows(SDValue(N, 0), DAG, N->getOpcode() == ISD::SDIV, - Results); + abort(); + return; case ISD::ATOMIC_CMP_SWAP: ReplaceCMP_SWAP_64Results(N, Results, DAG); return; @@ -12237,7 +12194,7 @@ } static TargetLowering::ArgListTy getDivRemArgList( - const SDNode *N, LLVMContext *Context) { + const SDNode *N, LLVMContext *Context, const ARMSubtarget *Subtarget) { assert((N->getOpcode() == ISD::SDIVREM || N->getOpcode() == ISD::UDIVREM || N->getOpcode() == ISD::SREM || N->getOpcode() == ISD::UREM) && "Unhandled Opcode in getDivRemArgList"); @@ -12246,9 +12203,10 @@ TargetLowering::ArgListTy Args; TargetLowering::ArgListEntry Entry; for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { - EVT ArgVT = N->getOperand(i).getValueType(); + unsigned src = Subtarget->isTargetWindows() ? e - 1 - i : i; + EVT ArgVT = N->getOperand(src).getValueType(); Type *ArgTy = ArgVT.getTypeForEVT(*Context); - Entry.Node = N->getOperand(i); + Entry.Node = N->getOperand(src); Entry.Ty = ArgTy; Entry.isSExt = isSigned; Entry.isZExt = !isSigned; @@ -12259,7 +12217,8 @@ SDValue ARMTargetLowering::LowerDivRem(SDValue Op, SelectionDAG &DAG) const { assert((Subtarget->isTargetAEABI() || Subtarget->isTargetAndroid() || - Subtarget->isTargetGNUAEABI() || Subtarget->isTargetMuslAEABI()) && + Subtarget->isTargetGNUAEABI() || Subtarget->isTargetMuslAEABI() || + Subtarget->isTargetWindows()) && "Register-based DivRem lowering only"); unsigned Opcode = Op->getOpcode(); assert((Opcode == ISD::SDIVREM || Opcode == ISD::UDIVREM) && @@ -12273,7 +12232,8 @@ SDValue InChain = DAG.getEntryNode(); TargetLowering::ArgListTy Args = getDivRemArgList(Op.getNode(), - DAG.getContext()); + DAG.getContext(), + Subtarget); SDValue Callee = DAG.getExternalSymbol(getLibcallName(LC), getPointerTy(DAG.getDataLayout())); @@ -12313,7 +12273,8 @@ RTLIB::Libcall LC = getDivRemLibcall(N, N->getValueType(0).getSimpleVT(). SimpleTy); SDValue InChain = DAG.getEntryNode(); - TargetLowering::ArgListTy Args = getDivRemArgList(N, DAG.getContext()); + TargetLowering::ArgListTy Args = getDivRemArgList(N, DAG.getContext(), + Subtarget); bool isSigned = N->getOpcode() == ISD::SREM; SDValue Callee = DAG.getExternalSymbol(getLibcallName(LC), getPointerTy(DAG.getDataLayout()));