diff options
Diffstat (limited to 'llvm/lib/Target/Mips')
26 files changed, 440 insertions, 537 deletions
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 9de34cc0e787..b81ebedfb9c7 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -740,9 +740,8 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO, return RegNo; } else if (MO.isImm()) { return static_cast<unsigned>(MO.getImm()); - } else if (MO.isFPImm()) { - return static_cast<unsigned>(APFloat(MO.getFPImm()) - .bitcastToAPInt().getHiBits(32).getLimitedValue()); + } else if (MO.isDFPImm()) { + return static_cast<unsigned>(bit_cast<double>(MO.getDFPImm())); } // MO must be an Expr. assert(MO.isExpr()); diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp index a4a953bcd7c3..befa883d5877 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp @@ -35,7 +35,7 @@ void MipsRegInfoRecord::EmitMipsOptionRecord() { // 1-byte long nor fixed length but it matches the value GAS emits. MCSectionELF *Sec = Context.getELFSection(".MIPS.options", ELF::SHT_MIPS_OPTIONS, - ELF::SHF_ALLOC | ELF::SHF_MIPS_NOSTRIP, 1, ""); + ELF::SHF_ALLOC | ELF::SHF_MIPS_NOSTRIP, 1); MCA.registerSection(*Sec); Sec->setAlignment(Align(8)); Streamer->SwitchSection(Sec); @@ -53,7 +53,7 @@ void MipsRegInfoRecord::EmitMipsOptionRecord() { Streamer->emitIntValue(ri_gp_value, 8); } else { MCSectionELF *Sec = Context.getELFSection(".reginfo", ELF::SHT_MIPS_REGINFO, - ELF::SHF_ALLOC, 24, ""); + ELF::SHF_ALLOC, 24); MCA.registerSection(*Sec); Sec->setAlignment(MTS->getABI().IsN32() ? Align(8) : Align(4)); Streamer->SwitchSection(Sec); diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index 6ec8fe805968..232d0eb33164 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -1309,7 +1309,7 @@ void MipsTargetELFStreamer::emitMipsAbiFlags() { MCContext &Context = MCA.getContext(); MCStreamer &OS = getStreamer(); MCSectionELF *Sec = Context.getELFSection( - ".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS, ELF::SHF_ALLOC, 24, ""); + ".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS, ELF::SHF_ALLOC, 24); MCA.registerSection(*Sec); Sec->setAlignment(Align(8)); OS.SwitchSection(Sec); diff --git a/llvm/lib/Target/Mips/Mips16HardFloat.cpp b/llvm/lib/Target/Mips/Mips16HardFloat.cpp index cc1f72c03632..6c5f63804d19 100644 --- a/llvm/lib/Target/Mips/Mips16HardFloat.cpp +++ b/llvm/lib/Target/Mips/Mips16HardFloat.cpp @@ -359,7 +359,7 @@ static const char *const IntrinsicInline[] = { "llvm.log10.f32", "llvm.log10.f64", "llvm.nearbyint.f32", "llvm.nearbyint.f64", "llvm.pow.f32", "llvm.pow.f64", - "llvm.powi.f32", "llvm.powi.f64", + "llvm.powi.f32.i32", "llvm.powi.f64.i32", "llvm.rint.f32", "llvm.rint.f64", "llvm.round.f32", "llvm.round.f64", "llvm.sin.f32", "llvm.sin.f64", diff --git a/llvm/lib/Target/Mips/Mips16ISelLowering.cpp b/llvm/lib/Target/Mips/Mips16ISelLowering.cpp index a3b86bdc2ca0..136612c59d96 100644 --- a/llvm/lib/Target/Mips/Mips16ISelLowering.cpp +++ b/llvm/lib/Target/Mips/Mips16ISelLowering.cpp @@ -156,7 +156,7 @@ llvm::createMips16TargetLowering(const MipsTargetMachine &TM, } bool Mips16TargetLowering::allowsMisalignedMemoryAccesses( - EVT VT, unsigned, unsigned, MachineMemOperand::Flags, bool *Fast) const { + EVT VT, unsigned, Align, MachineMemOperand::Flags, bool *Fast) const { return false; } diff --git a/llvm/lib/Target/Mips/Mips16ISelLowering.h b/llvm/lib/Target/Mips/Mips16ISelLowering.h index 200249933577..e8b5f60b9f5e 100644 --- a/llvm/lib/Target/Mips/Mips16ISelLowering.h +++ b/llvm/lib/Target/Mips/Mips16ISelLowering.h @@ -22,7 +22,7 @@ namespace llvm { const MipsSubtarget &STI); bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, - unsigned Align, + Align Alignment, MachineMemOperand::Flags Flags, bool *Fast) const override; diff --git a/llvm/lib/Target/Mips/MipsCCState.cpp b/llvm/lib/Target/Mips/MipsCCState.cpp index fe3fe82797c3..76acfa97c3b4 100644 --- a/llvm/lib/Target/Mips/MipsCCState.cpp +++ b/llvm/lib/Target/Mips/MipsCCState.cpp @@ -12,8 +12,7 @@ using namespace llvm; -/// This function returns true if CallSym is a long double emulation routine. -static bool isF128SoftLibCall(const char *CallSym) { +bool MipsCCState::isF128SoftLibCall(const char *CallSym) { const char *const LibCalls[] = { "__addtf3", "__divtf3", "__eqtf2", "__extenddftf2", "__extendsftf2", "__fixtfdi", "__fixtfsi", "__fixtfti", @@ -37,7 +36,7 @@ static bool isF128SoftLibCall(const char *CallSym) { /// This function returns true if Ty is fp128, {f128} or i128 which was /// originally a fp128. -static bool originalTypeIsF128(const Type *Ty, const char *Func) { +bool MipsCCState::originalTypeIsF128(const Type *Ty, const char *Func) { if (Ty->isFP128Ty()) return true; @@ -47,11 +46,12 @@ static bool originalTypeIsF128(const Type *Ty, const char *Func) { // If the Ty is i128 and the function being called is a long double emulation // routine, then the original type is f128. + // FIXME: This is unsound because these functions could be indirectly called return (Func && Ty->isIntegerTy(128) && isF128SoftLibCall(Func)); } /// Return true if the original type was vXfXX. -static bool originalEVTTypeIsVectorFloat(EVT Ty) { +bool MipsCCState::originalEVTTypeIsVectorFloat(EVT Ty) { if (Ty.isVector() && Ty.getVectorElementType().isFloatingPoint()) return true; @@ -59,7 +59,7 @@ static bool originalEVTTypeIsVectorFloat(EVT Ty) { } /// Return true if the original type was vXfXX / vXfXX. -static bool originalTypeIsVectorFloat(const Type * Ty) { +bool MipsCCState::originalTypeIsVectorFloat(const Type *Ty) { if (Ty->isVectorTy() && Ty->isFPOrFPVectorTy()) return true; @@ -126,6 +126,18 @@ void MipsCCState::PreAnalyzeReturnForVectorFloat( } } +void MipsCCState::PreAnalyzeReturnValue(EVT ArgVT) { + OriginalRetWasFloatVector.push_back(originalEVTTypeIsVectorFloat(ArgVT)); +} + +void MipsCCState::PreAnalyzeCallOperand(const Type *ArgTy, bool IsFixed, + const char *Func) { + OriginalArgWasF128.push_back(originalTypeIsF128(ArgTy, Func)); + OriginalArgWasFloat.push_back(ArgTy->isFloatingPointTy()); + OriginalArgWasFloatVector.push_back(ArgTy->isVectorTy()); + CallOperandIsFixed.push_back(IsFixed); +} + /// Identify lowered values that originated from f128, float and sret to vXfXX /// arguments and record this. void MipsCCState::PreAnalyzeCallOperands( @@ -142,6 +154,27 @@ void MipsCCState::PreAnalyzeCallOperands( } } +void MipsCCState::PreAnalyzeFormalArgument(const Type *ArgTy, + ISD::ArgFlagsTy Flags) { + // SRet arguments cannot originate from f128 or {f128} returns so we just + // push false. We have to handle this specially since SRet arguments + // aren't mapped to an original argument. + if (Flags.isSRet()) { + OriginalArgWasF128.push_back(false); + OriginalArgWasFloat.push_back(false); + OriginalArgWasFloatVector.push_back(false); + return; + } + + OriginalArgWasF128.push_back(originalTypeIsF128(ArgTy, nullptr)); + OriginalArgWasFloat.push_back(ArgTy->isFloatingPointTy()); + + // The MIPS vector ABI exhibits a corner case of sorts or quirk; if the + // first argument is actually an SRet pointer to a vector, then the next + // argument slot is $a2. + OriginalArgWasFloatVector.push_back(ArgTy->isVectorTy()); +} + /// Identify lowered values that originated from f128, float and vXfXX arguments /// and record this. void MipsCCState::PreAnalyzeFormalArgumentsForF128( diff --git a/llvm/lib/Target/Mips/MipsCCState.h b/llvm/lib/Target/Mips/MipsCCState.h index fd2fd97c8f13..bbb5225d5f67 100644 --- a/llvm/lib/Target/Mips/MipsCCState.h +++ b/llvm/lib/Target/Mips/MipsCCState.h @@ -26,6 +26,21 @@ public: getSpecialCallingConvForCallee(const SDNode *Callee, const MipsSubtarget &Subtarget); + /// This function returns true if CallSym is a long double emulation routine. + /// + /// FIXME: Changing the ABI based on the callee name is unsound. The lib func + /// address could be captured. + static bool isF128SoftLibCall(const char *CallSym); + + static bool originalTypeIsF128(const Type *Ty, const char *Func); + static bool originalEVTTypeIsVectorFloat(EVT Ty); + static bool originalTypeIsVectorFloat(const Type *Ty); + + void PreAnalyzeCallOperand(const Type *ArgTy, bool IsFixed, const char *Func); + + void PreAnalyzeFormalArgument(const Type *ArgTy, ISD::ArgFlagsTy Flags); + void PreAnalyzeReturnValue(EVT ArgVT); + private: /// Identify lowered values that originated from f128 arguments and record /// this for use by RetCC_MipsN. @@ -85,17 +100,23 @@ public: SpecialCallingConvType SpecialCC = NoSpecialCallingConv) : CCState(CC, isVarArg, MF, locs, C), SpecialCallingConv(SpecialCC) {} + void PreAnalyzeCallOperands( + const SmallVectorImpl<ISD::OutputArg> &Outs, CCAssignFn Fn, + std::vector<TargetLowering::ArgListEntry> &FuncArgs, const char *Func) { + OriginalArgWasF128.clear(); + OriginalArgWasFloat.clear(); + OriginalArgWasFloatVector.clear(); + CallOperandIsFixed.clear(); + PreAnalyzeCallOperands(Outs, FuncArgs, Func); + } + void AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, CCAssignFn Fn, std::vector<TargetLowering::ArgListEntry> &FuncArgs, const char *Func) { - PreAnalyzeCallOperands(Outs, FuncArgs, Func); + PreAnalyzeCallOperands(Outs, Fn, FuncArgs, Func); CCState::AnalyzeCallOperands(Outs, Fn); - OriginalArgWasF128.clear(); - OriginalArgWasFloat.clear(); - OriginalArgWasFloatVector.clear(); - CallOperandIsFixed.clear(); } // The AnalyzeCallOperands in the base class is not usable since we must @@ -107,34 +128,56 @@ public: SmallVectorImpl<ISD::ArgFlagsTy> &Flags, CCAssignFn Fn) = delete; + void PreAnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins, + CCAssignFn Fn) { + OriginalArgWasFloat.clear(); + OriginalArgWasF128.clear(); + OriginalArgWasFloatVector.clear(); + PreAnalyzeFormalArgumentsForF128(Ins); + } + void AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins, CCAssignFn Fn) { - PreAnalyzeFormalArgumentsForF128(Ins); + PreAnalyzeFormalArguments(Ins, Fn); CCState::AnalyzeFormalArguments(Ins, Fn); + } + + void PreAnalyzeCallResult(const Type *RetTy, const char *Func) { + OriginalArgWasF128.push_back(originalTypeIsF128(RetTy, Func)); + OriginalArgWasFloat.push_back(RetTy->isFloatingPointTy()); + OriginalRetWasFloatVector.push_back(originalTypeIsVectorFloat(RetTy)); + } + + void PreAnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins, + CCAssignFn Fn, const Type *RetTy, + const char *Func) { OriginalArgWasFloat.clear(); OriginalArgWasF128.clear(); OriginalArgWasFloatVector.clear(); + PreAnalyzeCallResultForF128(Ins, RetTy, Func); + PreAnalyzeCallResultForVectorFloat(Ins, RetTy); } void AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins, CCAssignFn Fn, const Type *RetTy, const char *Func) { - PreAnalyzeCallResultForF128(Ins, RetTy, Func); - PreAnalyzeCallResultForVectorFloat(Ins, RetTy); + PreAnalyzeCallResult(Ins, Fn, RetTy, Func); CCState::AnalyzeCallResult(Ins, Fn); + } + + void PreAnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, + CCAssignFn Fn) { OriginalArgWasFloat.clear(); OriginalArgWasF128.clear(); OriginalArgWasFloatVector.clear(); + PreAnalyzeReturnForF128(Outs); + PreAnalyzeReturnForVectorFloat(Outs); } void AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, CCAssignFn Fn) { - PreAnalyzeReturnForF128(Outs); - PreAnalyzeReturnForVectorFloat(Outs); + PreAnalyzeReturn(Outs, Fn); CCState::AnalyzeReturn(Outs, Fn); - OriginalArgWasFloat.clear(); - OriginalArgWasF128.clear(); - OriginalArgWasFloatVector.clear(); } bool CheckReturn(const SmallVectorImpl<ISD::OutputArg> &ArgsFlags, diff --git a/llvm/lib/Target/Mips/MipsCallLowering.cpp b/llvm/lib/Target/Mips/MipsCallLowering.cpp index 377aa4825b43..5c2549ee176b 100644 --- a/llvm/lib/Target/Mips/MipsCallLowering.cpp +++ b/llvm/lib/Target/Mips/MipsCallLowering.cpp @@ -24,98 +24,89 @@ using namespace llvm; MipsCallLowering::MipsCallLowering(const MipsTargetLowering &TLI) : CallLowering(&TLI) {} -bool MipsCallLowering::MipsHandler::assign(Register VReg, const CCValAssign &VA, - const EVT &VT) { - if (VA.isRegLoc()) { - assignValueToReg(VReg, VA, VT); - } else if (VA.isMemLoc()) { - assignValueToAddress(VReg, VA); - } else { - return false; +struct MipsOutgoingValueAssigner : public CallLowering::OutgoingValueAssigner { + /// This is the name of the function being called + /// FIXME: Relying on this is unsound + const char *Func = nullptr; + + /// Is this a return value, or an outgoing call operand. + bool IsReturn; + + MipsOutgoingValueAssigner(CCAssignFn *AssignFn_, const char *Func, + bool IsReturn) + : OutgoingValueAssigner(AssignFn_), Func(Func), IsReturn(IsReturn) {} + + bool assignArg(unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, + const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags, + CCState &State_) override { + MipsCCState &State = static_cast<MipsCCState &>(State_); + + if (IsReturn) + State.PreAnalyzeReturnValue(EVT::getEVT(Info.Ty)); + else + State.PreAnalyzeCallOperand(Info.Ty, Info.IsFixed, Func); + + return CallLowering::OutgoingValueAssigner::assignArg( + ValNo, OrigVT, ValVT, LocVT, LocInfo, Info, Flags, State); } - return true; -} +}; -bool MipsCallLowering::MipsHandler::assignVRegs(ArrayRef<Register> VRegs, - ArrayRef<CCValAssign> ArgLocs, - unsigned ArgLocsStartIndex, - const EVT &VT) { - for (unsigned i = 0; i < VRegs.size(); ++i) - if (!assign(VRegs[i], ArgLocs[ArgLocsStartIndex + i], VT)) - return false; - return true; -} +struct MipsIncomingValueAssigner : public CallLowering::IncomingValueAssigner { + /// This is the name of the function being called + /// FIXME: Relying on this is unsound + const char *Func = nullptr; -void MipsCallLowering::MipsHandler::setLeastSignificantFirst( - SmallVectorImpl<Register> &VRegs) { - if (!MIRBuilder.getMF().getDataLayout().isLittleEndian()) - std::reverse(VRegs.begin(), VRegs.end()); -} + /// Is this a call return value, or an incoming function argument. + bool IsReturn; -bool MipsCallLowering::MipsHandler::handle( - ArrayRef<CCValAssign> ArgLocs, ArrayRef<CallLowering::ArgInfo> Args) { - SmallVector<Register, 4> VRegs; - unsigned SplitLength; - const Function &F = MIRBuilder.getMF().getFunction(); - const DataLayout &DL = F.getParent()->getDataLayout(); - const MipsTargetLowering &TLI = *static_cast<const MipsTargetLowering *>( - MIRBuilder.getMF().getSubtarget().getTargetLowering()); - - for (unsigned ArgsIndex = 0, ArgLocsIndex = 0; ArgsIndex < Args.size(); - ++ArgsIndex, ArgLocsIndex += SplitLength) { - EVT VT = TLI.getValueType(DL, Args[ArgsIndex].Ty); - SplitLength = TLI.getNumRegistersForCallingConv(F.getContext(), - F.getCallingConv(), VT); - assert(Args[ArgsIndex].Regs.size() == 1 && "Can't handle multple regs yet"); - - if (SplitLength > 1) { - VRegs.clear(); - MVT RegisterVT = TLI.getRegisterTypeForCallingConv( - F.getContext(), F.getCallingConv(), VT); - for (unsigned i = 0; i < SplitLength; ++i) - VRegs.push_back(MRI.createGenericVirtualRegister(LLT{RegisterVT})); - - if (!handleSplit(VRegs, ArgLocs, ArgLocsIndex, Args[ArgsIndex].Regs[0], - VT)) - return false; - } else { - if (!assign(Args[ArgsIndex].Regs[0], ArgLocs[ArgLocsIndex], VT)) - return false; - } + MipsIncomingValueAssigner(CCAssignFn *AssignFn_, const char *Func, + bool IsReturn) + : IncomingValueAssigner(AssignFn_), Func(Func), IsReturn(IsReturn) {} + + bool assignArg(unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, + const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags, + CCState &State_) override { + MipsCCState &State = static_cast<MipsCCState &>(State_); + + if (IsReturn) + State.PreAnalyzeCallResult(Info.Ty, Func); + else + State.PreAnalyzeFormalArgument(Info.Ty, Flags); + + return CallLowering::IncomingValueAssigner::assignArg( + ValNo, OrigVT, ValVT, LocVT, LocInfo, Info, Flags, State); } - return true; -} +}; namespace { -class MipsIncomingValueHandler : public MipsCallLowering::MipsHandler { +class MipsIncomingValueHandler : public CallLowering::IncomingValueHandler { + const MipsSubtarget &STI; + public: MipsIncomingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI) - : MipsHandler(MIRBuilder, MRI) {} + : IncomingValueHandler(MIRBuilder, MRI), + STI(MIRBuilder.getMF().getSubtarget<MipsSubtarget>()) {} private: - void assignValueToReg(Register ValVReg, const CCValAssign &VA, - const EVT &VT) override; - - Register getStackAddress(const CCValAssign &VA, - MachineMemOperand *&MMO) override; + void assignValueToReg(Register ValVReg, Register PhysReg, + CCValAssign &VA) override; - void assignValueToAddress(Register ValVReg, const CCValAssign &VA) override; + Register getStackAddress(uint64_t Size, int64_t Offset, + MachinePointerInfo &MPO, + ISD::ArgFlagsTy Flags) override; + void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy, + MachinePointerInfo &MPO, CCValAssign &VA) override; - bool handleSplit(SmallVectorImpl<Register> &VRegs, - ArrayRef<CCValAssign> ArgLocs, unsigned ArgLocsStartIndex, - Register ArgsReg, const EVT &VT) override; + unsigned assignCustomValue(CallLowering::ArgInfo &Arg, + ArrayRef<CCValAssign> VAs) override; virtual void markPhysRegUsed(unsigned PhysReg) { MIRBuilder.getMRI()->addLiveIn(PhysReg); MIRBuilder.getMBB().addLiveIn(PhysReg); } - - MachineInstrBuilder buildLoad(const DstOp &Res, const CCValAssign &VA) { - MachineMemOperand *MMO; - Register Addr = getStackAddress(VA, MMO); - return MIRBuilder.buildLoad(Res, Addr, *MMO); - } }; class CallReturnHandler : public MipsIncomingValueHandler { @@ -135,190 +126,154 @@ private: } // end anonymous namespace void MipsIncomingValueHandler::assignValueToReg(Register ValVReg, - const CCValAssign &VA, - const EVT &VT) { - Register PhysReg = VA.getLocReg(); - if (VT == MVT::f64 && PhysReg >= Mips::A0 && PhysReg <= Mips::A3) { - const MipsSubtarget &STI = - static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget()); - bool IsEL = STI.isLittle(); - LLT s32 = LLT::scalar(32); - auto Lo = MIRBuilder.buildCopy(s32, Register(PhysReg + (IsEL ? 0 : 1))); - auto Hi = MIRBuilder.buildCopy(s32, Register(PhysReg + (IsEL ? 1 : 0))); - MIRBuilder.buildMerge(ValVReg, {Lo, Hi}); - markPhysRegUsed(PhysReg); - markPhysRegUsed(PhysReg + 1); - } else if (VT == MVT::f32 && PhysReg >= Mips::A0 && PhysReg <= Mips::A3) { - MIRBuilder.buildCopy(ValVReg, PhysReg); - markPhysRegUsed(PhysReg); - } else { - switch (VA.getLocInfo()) { - case CCValAssign::LocInfo::SExt: - case CCValAssign::LocInfo::ZExt: - case CCValAssign::LocInfo::AExt: { - auto Copy = MIRBuilder.buildCopy(LLT{VA.getLocVT()}, PhysReg); - MIRBuilder.buildTrunc(ValVReg, Copy); - break; - } - default: - MIRBuilder.buildCopy(ValVReg, PhysReg); - break; - } - markPhysRegUsed(PhysReg); - } + Register PhysReg, + CCValAssign &VA) { + markPhysRegUsed(PhysReg); + IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA); } -Register MipsIncomingValueHandler::getStackAddress(const CCValAssign &VA, - MachineMemOperand *&MMO) { +Register MipsIncomingValueHandler::getStackAddress(uint64_t Size, + int64_t Offset, + MachinePointerInfo &MPO, + ISD::ArgFlagsTy Flags) { + MachineFunction &MF = MIRBuilder.getMF(); - unsigned Size = alignTo(VA.getValVT().getSizeInBits(), 8) / 8; - unsigned Offset = VA.getLocMemOffset(); MachineFrameInfo &MFI = MF.getFrameInfo(); + // FIXME: This should only be immutable for non-byval memory arguments. int FI = MFI.CreateFixedObject(Size, Offset, true); - MachinePointerInfo MPO = - MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI); - - const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering(); - Align Alignment = commonAlignment(TFL->getStackAlign(), Offset); - MMO = - MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, Size, Alignment); + MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI); return MIRBuilder.buildFrameIndex(LLT::pointer(0, 32), FI).getReg(0); } void MipsIncomingValueHandler::assignValueToAddress(Register ValVReg, - const CCValAssign &VA) { - if (VA.getLocInfo() == CCValAssign::SExt || - VA.getLocInfo() == CCValAssign::ZExt || - VA.getLocInfo() == CCValAssign::AExt) { - auto Load = buildLoad(LLT::scalar(32), VA); - MIRBuilder.buildTrunc(ValVReg, Load); - } else - buildLoad(ValVReg, VA); + Register Addr, LLT MemTy, + MachinePointerInfo &MPO, + CCValAssign &VA) { + MachineFunction &MF = MIRBuilder.getMF(); + auto MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy, + inferAlignFromPtrInfo(MF, MPO)); + MIRBuilder.buildLoad(ValVReg, Addr, *MMO); } -bool MipsIncomingValueHandler::handleSplit(SmallVectorImpl<Register> &VRegs, - ArrayRef<CCValAssign> ArgLocs, - unsigned ArgLocsStartIndex, - Register ArgsReg, const EVT &VT) { - if (!assignVRegs(VRegs, ArgLocs, ArgLocsStartIndex, VT)) - return false; - setLeastSignificantFirst(VRegs); - MIRBuilder.buildMerge(ArgsReg, VRegs); - return true; +/// Handle cases when f64 is split into 2 32-bit GPRs. This is a custom +/// assignment because generic code assumes getNumRegistersForCallingConv is +/// accurate. In this case it is not because the type/number are context +/// dependent on other arguments. +unsigned +MipsIncomingValueHandler::assignCustomValue(CallLowering::ArgInfo &Arg, + ArrayRef<CCValAssign> VAs) { + const CCValAssign &VALo = VAs[0]; + const CCValAssign &VAHi = VAs[1]; + + assert(VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 && + VALo.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64 && + "unexpected custom value"); + + auto CopyLo = MIRBuilder.buildCopy(LLT::scalar(32), VALo.getLocReg()); + auto CopyHi = MIRBuilder.buildCopy(LLT::scalar(32), VAHi.getLocReg()); + if (!STI.isLittle()) + std::swap(CopyLo, CopyHi); + + Arg.OrigRegs.assign(Arg.Regs.begin(), Arg.Regs.end()); + Arg.Regs = { CopyLo.getReg(0), CopyHi.getReg(0) }; + MIRBuilder.buildMerge(Arg.OrigRegs[0], {CopyLo, CopyHi}); + + markPhysRegUsed(VALo.getLocReg()); + markPhysRegUsed(VAHi.getLocReg()); + return 2; } namespace { -class MipsOutgoingValueHandler : public MipsCallLowering::MipsHandler { +class MipsOutgoingValueHandler : public CallLowering::OutgoingValueHandler { + const MipsSubtarget &STI; + public: MipsOutgoingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, MachineInstrBuilder &MIB) - : MipsHandler(MIRBuilder, MRI), MIB(MIB) {} + : OutgoingValueHandler(MIRBuilder, MRI), + STI(MIRBuilder.getMF().getSubtarget<MipsSubtarget>()), MIB(MIB) {} private: - void assignValueToReg(Register ValVReg, const CCValAssign &VA, - const EVT &VT) override; + void assignValueToReg(Register ValVReg, Register PhysReg, + CCValAssign &VA) override; - Register getStackAddress(const CCValAssign &VA, - MachineMemOperand *&MMO) override; + Register getStackAddress(uint64_t Size, int64_t Offset, + MachinePointerInfo &MPO, + ISD::ArgFlagsTy Flags) override; - void assignValueToAddress(Register ValVReg, const CCValAssign &VA) override; - - bool handleSplit(SmallVectorImpl<Register> &VRegs, - ArrayRef<CCValAssign> ArgLocs, unsigned ArgLocsStartIndex, - Register ArgsReg, const EVT &VT) override; - - Register extendRegister(Register ValReg, const CCValAssign &VA); + void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy, + MachinePointerInfo &MPO, CCValAssign &VA) override; + unsigned assignCustomValue(CallLowering::ArgInfo &Arg, + ArrayRef<CCValAssign> VAs) override; MachineInstrBuilder &MIB; }; } // end anonymous namespace void MipsOutgoingValueHandler::assignValueToReg(Register ValVReg, - const CCValAssign &VA, - const EVT &VT) { - Register PhysReg = VA.getLocReg(); - if (VT == MVT::f64 && PhysReg >= Mips::A0 && PhysReg <= Mips::A3) { - const MipsSubtarget &STI = - static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget()); - bool IsEL = STI.isLittle(); - auto Unmerge = MIRBuilder.buildUnmerge(LLT::scalar(32), ValVReg); - MIRBuilder.buildCopy(Register(PhysReg + (IsEL ? 0 : 1)), Unmerge.getReg(0)); - MIRBuilder.buildCopy(Register(PhysReg + (IsEL ? 1 : 0)), Unmerge.getReg(1)); - } else if (VT == MVT::f32 && PhysReg >= Mips::A0 && PhysReg <= Mips::A3) { - MIRBuilder.buildCopy(PhysReg, ValVReg); - } else { - Register ExtReg = extendRegister(ValVReg, VA); - MIRBuilder.buildCopy(PhysReg, ExtReg); - MIB.addUse(PhysReg, RegState::Implicit); - } + Register PhysReg, + CCValAssign &VA) { + Register ExtReg = extendRegister(ValVReg, VA); + MIRBuilder.buildCopy(PhysReg, ExtReg); + MIB.addUse(PhysReg, RegState::Implicit); } -Register MipsOutgoingValueHandler::getStackAddress(const CCValAssign &VA, - MachineMemOperand *&MMO) { +Register MipsOutgoingValueHandler::getStackAddress(uint64_t Size, + int64_t Offset, + MachinePointerInfo &MPO, + ISD::ArgFlagsTy Flags) { MachineFunction &MF = MIRBuilder.getMF(); - const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering(); + MPO = MachinePointerInfo::getStack(MF, Offset); LLT p0 = LLT::pointer(0, 32); LLT s32 = LLT::scalar(32); auto SPReg = MIRBuilder.buildCopy(p0, Register(Mips::SP)); - unsigned Offset = VA.getLocMemOffset(); auto OffsetReg = MIRBuilder.buildConstant(s32, Offset); - auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg); - - MachinePointerInfo MPO = - MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset); - unsigned Size = alignTo(VA.getValVT().getSizeInBits(), 8) / 8; - Align Alignment = commonAlignment(TFL->getStackAlign(), Offset); - MMO = - MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore, Size, Alignment); - return AddrReg.getReg(0); } void MipsOutgoingValueHandler::assignValueToAddress(Register ValVReg, - const CCValAssign &VA) { - MachineMemOperand *MMO; - Register Addr = getStackAddress(VA, MMO); + Register Addr, LLT MemTy, + MachinePointerInfo &MPO, + CCValAssign &VA) { + MachineFunction &MF = MIRBuilder.getMF(); + uint64_t LocMemOffset = VA.getLocMemOffset(); + + auto MMO = MF.getMachineMemOperand( + MPO, MachineMemOperand::MOStore, MemTy, + commonAlignment(STI.getStackAlignment(), LocMemOffset)); + Register ExtReg = extendRegister(ValVReg, VA); MIRBuilder.buildStore(ExtReg, Addr, *MMO); } -Register MipsOutgoingValueHandler::extendRegister(Register ValReg, - const CCValAssign &VA) { - LLT LocTy{VA.getLocVT()}; - switch (VA.getLocInfo()) { - case CCValAssign::SExt: { - return MIRBuilder.buildSExt(LocTy, ValReg).getReg(0); - } - case CCValAssign::ZExt: { - return MIRBuilder.buildZExt(LocTy, ValReg).getReg(0); - } - case CCValAssign::AExt: { - return MIRBuilder.buildAnyExt(LocTy, ValReg).getReg(0); - } - // TODO : handle upper extends - case CCValAssign::Full: - return ValReg; - default: - break; - } - llvm_unreachable("unable to extend register"); -} - -bool MipsOutgoingValueHandler::handleSplit(SmallVectorImpl<Register> &VRegs, - ArrayRef<CCValAssign> ArgLocs, - unsigned ArgLocsStartIndex, - Register ArgsReg, const EVT &VT) { - MIRBuilder.buildUnmerge(VRegs, ArgsReg); - setLeastSignificantFirst(VRegs); - if (!assignVRegs(VRegs, ArgLocs, ArgLocsStartIndex, VT)) - return false; - - return true; +unsigned +MipsOutgoingValueHandler::assignCustomValue(CallLowering::ArgInfo &Arg, + ArrayRef<CCValAssign> VAs) { + const CCValAssign &VALo = VAs[0]; + const CCValAssign &VAHi = VAs[1]; + + assert(VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 && + VALo.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64 && + "unexpected custom value"); + + auto Unmerge = + MIRBuilder.buildUnmerge({LLT::scalar(32), LLT::scalar(32)}, Arg.Regs[0]); + Register Lo = Unmerge.getReg(0); + Register Hi = Unmerge.getReg(1); + + Arg.OrigRegs.assign(Arg.Regs.begin(), Arg.Regs.end()); + Arg.Regs = { Lo, Hi }; + if (!STI.isLittle()) + std::swap(Lo, Hi); + + MIRBuilder.buildCopy(VALo.getLocReg(), Lo); + MIRBuilder.buildCopy(VAHi.getLocReg(), Hi); + return 2; } static bool isSupportedArgumentType(Type *T) { @@ -343,36 +298,6 @@ static bool isSupportedReturnType(Type *T) { return false; } -static CCValAssign::LocInfo determineLocInfo(const MVT RegisterVT, const EVT VT, - const ISD::ArgFlagsTy &Flags) { - // > does not mean loss of information as type RegisterVT can't hold type VT, - // it means that type VT is split into multiple registers of type RegisterVT - if (VT.getFixedSizeInBits() >= RegisterVT.getFixedSizeInBits()) - return CCValAssign::LocInfo::Full; - if (Flags.isSExt()) - return CCValAssign::LocInfo::SExt; - if (Flags.isZExt()) - return CCValAssign::LocInfo::ZExt; - return CCValAssign::LocInfo::AExt; -} - -template <typename T> -static void setLocInfo(SmallVectorImpl<CCValAssign> &ArgLocs, - const SmallVectorImpl<T> &Arguments) { - for (unsigned i = 0; i < ArgLocs.size(); ++i) { - const CCValAssign &VA = ArgLocs[i]; - CCValAssign::LocInfo LocInfo = determineLocInfo( - Arguments[i].VT, Arguments[i].ArgVT, Arguments[i].Flags); - if (VA.isMemLoc()) - ArgLocs[i] = - CCValAssign::getMem(VA.getValNo(), VA.getValVT(), - VA.getLocMemOffset(), VA.getLocVT(), LocInfo); - else - ArgLocs[i] = CCValAssign::getReg(VA.getValNo(), VA.getValVT(), - VA.getLocReg(), VA.getLocVT(), LocInfo); - } -} - bool MipsCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, ArrayRef<Register> VRegs, FunctionLoweringInfo &FLI) const { @@ -389,26 +314,29 @@ bool MipsCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>(); SmallVector<ArgInfo, 8> RetInfos; - SmallVector<unsigned, 8> OrigArgIndices; - ArgInfo ArgRetInfo(VRegs, Val->getType()); + ArgInfo ArgRetInfo(VRegs, *Val, 0); setArgFlags(ArgRetInfo, AttributeList::ReturnIndex, DL, F); - splitToValueTypes(DL, ArgRetInfo, 0, RetInfos, OrigArgIndices); + splitToValueTypes(ArgRetInfo, RetInfos, DL, F.getCallingConv()); + SmallVector<CCValAssign, 16> ArgLocs; SmallVector<ISD::OutputArg, 8> Outs; - subTargetRegTypeForCallingConv(F, RetInfos, OrigArgIndices, Outs); - SmallVector<CCValAssign, 16> ArgLocs; MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext()); - CCInfo.AnalyzeReturn(Outs, TLI.CCAssignFnForReturn()); - setLocInfo(ArgLocs, Outs); MipsOutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret); - if (!RetHandler.handle(ArgLocs, RetInfos)) { + std::string FuncName = F.getName().str(); + MipsOutgoingValueAssigner Assigner(TLI.CCAssignFnForReturn(), + FuncName.c_str(), /*IsReturn*/ true); + + if (!determineAssignments(Assigner, RetInfos, CCInfo)) + return false; + + if (!handleAssignments(RetHandler, RetInfos, CCInfo, ArgLocs, MIRBuilder)) return false; - } } + MIRBuilder.insertInstr(Ret); return true; } @@ -432,18 +360,16 @@ bool MipsCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>(); SmallVector<ArgInfo, 8> ArgInfos; - SmallVector<unsigned, 8> OrigArgIndices; unsigned i = 0; for (auto &Arg : F.args()) { - ArgInfo AInfo(VRegs[i], Arg.getType()); + ArgInfo AInfo(VRegs[i], Arg, i); setArgFlags(AInfo, i + AttributeList::FirstArgIndex, DL, F); - ArgInfos.push_back(AInfo); - OrigArgIndices.push_back(i); + + splitToValueTypes(AInfo, ArgInfos, DL, F.getCallingConv()); ++i; } SmallVector<ISD::InputArg, 8> Ins; - subTargetRegTypeForCallingConv(F, ArgInfos, OrigArgIndices, Ins); SmallVector<CCValAssign, 16> ArgLocs; MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, @@ -454,11 +380,15 @@ bool MipsCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, const MipsABIInfo &ABI = TM.getABI(); CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(F.getCallingConv()), Align(1)); - CCInfo.AnalyzeFormalArguments(Ins, TLI.CCAssignFnForCall()); - setLocInfo(ArgLocs, Ins); + + const std::string FuncName = F.getName().str(); + MipsIncomingValueAssigner Assigner(TLI.CCAssignFnForCall(), FuncName.c_str(), + /*IsReturn*/ false); + if (!determineAssignments(Assigner, ArgInfos, CCInfo)) + return false; MipsIncomingValueHandler Handler(MIRBuilder, MF.getRegInfo()); - if (!Handler.handle(ArgLocs, ArgInfos)) + if (!handleAssignments(Handler, ArgInfos, CCInfo, ArgLocs, MIRBuilder)) return false; if (F.isVarArg()) { @@ -481,15 +411,16 @@ bool MipsCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, for (unsigned I = Idx; I < ArgRegs.size(); ++I, VaArgOffset += RegSize) { MIRBuilder.getMBB().addLiveIn(ArgRegs[I]); - + LLT RegTy = LLT::scalar(RegSize * 8); MachineInstrBuilder Copy = - MIRBuilder.buildCopy(LLT::scalar(RegSize * 8), Register(ArgRegs[I])); + MIRBuilder.buildCopy(RegTy, Register(ArgRegs[I])); FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true); MachinePointerInfo MPO = MachinePointerInfo::getFixedStack(MF, FI); - MachineInstrBuilder FrameIndex = - MIRBuilder.buildFrameIndex(LLT::pointer(MPO.getAddrSpace(), 32), FI); + + const LLT PtrTy = LLT::pointer(MPO.getAddrSpace(), 32); + auto FrameIndex = MIRBuilder.buildFrameIndex(PtrTy, FI); MachineMemOperand *MMO = MF.getMachineMemOperand( - MPO, MachineMemOperand::MOStore, RegSize, Align(RegSize)); + MPO, MachineMemOperand::MOStore, RegTy, Align(RegSize)); MIRBuilder.buildStore(Copy, FrameIndex, *MMO); } } @@ -543,27 +474,14 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, } else MIB.add(Info.Callee); const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); - MIB.addRegMask(TRI->getCallPreservedMask(MF, F.getCallingConv())); + MIB.addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv)); TargetLowering::ArgListTy FuncOrigArgs; FuncOrigArgs.reserve(Info.OrigArgs.size()); SmallVector<ArgInfo, 8> ArgInfos; - SmallVector<unsigned, 8> OrigArgIndices; - unsigned i = 0; - for (auto &Arg : Info.OrigArgs) { - - TargetLowering::ArgListEntry Entry; - Entry.Ty = Arg.Ty; - FuncOrigArgs.push_back(Entry); - - ArgInfos.push_back(Arg); - OrigArgIndices.push_back(i); - ++i; - } - - SmallVector<ISD::OutputArg, 8> Outs; - subTargetRegTypeForCallingConv(F, ArgInfos, OrigArgIndices, Outs); + for (auto &Arg : Info.OrigArgs) + splitToValueTypes(Arg, ArgInfos, DL, Info.CallConv); SmallVector<CCValAssign, 8> ArgLocs; bool IsCalleeVarArg = false; @@ -571,24 +489,33 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, const Function *CF = static_cast<const Function *>(Info.Callee.getGlobal()); IsCalleeVarArg = CF->isVarArg(); } - MipsCCState CCInfo(F.getCallingConv(), IsCalleeVarArg, MF, ArgLocs, + + // FIXME: Should use MipsCCState::getSpecialCallingConvForCallee, but it + // depends on looking directly at the call target. + MipsCCState CCInfo(Info.CallConv, IsCalleeVarArg, MF, ArgLocs, F.getContext()); CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(Info.CallConv), Align(1)); + const char *Call = Info.Callee.isSymbol() ? Info.Callee.getSymbolName() : nullptr; - CCInfo.AnalyzeCallOperands(Outs, TLI.CCAssignFnForCall(), FuncOrigArgs, Call); - setLocInfo(ArgLocs, Outs); - MipsOutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), MIB); - if (!RetHandler.handle(ArgLocs, ArgInfos)) { + MipsOutgoingValueAssigner Assigner(TLI.CCAssignFnForCall(), Call, + /*IsReturn*/ false); + if (!determineAssignments(Assigner, ArgInfos, CCInfo)) + return false; + + MipsOutgoingValueHandler ArgHandler(MIRBuilder, MF.getRegInfo(), MIB); + if (!handleAssignments(ArgHandler, ArgInfos, CCInfo, ArgLocs, MIRBuilder)) return false; - } unsigned NextStackOffset = CCInfo.getNextStackOffset(); - const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering(); - unsigned StackAlignment = TFL->getStackAlignment(); + unsigned StackAlignment = F.getParent()->getOverrideStackAlignment(); + if (!StackAlignment) { + const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering(); + StackAlignment = TFL->getStackAlignment(); + } NextStackOffset = alignTo(NextStackOffset, StackAlignment); CallSeqStart.addImm(NextStackOffset).addImm(0); @@ -608,23 +535,25 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, if (!Info.OrigRet.Ty->isVoidTy()) { ArgInfos.clear(); - SmallVector<unsigned, 8> OrigRetIndices; - splitToValueTypes(DL, Info.OrigRet, 0, ArgInfos, OrigRetIndices); + CallLowering::splitToValueTypes(Info.OrigRet, ArgInfos, DL, + F.getCallingConv()); + const std::string FuncName = F.getName().str(); SmallVector<ISD::InputArg, 8> Ins; - subTargetRegTypeForCallingConv(F, ArgInfos, OrigRetIndices, Ins); - SmallVector<CCValAssign, 8> ArgLocs; + MipsIncomingValueAssigner Assigner(TLI.CCAssignFnForReturn(), + FuncName.c_str(), + /*IsReturn*/ true); + CallReturnHandler RetHandler(MIRBuilder, MF.getRegInfo(), MIB); + MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext()); - CCInfo.AnalyzeCallResult(Ins, TLI.CCAssignFnForReturn(), Info.OrigRet.Ty, - Call); - setLocInfo(ArgLocs, Ins); + if (!determineAssignments(Assigner, ArgInfos, CCInfo)) + return false; - CallReturnHandler Handler(MIRBuilder, MF.getRegInfo(), MIB); - if (!Handler.handle(ArgLocs, ArgInfos)) + if (!handleAssignments(RetHandler, ArgInfos, CCInfo, ArgLocs, MIRBuilder)) return false; } @@ -632,54 +561,3 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, return true; } - -template <typename T> -void MipsCallLowering::subTargetRegTypeForCallingConv( - const Function &F, ArrayRef<ArgInfo> Args, - ArrayRef<unsigned> OrigArgIndices, SmallVectorImpl<T> &ISDArgs) const { - const DataLayout &DL = F.getParent()->getDataLayout(); - const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>(); - - unsigned ArgNo = 0; - for (auto &Arg : Args) { - - EVT VT = TLI.getValueType(DL, Arg.Ty); - MVT RegisterVT = TLI.getRegisterTypeForCallingConv(F.getContext(), - F.getCallingConv(), VT); - unsigned NumRegs = TLI.getNumRegistersForCallingConv( - F.getContext(), F.getCallingConv(), VT); - - for (unsigned i = 0; i < NumRegs; ++i) { - ISD::ArgFlagsTy Flags = Arg.Flags[0]; - - if (i == 0) - Flags.setOrigAlign(TLI.getABIAlignmentForCallingConv(Arg.Ty, DL)); - else - Flags.setOrigAlign(Align(1)); - - ISDArgs.emplace_back(Flags, RegisterVT, VT, true, OrigArgIndices[ArgNo], - 0); - } - ++ArgNo; - } -} - -void MipsCallLowering::splitToValueTypes( - const DataLayout &DL, const ArgInfo &OrigArg, unsigned OriginalIndex, - SmallVectorImpl<ArgInfo> &SplitArgs, - SmallVectorImpl<unsigned> &SplitArgsOrigIndices) const { - - SmallVector<EVT, 4> SplitEVTs; - SmallVector<Register, 4> SplitVRegs; - const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>(); - LLVMContext &Ctx = OrigArg.Ty->getContext(); - - ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitEVTs); - - for (unsigned i = 0; i < SplitEVTs.size(); ++i) { - ArgInfo Info = ArgInfo{OrigArg.Regs[i], SplitEVTs[i].getTypeForEVT(Ctx)}; - Info.Flags = OrigArg.Flags; - SplitArgs.push_back(Info); - SplitArgsOrigIndices.push_back(OriginalIndex); - } -} diff --git a/llvm/lib/Target/Mips/MipsCallLowering.h b/llvm/lib/Target/Mips/MipsCallLowering.h index 1c1c2080a76a..1d1406da3201 100644 --- a/llvm/lib/Target/Mips/MipsCallLowering.h +++ b/llvm/lib/Target/Mips/MipsCallLowering.h @@ -22,45 +22,7 @@ class MachineMemOperand; class MipsTargetLowering; class MipsCallLowering : public CallLowering { - public: - class MipsHandler { - public: - MipsHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI) - : MIRBuilder(MIRBuilder), MRI(MRI) {} - - virtual ~MipsHandler() = default; - - bool handle(ArrayRef<CCValAssign> ArgLocs, - ArrayRef<CallLowering::ArgInfo> Args); - - protected: - bool assignVRegs(ArrayRef<Register> VRegs, ArrayRef<CCValAssign> ArgLocs, - unsigned ArgLocsStartIndex, const EVT &VT); - - void setLeastSignificantFirst(SmallVectorImpl<Register> &VRegs); - - MachineIRBuilder &MIRBuilder; - MachineRegisterInfo &MRI; - - private: - bool assign(Register VReg, const CCValAssign &VA, const EVT &VT); - - virtual Register getStackAddress(const CCValAssign &VA, - MachineMemOperand *&MMO) = 0; - - virtual void assignValueToReg(Register ValVReg, const CCValAssign &VA, - const EVT &VT) = 0; - - virtual void assignValueToAddress(Register ValVReg, - const CCValAssign &VA) = 0; - - virtual bool handleSplit(SmallVectorImpl<Register> &VRegs, - ArrayRef<CCValAssign> ArgLocs, - unsigned ArgLocsStartIndex, Register ArgsReg, - const EVT &VT) = 0; - }; - MipsCallLowering(const MipsTargetLowering &TLI); bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, @@ -73,22 +35,6 @@ public: bool lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info) const override; - -private: - /// Based on registers available on target machine split or extend - /// type if needed, also change pointer type to appropriate integer - /// type. - template <typename T> - void subTargetRegTypeForCallingConv(const Function &F, ArrayRef<ArgInfo> Args, - ArrayRef<unsigned> OrigArgIndices, - SmallVectorImpl<T> &ISDArgs) const; - - /// Split structures and arrays, save original argument indices since - /// Mips calling convention needs info about original argument type. - void splitToValueTypes(const DataLayout &DL, const ArgInfo &OrigArg, - unsigned OriginalIndex, - SmallVectorImpl<ArgInfo> &SplitArgs, - SmallVectorImpl<unsigned> &SplitArgsOrigIndices) const; }; } // end namespace llvm diff --git a/llvm/lib/Target/Mips/MipsFastISel.cpp b/llvm/lib/Target/Mips/MipsFastISel.cpp index 8a847eaf6618..e963185eaeaa 100644 --- a/llvm/lib/Target/Mips/MipsFastISel.cpp +++ b/llvm/lib/Target/Mips/MipsFastISel.cpp @@ -228,14 +228,13 @@ private: unsigned fastEmitInst_rr(unsigned MachineInstOpcode, const TargetRegisterClass *RC, - unsigned Op0, bool Op0IsKill, - unsigned Op1, bool Op1IsKill); + unsigned Op0, unsigned Op1); // for some reason, this default is not generated by tablegen // so we explicitly generate it here. unsigned fastEmitInst_riir(uint64_t inst, const TargetRegisterClass *RC, - unsigned Op0, bool Op0IsKill, uint64_t imm1, - uint64_t imm2, unsigned Op3, bool Op3IsKill) { + unsigned Op0, uint64_t imm1, uint64_t imm2, + unsigned Op3) { return 0; } @@ -2122,8 +2121,7 @@ void MipsFastISel::simplifyAddress(Address &Addr) { unsigned MipsFastISel::fastEmitInst_rr(unsigned MachineInstOpcode, const TargetRegisterClass *RC, - unsigned Op0, bool Op0IsKill, - unsigned Op1, bool Op1IsKill) { + unsigned Op0, unsigned Op1) { // We treat the MUL instruction in a special way because it clobbers // the HI0 & LO0 registers. The TableGen definition of this instruction can // mark these registers only as implicitly defined. As a result, the @@ -2136,15 +2134,14 @@ unsigned MipsFastISel::fastEmitInst_rr(unsigned MachineInstOpcode, Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs()); Op1 = constrainOperandRegClass(II, Op1, II.getNumDefs() + 1); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, ResultReg) - .addReg(Op0, getKillRegState(Op0IsKill)) - .addReg(Op1, getKillRegState(Op1IsKill)) + .addReg(Op0) + .addReg(Op1) .addReg(Mips::HI0, RegState::ImplicitDefine | RegState::Dead) .addReg(Mips::LO0, RegState::ImplicitDefine | RegState::Dead); return ResultReg; } - return FastISel::fastEmitInst_rr(MachineInstOpcode, RC, Op0, Op0IsKill, Op1, - Op1IsKill); + return FastISel::fastEmitInst_rr(MachineInstOpcode, RC, Op0, Op1); } namespace llvm { diff --git a/llvm/lib/Target/Mips/MipsFrameLowering.cpp b/llvm/lib/Target/Mips/MipsFrameLowering.cpp index 8d5eabf59b71..99d225f9abfe 100644 --- a/llvm/lib/Target/Mips/MipsFrameLowering.cpp +++ b/llvm/lib/Target/Mips/MipsFrameLowering.cpp @@ -95,15 +95,15 @@ bool MipsFrameLowering::hasFP(const MachineFunction &MF) const { const TargetRegisterInfo *TRI = STI.getRegisterInfo(); return MF.getTarget().Options.DisableFramePointerElim(MF) || - MFI.hasVarSizedObjects() || MFI.isFrameAddressTaken() || - TRI->needsStackRealignment(MF); + MFI.hasVarSizedObjects() || MFI.isFrameAddressTaken() || + TRI->hasStackRealignment(MF); } bool MipsFrameLowering::hasBP(const MachineFunction &MF) const { const MachineFrameInfo &MFI = MF.getFrameInfo(); const TargetRegisterInfo *TRI = STI.getRegisterInfo(); - return MFI.hasVarSizedObjects() && TRI->needsStackRealignment(MF); + return MFI.hasVarSizedObjects() && TRI->hasStackRealignment(MF); } // Estimate the size of the stack, including the incoming arguments. We need to diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp index 8b599bca3915..9399c949a3f2 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -122,9 +122,7 @@ unsigned MipsTargetLowering::getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const { if (VT.isVector()) - return std::max(((unsigned)VT.getSizeInBits() / - (Subtarget.isABI_O32() ? 32 : 64)), - 1U); + return divideCeil(VT.getSizeInBits(), Subtarget.isABI_O32() ? 32 : 64); return MipsTargetLowering::getNumRegisters(Context, VT); } @@ -134,10 +132,10 @@ unsigned MipsTargetLowering::getVectorTypeBreakdownForCallingConv( // Break down vector types to either 2 i64s or 4 i32s. RegisterVT = getRegisterTypeForCallingConv(Context, CC, VT); IntermediateVT = RegisterVT; - NumIntermediates = VT.getFixedSizeInBits() < RegisterVT.getFixedSizeInBits() - ? VT.getVectorNumElements() - : VT.getSizeInBits() / RegisterVT.getSizeInBits(); - + NumIntermediates = + VT.getFixedSizeInBits() < RegisterVT.getFixedSizeInBits() + ? VT.getVectorNumElements() + : divideCeil(VT.getSizeInBits(), RegisterVT.getSizeInBits()); return NumIntermediates; } @@ -2928,13 +2926,23 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT, Reg = State.AllocateReg(IntRegs); LocVT = MVT::i32; } else if (ValVT == MVT::f64 && AllocateFloatsInIntReg) { + LocVT = MVT::i32; + // Allocate int register and shadow next int register. If first // available register is Mips::A1 or Mips::A3, shadow it too. Reg = State.AllocateReg(IntRegs); if (Reg == Mips::A1 || Reg == Mips::A3) Reg = State.AllocateReg(IntRegs); - State.AllocateReg(IntRegs); - LocVT = MVT::i32; + + if (Reg) { + State.addLoc( + CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); + MCRegister HiReg = State.AllocateReg(IntRegs); + assert(HiReg); + State.addLoc( + CCValAssign::getCustomReg(ValNo, ValVT, HiReg, LocVT, LocInfo)); + return false; + } } else if (ValVT.isFloatingPoint() && !AllocateFloatsInIntReg) { // we are guaranteed to find an available float register if (ValVT == MVT::f32) { @@ -2994,12 +3002,6 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT, // Call Calling Convention Implementation //===----------------------------------------------------------------------===// -// Return next O32 integer argument register. -static unsigned getNextIntArgReg(unsigned Reg) { - assert((Reg == Mips::A0) || (Reg == Mips::A2)); - return (Reg == Mips::A0) ? Mips::A1 : Mips::A3; -} - SDValue MipsTargetLowering::passArgOnStack(SDValue StackPtr, unsigned Offset, SDValue Chain, SDValue Arg, const SDLoc &DL, bool IsTailCall, @@ -3251,11 +3253,11 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, CCInfo.rewindByValRegsInfo(); // Walk the register/memloc assignments, inserting copies/loads. - for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { - SDValue Arg = OutVals[i]; + for (unsigned i = 0, e = ArgLocs.size(), OutIdx = 0; i != e; ++i, ++OutIdx) { + SDValue Arg = OutVals[OutIdx]; CCValAssign &VA = ArgLocs[i]; MVT ValVT = VA.getValVT(), LocVT = VA.getLocVT(); - ISD::ArgFlagsTy Flags = Outs[i].Flags; + ISD::ArgFlagsTy Flags = Outs[OutIdx].Flags; bool UseUpperBits = false; // ByVal Arg. @@ -3293,8 +3295,11 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, Arg, DAG.getConstant(1, DL, MVT::i32)); if (!Subtarget.isLittle()) std::swap(Lo, Hi); + + assert(VA.needsCustom()); + Register LocRegLo = VA.getLocReg(); - unsigned LocRegHigh = getNextIntArgReg(LocRegLo); + Register LocRegHigh = ArgLocs[++i].getLocReg(); RegsToPass.push_back(std::make_pair(LocRegLo, Lo)); RegsToPass.push_back(std::make_pair(LocRegHigh, Hi)); continue; @@ -3325,7 +3330,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, } if (UseUpperBits) { - unsigned ValSizeInBits = Outs[i].ArgVT.getSizeInBits(); + unsigned ValSizeInBits = Outs[OutIdx].ArgVT.getSizeInBits(); unsigned LocSizeInBits = VA.getLocVT().getSizeInBits(); Arg = DAG.getNode( ISD::SHL, DL, VA.getLocVT(), Arg, @@ -3636,18 +3641,18 @@ SDValue MipsTargetLowering::LowerFormalArguments( unsigned CurArgIdx = 0; CCInfo.rewindByValRegsInfo(); - for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { + for (unsigned i = 0, e = ArgLocs.size(), InsIdx = 0; i != e; ++i, ++InsIdx) { CCValAssign &VA = ArgLocs[i]; - if (Ins[i].isOrigArg()) { - std::advance(FuncArg, Ins[i].getOrigArgIndex() - CurArgIdx); - CurArgIdx = Ins[i].getOrigArgIndex(); + if (Ins[InsIdx].isOrigArg()) { + std::advance(FuncArg, Ins[InsIdx].getOrigArgIndex() - CurArgIdx); + CurArgIdx = Ins[InsIdx].getOrigArgIndex(); } EVT ValVT = VA.getValVT(); - ISD::ArgFlagsTy Flags = Ins[i].Flags; + ISD::ArgFlagsTy Flags = Ins[InsIdx].Flags; bool IsRegLoc = VA.isRegLoc(); if (Flags.isByVal()) { - assert(Ins[i].isOrigArg() && "Byval arguments cannot be implicit"); + assert(Ins[InsIdx].isOrigArg() && "Byval arguments cannot be implicit"); unsigned FirstByValReg, LastByValReg; unsigned ByValIdx = CCInfo.getInRegsParamsProcessed(); CCInfo.getInRegsParamInfo(ByValIdx, FirstByValReg, LastByValReg); @@ -3672,7 +3677,8 @@ SDValue MipsTargetLowering::LowerFormalArguments( unsigned Reg = addLiveIn(DAG.getMachineFunction(), ArgReg, RC); SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, RegVT); - ArgValue = UnpackFromArgumentSlot(ArgValue, VA, Ins[i].ArgVT, DL, DAG); + ArgValue = + UnpackFromArgumentSlot(ArgValue, VA, Ins[InsIdx].ArgVT, DL, DAG); // Handle floating point arguments passed in integer registers and // long double arguments passed in floating point registers. @@ -3682,8 +3688,10 @@ SDValue MipsTargetLowering::LowerFormalArguments( ArgValue = DAG.getNode(ISD::BITCAST, DL, ValVT, ArgValue); else if (ABI.IsO32() && RegVT == MVT::i32 && ValVT == MVT::f64) { - unsigned Reg2 = addLiveIn(DAG.getMachineFunction(), - getNextIntArgReg(ArgReg), RC); + assert(VA.needsCustom() && "Expected custom argument for f64 split"); + CCValAssign &NextVA = ArgLocs[++i]; + unsigned Reg2 = + addLiveIn(DAG.getMachineFunction(), NextVA.getLocReg(), RC); SDValue ArgValue2 = DAG.getCopyFromReg(Chain, DL, Reg2, RegVT); if (!Subtarget.isLittle()) std::swap(ArgValue, ArgValue2); @@ -3695,6 +3703,8 @@ SDValue MipsTargetLowering::LowerFormalArguments( } else { // VA.isRegLoc() MVT LocVT = VA.getLocVT(); + assert(!VA.needsCustom() && "unexpected custom memory argument"); + if (ABI.IsO32()) { // We ought to be able to use LocVT directly but O32 sets it to i32 // when allocating floating point values to integer registers. @@ -3718,17 +3728,24 @@ SDValue MipsTargetLowering::LowerFormalArguments( MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI)); OutChains.push_back(ArgValue.getValue(1)); - ArgValue = UnpackFromArgumentSlot(ArgValue, VA, Ins[i].ArgVT, DL, DAG); + ArgValue = + UnpackFromArgumentSlot(ArgValue, VA, Ins[InsIdx].ArgVT, DL, DAG); InVals.push_back(ArgValue); } } - for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { + for (unsigned i = 0, e = ArgLocs.size(), InsIdx = 0; i != e; ++i, ++InsIdx) { + + if (ArgLocs[i].needsCustom()) { + ++i; + continue; + } + // The mips ABIs for returning structs by value requires that we copy // the sret argument into $v0 for the return. Save the argument into // a virtual register so that we can access it from the return points. - if (Ins[i].Flags.isSRet()) { + if (Ins[InsIdx].Flags.isSRet()) { unsigned Reg = MipsFI->getSRetReturnReg(); if (!Reg) { Reg = MF.getRegInfo().createVirtualRegister( diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h index 3820c42ba8aa..3905a18895de 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.h +++ b/llvm/lib/Target/Mips/MipsISelLowering.h @@ -303,7 +303,7 @@ class TargetRegisterClass; /// Return the correct alignment for the current calling convention. Align getABIAlignmentForCallingConv(Type *ArgTy, - DataLayout DL) const override { + const DataLayout &DL) const override { const Align ABIAlign = DL.getABITypeAlign(ArgTy); if (ArgTy->isVectorTy()) return std::min(ABIAlign, Align(8)); diff --git a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp index 2692c08b93de..588b7e85c94c 100644 --- a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp +++ b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp @@ -37,7 +37,7 @@ static bool isUnalignedMemmoryAccess(uint64_t MemSize, uint64_t AlignInBits) { static bool CheckTy0Ty1MemSizeAlign(const LegalityQuery &Query, std::initializer_list<TypesAndMemOps> SupportedValues) { - unsigned QueryMemSize = Query.MMODescrs[0].SizeInBits; + unsigned QueryMemSize = Query.MMODescrs[0].MemoryTy.getSizeInBits(); // Non power of two memory access is never legal. if (!isPowerOf2_64(QueryMemSize)) @@ -60,22 +60,21 @@ CheckTy0Ty1MemSizeAlign(const LegalityQuery &Query, static bool CheckTyN(unsigned N, const LegalityQuery &Query, std::initializer_list<LLT> SupportedValues) { - for (auto &Val : SupportedValues) - if (Val == Query.Types[N]) - return true; - return false; + return llvm::is_contained(SupportedValues, Query.Types[N]); } MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) { using namespace TargetOpcode; const LLT s1 = LLT::scalar(1); + const LLT s8 = LLT::scalar(8); + const LLT s16 = LLT::scalar(16); const LLT s32 = LLT::scalar(32); const LLT s64 = LLT::scalar(64); - const LLT v16s8 = LLT::vector(16, 8); - const LLT v8s16 = LLT::vector(8, 16); - const LLT v4s32 = LLT::vector(4, 32); - const LLT v2s64 = LLT::vector(2, 64); + const LLT v16s8 = LLT::fixed_vector(16, 8); + const LLT v8s16 = LLT::fixed_vector(8, 16); + const LLT v4s32 = LLT::fixed_vector(4, 32); + const LLT v2s64 = LLT::fixed_vector(2, 64); const LLT p0 = LLT::pointer(0, 32); getActionDefinitionsBuilder({G_ADD, G_SUB, G_MUL}) @@ -128,13 +127,13 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) { return false; unsigned Size = Query.Types[0].getSizeInBits(); - unsigned QueryMemSize = Query.MMODescrs[0].SizeInBits; + unsigned QueryMemSize = Query.MMODescrs[0].MemoryTy.getSizeInBits(); assert(QueryMemSize <= Size && "Scalar can't hold MemSize"); if (Size > 64 || QueryMemSize > 64) return false; - if (!isPowerOf2_64(Query.MMODescrs[0].SizeInBits)) + if (!isPowerOf2_64(Query.MMODescrs[0].MemoryTy.getSizeInBits())) return true; if (!ST.systemSupportsUnalignedAccess() && @@ -146,7 +145,8 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) { return false; }) - .minScalar(0, s32); + .minScalar(0, s32) + .lower(); getActionDefinitionsBuilder(G_IMPLICIT_DEF) .legalFor({s32, s64}); @@ -158,8 +158,8 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) { .legalFor({{s64, s32}}); getActionDefinitionsBuilder({G_ZEXTLOAD, G_SEXTLOAD}) - .legalForTypesWithMemDesc({{s32, p0, 8, 8}, - {s32, p0, 16, 8}}) + .legalForTypesWithMemDesc({{s32, p0, s8, 8}, + {s32, p0, s16, 8}}) .clampScalar(0, s32, s32); getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT}) @@ -324,7 +324,7 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) { getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE, G_MEMSET}).libcall(); - computeTables(); + getLegacyLegalizerInfo().computeTables(); verify(*ST.getInstrInfo()); } @@ -516,13 +516,14 @@ bool MipsLegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper, } case Intrinsic::vacopy: { MachinePointerInfo MPO; + LLT PtrTy = LLT::pointer(0, 32); auto Tmp = - MIRBuilder.buildLoad(LLT::pointer(0, 32), MI.getOperand(2), + MIRBuilder.buildLoad(PtrTy, MI.getOperand(2), *MI.getMF()->getMachineMemOperand( - MPO, MachineMemOperand::MOLoad, 4, Align(4))); + MPO, MachineMemOperand::MOLoad, PtrTy, Align(4))); MIRBuilder.buildStore(Tmp, MI.getOperand(1), *MI.getMF()->getMachineMemOperand( - MPO, MachineMemOperand::MOStore, 4, Align(4))); + MPO, MachineMemOperand::MOStore, PtrTy, Align(4))); MI.eraseFromParent(); return true; } diff --git a/llvm/lib/Target/Mips/MipsMSAInstrInfo.td b/llvm/lib/Target/Mips/MipsMSAInstrInfo.td index 3e32574596ca..301f1c158010 100644 --- a/llvm/lib/Target/Mips/MipsMSAInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsMSAInstrInfo.td @@ -365,18 +365,14 @@ def vsplat_imm_eq_1 : PatLeaf<(build_vector), [{ }]>; def vbclr_b : PatFrag<(ops node:$ws, node:$wt), - (and node:$ws, (xor (shl vsplat_imm_eq_1, node:$wt), - immAllOnesV))>; + (and node:$ws, (vnot (shl vsplat_imm_eq_1, node:$wt)))>; def vbclr_h : PatFrag<(ops node:$ws, node:$wt), - (and node:$ws, (xor (shl vsplat_imm_eq_1, node:$wt), - immAllOnesV))>; + (and node:$ws, (vnot (shl vsplat_imm_eq_1, node:$wt)))>; def vbclr_w : PatFrag<(ops node:$ws, node:$wt), - (and node:$ws, (xor (shl vsplat_imm_eq_1, node:$wt), - immAllOnesV))>; + (and node:$ws, (vnot (shl vsplat_imm_eq_1, node:$wt)))>; def vbclr_d : PatFrag<(ops node:$ws, node:$wt), - (and node:$ws, (xor (shl (v2i64 vsplati64_imm_eq_1), - node:$wt), - (bitconvert (v4i32 immAllOnesV))))>; + (and node:$ws, (vnot (shl (v2i64 vsplati64_imm_eq_1), + node:$wt)))>; def vbneg_b : PatFrag<(ops node:$ws, node:$wt), (xor node:$ws, (shl vsplat_imm_eq_1, node:$wt))>; @@ -3884,21 +3880,17 @@ defm : MSAShiftPats<sra, "SRA">; defm : MSABitPats<xor, "BNEG">; defm : MSABitPats<or, "BSET">; -def : MSAPat<(and v16i8:$ws, (xor (shl vsplat_imm_eq_1, - (vsplati8imm7 v16i8:$wt)), - immAllOnesV)), +def : MSAPat<(and v16i8:$ws, (vnot (shl vsplat_imm_eq_1, + (vsplati8imm7 v16i8:$wt)))), (v16i8 (BCLR_B v16i8:$ws, v16i8:$wt))>; -def : MSAPat<(and v8i16:$ws, (xor (shl vsplat_imm_eq_1, - (vsplati16imm15 v8i16:$wt)), - immAllOnesV)), +def : MSAPat<(and v8i16:$ws, (vnot (shl vsplat_imm_eq_1, + (vsplati16imm15 v8i16:$wt)))), (v8i16 (BCLR_H v8i16:$ws, v8i16:$wt))>; -def : MSAPat<(and v4i32:$ws, (xor (shl vsplat_imm_eq_1, - (vsplati32imm31 v4i32:$wt)), - immAllOnesV)), +def : MSAPat<(and v4i32:$ws, (vnot (shl vsplat_imm_eq_1, + (vsplati32imm31 v4i32:$wt)))), (v4i32 (BCLR_W v4i32:$ws, v4i32:$wt))>; -def : MSAPat<(and v2i64:$ws, (xor (shl (v2i64 vsplati64_imm_eq_1), - (vsplati64imm63 v2i64:$wt)), - (bitconvert (v4i32 immAllOnesV)))), +def : MSAPat<(and v2i64:$ws, (vnot (shl (v2i64 vsplati64_imm_eq_1), + (vsplati64imm63 v2i64:$wt)))), (v2i64 (BCLR_D v2i64:$ws, v2i64:$wt))>; // Vector extraction with fixed index. diff --git a/llvm/lib/Target/Mips/MipsPreLegalizerCombiner.cpp b/llvm/lib/Target/Mips/MipsPreLegalizerCombiner.cpp index 310e54b0ea8d..2ad9ffe4eb77 100644 --- a/llvm/lib/Target/Mips/MipsPreLegalizerCombiner.cpp +++ b/llvm/lib/Target/Mips/MipsPreLegalizerCombiner.cpp @@ -42,6 +42,8 @@ bool MipsPreLegalizerCombinerInfo::combine(GISelChangeObserver &Observer, switch (MI.getOpcode()) { default: return false; + case TargetOpcode::G_MEMCPY_INLINE: + return Helper.tryEmitMemcpyInline(MI); case TargetOpcode::G_LOAD: case TargetOpcode::G_SEXTLOAD: case TargetOpcode::G_ZEXTLOAD: { diff --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp index 3101820d476e..04b69c66bc0d 100644 --- a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp +++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp @@ -716,10 +716,11 @@ void MipsRegisterBankInfo::setRegBank(MachineInstr &MI, static void combineAwayG_UNMERGE_VALUES(LegalizationArtifactCombiner &ArtCombiner, - MachineInstr &MI, GISelChangeObserver &Observer) { + GUnmerge &MI, GISelChangeObserver &Observer) { SmallVector<Register, 4> UpdatedDefs; SmallVector<MachineInstr *, 2> DeadInstrs; - ArtCombiner.tryCombineUnmergeValues(MI, DeadInstrs, UpdatedDefs, Observer); + ArtCombiner.tryCombineUnmergeValues(MI, DeadInstrs, + UpdatedDefs, Observer); for (MachineInstr *DeadMI : DeadInstrs) DeadMI->eraseFromParent(); } @@ -750,8 +751,8 @@ void MipsRegisterBankInfo::applyMappingImpl( // This is new G_UNMERGE that was created during narrowScalar and will // not be considered for regbank selection. RegBankSelect for mips // visits/makes corresponding G_MERGE first. Combine them here. - if (NewMI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) - combineAwayG_UNMERGE_VALUES(ArtCombiner, *NewMI, NewInstrObserver); + if (auto *Unmerge = dyn_cast<GUnmerge>(NewMI)) + combineAwayG_UNMERGE_VALUES(ArtCombiner, *Unmerge, NewInstrObserver); // This G_MERGE will be combined away when its corresponding G_UNMERGE // gets regBankSelected. else if (NewMI->getOpcode() == TargetOpcode::G_MERGE_VALUES) @@ -763,7 +764,8 @@ void MipsRegisterBankInfo::applyMappingImpl( return; } case TargetOpcode::G_UNMERGE_VALUES: - combineAwayG_UNMERGE_VALUES(ArtCombiner, MI, NewInstrObserver); + combineAwayG_UNMERGE_VALUES(ArtCombiner, cast<GUnmerge>(MI), + NewInstrObserver); return; default: break; diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterInfo.cpp index 3452bf495a34..7cba3118cd62 100644 --- a/llvm/lib/Target/Mips/MipsRegisterInfo.cpp +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.cpp @@ -198,8 +198,7 @@ getReservedRegs(const MachineFunction &MF) const { // Reserve the base register if we need to both realign the stack and // allocate variable-sized objects at runtime. This should test the // same conditions as MipsFrameLowering::hasBP(). - if (needsStackRealignment(MF) && - MF.getFrameInfo().hasVarSizedObjects()) { + if (hasStackRealignment(MF) && MF.getFrameInfo().hasVarSizedObjects()) { Reserved.set(Mips::S7); Reserved.set(Mips::S7_64); } diff --git a/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp b/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp index f31ba06a1e7c..bb4b9c6fa6a7 100644 --- a/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp +++ b/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp @@ -535,7 +535,7 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF, BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex); - if (RegInfo.needsStackRealignment(MF)) { + if (RegInfo.hasStackRealignment(MF)) { // addiu $Reg, $zero, -MaxAlignment // andi $sp, $sp, $Reg Register VR = MF.getRegInfo().createVirtualRegister(RC); diff --git a/llvm/lib/Target/Mips/MipsSEFrameLowering.h b/llvm/lib/Target/Mips/MipsSEFrameLowering.h index bed2776c28da..226f7878fa14 100644 --- a/llvm/lib/Target/Mips/MipsSEFrameLowering.h +++ b/llvm/lib/Target/Mips/MipsSEFrameLowering.h @@ -10,8 +10,6 @@ #define LLVM_LIB_TARGET_MIPS_MIPSSEFRAMELOWERING_H #include "MipsFrameLowering.h" -#include "llvm/Support/TypeSize.h" -#include <vector> namespace llvm { diff --git a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp index 4a448a5f7c68..37d4313cc506 100644 --- a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp @@ -422,7 +422,7 @@ SDValue MipsSETargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const { } bool MipsSETargetLowering::allowsMisalignedMemoryAccesses( - EVT VT, unsigned, unsigned, MachineMemOperand::Flags, bool *Fast) const { + EVT VT, unsigned, Align, MachineMemOperand::Flags, bool *Fast) const { MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy; if (Subtarget.systemSupportsUnalignedAccess()) { diff --git a/llvm/lib/Target/Mips/MipsSEISelLowering.h b/llvm/lib/Target/Mips/MipsSEISelLowering.h index 433d019332cf..0ee36ae9f942 100644 --- a/llvm/lib/Target/Mips/MipsSEISelLowering.h +++ b/llvm/lib/Target/Mips/MipsSEISelLowering.h @@ -41,7 +41,7 @@ class TargetRegisterClass; const TargetRegisterClass *RC); bool allowsMisalignedMemoryAccesses( - EVT VT, unsigned AS = 0, unsigned Align = 1, + EVT VT, unsigned AS = 0, Align Alignment = Align(1), MachineMemOperand::Flags Flags = MachineMemOperand::MONone, bool *Fast = nullptr) const override; diff --git a/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp b/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp index a48088c28919..b05e9ad827c4 100644 --- a/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp +++ b/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp @@ -180,7 +180,7 @@ void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II, if ((FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI) || EhDataRegFI || IsISRRegFI) FrameReg = ABI.GetStackPtr(); - else if (RegInfo->needsStackRealignment(MF)) { + else if (RegInfo->hasStackRealignment(MF)) { if (MFI.hasVarSizedObjects() && !MFI.isFixedObjectIndex(FrameIndex)) FrameReg = ABI.GetBasePtr(); else if (MFI.isFixedObjectIndex(FrameIndex)) diff --git a/llvm/lib/Target/Mips/MipsTargetMachine.cpp b/llvm/lib/Target/Mips/MipsTargetMachine.cpp index 7e2c43164d52..7dd030f73d55 100644 --- a/llvm/lib/Target/Mips/MipsTargetMachine.cpp +++ b/llvm/lib/Target/Mips/MipsTargetMachine.cpp @@ -120,15 +120,11 @@ MipsTargetMachine::MipsTargetMachine(const Target &T, const Triple &TT, getEffectiveCodeModel(CM, CodeModel::Small), OL), isLittle(isLittle), TLOF(std::make_unique<MipsTargetObjectFile>()), ABI(MipsABIInfo::computeTargetABI(TT, CPU, Options.MCOptions)), - Subtarget(nullptr), - DefaultSubtarget(TT, CPU, FS, isLittle, *this, - MaybeAlign(Options.StackAlignmentOverride)), + Subtarget(nullptr), DefaultSubtarget(TT, CPU, FS, isLittle, *this, None), NoMips16Subtarget(TT, CPU, FS.empty() ? "-mips16" : FS.str() + ",-mips16", - isLittle, *this, - MaybeAlign(Options.StackAlignmentOverride)), + isLittle, *this, None), Mips16Subtarget(TT, CPU, FS.empty() ? "+mips16" : FS.str() + ",+mips16", - isLittle, *this, - MaybeAlign(Options.StackAlignmentOverride)) { + isLittle, *this, None) { Subtarget = &DefaultSubtarget; initAsmInfo(); @@ -176,9 +172,7 @@ MipsTargetMachine::getSubtargetImpl(const Function &F) const { // FIXME: This is related to the code below to reset the target options, // we need to know whether or not the soft float flag is set on the // function, so we can enable it as a subtarget feature. - bool softFloat = - F.hasFnAttribute("use-soft-float") && - F.getFnAttribute("use-soft-float").getValueAsString() == "true"; + bool softFloat = F.getFnAttribute("use-soft-float").getValueAsBool(); if (hasMips16Attr) FS += FS.empty() ? "+mips16" : ",+mips16"; @@ -199,7 +193,7 @@ MipsTargetMachine::getSubtargetImpl(const Function &F) const { resetTargetOptions(F); I = std::make_unique<MipsSubtarget>( TargetTriple, CPU, FS, isLittle, *this, - MaybeAlign(Options.StackAlignmentOverride)); + MaybeAlign(F.getParent()->getOverrideStackAlignment())); } return I.get(); } @@ -335,6 +329,6 @@ bool MipsPassConfig::addRegBankSelect() { } bool MipsPassConfig::addGlobalInstructionSelect() { - addPass(new InstructionSelect()); + addPass(new InstructionSelect(getOptLevel())); return false; } diff --git a/llvm/lib/Target/Mips/MipsTargetStreamer.h b/llvm/lib/Target/Mips/MipsTargetStreamer.h index f4282f5d6974..44615b987e3c 100644 --- a/llvm/lib/Target/Mips/MipsTargetStreamer.h +++ b/llvm/lib/Target/Mips/MipsTargetStreamer.h @@ -19,6 +19,8 @@ namespace llvm { +class formatted_raw_ostream; + class MipsTargetStreamer : public MCTargetStreamer { public: MipsTargetStreamer(MCStreamer &S); |