aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/Mips
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
commit344a3780b2e33f6ca763666c380202b18aab72a3 (patch)
treef0b203ee6eb71d7fdd792373e3c81eb18d6934dd /llvm/lib/Target/Mips
parentb60736ec1405bb0a8dd40989f67ef4c93da068ab (diff)
downloadsrc-344a3780b2e33f6ca763666c380202b18aab72a3.tar.gz
src-344a3780b2e33f6ca763666c380202b18aab72a3.zip
the upstream release/13.x branch was created.
Diffstat (limited to 'llvm/lib/Target/Mips')
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp5
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp4
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp2
-rw-r--r--llvm/lib/Target/Mips/Mips16HardFloat.cpp2
-rw-r--r--llvm/lib/Target/Mips/Mips16ISelLowering.cpp2
-rw-r--r--llvm/lib/Target/Mips/Mips16ISelLowering.h2
-rw-r--r--llvm/lib/Target/Mips/MipsCCState.cpp43
-rw-r--r--llvm/lib/Target/Mips/MipsCCState.h69
-rw-r--r--llvm/lib/Target/Mips/MipsCallLowering.cpp570
-rw-r--r--llvm/lib/Target/Mips/MipsCallLowering.h54
-rw-r--r--llvm/lib/Target/Mips/MipsFastISel.cpp17
-rw-r--r--llvm/lib/Target/Mips/MipsFrameLowering.cpp6
-rw-r--r--llvm/lib/Target/Mips/MipsISelLowering.cpp81
-rw-r--r--llvm/lib/Target/Mips/MipsISelLowering.h2
-rw-r--r--llvm/lib/Target/Mips/MipsLegalizerInfo.cpp37
-rw-r--r--llvm/lib/Target/Mips/MipsMSAInstrInfo.td34
-rw-r--r--llvm/lib/Target/Mips/MipsPreLegalizerCombiner.cpp2
-rw-r--r--llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp12
-rw-r--r--llvm/lib/Target/Mips/MipsRegisterInfo.cpp3
-rw-r--r--llvm/lib/Target/Mips/MipsSEFrameLowering.cpp2
-rw-r--r--llvm/lib/Target/Mips/MipsSEFrameLowering.h2
-rw-r--r--llvm/lib/Target/Mips/MipsSEISelLowering.cpp2
-rw-r--r--llvm/lib/Target/Mips/MipsSEISelLowering.h2
-rw-r--r--llvm/lib/Target/Mips/MipsSERegisterInfo.cpp2
-rw-r--r--llvm/lib/Target/Mips/MipsTargetMachine.cpp18
-rw-r--r--llvm/lib/Target/Mips/MipsTargetStreamer.h2
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);