summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/Mips
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Mips')
-rw-r--r--llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp441
-rw-r--r--llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp42
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h4
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp1
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp6
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h12
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp7
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.h6
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp18
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h3
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp15
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp3
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp9
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp4
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp24
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp35
-rw-r--r--llvm/lib/Target/Mips/MicroMips32r6InstrFormats.td17
-rw-r--r--llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td22
-rw-r--r--llvm/lib/Target/Mips/MicroMipsInstrFPU.td3
-rw-r--r--llvm/lib/Target/Mips/MicroMipsInstrInfo.td9
-rw-r--r--llvm/lib/Target/Mips/Mips.td17
-rw-r--r--llvm/lib/Target/Mips/Mips16ISelLowering.cpp3
-rw-r--r--llvm/lib/Target/Mips/Mips16InstrInfo.cpp23
-rw-r--r--llvm/lib/Target/Mips/Mips16InstrInfo.h9
-rw-r--r--llvm/lib/Target/Mips/Mips16InstrInfo.td8
-rw-r--r--llvm/lib/Target/Mips/Mips32r6InstrInfo.td10
-rw-r--r--llvm/lib/Target/Mips/Mips64InstrInfo.td43
-rw-r--r--llvm/lib/Target/Mips/Mips64r6InstrInfo.td7
-rw-r--r--llvm/lib/Target/Mips/MipsAsmPrinter.cpp12
-rw-r--r--llvm/lib/Target/Mips/MipsCallLowering.cpp5
-rw-r--r--llvm/lib/Target/Mips/MipsCallingConv.td3
-rw-r--r--llvm/lib/Target/Mips/MipsCondMov.td16
-rw-r--r--llvm/lib/Target/Mips/MipsConstantIslandPass.cpp10
-rw-r--r--llvm/lib/Target/Mips/MipsDSPInstrInfo.td11
-rw-r--r--llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp72
-rw-r--r--llvm/lib/Target/Mips/MipsExpandPseudo.cpp230
-rw-r--r--llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp1
-rw-r--r--llvm/lib/Target/Mips/MipsISelLowering.cpp220
-rw-r--r--llvm/lib/Target/Mips/MipsISelLowering.h2
-rw-r--r--llvm/lib/Target/Mips/MipsInstrFPU.td48
-rw-r--r--llvm/lib/Target/Mips/MipsInstrFormats.td19
-rw-r--r--llvm/lib/Target/Mips/MipsInstrInfo.cpp4
-rw-r--r--llvm/lib/Target/Mips/MipsInstrInfo.td194
-rw-r--r--llvm/lib/Target/Mips/MipsInstructionSelector.cpp148
-rw-r--r--llvm/lib/Target/Mips/MipsLegalizerInfo.cpp113
-rw-r--r--llvm/lib/Target/Mips/MipsMCInstLower.cpp8
-rw-r--r--llvm/lib/Target/Mips/MipsMCInstLower.h4
-rw-r--r--llvm/lib/Target/Mips/MipsMSAInstrInfo.td1
-rw-r--r--llvm/lib/Target/Mips/MipsPreLegalizerCombiner.cpp1
-rw-r--r--llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp27
-rw-r--r--llvm/lib/Target/Mips/MipsRegisterBankInfo.h4
-rw-r--r--llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp22
-rw-r--r--llvm/lib/Target/Mips/MipsSEISelLowering.cpp1
-rw-r--r--llvm/lib/Target/Mips/MipsSEInstrInfo.cpp27
-rw-r--r--llvm/lib/Target/Mips/MipsSEInstrInfo.h10
-rw-r--r--llvm/lib/Target/Mips/MipsScheduleGeneric.td12
-rw-r--r--llvm/lib/Target/Mips/MipsScheduleP5600.td6
-rw-r--r--llvm/lib/Target/Mips/MipsSubtarget.cpp25
-rw-r--r--llvm/lib/Target/Mips/MipsSubtarget.h4
-rw-r--r--llvm/lib/Target/Mips/MipsTargetMachine.cpp7
-rw-r--r--llvm/lib/Target/Mips/MipsTargetStreamer.h4
-rw-r--r--llvm/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp2
62 files changed, 1364 insertions, 710 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 21d0df74d458..e467ed36938b 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -126,13 +126,16 @@ const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
- Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
+ Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
+ Mips::FeatureNaN2008
};
namespace {
class MipsAsmParser : public MCTargetAsmParser {
MipsTargetStreamer &getTargetStreamer() {
+ assert(getParser().getStreamer().getTargetStreamer() &&
+ "do not have a target streamer");
MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
return static_cast<MipsTargetStreamer &>(TS);
}
@@ -251,8 +254,10 @@ class MipsAsmParser : public MCTargetAsmParser {
bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI);
- void expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
- const MCSubtargetInfo *STI, bool IsLoad);
+ void expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
+ const MCSubtargetInfo *STI, bool IsLoad);
+ void expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
+ const MCSubtargetInfo *STI, bool IsLoad);
bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI);
@@ -330,12 +335,14 @@ class MipsAsmParser : public MCTargetAsmParser {
bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI);
+ bool expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
+ const MCSubtargetInfo *STI);
+
bool reportParseError(Twine ErrorMsg);
bool reportParseError(SMLoc Loc, Twine ErrorMsg);
bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
- bool isEvaluated(const MCExpr *Expr);
bool parseSetMips0Directive();
bool parseSetArchDirective();
bool parseSetFeature(uint64_t Feature);
@@ -558,6 +565,19 @@ public:
return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
}
+ bool isJalrRelocAvailable(const MCExpr *JalExpr) {
+ if (!EmitJalrReloc)
+ return false;
+ MCValue Res;
+ if (!JalExpr->evaluateAsRelocatable(Res, nullptr, nullptr))
+ return false;
+ if (Res.getSymB() != nullptr)
+ return false;
+ if (Res.getConstant() != 0)
+ return ABI.IsN32() || ABI.IsN64();
+ return true;
+ }
+
const MipsABIInfo &getABI() const { return ABI; }
bool isABI_N32() const { return ABI.IsN32(); }
bool isABI_N64() const { return ABI.IsN64(); }
@@ -654,6 +674,10 @@ public:
return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
}
+ bool hasCnMipsP() const {
+ return (getSTI().getFeatureBits()[Mips::FeatureCnMipsP]);
+ }
+
bool inPicMode() {
return IsPicEnabled;
}
@@ -1295,8 +1319,6 @@ public:
}
// Allow relocation operators.
- // FIXME: This predicate and others need to look through binary expressions
- // and determine whether a Value is a constant or not.
template <unsigned Bits, unsigned ShiftAmount = 0>
bool isMemWithSimmOffset() const {
if (!isMem())
@@ -1777,17 +1799,71 @@ static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
return 0;
}
+static bool isEvaluated(const MCExpr *Expr) {
+ switch (Expr->getKind()) {
+ case MCExpr::Constant:
+ return true;
+ case MCExpr::SymbolRef:
+ return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
+ case MCExpr::Binary: {
+ const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
+ if (!isEvaluated(BE->getLHS()))
+ return false;
+ return isEvaluated(BE->getRHS());
+ }
+ case MCExpr::Unary:
+ return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
+ case MCExpr::Target:
+ return true;
+ }
+ return false;
+}
+
+static bool needsExpandMemInst(MCInst &Inst) {
+ const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
+
+ unsigned NumOp = MCID.getNumOperands();
+ if (NumOp != 3 && NumOp != 4)
+ return false;
+
+ const MCOperandInfo &OpInfo = MCID.OpInfo[NumOp - 1];
+ if (OpInfo.OperandType != MCOI::OPERAND_MEMORY &&
+ OpInfo.OperandType != MCOI::OPERAND_UNKNOWN &&
+ OpInfo.OperandType != MipsII::OPERAND_MEM_SIMM9)
+ return false;
+
+ MCOperand &Op = Inst.getOperand(NumOp - 1);
+ if (Op.isImm()) {
+ if (OpInfo.OperandType == MipsII::OPERAND_MEM_SIMM9)
+ return !isInt<9>(Op.getImm());
+ // Offset can't exceed 16bit value.
+ return !isInt<16>(Op.getImm());
+ }
+
+ if (Op.isExpr()) {
+ const MCExpr *Expr = Op.getExpr();
+ if (Expr->getKind() != MCExpr::SymbolRef)
+ return !isEvaluated(Expr);
+
+ // Expand symbol.
+ const MCSymbolRefExpr *SR = static_cast<const MCSymbolRefExpr *>(Expr);
+ return SR->getKind() == MCSymbolRefExpr::VK_None;
+ }
+
+ return false;
+}
+
bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
MCStreamer &Out,
const MCSubtargetInfo *STI) {
MipsTargetStreamer &TOut = getTargetStreamer();
- const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
+ const unsigned Opcode = Inst.getOpcode();
+ const MCInstrDesc &MCID = getInstDesc(Opcode);
bool ExpandedJalSym = false;
Inst.setLoc(IDLoc);
if (MCID.isBranch() || MCID.isCall()) {
- const unsigned Opcode = Inst.getOpcode();
MCOperand Offset;
switch (Opcode) {
@@ -1901,14 +1977,13 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
// SSNOP is deprecated on MIPS32r6/MIPS64r6
// We still accept it but it is a normal nop.
- if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
+ if (hasMips32r6() && Opcode == Mips::SSNOP) {
std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
"nop instruction");
}
if (hasCnMips()) {
- const unsigned Opcode = Inst.getOpcode();
MCOperand Opnd;
int Imm;
@@ -1958,7 +2033,7 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
// not in the operands.
unsigned FirstOp = 1;
unsigned SecondOp = 2;
- switch (Inst.getOpcode()) {
+ switch (Opcode) {
default:
break;
case Mips::SDivIMacro:
@@ -2004,8 +2079,7 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
}
// For PIC code convert unconditional jump to unconditional branch.
- if ((Inst.getOpcode() == Mips::J || Inst.getOpcode() == Mips::J_MM) &&
- inPicMode()) {
+ if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
MCInst BInst;
BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
BInst.addOperand(MCOperand::createReg(Mips::ZERO));
@@ -2016,8 +2090,7 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
// This expansion is not in a function called by tryExpandInstruction()
// because the pseudo-instruction doesn't have a distinct opcode.
- if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
- inPicMode()) {
+ if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
warnIfNoMacro(IDLoc);
const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
@@ -2031,62 +2104,19 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
// of the assembler. We ought to leave it to those later stages.
const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
- // FIXME: Add support for label+offset operands (currently causes an error).
- // FIXME: Add support for forward-declared local symbols.
- // FIXME: Add expansion for when the LargeGOT option is enabled.
- if (JalSym->isInSection() || JalSym->isTemporary() ||
- (JalSym->isELF() &&
- cast<MCSymbolELF>(JalSym)->getBinding() == ELF::STB_LOCAL)) {
- if (isABI_O32()) {
- // If it's a local symbol and the O32 ABI is being used, we expand to:
- // lw $25, 0($gp)
- // R_(MICRO)MIPS_GOT16 label
- // addiu $25, $25, 0
- // R_(MICRO)MIPS_LO16 label
- // jalr $25
- const MCExpr *Got16RelocExpr =
- MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
- const MCExpr *Lo16RelocExpr =
- MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
-
- TOut.emitRRX(Mips::LW, Mips::T9, GPReg,
- MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
- TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
- MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
- } else if (isABI_N32() || isABI_N64()) {
- // If it's a local symbol and the N32/N64 ABIs are being used,
- // we expand to:
- // lw/ld $25, 0($gp)
- // R_(MICRO)MIPS_GOT_DISP label
- // jalr $25
- const MCExpr *GotDispRelocExpr =
- MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
-
- TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
- GPReg, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
- STI);
- }
- } else {
- // If it's an external/weak symbol, we expand to:
- // lw/ld $25, 0($gp)
- // R_(MICRO)MIPS_CALL16 label
- // jalr $25
- const MCExpr *Call16RelocExpr =
- MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
-
- TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, GPReg,
- MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
- }
+ if (expandLoadAddress(Mips::T9, Mips::NoRegister, Inst.getOperand(0),
+ !isGP64bit(), IDLoc, Out, STI))
+ return true;
MCInst JalrInst;
- if (IsCpRestoreSet && inMicroMipsMode())
- JalrInst.setOpcode(Mips::JALRS_MM);
+ if (inMicroMipsMode())
+ JalrInst.setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
else
- JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
+ JalrInst.setOpcode(Mips::JALR);
JalrInst.addOperand(MCOperand::createReg(Mips::RA));
JalrInst.addOperand(MCOperand::createReg(Mips::T9));
- if (EmitJalrReloc) {
+ if (isJalrRelocAvailable(JalExpr)) {
// As an optimization hint for the linker, before the JALR we add:
// .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
// tmplabel:
@@ -2106,43 +2136,25 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
ExpandedJalSym = true;
}
- bool IsPCRelativeLoad = (MCID.TSFlags & MipsII::IsPCRelativeLoad) != 0;
- if ((MCID.mayLoad() || MCID.mayStore()) && !IsPCRelativeLoad) {
+ if (MCID.mayLoad() || MCID.mayStore()) {
// Check the offset of memory operand, if it is a symbol
// reference or immediate we may have to expand instructions.
- for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
- const MCOperandInfo &OpInfo = MCID.OpInfo[i];
- if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
- (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
- MCOperand &Op = Inst.getOperand(i);
- if (Op.isImm()) {
- int64_t MemOffset = Op.getImm();
- if (MemOffset < -32768 || MemOffset > 32767) {
- // Offset can't exceed 16bit value.
- expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
- return getParser().hasPendingError();
- }
- } else if (Op.isExpr()) {
- const MCExpr *Expr = Op.getExpr();
- if (Expr->getKind() == MCExpr::SymbolRef) {
- const MCSymbolRefExpr *SR =
- static_cast<const MCSymbolRefExpr *>(Expr);
- if (SR->getKind() == MCSymbolRefExpr::VK_None) {
- // Expand symbol.
- expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
- return getParser().hasPendingError();
- }
- } else if (!isEvaluated(Expr)) {
- expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
- return getParser().hasPendingError();
- }
- }
+ if (needsExpandMemInst(Inst)) {
+ const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
+ switch (MCID.OpInfo[MCID.getNumOperands() - 1].OperandType) {
+ case MipsII::OPERAND_MEM_SIMM9:
+ expandMem9Inst(Inst, IDLoc, Out, STI, MCID.mayLoad());
+ break;
+ default:
+ expandMem16Inst(Inst, IDLoc, Out, STI, MCID.mayLoad());
+ break;
}
- } // for
- } // if load/store
+ return getParser().hasPendingError();
+ }
+ }
if (inMicroMipsMode()) {
- if (MCID.mayLoad() && Inst.getOpcode() != Mips::LWP_MM) {
+ if (MCID.mayLoad() && Opcode != Mips::LWP_MM) {
// Try to create 16-bit GP relative load instruction.
for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
const MCOperandInfo &OpInfo = MCID.OpInfo[i];
@@ -2173,7 +2185,7 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
MCOperand Opnd;
int Imm;
- switch (Inst.getOpcode()) {
+ switch (Opcode) {
default:
break;
case Mips::ADDIUSP_MM:
@@ -2321,8 +2333,8 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
TOut.emitDirectiveSetReorder();
}
- if ((Inst.getOpcode() == Mips::JalOneReg ||
- Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
+ if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
+ ExpandedJalSym) &&
isPicAndNotNxxAbi()) {
if (IsCpRestoreSet) {
// We need a NOP between the JALR and the LW:
@@ -2586,6 +2598,9 @@ MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
case Mips::MFTHC1: case Mips::MTTHC1:
case Mips::CFTC1: case Mips::CTTC1:
return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
+ case Mips::SaaAddr:
+ case Mips::SaadAddr:
+ return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
}
}
@@ -2837,13 +2852,9 @@ bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
const MCSubtargetInfo *STI) {
// la can't produce a usable address when addresses are 64-bit.
if (Is32BitAddress && ABI.ArePtrs64bit()) {
- // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
- // We currently can't do this because we depend on the equality
- // operator and N64 can end up with a GPR32/GPR64 mismatch.
- Error(IDLoc, "la used to load 64-bit address");
+ Warning(IDLoc, "la used to load 64-bit address");
// Continue as if we had 'dla' instead.
Is32BitAddress = false;
- return true;
}
// dla requires 64-bit addresses.
@@ -2933,6 +2944,9 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
TmpReg = ATReg;
}
+ // FIXME: In case of N32 / N64 ABI and emabled XGOT, local addresses
+ // loaded using R_MIPS_GOT_PAGE / R_MIPS_GOT_OFST pair of relocations.
+ // FIXME: Implement XGOT for microMIPS.
if (UseXGOT) {
// Loading address from XGOT
// External GOT: lui $tmp, %got_hi(symbol)($gp)
@@ -2969,7 +2983,7 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
const MipsMCExpr *GotExpr = nullptr;
const MCExpr *LoExpr = nullptr;
- if (IsPtr64) {
+ if (ABI.IsN32() || ABI.IsN64()) {
// The remaining cases are:
// Small offset: ld $tmp, %got_disp(symbol)($gp)
// >daddiu $tmp, $tmp, offset
@@ -3079,7 +3093,7 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
return false;
- } else if (canUseATReg() && !RdRegIsRsReg) {
+ } else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
unsigned ATReg = getATReg(IDLoc);
// If the $rs is different from $rd or if $rs isn't specified and we
@@ -3106,7 +3120,8 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
return false;
- } else if (!canUseATReg() && !RdRegIsRsReg) {
+ } else if ((!canUseATReg() && !RdRegIsRsReg) ||
+ (canUseATReg() && DstReg == getATReg(IDLoc))) {
// Otherwise, synthesize the address in the destination register
// serially:
// (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
@@ -3631,20 +3646,26 @@ bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
return false;
}
-void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
- const MCSubtargetInfo *STI, bool IsLoad) {
- const MCOperand &DstRegOp = Inst.getOperand(0);
+void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
+ const MCSubtargetInfo *STI, bool IsLoad) {
+ unsigned NumOp = Inst.getNumOperands();
+ assert((NumOp == 3 || NumOp == 4) && "unexpected operands number");
+ unsigned StartOp = NumOp == 3 ? 0 : 1;
+
+ const MCOperand &DstRegOp = Inst.getOperand(StartOp);
assert(DstRegOp.isReg() && "expected register operand kind");
- const MCOperand &BaseRegOp = Inst.getOperand(1);
+ const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
assert(BaseRegOp.isReg() && "expected register operand kind");
+ const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
MipsTargetStreamer &TOut = getTargetStreamer();
+ unsigned OpCode = Inst.getOpcode();
unsigned DstReg = DstRegOp.getReg();
unsigned BaseReg = BaseRegOp.getReg();
unsigned TmpReg = DstReg;
- const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
- int16_t DstRegClass = Desc.OpInfo[0].RegClass;
+ const MCInstrDesc &Desc = getInstDesc(OpCode);
+ int16_t DstRegClass = Desc.OpInfo[StartOp].RegClass;
unsigned DstRegClassID =
getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
@@ -3658,25 +3679,12 @@ void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
return;
}
- if (Inst.getNumOperands() > 3) {
- const MCOperand &BaseRegOp = Inst.getOperand(2);
- assert(BaseRegOp.isReg() && "expected register operand kind");
- const MCOperand &ExprOp = Inst.getOperand(3);
- assert(ExprOp.isExpr() && "expected expression oprand kind");
-
- unsigned BaseReg = BaseRegOp.getReg();
- const MCExpr *ExprOffset = ExprOp.getExpr();
-
- MCOperand LoOperand = MCOperand::createExpr(
- MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
- MCOperand HiOperand = MCOperand::createExpr(
- MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
- TOut.emitSCWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
- LoOperand, TmpReg, IDLoc, STI);
- return;
- }
-
- const MCOperand &OffsetOp = Inst.getOperand(2);
+ auto emitInstWithOffset = [&](const MCOperand &Off) {
+ if (NumOp == 3)
+ TOut.emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
+ else
+ TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
+ };
if (OffsetOp.isImm()) {
int64_t LoOffset = OffsetOp.getImm() & 0xffff;
@@ -3690,16 +3698,16 @@ void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
bool IsLargeOffset = HiOffset != 0;
if (IsLargeOffset) {
- bool Is32BitImm = (HiOffset >> 32) == 0;
+ bool Is32BitImm = isInt<32>(OffsetOp.getImm());
if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm, true,
IDLoc, Out, STI))
return;
}
if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
- TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg,
- BaseReg, IDLoc, STI);
- TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, LoOffset, IDLoc, STI);
+ TOut.emitRRR(ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
+ TmpReg, BaseReg, IDLoc, STI);
+ emitInstWithOffset(MCOperand::createImm(int16_t(LoOffset)));
return;
}
@@ -3723,26 +3731,41 @@ void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
loadAndAddSymbolAddress(Res.getSymA(), TmpReg, BaseReg,
!ABI.ArePtrs64bit(), IDLoc, Out, STI);
- TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, Res.getConstant(), IDLoc,
- STI);
+ emitInstWithOffset(MCOperand::createImm(int16_t(Res.getConstant())));
} else {
// FIXME: Implement 64-bit case.
// 1) lw $8, sym => lui $8, %hi(sym)
// lw $8, %lo(sym)($8)
// 2) sw $8, sym => lui $at, %hi(sym)
// sw $8, %lo(sym)($at)
- const MCExpr *ExprOffset = OffsetOp.getExpr();
+ const MCExpr *OffExpr = OffsetOp.getExpr();
MCOperand LoOperand = MCOperand::createExpr(
- MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
+ MipsMCExpr::create(MipsMCExpr::MEK_LO, OffExpr, getContext()));
MCOperand HiOperand = MCOperand::createExpr(
- MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
+ MipsMCExpr::create(MipsMCExpr::MEK_HI, OffExpr, getContext()));
+
+ if (ABI.IsN64()) {
+ MCOperand HighestOperand = MCOperand::createExpr(
+ MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, OffExpr, getContext()));
+ MCOperand HigherOperand = MCOperand::createExpr(
+ MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, OffExpr, getContext()));
- // Generate the base address in TmpReg.
- TOut.emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
- if (BaseReg != Mips::ZERO)
- TOut.emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
- // Emit the load or store with the adjusted base and offset.
- TOut.emitRRX(Inst.getOpcode(), DstReg, TmpReg, LoOperand, IDLoc, STI);
+ TOut.emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
+ TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
+ TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
+ TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
+ TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
+ if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
+ TOut.emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
+ emitInstWithOffset(LoOperand);
+ } else {
+ // Generate the base address in TmpReg.
+ TOut.emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
+ if (BaseReg != Mips::ZERO)
+ TOut.emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
+ // Emit the load or store with the adjusted base and offset.
+ emitInstWithOffset(LoOperand);
+ }
}
return;
}
@@ -3750,6 +3773,64 @@ void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
llvm_unreachable("unexpected operand type");
}
+void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
+ const MCSubtargetInfo *STI, bool IsLoad) {
+ unsigned NumOp = Inst.getNumOperands();
+ assert((NumOp == 3 || NumOp == 4) && "unexpected operands number");
+ unsigned StartOp = NumOp == 3 ? 0 : 1;
+
+ const MCOperand &DstRegOp = Inst.getOperand(StartOp);
+ assert(DstRegOp.isReg() && "expected register operand kind");
+ const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
+ assert(BaseRegOp.isReg() && "expected register operand kind");
+ const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
+
+ MipsTargetStreamer &TOut = getTargetStreamer();
+ unsigned OpCode = Inst.getOpcode();
+ unsigned DstReg = DstRegOp.getReg();
+ unsigned BaseReg = BaseRegOp.getReg();
+ unsigned TmpReg = DstReg;
+
+ const MCInstrDesc &Desc = getInstDesc(OpCode);
+ int16_t DstRegClass = Desc.OpInfo[StartOp].RegClass;
+ unsigned DstRegClassID =
+ getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
+ bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
+ (DstRegClassID == Mips::GPR64RegClassID);
+
+ if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
+ // At this point we need AT to perform the expansions
+ // and we exit if it is not available.
+ TmpReg = getATReg(IDLoc);
+ if (!TmpReg)
+ return;
+ }
+
+ auto emitInst = [&]() {
+ if (NumOp == 3)
+ TOut.emitRRX(OpCode, DstReg, TmpReg, MCOperand::createImm(0), IDLoc, STI);
+ else
+ TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, MCOperand::createImm(0),
+ IDLoc, STI);
+ };
+
+ if (OffsetOp.isImm()) {
+ loadImmediate(OffsetOp.getImm(), TmpReg, BaseReg, !ABI.ArePtrs64bit(), true,
+ IDLoc, Out, STI);
+ emitInst();
+ return;
+ }
+
+ if (OffsetOp.isExpr()) {
+ loadAndAddSymbolAddress(OffsetOp.getExpr(), TmpReg, BaseReg,
+ !ABI.ArePtrs64bit(), IDLoc, Out, STI);
+ emitInst();
+ return;
+ }
+
+ llvm_unreachable("unexpected operand type");
+}
+
bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
MCStreamer &Out,
const MCSubtargetInfo *STI) {
@@ -4051,8 +4132,8 @@ bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
// D(S)DivMacro.
bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
- const MCSubtargetInfo *STI, const bool IsMips64,
- const bool Signed) {
+ const MCSubtargetInfo *STI,
+ const bool IsMips64, const bool Signed) {
MipsTargetStreamer &TOut = getTargetStreamer();
warnIfNoMacro(IDLoc);
@@ -5450,6 +5531,39 @@ bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
return false;
}
+bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
+ const MCSubtargetInfo *STI) {
+ assert(Inst.getNumOperands() == 3 && "expected three operands");
+ assert(Inst.getOperand(0).isReg() && "expected register operand kind");
+ assert(Inst.getOperand(1).isReg() && "expected register operand kind");
+
+ warnIfNoMacro(IDLoc);
+
+ MipsTargetStreamer &TOut = getTargetStreamer();
+ unsigned Opcode = Inst.getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
+ unsigned RtReg = Inst.getOperand(0).getReg();
+ unsigned BaseReg = Inst.getOperand(1).getReg();
+ const MCOperand &BaseOp = Inst.getOperand(2);
+
+ if (BaseOp.isImm()) {
+ int64_t ImmValue = BaseOp.getImm();
+ if (ImmValue == 0) {
+ TOut.emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
+ return false;
+ }
+ }
+
+ unsigned ATReg = getATReg(IDLoc);
+ if (!ATReg)
+ return true;
+
+ if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
+ return true;
+
+ TOut.emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
+ return false;
+}
+
unsigned
MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
const OperandVector &Operands) {
@@ -6086,26 +6200,6 @@ bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
return true;
}
-bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
- switch (Expr->getKind()) {
- case MCExpr::Constant:
- return true;
- case MCExpr::SymbolRef:
- return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
- case MCExpr::Binary: {
- const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
- if (!isEvaluated(BE->getLHS()))
- return false;
- return isEvaluated(BE->getRHS());
- }
- case MCExpr::Unary:
- return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
- case MCExpr::Target:
- return true;
- }
- return false;
-}
-
bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
SMLoc &EndLoc) {
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
@@ -7168,8 +7262,8 @@ bool MipsAsmParser::parseSetArchDirective() {
return reportParseError("unexpected token, expected equals sign");
Parser.Lex();
- StringRef Arch;
- if (Parser.parseIdentifier(Arch))
+ StringRef Arch = getParser().parseStringToEndOfStatement().trim();
+ if (Arch.empty())
return reportParseError("expected arch identifier");
StringRef ArchFeatureName =
@@ -7190,6 +7284,7 @@ bool MipsAsmParser::parseSetArchDirective() {
.Case("mips64r5", "mips64r5")
.Case("mips64r6", "mips64r6")
.Case("octeon", "cnmips")
+ .Case("octeon+", "cnmipsp")
.Case("r4000", "mips3") // This is an implementation of Mips3.
.Default("");
@@ -8550,7 +8645,7 @@ bool MipsAsmParser::parseInternalDirectiveReallowModule() {
return false;
}
-extern "C" void LLVMInitializeMipsAsmParser() {
+extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsAsmParser() {
RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget());
RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget());
RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target());
diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
index c3e98fe410c1..6f197e424561 100644
--- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
+++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
@@ -63,6 +63,8 @@ public:
bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; }
+ bool hasCnMipsP() const { return STI.getFeatureBits()[Mips::FeatureCnMipsP]; }
+
bool hasCOP3() const {
// Only present in MIPS-I and MIPS-II
return !hasMips32() && !hasMips3();
@@ -70,7 +72,6 @@ public:
DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
ArrayRef<uint8_t> Bytes, uint64_t Address,
- raw_ostream &VStream,
raw_ostream &CStream) const override;
};
@@ -446,16 +447,16 @@ static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
const void *Decoder);
template <typename InsnType>
-static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
- const void *Decoder);
+static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn,
+ uint64_t Address, const void *Decoder);
template <typename InsnType>
static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
const void *Decoder);
template <typename InsnType>
-static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
- const void *Decoder);
+static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn,
+ uint64_t Address, const void *Decoder);
template <typename InsnType>
static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
@@ -562,7 +563,7 @@ static MCDisassembler *createMipselDisassembler(
return new MipsDisassembler(STI, Ctx, false);
}
-extern "C" void LLVMInitializeMipsDisassembler() {
+extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsDisassembler() {
// Register the disassembler.
TargetRegistry::RegisterMCDisassembler(getTheMipsTarget(),
createMipsDisassembler);
@@ -630,8 +631,8 @@ static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
}
template <typename InsnType>
-static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
- const void *Decoder) {
+static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn,
+ uint64_t Address, const void *Decoder) {
InsnType Rs = fieldFromInstruction(insn, 16, 5);
InsnType Imm = fieldFromInstruction(insn, 0, 16);
MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
@@ -1091,8 +1092,10 @@ static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
InsnType Rs = fieldFromInstruction(Insn, 21, 5);
InsnType Rt = fieldFromInstruction(Insn, 16, 5);
- MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
- MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
+ MI.addOperand(
+ MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
+ MI.addOperand(
+ MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
MI.addOperand(MCOperand::createImm(Pos));
MI.addOperand(MCOperand::createImm(Size));
@@ -1132,8 +1135,10 @@ static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
InsnType Rt = fieldFromInstruction(Insn, 16, 5);
MI.setOpcode(Mips::DINS);
- MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
- MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
+ MI.addOperand(
+ MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
+ MI.addOperand(
+ MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
MI.addOperand(MCOperand::createImm(Pos));
MI.addOperand(MCOperand::createImm(Size));
@@ -1214,7 +1219,6 @@ static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
ArrayRef<uint8_t> Bytes,
uint64_t Address,
- raw_ostream &VStream,
raw_ostream &CStream) const {
uint32_t Insn;
DecodeStatus Result;
@@ -1256,8 +1260,8 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
LLVM_DEBUG(
dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
// Calling the auto-generated decoder function.
- Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
- this, STI);
+ Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn,
+ Address, this, STI);
if (Result != MCDisassembler::Fail) {
Size = 4;
return Result;
@@ -1353,6 +1357,14 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
return Result;
}
+ if (hasCnMipsP()) {
+ LLVM_DEBUG(dbgs() << "Trying CnMipsP table (32-bit opcodes):\n");
+ Result = decodeInstruction(DecoderTableCnMipsP32, Instr, Insn,
+ Address, this, STI);
+ if (Result != MCDisassembler::Fail)
+ return Result;
+ }
+
if (isGP64()) {
LLVM_DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h
index 239e55495e9d..6091ee24b04d 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h
@@ -139,7 +139,9 @@ public:
template <class PredicateLibrary>
void setISAExtensionFromPredicates(const PredicateLibrary &P) {
- if (P.hasCnMips())
+ if (P.hasCnMipsP())
+ ISAExtension = Mips::AFL_EXT_OCTEONP;
+ else if (P.hasCnMips())
ISAExtension = Mips::AFL_EXT_OCTEON;
else
ISAExtension = Mips::AFL_EXT_NONE;
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
index bdd190fc17c9..37e970f2f15b 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
@@ -11,6 +11,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Support/CommandLine.h"
using namespace llvm;
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
index 70f2a7bdf10f..94d338746a6c 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
@@ -585,6 +585,8 @@ MCAsmBackend *llvm::createMipsAsmBackend(const Target &T,
const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI,
const MCTargetOptions &Options) {
- MipsABIInfo ABI = MipsABIInfo::computeTargetABI(STI.getTargetTriple(), STI.getCPU(), Options);
- return new MipsAsmBackend(T, MRI, STI.getTargetTriple(), STI.getCPU(), ABI.IsN32());
+ MipsABIInfo ABI = MipsABIInfo::computeTargetABI(STI.getTargetTriple(),
+ STI.getCPU(), Options);
+ return new MipsAsmBackend(T, MRI, STI.getTargetTriple(), STI.getCPU(),
+ ABI.IsN32());
}
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h
index 6d8cb264158f..02ab5ede2c1a 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h
@@ -16,6 +16,7 @@
#include "MipsFixupKinds.h"
#include "MipsMCTargetDesc.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCInstrDesc.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
@@ -123,13 +124,16 @@ namespace MipsII {
IsCTI = 1 << 4,
/// HasForbiddenSlot - Instruction has a forbidden slot.
HasForbiddenSlot = 1 << 5,
- /// IsPCRelativeLoad - A Load instruction with implicit source register
- /// ($pc) with explicit offset and destination register
- IsPCRelativeLoad = 1 << 6,
/// HasFCCRegOperand - Instruction uses an $fcc<x> register.
- HasFCCRegOperand = 1 << 7
+ HasFCCRegOperand = 1 << 6
};
+
+ enum OperandType : unsigned {
+ OPERAND_FIRST_MIPS_MEM_IMM = MCOI::OPERAND_FIRST_TARGET,
+ OPERAND_MEM_SIMM9 = OPERAND_FIRST_MIPS_MEM_IMM,
+ OPERAND_LAST_MIPS_MEM_IMM = OPERAND_MEM_SIMM9
+ };
}
}
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp
index fb290a8e3f26..649ba20324bf 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp
@@ -75,8 +75,9 @@ void MipsInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
OS << '$' << StringRef(getRegisterName(RegNo)).lower();
}
-void MipsInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
- StringRef Annot, const MCSubtargetInfo &STI) {
+void MipsInstPrinter::printInst(const MCInst *MI, uint64_t Address,
+ StringRef Annot, const MCSubtargetInfo &STI,
+ raw_ostream &O) {
switch (MI->getOpcode()) {
default:
break;
@@ -109,7 +110,7 @@ void MipsInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
// Try to print any aliases first.
if (!printAliasInstr(MI, O) && !printAlias(*MI, O))
- printInstruction(MI, O);
+ printInstruction(MI, Address, O);
printAnnotation(O, Annot);
switch (MI->getOpcode()) {
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.h
index a34a5c1d6418..0b1ee800e440 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.h
@@ -79,12 +79,12 @@ public:
: MCInstPrinter(MAI, MII, MRI) {}
// Autogenerated by tblgen.
- void printInstruction(const MCInst *MI, raw_ostream &O);
+ void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
static const char *getRegisterName(unsigned RegNo);
void printRegName(raw_ostream &OS, unsigned RegNo) const override;
- void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot,
- const MCSubtargetInfo &STI) override;
+ void printInst(const MCInst *MI, uint64_t Address, StringRef Annot,
+ const MCSubtargetInfo &STI, raw_ostream &O) override;
bool printAliasInstr(const MCInst *MI, raw_ostream &OS);
void printCustomAliasOperand(const MCInst *MI, unsigned OpIdx,
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
index ec78158d387d..5182205edaea 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
@@ -11,25 +11,27 @@
//===----------------------------------------------------------------------===//
#include "MipsMCAsmInfo.h"
+#include "MipsABIInfo.h"
#include "llvm/ADT/Triple.h"
using namespace llvm;
void MipsMCAsmInfo::anchor() { }
-MipsMCAsmInfo::MipsMCAsmInfo(const Triple &TheTriple) {
+MipsMCAsmInfo::MipsMCAsmInfo(const Triple &TheTriple,
+ const MCTargetOptions &Options) {
IsLittleEndian = TheTriple.isLittleEndian();
- if (TheTriple.isMIPS64() && TheTriple.getEnvironment() != Triple::GNUABIN32)
+ MipsABIInfo ABI = MipsABIInfo::computeTargetABI(TheTriple, "", Options);
+
+ if (TheTriple.isMIPS64() && !ABI.IsN32())
CodePointerSize = CalleeSaveStackSlotSize = 8;
- // FIXME: This condition isn't quite right but it's the best we can do until
- // this object can identify the ABI. It will misbehave when using O32
- // on a mips64*-* triple.
- if (TheTriple.isMIPS32()) {
+ if (ABI.IsO32())
PrivateGlobalPrefix = "$";
- PrivateLabelPrefix = "$";
- }
+ else if (ABI.IsN32() || ABI.IsN64())
+ PrivateGlobalPrefix = ".L";
+ PrivateLabelPrefix = PrivateGlobalPrefix;
AlignmentIsInBytes = false;
Data16bitsDirective = "\t.2byte\t";
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h
index 867f4d223de4..d8bfe58d24a8 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h
@@ -22,7 +22,8 @@ class MipsMCAsmInfo : public MCAsmInfoELF {
void anchor() override;
public:
- explicit MipsMCAsmInfo(const Triple &TheTriple);
+ explicit MipsMCAsmInfo(const Triple &TheTriple,
+ const MCTargetOptions &Options);
};
} // namespace llvm
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
index 142e9cebb79e..846f508005f5 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
@@ -600,7 +600,8 @@ getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
}
if (Kind == MCExpr::Binary) {
- unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI);
+ unsigned Res =
+ getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI);
Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI);
return Res;
}
@@ -729,7 +730,8 @@ getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
default: llvm_unreachable("Unknown fixup kind!");
break;
case MCSymbolRefExpr::VK_None:
- FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64.
+ // FIXME: This is ok for O32/N32 but not N64.
+ FixupKind = Mips::fixup_Mips_32;
break;
} // switch
@@ -768,7 +770,8 @@ unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
const MCSubtargetInfo &STI) const {
// Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
assert(MI.getOperand(OpNo).isReg());
- unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
+ unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI)
+ << 16;
unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
// Apply the scale factor if there is one.
@@ -857,7 +860,8 @@ getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo,
assert(MI.getOperand(OpNo).isReg());
unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
STI) << 16;
- unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI);
+ unsigned OffBits =
+ getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI);
return (OffBits & 0x1FF) | RegBits;
}
@@ -892,7 +896,8 @@ getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
// Base register is encoded in bits 20-16, offset is encoded in bits 11-0.
assert(MI.getOperand(OpNo).isReg());
- unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16;
+ unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI)
+ << 16;
unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
return (OffBits & 0x0FFF) | RegBits;
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp
index 680806c4deb2..a25783b5cf04 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp
@@ -211,7 +211,8 @@ MipsMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
// The value of getKind() that is given to MCValue is only intended to aid
// debugging when inspecting MCValue objects. It shouldn't be relied upon
// for decision making.
- Res = MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind());
+ Res =
+ MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind());
return true;
}
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
index 79c47d1b6508..de582bd60cbf 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
@@ -12,6 +12,7 @@
#include "MipsMCTargetDesc.h"
#include "MipsAsmBackend.h"
+#include "MipsBaseInfo.h"
#include "MipsELFStreamer.h"
#include "MipsInstPrinter.h"
#include "MipsMCAsmInfo.h"
@@ -44,7 +45,6 @@ using namespace llvm;
#include "MipsGenRegisterInfo.inc"
/// Select the Mips CPU for the given triple and cpu name.
-/// FIXME: Merge with the copy in MipsSubtarget.cpp
StringRef MIPS_MC::selectMipsCPU(const Triple &TT, StringRef CPU) {
if (CPU.empty() || CPU == "generic") {
if (TT.getSubArch() == llvm::Triple::MipsSubArch_r6) {
@@ -81,8 +81,9 @@ static MCSubtargetInfo *createMipsMCSubtargetInfo(const Triple &TT,
}
static MCAsmInfo *createMipsMCAsmInfo(const MCRegisterInfo &MRI,
- const Triple &TT) {
- MCAsmInfo *MAI = new MipsMCAsmInfo(TT);
+ const Triple &TT,
+ const MCTargetOptions &Options) {
+ MCAsmInfo *MAI = new MipsMCAsmInfo(TT, Options);
unsigned SP = MRI.getDwarfRegNum(Mips::SP, true);
MCCFIInstruction Inst = MCCFIInstruction::createDefCfaRegister(nullptr, SP);
@@ -165,7 +166,7 @@ static MCInstrAnalysis *createMipsMCInstrAnalysis(const MCInstrInfo *Info) {
return new MipsMCInstrAnalysis(Info);
}
-extern "C" void LLVMInitializeMipsTargetMC() {
+extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsTargetMC() {
for (Target *T : {&getTheMipsTarget(), &getTheMipselTarget(),
&getTheMips64Target(), &getTheMips64elTarget()}) {
// Register the MC asm info.
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp
index 2d53750ad0ee..0544758f8a25 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp
@@ -154,8 +154,8 @@ public:
}
// Sandbox loads, stores and SP changes.
- unsigned AddrIdx;
- bool IsStore;
+ unsigned AddrIdx = 0;
+ bool IsStore = false;
bool IsMemAccess = isBasePlusOffsetMemoryAccess(Inst.getOpcode(), &AddrIdx,
&IsStore);
bool IsSPFirstOperand = isStackPointerFirstOperand(Inst);
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp
index 3ff9c722484b..bdfb70aa9813 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp
@@ -74,27 +74,23 @@ void MipsRegInfoRecord::SetPhysRegUsed(unsigned Reg,
const MCRegisterInfo *MCRegInfo) {
unsigned Value = 0;
- for (MCSubRegIterator SubRegIt(Reg, MCRegInfo, true); SubRegIt.isValid();
- ++SubRegIt) {
- unsigned CurrentSubReg = *SubRegIt;
-
- unsigned EncVal = MCRegInfo->getEncodingValue(CurrentSubReg);
+ for (const MCPhysReg &SubReg : MCRegInfo->subregs_inclusive(Reg)) {
+ unsigned EncVal = MCRegInfo->getEncodingValue(SubReg);
Value |= 1 << EncVal;
- if (GPR32RegClass->contains(CurrentSubReg) ||
- GPR64RegClass->contains(CurrentSubReg))
+ if (GPR32RegClass->contains(SubReg) || GPR64RegClass->contains(SubReg))
ri_gprmask |= Value;
- else if (COP0RegClass->contains(CurrentSubReg))
+ else if (COP0RegClass->contains(SubReg))
ri_cprmask[0] |= Value;
// MIPS COP1 is the FPU.
- else if (FGR32RegClass->contains(CurrentSubReg) ||
- FGR64RegClass->contains(CurrentSubReg) ||
- AFGR64RegClass->contains(CurrentSubReg) ||
- MSA128BRegClass->contains(CurrentSubReg))
+ else if (FGR32RegClass->contains(SubReg) ||
+ FGR64RegClass->contains(SubReg) ||
+ AFGR64RegClass->contains(SubReg) ||
+ MSA128BRegClass->contains(SubReg))
ri_cprmask[1] |= Value;
- else if (COP2RegClass->contains(CurrentSubReg))
+ else if (COP2RegClass->contains(SubReg))
ri_cprmask[2] |= Value;
- else if (COP3RegClass->contains(CurrentSubReg))
+ else if (COP3RegClass->contains(SubReg))
ri_cprmask[3] |= Value;
}
}
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
index b6dae9f6dea8..054dc79f4aa9 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
@@ -34,11 +34,6 @@ static cl::opt<bool> RoundSectionSizes(
cl::desc("Round section sizes up to the section alignment"), cl::Hidden);
} // end anonymous namespace
-static bool isMipsR6(const MCSubtargetInfo *STI) {
- return STI->getFeatureBits()[Mips::FeatureMips32r6] ||
- STI->getFeatureBits()[Mips::FeatureMips64r6];
-}
-
static bool isMicroMips(const MCSubtargetInfo *STI) {
return STI->getFeatureBits()[Mips::FeatureMicroMips];
}
@@ -332,36 +327,6 @@ void MipsTargetStreamer::emitStoreWithImmOffset(
emitRRI(Opcode, SrcReg, ATReg, LoOffset, IDLoc, STI);
}
-/// Emit a store instruction with an symbol offset.
-void MipsTargetStreamer::emitSCWithSymOffset(unsigned Opcode, unsigned SrcReg,
- unsigned BaseReg,
- MCOperand &HiOperand,
- MCOperand &LoOperand,
- unsigned ATReg, SMLoc IDLoc,
- const MCSubtargetInfo *STI) {
- // sc $8, sym => lui $at, %hi(sym)
- // sc $8, %lo(sym)($at)
-
- // Generate the base address in ATReg.
- emitRX(Mips::LUi, ATReg, HiOperand, IDLoc, STI);
- if (!isMicroMips(STI) && isMipsR6(STI)) {
- // For non-micromips r6 offset for 'sc' is not in the lower 16 bits so we
- // put it in 'at'.
- // sc $8, sym => lui $at, %hi(sym)
- // addiu $at, $at, %lo(sym)
- // sc $8, 0($at)
- emitRRX(Mips::ADDiu, ATReg, ATReg, LoOperand, IDLoc, STI);
- MCOperand Offset = MCOperand::createImm(0);
- // Emit the store with the adjusted base and offset.
- emitRRRX(Opcode, SrcReg, SrcReg, ATReg, Offset, IDLoc, STI);
- } else {
- if (BaseReg != Mips::ZERO)
- emitRRR(Mips::ADDu, ATReg, ATReg, BaseReg, IDLoc, STI);
- // Emit the store with the adjusted base and offset.
- emitRRRX(Opcode, SrcReg, SrcReg, ATReg, LoOperand, IDLoc, STI);
- }
-}
-
/// Emit a load instruction with an immediate offset. DstReg and TmpReg are
/// permitted to be the same register iff DstReg is distinct from BaseReg and
/// DstReg is a GPR. It is the callers responsibility to identify such cases
diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrFormats.td b/llvm/lib/Target/Mips/MicroMips32r6InstrFormats.td
index dbff0f6200f2..da8a06b0cff8 100644
--- a/llvm/lib/Target/Mips/MicroMips32r6InstrFormats.td
+++ b/llvm/lib/Target/Mips/MicroMips32r6InstrFormats.td
@@ -234,7 +234,8 @@ class POOL32A_FM_MMR6<bits<10> funct> : MipsR6Inst {
let Inst{9-0} = funct;
}
-class POOL32A_PAUSE_FM_MMR6<string instr_asm, bits<5> op> : MMR6Arch<instr_asm> {
+class POOL32A_PAUSE_FM_MMR6<string instr_asm, bits<5> op>
+ : MMR6Arch<instr_asm> {
bits<32> Inst;
let Inst{31-26} = 0;
@@ -512,7 +513,8 @@ class BARRIER_MMR6_ENC<string instr_asm, bits<5> op> : MMR6Arch<instr_asm> {
class POOL32A_EIDI_MMR6_ENC<string instr_asm, bits<10> funct>
: MMR6Arch<instr_asm> {
bits<32> Inst;
- bits<5> rt; // Actually rs but we're sharing code with the standard encodings which call it rt
+ bits<5> rt; // Actually rs but we're sharing code with the standard encodings
+ // which call it rt
let Inst{31-26} = 0x00;
let Inst{25-21} = 0x00;
@@ -521,7 +523,8 @@ class POOL32A_EIDI_MMR6_ENC<string instr_asm, bits<10> funct>
let Inst{5-0} = 0x3c;
}
-class SHIFT_MMR6_ENC<string instr_asm, bits<10> funct, bit rotate> : MMR6Arch<instr_asm> {
+class SHIFT_MMR6_ENC<string instr_asm, bits<10> funct, bit rotate>
+ : MMR6Arch<instr_asm> {
bits<5> rd;
bits<5> rt;
bits<5> shamt;
@@ -809,8 +812,8 @@ class POOL32F_RECIP_ROUND_FM_MMR6<string instr_asm, bits<1> fmt, bits<8> funct>
let Inst{5-0} = 0b111011;
}
-class POOL32F_RINT_FM_MMR6<string instr_asm, bits<2> fmt>
- : MMR6Arch<instr_asm>, MipsR6Inst {
+class POOL32F_RINT_FM_MMR6<string instr_asm, bits<2> fmt> : MMR6Arch<instr_asm>,
+ MipsR6Inst {
bits<5> fs;
bits<5> fd;
@@ -1012,8 +1015,8 @@ class POOL32B_LDWC2_SDWC2_FM_MMR6<string instr_asm, bits<4> funct>
}
class POOL32C_LL_E_SC_E_FM_MMR6<string instr_asm, bits<4> majorFunc,
- bits<3> minorFunc>
- : MMR6Arch<instr_asm>, MipsR6Inst {
+ bits<3> minorFunc> : MMR6Arch<instr_asm>,
+ MipsR6Inst {
bits<5> rt;
bits<21> addr;
bits<5> base = addr{20-16};
diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
index 425773dc57f1..832124cb3f57 100644
--- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
@@ -341,7 +341,8 @@ class BNEC_MMR6_DESC : CMP_CBR_2R_MMR6_DESC_BASE<"bnec", brtarget_lsl2_mm,
GPR32Opnd>;
class ADD_MMR6_DESC : ArithLogicR<"add", GPR32Opnd, 1, II_ADD>;
-class ADDIU_MMR6_DESC : ArithLogicI<"addiu", simm16, GPR32Opnd, II_ADDIU, immSExt16, add>;
+class ADDIU_MMR6_DESC
+ : ArithLogicI<"addiu", simm16, GPR32Opnd, II_ADDIU, immSExt16, add>;
class ADDU_MMR6_DESC : ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU>;
class MUL_MMR6_DESC : ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>;
class MUH_MMR6_DESC : ArithLogicR<"muh", GPR32Opnd, 1, II_MUH, mulhs>;
@@ -1045,8 +1046,8 @@ class TRUNC_W_D_MMR6_DESC : ABSS_FT_MMR6_DESC_BASE<"trunc.w.d", FGR32Opnd,
FGR64Opnd, II_TRUNC>;
class SQRT_S_MMR6_DESC : ABSS_FT_MMR6_DESC_BASE<"sqrt.s", FGR32Opnd, FGR32Opnd,
II_SQRT_S, fsqrt>;
-class SQRT_D_MMR6_DESC : ABSS_FT_MMR6_DESC_BASE<"sqrt.d", AFGR64Opnd, AFGR64Opnd,
- II_SQRT_D, fsqrt>;
+class SQRT_D_MMR6_DESC : ABSS_FT_MMR6_DESC_BASE<"sqrt.d", AFGR64Opnd,
+ AFGR64Opnd, II_SQRT_D, fsqrt>;
class ROUND_L_S_MMR6_DESC : ABSS_FT_MMR6_DESC_BASE<"round.l.s", FGR64Opnd,
FGR32Opnd, II_ROUND>;
class ROUND_L_D_MMR6_DESC : ABSS_FT_MMR6_DESC_BASE<"round.l.d", FGR64Opnd,
@@ -1101,14 +1102,16 @@ class SLL16_MMR6_DESC : ShiftIMM16<"sll16", uimm3_shift, GPRMM16Opnd, II_SLL>,
MMR6Arch<"sll16">;
class SRL16_MMR6_DESC : ShiftIMM16<"srl16", uimm3_shift, GPRMM16Opnd, II_SRL>,
MMR6Arch<"srl16">;
-class BREAK16_MMR6_DESC : BrkSdbbp16MM<"break16", II_BREAK>, MMR6Arch<"break16">;
+class BREAK16_MMR6_DESC : BrkSdbbp16MM<"break16", II_BREAK>,
+ MMR6Arch<"break16">;
class LI16_MMR6_DESC : LoadImmMM16<"li16", li16_imm, GPRMM16Opnd>,
MMR6Arch<"li16">, IsAsCheapAsAMove;
class MOVE16_MMR6_DESC : MoveMM16<"move16", GPR32Opnd>, MMR6Arch<"move16">;
class MOVEP_MMR6_DESC : MovePMM16<"movep", GPRMM16OpndMovePPairFirst,
GPRMM16OpndMovePPairSecond, GPRMM16OpndMoveP>,
MMR6Arch<"movep">;
-class SDBBP16_MMR6_DESC : BrkSdbbp16MM<"sdbbp16", II_SDBBP>, MMR6Arch<"sdbbp16">;
+class SDBBP16_MMR6_DESC : BrkSdbbp16MM<"sdbbp16", II_SDBBP>,
+ MMR6Arch<"sdbbp16">;
class SUBU16_MMR6_DESC : ArithRMM16<"subu16", GPRMM16Opnd, 0, II_SUBU, sub>,
MMR6Arch<"subu16"> {
int AddedComplexity = 1;
@@ -1439,7 +1442,8 @@ def SYNCI_MMR6 : StdMMR6Rel, SYNCI_MMR6_DESC, SYNCI_MMR6_ENC, ISA_MICROMIPS32R6;
def RDPGPR_MMR6 : R6MMR6Rel, RDPGPR_MMR6_DESC, RDPGPR_MMR6_ENC,
ISA_MICROMIPS32R6;
def SDBBP_MMR6 : R6MMR6Rel, SDBBP_MMR6_DESC, SDBBP_MMR6_ENC, ISA_MICROMIPS32R6;
-def SIGRIE_MMR6 : R6MMR6Rel, SIGRIE_MMR6_DESC, SIGRIE_MMR6_ENC, ISA_MICROMIPS32R6;
+def SIGRIE_MMR6 : R6MMR6Rel, SIGRIE_MMR6_DESC, SIGRIE_MMR6_ENC,
+ ISA_MICROMIPS32R6;
def XOR_MMR6 : StdMMR6Rel, XOR_MMR6_DESC, XOR_MMR6_ENC, ISA_MICROMIPS32R6;
def XORI_MMR6 : StdMMR6Rel, XORI_MMR6_DESC, XORI_MMR6_ENC, ISA_MICROMIPS32R6;
let DecoderMethod = "DecodeMemMMImm16" in {
@@ -1557,7 +1561,8 @@ def INS_MMR6 : StdMMR6Rel, INS_MMR6_ENC, INS_MMR6_DESC, ISA_MICROMIPS32R6;
def JALRC_MMR6 : R6MMR6Rel, JALRC_MMR6_ENC, JALRC_MMR6_DESC, ISA_MICROMIPS32R6;
def RINT_S_MMR6 : StdMMR6Rel, RINT_S_MMR6_ENC, RINT_S_MMR6_DESC,
ISA_MICROMIPS32R6;
-def RINT_D_MMR6 : StdMMR6Rel, RINT_D_MMR6_ENC, RINT_D_MMR6_DESC, ISA_MICROMIPS32R6;
+def RINT_D_MMR6 : StdMMR6Rel, RINT_D_MMR6_ENC, RINT_D_MMR6_DESC,
+ ISA_MICROMIPS32R6;
def ROUND_L_S_MMR6 : StdMMR6Rel, ROUND_L_S_MMR6_ENC, ROUND_L_S_MMR6_DESC,
ISA_MICROMIPS32R6;
def ROUND_L_D_MMR6 : StdMMR6Rel, ROUND_L_D_MMR6_ENC, ROUND_L_D_MMR6_DESC,
@@ -1751,7 +1756,8 @@ defm S_MMR6 : Cmp_Pats<f32, NOR_MMR6, ZERO>, ISA_MICROMIPS32R6;
defm D_MMR6 : Cmp_Pats<f64, NOR_MMR6, ZERO>, ISA_MICROMIPS32R6;
def : MipsPat<(f32 fpimm0), (MTC1_MMR6 ZERO)>, ISA_MICROMIPS32R6;
-def : MipsPat<(f32 fpimm0neg), (FNEG_S_MMR6 (MTC1_MMR6 ZERO))>, ISA_MICROMIPS32R6;
+def : MipsPat<(f32 fpimm0neg), (FNEG_S_MMR6(MTC1_MMR6 ZERO))>,
+ ISA_MICROMIPS32R6;
def : MipsPat<(MipsTruncIntFP FGR64Opnd:$src),
(TRUNC_W_D_MMR6 FGR64Opnd:$src)>, ISA_MICROMIPS32R6;
def : MipsPat<(MipsTruncIntFP FGR32Opnd:$src),
diff --git a/llvm/lib/Target/Mips/MicroMipsInstrFPU.td b/llvm/lib/Target/Mips/MicroMipsInstrFPU.td
index 5d87068ff407..eea4d7746fa6 100644
--- a/llvm/lib/Target/Mips/MicroMipsInstrFPU.td
+++ b/llvm/lib/Target/Mips/MicroMipsInstrFPU.td
@@ -230,7 +230,8 @@ let DecoderNamespace = "MicroMips" in {
def FSQRT_S_MM : MMRel, ABSS_FT<"sqrt.s", FGR32Opnd, FGR32Opnd, II_SQRT_S,
fsqrt>, ROUND_W_FM_MM<0, 0x28>, ISA_MICROMIPS;
- def MTHC1_D32_MM : MMRel, MTC1_64_FT<"mthc1", AFGR64Opnd, GPR32Opnd, II_MTHC1>,
+ def MTHC1_D32_MM : MMRel,
+ MTC1_64_FT<"mthc1", AFGR64Opnd, GPR32Opnd, II_MTHC1>,
MFC1_FM_MM<0xe0>, ISA_MICROMIPS, FGR_32;
def MFHC1_D32_MM : MMRel, MFC1_FT<"mfhc1", GPR32Opnd, AFGR64Opnd, II_MFHC1>,
MFC1_FM_MM<0xc0>, ISA_MICROMIPS, FGR_32;
diff --git a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td
index 8cc0029fc896..b707f1b96184 100644
--- a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td
+++ b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td
@@ -116,7 +116,7 @@ def mem_mm_9 : Operand<i32> {
let PrintMethod = "printMemOperand";
let MIOperandInfo = (ops ptr_rc, simm9);
let EncoderMethod = "getMemEncodingMMImm9";
- let ParserMatchClass = MipsMemSimm9AsmOperand;
+ let ParserMatchClass = MipsMemSimmAsmOperand<9>;
let OperandType = "OPERAND_MEMORY";
}
@@ -124,7 +124,7 @@ def mem_mm_11 : Operand<i32> {
let PrintMethod = "printMemOperand";
let MIOperandInfo = (ops GPR32, simm11);
let EncoderMethod = "getMemEncodingMMImm11";
- let ParserMatchClass = MipsMemSimm11AsmOperand;
+ let ParserMatchClass = MipsMemSimmAsmOperand<11>;
let OperandType = "OPERAND_MEMORY";
}
@@ -141,7 +141,7 @@ def mem_mm_16 : Operand<i32> {
let MIOperandInfo = (ops ptr_rc, simm16);
let EncoderMethod = "getMemEncodingMMImm16";
let DecoderMethod = "DecodeMemMMImm16";
- let ParserMatchClass = MipsMemSimm16AsmOperand;
+ let ParserMatchClass = MipsMemSimmAsmOperand<16>;
let OperandType = "OPERAND_MEMORY";
}
@@ -506,7 +506,8 @@ class LoadWordIndexedScaledMM<string opstr, RegisterOperand RO,
class PrefetchIndexed<string opstr> :
InstSE<(outs), (ins PtrRC:$base, PtrRC:$index, uimm5:$hint),
- !strconcat(opstr, "\t$hint, ${index}(${base})"), [], II_PREF, FrmOther>;
+ !strconcat(opstr, "\t$hint, ${index}(${base})"),
+ [], II_PREF, FrmOther>;
class AddImmUPC<string opstr, RegisterOperand RO> :
InstSE<(outs RO:$rs), (ins simm23_lsl2:$imm),
diff --git a/llvm/lib/Target/Mips/Mips.td b/llvm/lib/Target/Mips/Mips.td
index a5908362e81f..b8a69815cc12 100644
--- a/llvm/lib/Target/Mips/Mips.td
+++ b/llvm/lib/Target/Mips/Mips.td
@@ -192,17 +192,22 @@ def FeatureGINV : SubtargetFeature<"ginv", "HasGINV", "true",
def FeatureMicroMips : SubtargetFeature<"micromips", "InMicroMipsMode", "true",
"microMips mode">;
-def FeatureCnMips : SubtargetFeature<"cnmips", "HasCnMips",
- "true", "Octeon cnMIPS Support",
- [FeatureMips64r2]>;
+def FeatureCnMips : SubtargetFeature<"cnmips", "HasCnMips",
+ "true", "Octeon cnMIPS Support",
+ [FeatureMips64r2]>;
+
+def FeatureCnMipsP : SubtargetFeature<"cnmipsp", "HasCnMipsP",
+ "true", "Octeon+ cnMIPS Support",
+ [FeatureCnMips]>;
def FeatureUseTCCInDIV : SubtargetFeature<
"use-tcc-in-div",
"UseTCCInDIV", "false",
"Force the assembler to use trapping">;
-def FeatureMadd4 : SubtargetFeature<"nomadd4", "DisableMadd4", "true",
- "Disable 4-operand madd.fmt and related instructions">;
+def FeatureMadd4
+ : SubtargetFeature<"nomadd4", "DisableMadd4", "true",
+ "Disable 4-operand madd.fmt and related instructions">;
def FeatureMT : SubtargetFeature<"mt", "HasMT", "true", "Mips MT ASE">;
@@ -227,6 +232,7 @@ def ImplP5600 : SubtargetFeature<"p5600", "ProcImpl",
class Proc<string Name, list<SubtargetFeature> Features>
: ProcessorModel<Name, MipsGenericModel, Features>;
+def : Proc<"generic", [FeatureMips32]>;
def : Proc<"mips1", [FeatureMips1]>;
def : Proc<"mips2", [FeatureMips2]>;
def : Proc<"mips32", [FeatureMips32]>;
@@ -244,6 +250,7 @@ def : Proc<"mips64r3", [FeatureMips64r3]>;
def : Proc<"mips64r5", [FeatureMips64r5]>;
def : Proc<"mips64r6", [FeatureMips64r6]>;
def : Proc<"octeon", [FeatureMips64r2, FeatureCnMips]>;
+def : Proc<"octeon+", [FeatureMips64r2, FeatureCnMips, FeatureCnMipsP]>;
def : ProcessorModel<"p5600", MipsP5600Model, [ImplP5600]>;
def MipsAsmParser : AsmParser {
diff --git a/llvm/lib/Target/Mips/Mips16ISelLowering.cpp b/llvm/lib/Target/Mips/Mips16ISelLowering.cpp
index 5a5b78c9d5f9..5425df77d9b8 100644
--- a/llvm/lib/Target/Mips/Mips16ISelLowering.cpp
+++ b/llvm/lib/Target/Mips/Mips16ISelLowering.cpp
@@ -252,9 +252,6 @@ void Mips16TargetLowering::setMips16HardFloatLibCalls() {
if (HardFloatLibCalls[I].Libcall != RTLIB::UNKNOWN_LIBCALL)
setLibcallName(HardFloatLibCalls[I].Libcall, HardFloatLibCalls[I].Name);
}
-
- setLibcallName(RTLIB::O_F64, "__mips16_unorddf2");
- setLibcallName(RTLIB::O_F32, "__mips16_unordsf2");
}
//
diff --git a/llvm/lib/Target/Mips/Mips16InstrInfo.cpp b/llvm/lib/Target/Mips/Mips16InstrInfo.cpp
index 0d735c20ec2f..d2a1ba39cb0e 100644
--- a/llvm/lib/Target/Mips/Mips16InstrInfo.cpp
+++ b/llvm/lib/Target/Mips/Mips16InstrInfo.cpp
@@ -68,8 +68,8 @@ unsigned Mips16InstrInfo::isStoreToStackSlot(const MachineInstr &MI,
void Mips16InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
- const DebugLoc &DL, unsigned DestReg,
- unsigned SrcReg, bool KillSrc) const {
+ const DebugLoc &DL, MCRegister DestReg,
+ MCRegister SrcReg, bool KillSrc) const {
unsigned Opc = 0;
if (Mips::CPU16RegsRegClass.contains(DestReg) &&
@@ -96,15 +96,11 @@ void Mips16InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MIB.addReg(SrcReg, getKillRegState(KillSrc));
}
-bool Mips16InstrInfo::isCopyInstrImpl(const MachineInstr &MI,
- const MachineOperand *&Src,
- const MachineOperand *&Dest) const {
- if (MI.isMoveReg()) {
- Dest = &MI.getOperand(0);
- Src = &MI.getOperand(1);
- return true;
- }
- return false;
+Optional<DestSourcePair>
+Mips16InstrInfo::isCopyInstrImpl(const MachineInstr &MI) const {
+ if (MI.isMoveReg())
+ return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
+ return None;
}
void Mips16InstrInfo::storeRegToStack(MachineBasicBlock &MBB,
@@ -418,8 +414,9 @@ unsigned Mips16InstrInfo::loadImmediate(unsigned FrameReg, int64_t Imm,
else
Available.reset(SpReg);
copyPhysReg(MBB, II, DL, SpReg, Mips::SP, false);
- BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(SpReg, RegState::Kill)
- .addReg(Reg);
+ BuildMI(MBB, II, DL, get(Mips::AdduRxRyRz16), Reg)
+ .addReg(SpReg, RegState::Kill)
+ .addReg(Reg);
}
else
BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(FrameReg)
diff --git a/llvm/lib/Target/Mips/Mips16InstrInfo.h b/llvm/lib/Target/Mips/Mips16InstrInfo.h
index dadcaa3055b3..2ff849cb2ca2 100644
--- a/llvm/lib/Target/Mips/Mips16InstrInfo.h
+++ b/llvm/lib/Target/Mips/Mips16InstrInfo.h
@@ -49,7 +49,7 @@ public:
int &FrameIndex) const override;
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
- const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
+ const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg,
bool KillSrc) const override;
void storeRegToStack(MachineBasicBlock &MBB,
@@ -104,10 +104,9 @@ public:
protected:
/// If the specific machine instruction is a instruction that moves/copies
- /// value from one register to another register return true along with
- /// @Source machine operand and @Destination machine operand.
- bool isCopyInstrImpl(const MachineInstr &MI, const MachineOperand *&Source,
- const MachineOperand *&Destination) const override;
+ /// value from one register to another register return destination and source
+ /// registers as machine operands.
+ Optional<DestSourcePair> isCopyInstrImpl(const MachineInstr &MI) const override;
private:
unsigned getAnalyzableBrOpc(unsigned Opc) const override;
diff --git a/llvm/lib/Target/Mips/Mips16InstrInfo.td b/llvm/lib/Target/Mips/Mips16InstrInfo.td
index 36b6c73d1008..19ea50c89b96 100644
--- a/llvm/lib/Target/Mips/Mips16InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips16InstrInfo.td
@@ -67,7 +67,7 @@ class FI816_ins_base<bits<3> _func, string asmstr,
class FI816_ins<bits<3> _func, string asmstr,
InstrItinClass itin>:
FI816_ins_base<_func, asmstr, "\t$imm # 16 bit inst", itin>;
-
+
class FI816_SP_ins<bits<3> _func, string asmstr,
InstrItinClass itin>:
FI816_ins_base<_func, asmstr, "\t$$sp, $imm # 16 bit inst", itin>;
@@ -90,7 +90,7 @@ class FRI16_TCP_ins<bits<5> _op, string asmstr,
InstrItinClass itin>:
FRI16<_op, (outs CPU16Regs:$rx), (ins pcrel16:$imm, i32imm:$size),
!strconcat(asmstr, "\t$rx, $imm\t# 16 bit inst"), [], itin>;
-
+
class FRI16R_ins_base<bits<5> op, string asmstr, string asmstr2,
InstrItinClass itin>:
FRI16<op, (outs), (ins CPU16Regs:$rx, simm16:$imm),
@@ -983,7 +983,7 @@ def RestoreX16:
// To set up a stack frame on entry to a subroutine,
// saving return address and static registers, and adjusting stack
//
-def Save16:
+def Save16:
FI8_SVRS16<0b1, (outs), (ins variable_ops),
"", [], II_SAVE >, MayStore {
let isCodeGenOnly = 1;
@@ -1883,7 +1883,7 @@ def : Mips16Pat<(sext_inreg CPU16Regs:$val, i8),
def : Mips16Pat<(sext_inreg CPU16Regs:$val, i16),
(SehRx16 CPU16Regs:$val)>;
-def GotPrologue16:
+def GotPrologue16:
MipsPseudo16<
(outs CPU16Regs:$rh, CPU16Regs:$rl),
(ins simm16:$immHi, simm16:$immLo),
diff --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
index 2c3048411a5c..9607d008bc97 100644
--- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
@@ -765,12 +765,12 @@ class LL_R6_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
InstrItinClass Itinerary = itin;
}
-class LL_R6_DESC : LL_R6_DESC_BASE<"ll", GPR32Opnd, mem_simm9, II_LL>;
+class LL_R6_DESC : LL_R6_DESC_BASE<"ll", GPR32Opnd, mem_simm9_exp, II_LL>;
class SC_R6_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
InstrItinClass itin> {
dag OutOperandList = (outs GPROpnd:$dst);
- dag InOperandList = (ins GPROpnd:$rt, mem_simm9:$addr);
+ dag InOperandList = (ins GPROpnd:$rt, mem_simm9_exp:$addr);
string AsmString = !strconcat(instr_asm, "\t$rt, $addr");
list<dag> Pattern = [];
bit mayStore = 1;
@@ -996,13 +996,15 @@ def : MipsInstAlias<"evp", (EVP ZERO), 0>, ISA_MIPS32R6;
let AdditionalPredicates = [NotInMicroMips] in {
def : MipsInstAlias<"sdbbp", (SDBBP_R6 0)>, ISA_MIPS32R6;
def : MipsInstAlias<"sigrie", (SIGRIE 0)>, ISA_MIPS32R6;
-def : MipsInstAlias<"jr $rs", (JALR ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS32R6, GPR_32;
+def : MipsInstAlias<"jr $rs", (JALR ZERO, GPR32Opnd:$rs), 1>,
+ ISA_MIPS32R6, GPR_32;
}
def : MipsInstAlias<"jrc $rs", (JIC GPR32Opnd:$rs, 0), 1>, ISA_MIPS32R6, GPR_32;
let AdditionalPredicates = [NotInMicroMips] in {
-def : MipsInstAlias<"jalrc $rs", (JIALC GPR32Opnd:$rs, 0), 1>, ISA_MIPS32R6, GPR_32;
+def : MipsInstAlias<"jalrc $rs", (JIALC GPR32Opnd:$rs, 0), 1>,
+ ISA_MIPS32R6, GPR_32;
}
def : MipsInstAlias<"div $rs, $rt", (DIV GPR32Opnd:$rs, GPR32Opnd:$rs,
diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td
index cc15949b0d57..306289d56e4b 100644
--- a/llvm/lib/Target/Mips/Mips64InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td
@@ -83,6 +83,10 @@ let usesCustomInserter = 1 in {
def ATOMIC_LOAD_NAND_I64 : Atomic2Ops<atomic_load_nand_64, GPR64>;
def ATOMIC_SWAP_I64 : Atomic2Ops<atomic_swap_64, GPR64>;
def ATOMIC_CMP_SWAP_I64 : AtomicCmpSwap<atomic_cmp_swap_64, GPR64>;
+ def ATOMIC_LOAD_MIN_I64 : Atomic2Ops<atomic_load_min_64, GPR64>;
+ def ATOMIC_LOAD_MAX_I64 : Atomic2Ops<atomic_load_max_64, GPR64>;
+ def ATOMIC_LOAD_UMIN_I64 : Atomic2Ops<atomic_load_umin_64, GPR64>;
+ def ATOMIC_LOAD_UMAX_I64 : Atomic2Ops<atomic_load_umax_64, GPR64>;
}
def ATOMIC_LOAD_ADD_I64_POSTRA : Atomic2OpsPostRA<GPR64>;
@@ -96,6 +100,11 @@ def ATOMIC_SWAP_I64_POSTRA : Atomic2OpsPostRA<GPR64>;
def ATOMIC_CMP_SWAP_I64_POSTRA : AtomicCmpSwapPostRA<GPR64>;
+def ATOMIC_LOAD_MIN_I64_POSTRA : Atomic2OpsPostRA<GPR64>;
+def ATOMIC_LOAD_MAX_I64_POSTRA : Atomic2OpsPostRA<GPR64>;
+def ATOMIC_LOAD_UMIN_I64_POSTRA : Atomic2OpsPostRA<GPR64>;
+def ATOMIC_LOAD_UMAX_I64_POSTRA : Atomic2OpsPostRA<GPR64>;
+
/// Pseudo instructions for loading and storing accumulator registers.
let isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
def LOAD_ACC128 : Load<"", ACC128>;
@@ -395,11 +404,11 @@ let AdditionalPredicates = [NotInMicroMips] in {
}
let isCodeGenOnly = 1, AdditionalPredicates = [NotInMicroMips] in {
- def DEXT64_32 : InstSE<(outs GPR64Opnd:$rt),
- (ins GPR32Opnd:$rs, uimm5_report_uimm6:$pos,
- uimm5_plus1:$size),
- "dext $rt, $rs, $pos, $size", [], II_EXT, FrmR, "dext">,
- EXT_FM<3>, ISA_MIPS64R2;
+ def DEXT64_32
+ : InstSE<(outs GPR64Opnd:$rt),
+ (ins GPR32Opnd:$rs, uimm5_report_uimm6:$pos, uimm5_plus1:$size),
+ "dext $rt, $rs, $pos, $size", [], II_EXT, FrmR, "dext">,
+ EXT_FM<3>, ISA_MIPS64R2;
}
let isCodeGenOnly = 1, rs = 0, shamt = 0 in {
@@ -586,6 +595,24 @@ def DMTC2_OCTEON : MFC2OP<"dmtc2", GPR64Opnd, II_DMTC2>, MFC2OP_FM<0x12, 5>,
ASE_CNMIPS;
}
+// Cavium Octeon+ cnMIPS instructions
+let DecoderNamespace = "CnMipsP",
+ // FIXME: The lack of HasStdEnc is probably a bug
+ EncodingPredicates = []<Predicate> in {
+
+class Saa<string opstr>:
+ InstSE<(outs), (ins GPR64Opnd:$rt, GPR64Opnd:$rs),
+ !strconcat(opstr, "\t$rt, (${rs})"), [], NoItinerary, FrmR, opstr>;
+
+def SAA : Saa<"saa">, SAA_FM<0x18>, ASE_CNMIPSP;
+def SAAD : Saa<"saad">, SAA_FM<0x19>, ASE_CNMIPSP;
+
+def SaaAddr : MipsAsmPseudoInst<(outs), (ins GPR64Opnd:$rt, mem:$addr),
+ "saa\t$rt, $addr">, ASE_CNMIPSP;
+def SaadAddr : MipsAsmPseudoInst<(outs), (ins GPR64Opnd:$rt, mem:$addr),
+ "saad\t$rt, $addr">, ASE_CNMIPSP;
+}
+
}
/// Move between CPU and coprocessor registers
@@ -1027,8 +1054,10 @@ let AdditionalPredicates = [NotInMicroMips] in {
(DMTGC0 COP0Opnd:$rd, GPR64Opnd:$rt, 0), 0>,
ISA_MIPS64R5, ASE_VIRT;
}
-def : MipsInstAlias<"dmfc2 $rt, $rd", (DMFC2 GPR64Opnd:$rt, COP2Opnd:$rd, 0), 0>;
-def : MipsInstAlias<"dmtc2 $rt, $rd", (DMTC2 COP2Opnd:$rd, GPR64Opnd:$rt, 0), 0>;
+def : MipsInstAlias<"dmfc2 $rt, $rd",
+ (DMFC2 GPR64Opnd:$rt, COP2Opnd:$rd, 0), 0>;
+def : MipsInstAlias<"dmtc2 $rt, $rd",
+ (DMTC2 COP2Opnd:$rd, GPR64Opnd:$rt, 0), 0>;
def : MipsInstAlias<"synciobdma", (SYNC 0x2), 0>, ASE_MIPS64_CNMIPS;
def : MipsInstAlias<"syncs", (SYNC 0x6), 0>, ASE_MIPS64_CNMIPS;
diff --git a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td
index d746bb61f824..33132d9ede92 100644
--- a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td
@@ -48,7 +48,8 @@ class CRC32CD_ENC : SPECIAL3_2R_SZ_CRC<3,1>;
//
//===----------------------------------------------------------------------===//
-class AHI_ATI_DESC_BASE<string instr_asm, RegisterOperand GPROpnd, InstrItinClass itin> {
+class AHI_ATI_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
+ InstrItinClass itin> {
dag OutOperandList = (outs GPROpnd:$rs);
dag InOperandList = (ins GPROpnd:$rt, uimm16_altrelaxed:$imm);
string AsmString = !strconcat(instr_asm, "\t$rs, $rt, $imm");
@@ -74,7 +75,7 @@ class DMUL_R6_DESC : MUL_R6_DESC_BASE<"dmul", GPR64Opnd, II_DMUL, mul>;
class DMULU_DESC : MUL_R6_DESC_BASE<"dmulu", GPR64Opnd, II_DMUL>;
class LDPC_DESC : PCREL_DESC_BASE<"ldpc", GPR64Opnd, simm18_lsl3, II_LDPC>;
class LWUPC_DESC : PCREL_DESC_BASE<"lwupc", GPR32Opnd, simm19_lsl2, II_LWUPC>;
-class LLD_R6_DESC : LL_R6_DESC_BASE<"lld", GPR64Opnd, mem_simmptr, II_LLD>;
+class LLD_R6_DESC : LL_R6_DESC_BASE<"lld", GPR64Opnd, mem_simm9_exp, II_LLD>;
class SCD_R6_DESC : SC_R6_DESC_BASE<"scd", GPR64Opnd, II_SCD>;
class SELEQZ64_DESC : SELEQNE_Z_DESC_BASE<"seleqz", GPR64Opnd>;
class SELNEZ64_DESC : SELEQNE_Z_DESC_BASE<"selnez", GPR64Opnd>;
@@ -105,7 +106,7 @@ class JIC64_DESC : JMP_IDX_COMPACT_DESC_BASE<"jic", jmpoffset16, GPR64Opnd,
list<Register> Defs = [AT];
}
-class LL64_R6_DESC : LL_R6_DESC_BASE<"ll", GPR32Opnd, mem_simm9, II_LL>;
+class LL64_R6_DESC : LL_R6_DESC_BASE<"ll", GPR32Opnd, mem_simm9_exp, II_LL>;
class SC64_R6_DESC : SC_R6_DESC_BASE<"sc", GPR32Opnd, II_SC>;
class JR_HB64_R6_DESC : JR_HB_DESC_BASE<"jr.hb", GPR64Opnd> {
diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
index 2201545adc94..8f75336dce5a 100644
--- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -257,6 +257,10 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
if (emitPseudoExpansionLowering(*OutStreamer, &*I))
continue;
+ // Skip the BUNDLE pseudo instruction and lower the contents
+ if (I->isBundle())
+ continue;
+
if (I->getOpcode() == Mips::PseudoReturn ||
I->getOpcode() == Mips::PseudoReturn64 ||
I->getOpcode() == Mips::PseudoIndirectBranch ||
@@ -623,8 +627,10 @@ bool MipsAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
assert(OpNum + 1 < MI->getNumOperands() && "Insufficient operands");
const MachineOperand &BaseMO = MI->getOperand(OpNum);
const MachineOperand &OffsetMO = MI->getOperand(OpNum + 1);
- assert(BaseMO.isReg() && "Unexpected base pointer for inline asm memory operand.");
- assert(OffsetMO.isImm() && "Unexpected offset for inline asm memory operand.");
+ assert(BaseMO.isReg() &&
+ "Unexpected base pointer for inline asm memory operand.");
+ assert(OffsetMO.isImm() &&
+ "Unexpected offset for inline asm memory operand.");
int Offset = OffsetMO.getImm();
// Currently we are expecting either no ExtraCode or 'D','M','L'.
@@ -1300,7 +1306,7 @@ bool MipsAsmPrinter::isLongBranchPseudo(int Opcode) const {
}
// Force static initialization.
-extern "C" void LLVMInitializeMipsAsmPrinter() {
+extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsAsmPrinter() {
RegisterAsmPrinter<MipsAsmPrinter> X(getTheMipsTarget());
RegisterAsmPrinter<MipsAsmPrinter> Y(getTheMipselTarget());
RegisterAsmPrinter<MipsAsmPrinter> A(getTheMips64Target());
diff --git a/llvm/lib/Target/Mips/MipsCallLowering.cpp b/llvm/lib/Target/Mips/MipsCallLowering.cpp
index cad82953af50..6ba15c232867 100644
--- a/llvm/lib/Target/Mips/MipsCallLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsCallLowering.cpp
@@ -299,7 +299,7 @@ Register OutgoingValueHandler::getStackAddress(const CCValAssign &VA,
MIRBuilder.buildConstant(OffsetReg, Offset);
Register AddrReg = MRI.createGenericVirtualRegister(p0);
- MIRBuilder.buildGEP(AddrReg, SPReg, OffsetReg);
+ MIRBuilder.buildPtrAdd(AddrReg, SPReg, OffsetReg);
MachinePointerInfo MPO =
MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
@@ -655,7 +655,8 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
F.getContext());
- CCInfo.AnalyzeCallResult(Ins, TLI.CCAssignFnForReturn(), Info.OrigRet.Ty, Call);
+ CCInfo.AnalyzeCallResult(Ins, TLI.CCAssignFnForReturn(), Info.OrigRet.Ty,
+ Call);
setLocInfo(ArgLocs, Ins);
CallReturnHandler Handler(MIRBuilder, MF.getRegInfo(), MIB);
diff --git a/llvm/lib/Target/Mips/MipsCallingConv.td b/llvm/lib/Target/Mips/MipsCallingConv.td
index 88236d8e9abd..204f11f1107c 100644
--- a/llvm/lib/Target/Mips/MipsCallingConv.td
+++ b/llvm/lib/Target/Mips/MipsCallingConv.td
@@ -139,7 +139,8 @@ def CC_MipsN : CallingConv<[
CCIfType<[i8, i16, i32], CCIfOrigArgWasNotFloat<CCPromoteToType<i64>>>,
// The only i32's we have left are soft-float arguments.
- CCIfSubtarget<"useSoftFloat()", CCIfType<[i32], CCDelegateTo<CC_MipsN_SoftFloat>>>,
+ CCIfSubtarget<"useSoftFloat()", CCIfType<[i32],
+ CCDelegateTo<CC_MipsN_SoftFloat>>>,
// Integer arguments are passed in integer registers.
CCIfType<[i64], CCAssignToRegWithShadow<[A0_64, A1_64, A2_64, A3_64,
diff --git a/llvm/lib/Target/Mips/MipsCondMov.td b/llvm/lib/Target/Mips/MipsCondMov.td
index 5affbcbc2101..e9e09a188bf5 100644
--- a/llvm/lib/Target/Mips/MipsCondMov.td
+++ b/llvm/lib/Target/Mips/MipsCondMov.td
@@ -116,8 +116,8 @@ let AdditionalPredicates = [NotInMicroMips] in {
ADD_FM<0, 0xa>, INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
}
- def MOVN_I_I : MMRel, CMov_I_I_FT<"movn", GPR32Opnd, GPR32Opnd, II_MOVN>,
- ADD_FM<0, 0xb>, INSN_MIPS4_32_NOT_32R6_64R6;
+ def MOVN_I_I : MMRel, CMov_I_I_FT<"movn", GPR32Opnd, GPR32Opnd, II_MOVN>,
+ ADD_FM<0, 0xb>, INSN_MIPS4_32_NOT_32R6_64R6;
let isCodeGenOnly = 1 in {
def MOVN_I_I64 : CMov_I_I_FT<"movn", GPR32Opnd, GPR64Opnd, II_MOVN>,
@@ -226,8 +226,8 @@ let AdditionalPredicates = [NotInMicroMips] in {
GPR_64;
defm : MovnPats<GPR64, GPR32, MOVN_I64_I, XOR64>, INSN_MIPS4_32_NOT_32R6_64R6,
GPR_64;
- defm : MovnPats<GPR64, GPR64, MOVN_I64_I64, XOR64>, INSN_MIPS4_32_NOT_32R6_64R6,
- GPR_64;
+ defm : MovnPats<GPR64, GPR64, MOVN_I64_I64, XOR64>,
+ INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
defm : MovzPats0<GPR32, FGR32, MOVZ_I_S, SLT, SLTu, SLTi, SLTiu>,
INSN_MIPS4_32_NOT_32R6_64R6;
@@ -236,8 +236,8 @@ let AdditionalPredicates = [NotInMicroMips] in {
defm : MovzPats0<GPR64, FGR32, MOVZ_I_S, SLT64, SLTu64, SLTi64, SLTiu64>,
INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
- defm : MovzPats1<GPR64, FGR32, MOVZ_I64_S, XOR64>, INSN_MIPS4_32_NOT_32R6_64R6,
- GPR_64;
+ defm : MovzPats1<GPR64, FGR32, MOVZ_I64_S, XOR64>,
+ INSN_MIPS4_32_NOT_32R6_64R6, GPR_64;
defm : MovnPats<GPR64, FGR32, MOVN_I64_S, XOR64>, INSN_MIPS4_32_NOT_32R6_64R6,
GPR_64;
@@ -258,8 +258,8 @@ let AdditionalPredicates = [NotInMicroMips] in {
INSN_MIPS4_32_NOT_32R6_64R6, FGR_64;
defm : MovnPats<GPR32, FGR64, MOVN_I_D64, XOR>, INSN_MIPS4_32_NOT_32R6_64R6,
FGR_64;
- defm : MovnPats<GPR64, FGR64, MOVN_I64_D64, XOR64>, INSN_MIPS4_32_NOT_32R6_64R6,
- FGR_64;
+ defm : MovnPats<GPR64, FGR64, MOVN_I64_D64, XOR64>,
+ INSN_MIPS4_32_NOT_32R6_64R6, FGR_64;
}
// For targets that don't have conditional-move instructions
// we have to match SELECT nodes with pseudo instructions.
diff --git a/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp b/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp
index f50640521738..1f1a1574443c 100644
--- a/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp
+++ b/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp
@@ -127,9 +127,9 @@ static unsigned int longformBranchOpcode(unsigned int Opcode) {
llvm_unreachable("Unknown branch type");
}
-// FIXME: need to go through this whole constant islands port and check the math
-// for branch ranges and clean this up and make some functions to calculate things
-// that are done many times identically.
+// FIXME: need to go through this whole constant islands port and check
+// the math for branch ranges and clean this up and make some functions
+// to calculate things that are done many times identically.
// Need to refactor some of the code to call this routine.
static unsigned int branchMaxOffsets(unsigned int Opcode) {
unsigned Bits, Scale;
@@ -1519,8 +1519,8 @@ MipsConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {
// we know that RA is saved because we always save it right now.
// this requirement will be relaxed later but we also have an alternate
// way to implement this that I will implement that does not need jal.
- // We should have a way to back out this alignment restriction if we "can" later.
- // but it is not harmful.
+ // We should have a way to back out this alignment restriction
+ // if we "can" later. but it is not harmful.
//
DestBB->setAlignment(Align(4));
Br.MaxDisp = ((1<<24)-1) * 2;
diff --git a/llvm/lib/Target/Mips/MipsDSPInstrInfo.td b/llvm/lib/Target/Mips/MipsDSPInstrInfo.td
index d3e68c014fb7..727d47d06ad4 100644
--- a/llvm/lib/Target/Mips/MipsDSPInstrInfo.td
+++ b/llvm/lib/Target/Mips/MipsDSPInstrInfo.td
@@ -376,7 +376,7 @@ class LX_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
class ADDUH_QB_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
InstrItinClass itin, RegisterOperand ROD,
- RegisterOperand ROS = ROD, RegisterOperand ROT = ROD> {
+ RegisterOperand ROS = ROD, RegisterOperand ROT = ROD> {
dag OutOperandList = (outs ROD:$rd);
dag InOperandList = (ins ROS:$rs, ROT:$rt);
string AsmString = !strconcat(instr_asm, "\t$rd, $rs, $rt");
@@ -386,7 +386,8 @@ class ADDUH_QB_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
}
class APPEND_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
- Operand ImmOp, SDPatternOperator Imm, InstrItinClass itin> {
+ Operand ImmOp, SDPatternOperator Imm,
+ InstrItinClass itin> {
dag OutOperandList = (outs GPR32Opnd:$rt);
dag InOperandList = (ins GPR32Opnd:$rs, ImmOp:$sa, GPR32Opnd:$src);
string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $sa");
@@ -511,7 +512,8 @@ class MFHI_DESC_BASE<string instr_asm, RegisterOperand RO, SDNode OpNode,
bit isMoveReg = 1;
}
-class MTHI_DESC_BASE<string instr_asm, RegisterOperand RO, InstrItinClass itin> {
+class MTHI_DESC_BASE<string instr_asm, RegisterOperand RO,
+ InstrItinClass itin> {
dag OutOperandList = (outs RO:$ac);
dag InOperandList = (ins GPR32Opnd:$rs);
string AsmString = !strconcat(instr_asm, "\t$rs, $ac");
@@ -1304,7 +1306,8 @@ let DecoderNamespace = "MipsDSP", Arch = "dsp",
// Pseudo CMP and PICK instructions.
class PseudoCMP<Instruction RealInst> :
PseudoDSP<(outs DSPCC:$cmp), (ins DSPROpnd:$rs, DSPROpnd:$rt), []>,
- PseudoInstExpansion<(RealInst DSPROpnd:$rs, DSPROpnd:$rt)>, NeverHasSideEffects;
+ PseudoInstExpansion<(RealInst DSPROpnd:$rs, DSPROpnd:$rt)>,
+ NeverHasSideEffects;
class PseudoPICK<Instruction RealInst> :
PseudoDSP<(outs DSPROpnd:$rd), (ins DSPCC:$cmp, DSPROpnd:$rs, DSPROpnd:$rt), []>,
diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
index aa07dac86828..84ff674569cd 100644
--- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
+++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
@@ -91,15 +91,14 @@ enum CompactBranchPolicy {
};
static cl::opt<CompactBranchPolicy> MipsCompactBranchPolicy(
- "mips-compact-branches",cl::Optional,
- cl::init(CB_Optimal),
- cl::desc("MIPS Specific: Compact branch policy."),
- cl::values(
- clEnumValN(CB_Never, "never", "Do not use compact branches if possible."),
- clEnumValN(CB_Optimal, "optimal", "Use compact branches where appropiate (default)."),
- clEnumValN(CB_Always, "always", "Always use compact branches if possible.")
- )
-);
+ "mips-compact-branches", cl::Optional, cl::init(CB_Optimal),
+ cl::desc("MIPS Specific: Compact branch policy."),
+ cl::values(clEnumValN(CB_Never, "never",
+ "Do not use compact branches if possible."),
+ clEnumValN(CB_Optimal, "optimal",
+ "Use compact branches where appropiate (default)."),
+ clEnumValN(CB_Always, "always",
+ "Always use compact branches if possible.")));
namespace {
@@ -417,8 +416,14 @@ bool RegDefsUses::update(const MachineInstr &MI, unsigned Begin, unsigned End) {
for (unsigned I = Begin; I != End; ++I) {
const MachineOperand &MO = MI.getOperand(I);
- if (MO.isReg() && MO.getReg())
- HasHazard |= checkRegDefsUses(NewDefs, NewUses, MO.getReg(), MO.isDef());
+ if (MO.isReg() && MO.getReg()) {
+ if (checkRegDefsUses(NewDefs, NewUses, MO.getReg(), MO.isDef())) {
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found register hazard for operand "
+ << I << ": ";
+ MO.dump());
+ HasHazard = true;
+ }
+ }
}
Defs |= NewDefs;
@@ -613,12 +618,18 @@ bool MipsDelaySlotFiller::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
if (MipsCompactBranchPolicy.getValue() != CB_Always ||
!TII->getEquivalentCompactForm(I)) {
if (searchBackward(MBB, *I)) {
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot"
+ " in backwards search.\n");
Filled = true;
} else if (I->isTerminator()) {
if (searchSuccBBs(MBB, I)) {
Filled = true;
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot"
+ " in successor BB search.\n");
}
} else if (searchForward(MBB, I)) {
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot"
+ " in forwards search.\n");
Filled = true;
}
}
@@ -663,6 +674,8 @@ bool MipsDelaySlotFiller::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
}
// Bundle the NOP to the instruction with the delay slot.
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": could not fill delay slot for ";
+ I->dump());
BuildMI(MBB, std::next(I), I->getDebugLoc(), TII->get(Mips::NOP));
MIBundleBuilder(MBB, I, std::next(I, 2));
++FilledSlots;
@@ -680,13 +693,27 @@ bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin,
for (IterTy I = Begin; I != End;) {
IterTy CurrI = I;
++I;
-
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE ": checking instruction: "; CurrI->dump());
// skip debug value
- if (CurrI->isDebugInstr())
+ if (CurrI->isDebugInstr()) {
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE ": ignoring debug instruction: ";
+ CurrI->dump());
continue;
+ }
+
+ if (CurrI->isBundle()) {
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE ": ignoring BUNDLE instruction: ";
+ CurrI->dump());
+ // However, we still need to update the register def-use information.
+ RegDU.update(*CurrI, 0, CurrI->getNumOperands());
+ continue;
+ }
- if (terminateSearch(*CurrI))
+ if (terminateSearch(*CurrI)) {
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE ": should terminate search: ";
+ CurrI->dump());
break;
+ }
assert((!CurrI->isCall() && !CurrI->isReturn() && !CurrI->isBranch()) &&
"Cannot put calls, returns or branches in delay slot.");
@@ -732,6 +759,9 @@ bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin,
continue;
Filler = CurrI;
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot: ";
+ CurrI->dump());
+
return true;
}
@@ -752,8 +782,11 @@ bool MipsDelaySlotFiller::searchBackward(MachineBasicBlock &MBB,
MachineBasicBlock::iterator SlotI = Slot;
if (!searchRange(MBB, ++SlotI.getReverse(), MBB.rend(), RegDU, MemDU, Slot,
- Filler))
+ Filler)) {
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE ": could not find instruction for delay "
+ "slot using backwards search.\n");
return false;
+ }
MBB.splice(std::next(SlotI), &MBB, Filler.getReverse());
MIBundleBuilder(MBB, SlotI, std::next(SlotI, 2));
@@ -773,8 +806,11 @@ bool MipsDelaySlotFiller::searchForward(MachineBasicBlock &MBB,
RegDU.setCallerSaved(*Slot);
- if (!searchRange(MBB, std::next(Slot), MBB.end(), RegDU, NM, Slot, Filler))
+ if (!searchRange(MBB, std::next(Slot), MBB.end(), RegDU, NM, Slot, Filler)) {
+ LLVM_DEBUG(dbgs() << DEBUG_TYPE ": could not find instruction for delay "
+ "slot using forwards search.\n");
return false;
+ }
MBB.splice(std::next(Slot), &MBB, Filler);
MIBundleBuilder(MBB, Slot, std::next(Slot, 2));
@@ -927,4 +963,6 @@ bool MipsDelaySlotFiller::terminateSearch(const MachineInstr &Candidate) const {
/// createMipsDelaySlotFillerPass - Returns a pass that fills in delay
/// slots in Mips MachineFunctions
-FunctionPass *llvm::createMipsDelaySlotFillerPass() { return new MipsDelaySlotFiller(); }
+FunctionPass *llvm::createMipsDelaySlotFillerPass() {
+ return new MipsDelaySlotFiller();
+}
diff --git a/llvm/lib/Target/Mips/MipsExpandPseudo.cpp b/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
index 00cd284e7094..b1abf4a33717 100644
--- a/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
+++ b/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
@@ -308,7 +308,7 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
DebugLoc DL = I->getDebugLoc();
- unsigned LL, SC;
+ unsigned LL, SC, SLT, SLTu, OR, MOVN, MOVZ, SELNEZ, SELEQZ;
unsigned BEQ = Mips::BEQ;
unsigned SEOp = Mips::SEH;
@@ -316,15 +316,32 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
+ SLT = Mips::SLT_MM;
+ SLTu = Mips::SLTu_MM;
+ OR = STI->hasMips32r6() ? Mips::OR_MMR6 : Mips::OR_MM;
+ MOVN = Mips::MOVN_I_MM;
+ MOVZ = Mips::MOVZ_I_MM;
+ SELNEZ = STI->hasMips32r6() ? Mips::SELNEZ_MMR6 : Mips::SELNEZ;
+ SELEQZ = STI->hasMips32r6() ? Mips::SELEQZ_MMR6 : Mips::SELEQZ;
} else {
LL = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
: (ArePtrs64bit ? Mips::LL64 : Mips::LL);
SC = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
: (ArePtrs64bit ? Mips::SC64 : Mips::SC);
+ SLT = Mips::SLT;
+ SLTu = Mips::SLTu;
+ OR = Mips::OR;
+ MOVN = Mips::MOVN_I_I;
+ MOVZ = Mips::MOVZ_I_I;
+ SELNEZ = Mips::SELNEZ;
+ SELEQZ = Mips::SELEQZ;
}
bool IsSwap = false;
bool IsNand = false;
+ bool IsMin = false;
+ bool IsMax = false;
+ bool IsUnsigned = false;
unsigned Opcode = 0;
switch (I->getOpcode()) {
@@ -370,6 +387,22 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
case Mips::ATOMIC_LOAD_XOR_I16_POSTRA:
Opcode = Mips::XOR;
break;
+ case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA:
+ case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA:
+ IsUnsigned = true;
+ LLVM_FALLTHROUGH;
+ case Mips::ATOMIC_LOAD_MIN_I8_POSTRA:
+ case Mips::ATOMIC_LOAD_MIN_I16_POSTRA:
+ IsMin = true;
+ break;
+ case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA:
+ case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA:
+ IsUnsigned = true;
+ LLVM_FALLTHROUGH;
+ case Mips::ATOMIC_LOAD_MAX_I8_POSTRA:
+ case Mips::ATOMIC_LOAD_MAX_I16_POSTRA:
+ IsMax = true;
+ break;
default:
llvm_unreachable("Unknown subword atomic pseudo for expansion!");
}
@@ -415,6 +448,68 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
.addReg(BinOpRes)
.addReg(Mask);
+ } else if (IsMin || IsMax) {
+
+ assert(I->getNumOperands() == 10 &&
+ "Atomics min|max|umin|umax use an additional register");
+ Register Scratch4 = I->getOperand(9).getReg();
+
+ unsigned SLTScratch4 = IsUnsigned ? SLTu : SLT;
+ unsigned SELIncr = IsMax ? SELNEZ : SELEQZ;
+ unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ;
+ unsigned MOVIncr = IsMax ? MOVN : MOVZ;
+
+ // For little endian we need to clear uninterested bits.
+ if (STI->isLittle()) {
+ // and OldVal, OldVal, Mask
+ // and Incr, Incr, Mask
+ BuildMI(loopMBB, DL, TII->get(Mips::AND), OldVal)
+ .addReg(OldVal)
+ .addReg(Mask);
+ BuildMI(loopMBB, DL, TII->get(Mips::AND), Incr).addReg(Incr).addReg(Mask);
+ }
+
+ // unsigned: sltu Scratch4, oldVal, Incr
+ // signed: slt Scratch4, oldVal, Incr
+ BuildMI(loopMBB, DL, TII->get(SLTScratch4), Scratch4)
+ .addReg(OldVal)
+ .addReg(Incr);
+
+ if (STI->hasMips64r6() || STI->hasMips32r6()) {
+ // max: seleqz BinOpRes, OldVal, Scratch4
+ // selnez Scratch4, Incr, Scratch4
+ // or BinOpRes, BinOpRes, Scratch4
+ // min: selnqz BinOpRes, OldVal, Scratch4
+ // seleqz Scratch4, Incr, Scratch4
+ // or BinOpRes, BinOpRes, Scratch4
+ BuildMI(loopMBB, DL, TII->get(SELOldVal), BinOpRes)
+ .addReg(OldVal)
+ .addReg(Scratch4);
+ BuildMI(loopMBB, DL, TII->get(SELIncr), Scratch4)
+ .addReg(Incr)
+ .addReg(Scratch4);
+ BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)
+ .addReg(BinOpRes)
+ .addReg(Scratch4);
+ } else {
+ // max: move BinOpRes, OldVal
+ // movn BinOpRes, Incr, Scratch4, BinOpRes
+ // min: move BinOpRes, OldVal
+ // movz BinOpRes, Incr, Scratch4, BinOpRes
+ BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)
+ .addReg(OldVal)
+ .addReg(Mips::ZERO);
+ BuildMI(loopMBB, DL, TII->get(MOVIncr), BinOpRes)
+ .addReg(Incr)
+ .addReg(Scratch4)
+ .addReg(BinOpRes);
+ }
+
+ // and BinOpRes, BinOpRes, Mask
+ BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
+ .addReg(BinOpRes)
+ .addReg(Mask);
+
} else if (!IsSwap) {
// <binop> binopres, oldval, incr2
// and newval, binopres, mask
@@ -488,13 +583,20 @@ bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB,
const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
DebugLoc DL = I->getDebugLoc();
- unsigned LL, SC, ZERO, BEQ;
+ unsigned LL, SC, ZERO, BEQ, SLT, SLTu, OR, MOVN, MOVZ, SELNEZ, SELEQZ;
if (Size == 4) {
if (STI->inMicroMipsMode()) {
LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
+ SLT = Mips::SLT_MM;
+ SLTu = Mips::SLTu_MM;
+ OR = STI->hasMips32r6() ? Mips::OR_MMR6 : Mips::OR_MM;
+ MOVN = Mips::MOVN_I_MM;
+ MOVZ = Mips::MOVZ_I_MM;
+ SELNEZ = STI->hasMips32r6() ? Mips::SELNEZ_MMR6 : Mips::SELNEZ;
+ SELEQZ = STI->hasMips32r6() ? Mips::SELEQZ_MMR6 : Mips::SELEQZ;
} else {
LL = STI->hasMips32r6()
? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
@@ -503,6 +605,13 @@ bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB,
? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
: (ArePtrs64bit ? Mips::SC64 : Mips::SC);
BEQ = Mips::BEQ;
+ SLT = Mips::SLT;
+ SLTu = Mips::SLTu;
+ OR = Mips::OR;
+ MOVN = Mips::MOVN_I_I;
+ MOVZ = Mips::MOVZ_I_I;
+ SELNEZ = Mips::SELNEZ;
+ SELEQZ = Mips::SELEQZ;
}
ZERO = Mips::ZERO;
@@ -511,6 +620,13 @@ bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB,
SC = STI->hasMips64r6() ? Mips::SCD_R6 : Mips::SCD;
ZERO = Mips::ZERO_64;
BEQ = Mips::BEQ64;
+ SLT = Mips::SLT64;
+ SLTu = Mips::SLTu64;
+ OR = Mips::OR64;
+ MOVN = Mips::MOVN_I64_I64;
+ MOVZ = Mips::MOVZ_I64_I64;
+ SELNEZ = Mips::SELNEZ64;
+ SELEQZ = Mips::SELEQZ64;
}
Register OldVal = I->getOperand(0).getReg();
@@ -519,10 +635,15 @@ bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB,
Register Scratch = I->getOperand(3).getReg();
unsigned Opcode = 0;
- unsigned OR = 0;
unsigned AND = 0;
unsigned NOR = 0;
+
+ bool IsOr = false;
bool IsNand = false;
+ bool IsMin = false;
+ bool IsMax = false;
+ bool IsUnsigned = false;
+
switch (I->getOpcode()) {
case Mips::ATOMIC_LOAD_ADD_I32_POSTRA:
Opcode = Mips::ADDu;
@@ -545,7 +666,7 @@ bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB,
NOR = Mips::NOR;
break;
case Mips::ATOMIC_SWAP_I32_POSTRA:
- OR = Mips::OR;
+ IsOr = true;
break;
case Mips::ATOMIC_LOAD_ADD_I64_POSTRA:
Opcode = Mips::DADDu;
@@ -568,7 +689,23 @@ bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB,
NOR = Mips::NOR64;
break;
case Mips::ATOMIC_SWAP_I64_POSTRA:
- OR = Mips::OR64;
+ IsOr = true;
+ break;
+ case Mips::ATOMIC_LOAD_UMIN_I32_POSTRA:
+ case Mips::ATOMIC_LOAD_UMIN_I64_POSTRA:
+ IsUnsigned = true;
+ LLVM_FALLTHROUGH;
+ case Mips::ATOMIC_LOAD_MIN_I32_POSTRA:
+ case Mips::ATOMIC_LOAD_MIN_I64_POSTRA:
+ IsMin = true;
+ break;
+ case Mips::ATOMIC_LOAD_UMAX_I32_POSTRA:
+ case Mips::ATOMIC_LOAD_UMAX_I64_POSTRA:
+ IsUnsigned = true;
+ LLVM_FALLTHROUGH;
+ case Mips::ATOMIC_LOAD_MAX_I32_POSTRA:
+ case Mips::ATOMIC_LOAD_MAX_I64_POSTRA:
+ IsMax = true;
break;
default:
llvm_unreachable("Unknown pseudo atomic!");
@@ -592,7 +729,59 @@ bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB,
BuildMI(loopMBB, DL, TII->get(LL), OldVal).addReg(Ptr).addImm(0);
assert((OldVal != Ptr) && "Clobbered the wrong ptr reg!");
assert((OldVal != Incr) && "Clobbered the wrong reg!");
- if (Opcode) {
+ if (IsMin || IsMax) {
+
+ assert(I->getNumOperands() == 5 &&
+ "Atomics min|max|umin|umax use an additional register");
+ Register Scratch2 = I->getOperand(4).getReg();
+
+ // On Mips64 result of slt is GPR32.
+ Register Scratch2_32 =
+ (Size == 8) ? STI->getRegisterInfo()->getSubReg(Scratch2, Mips::sub_32)
+ : Scratch2;
+
+ unsigned SLTScratch2 = IsUnsigned ? SLTu : SLT;
+ unsigned SELIncr = IsMax ? SELNEZ : SELEQZ;
+ unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ;
+ unsigned MOVIncr = IsMax ? MOVN : MOVZ;
+
+ // unsigned: sltu Scratch2, oldVal, Incr
+ // signed: slt Scratch2, oldVal, Incr
+ BuildMI(loopMBB, DL, TII->get(SLTScratch2), Scratch2_32)
+ .addReg(OldVal)
+ .addReg(Incr);
+
+ if (STI->hasMips64r6() || STI->hasMips32r6()) {
+ // max: seleqz Scratch, OldVal, Scratch2
+ // selnez Scratch2, Incr, Scratch2
+ // or Scratch, Scratch, Scratch2
+ // min: selnez Scratch, OldVal, Scratch2
+ // seleqz Scratch2, Incr, Scratch2
+ // or Scratch, Scratch, Scratch2
+ BuildMI(loopMBB, DL, TII->get(SELOldVal), Scratch)
+ .addReg(OldVal)
+ .addReg(Scratch2);
+ BuildMI(loopMBB, DL, TII->get(SELIncr), Scratch2)
+ .addReg(Incr)
+ .addReg(Scratch2);
+ BuildMI(loopMBB, DL, TII->get(OR), Scratch)
+ .addReg(Scratch)
+ .addReg(Scratch2);
+ } else {
+ // max: move Scratch, OldVal
+ // movn Scratch, Incr, Scratch2, Scratch
+ // min: move Scratch, OldVal
+ // movz Scratch, Incr, Scratch2, Scratch
+ BuildMI(loopMBB, DL, TII->get(OR), Scratch)
+ .addReg(OldVal)
+ .addReg(ZERO);
+ BuildMI(loopMBB, DL, TII->get(MOVIncr), Scratch)
+ .addReg(Incr)
+ .addReg(Scratch2)
+ .addReg(Scratch);
+ }
+
+ } else if (Opcode) {
BuildMI(loopMBB, DL, TII->get(Opcode), Scratch).addReg(OldVal).addReg(Incr);
} else if (IsNand) {
assert(AND && NOR &&
@@ -600,12 +789,19 @@ bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB,
BuildMI(loopMBB, DL, TII->get(AND), Scratch).addReg(OldVal).addReg(Incr);
BuildMI(loopMBB, DL, TII->get(NOR), Scratch).addReg(ZERO).addReg(Scratch);
} else {
- assert(OR && "Unknown instruction for atomic pseudo expansion!");
+ assert(IsOr && OR && "Unknown instruction for atomic pseudo expansion!");
+ (void)IsOr;
BuildMI(loopMBB, DL, TII->get(OR), Scratch).addReg(Incr).addReg(ZERO);
}
- BuildMI(loopMBB, DL, TII->get(SC), Scratch).addReg(Scratch).addReg(Ptr).addImm(0);
- BuildMI(loopMBB, DL, TII->get(BEQ)).addReg(Scratch).addReg(ZERO).addMBB(loopMBB);
+ BuildMI(loopMBB, DL, TII->get(SC), Scratch)
+ .addReg(Scratch)
+ .addReg(Ptr)
+ .addImm(0);
+ BuildMI(loopMBB, DL, TII->get(BEQ))
+ .addReg(Scratch)
+ .addReg(ZERO)
+ .addMBB(loopMBB);
NMBBI = BB.end();
I->eraseFromParent();
@@ -644,6 +840,14 @@ bool MipsExpandPseudo::expandMI(MachineBasicBlock &MBB,
case Mips::ATOMIC_LOAD_OR_I16_POSTRA:
case Mips::ATOMIC_LOAD_XOR_I8_POSTRA:
case Mips::ATOMIC_LOAD_XOR_I16_POSTRA:
+ case Mips::ATOMIC_LOAD_MIN_I8_POSTRA:
+ case Mips::ATOMIC_LOAD_MIN_I16_POSTRA:
+ case Mips::ATOMIC_LOAD_MAX_I8_POSTRA:
+ case Mips::ATOMIC_LOAD_MAX_I16_POSTRA:
+ case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA:
+ case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA:
+ case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA:
+ case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA:
return expandAtomicBinOpSubword(MBB, MBBI, NMBB);
case Mips::ATOMIC_LOAD_ADD_I32_POSTRA:
case Mips::ATOMIC_LOAD_SUB_I32_POSTRA:
@@ -652,6 +856,10 @@ bool MipsExpandPseudo::expandMI(MachineBasicBlock &MBB,
case Mips::ATOMIC_LOAD_XOR_I32_POSTRA:
case Mips::ATOMIC_LOAD_NAND_I32_POSTRA:
case Mips::ATOMIC_SWAP_I32_POSTRA:
+ case Mips::ATOMIC_LOAD_MIN_I32_POSTRA:
+ case Mips::ATOMIC_LOAD_MAX_I32_POSTRA:
+ case Mips::ATOMIC_LOAD_UMIN_I32_POSTRA:
+ case Mips::ATOMIC_LOAD_UMAX_I32_POSTRA:
return expandAtomicBinOp(MBB, MBBI, NMBB, 4);
case Mips::ATOMIC_LOAD_ADD_I64_POSTRA:
case Mips::ATOMIC_LOAD_SUB_I64_POSTRA:
@@ -660,6 +868,10 @@ bool MipsExpandPseudo::expandMI(MachineBasicBlock &MBB,
case Mips::ATOMIC_LOAD_XOR_I64_POSTRA:
case Mips::ATOMIC_LOAD_NAND_I64_POSTRA:
case Mips::ATOMIC_SWAP_I64_POSTRA:
+ case Mips::ATOMIC_LOAD_MIN_I64_POSTRA:
+ case Mips::ATOMIC_LOAD_MAX_I64_POSTRA:
+ case Mips::ATOMIC_LOAD_UMIN_I64_POSTRA:
+ case Mips::ATOMIC_LOAD_UMAX_I64_POSTRA:
return expandAtomicBinOp(MBB, MBBI, NMBB, 8);
default:
return Modified;
diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp
index e5997af3bcc5..8c36bcd5c8f2 100644
--- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp
+++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp
@@ -314,7 +314,6 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
switch(ConstraintID) {
default:
llvm_unreachable("Unexpected asm memory constraint");
- case InlineAsm::Constraint_i:
case InlineAsm::Constraint_m:
case InlineAsm::Constraint_R:
case InlineAsm::Constraint_ZC:
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index bf1b4756b24f..46b1f35a6fc7 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -111,21 +111,19 @@ static bool isShiftedMask(uint64_t I, uint64_t &Pos, uint64_t &Size) {
MVT MipsTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,
CallingConv::ID CC,
EVT VT) const {
- if (VT.isVector()) {
- if (Subtarget.isABI_O32()) {
- return MVT::i32;
- } else {
- return (VT.getSizeInBits() == 32) ? MVT::i32 : MVT::i64;
- }
- }
- return MipsTargetLowering::getRegisterType(Context, VT);
+ if (!VT.isVector())
+ return getRegisterType(Context, VT);
+
+ return Subtarget.isABI_O32() || VT.getSizeInBits() == 32 ? MVT::i32
+ : MVT::i64;
}
unsigned MipsTargetLowering::getNumRegistersForCallingConv(LLVMContext &Context,
CallingConv::ID CC,
EVT VT) const {
if (VT.isVector())
- return std::max((VT.getSizeInBits() / (Subtarget.isABI_O32() ? 32 : 64)),
+ return std::max(((unsigned)VT.getSizeInBits() /
+ (Subtarget.isABI_O32() ? 32 : 64)),
1U);
return MipsTargetLowering::getNumRegisters(Context, VT);
}
@@ -528,8 +526,9 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
isMicroMips = Subtarget.inMicroMipsMode();
}
-const MipsTargetLowering *MipsTargetLowering::create(const MipsTargetMachine &TM,
- const MipsSubtarget &STI) {
+const MipsTargetLowering *
+MipsTargetLowering::create(const MipsTargetMachine &TM,
+ const MipsSubtarget &STI) {
if (STI.inMips16Mode())
return createMips16TargetLowering(TM, STI);
@@ -710,7 +709,8 @@ static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG,
SDValue True = N->getOperand(1);
SetCC = DAG.getSetCC(DL, SetCC.getValueType(), SetCC.getOperand(0),
- SetCC.getOperand(1), ISD::getSetCCInverse(CC, true));
+ SetCC.getOperand(1),
+ ISD::getSetCCInverse(CC, SetCC.getValueType()));
return DAG.getNode(ISD::SELECT, DL, FalseTy, SetCC, False, True);
}
@@ -744,7 +744,8 @@ static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG,
if (Diff == -1) {
ISD::CondCode CC = cast<CondCodeSDNode>(SetCC.getOperand(2))->get();
SetCC = DAG.getSetCC(DL, SetCC.getValueType(), SetCC.getOperand(0),
- SetCC.getOperand(1), ISD::getSetCCInverse(CC, true));
+ SetCC.getOperand(1),
+ ISD::getSetCCInverse(CC, SetCC.getValueType()));
return DAG.getNode(ISD::ADD, DL, SetCC.getValueType(), SetCC, True);
}
@@ -1367,6 +1368,43 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
return emitAtomicCmpSwap(MI, BB);
case Mips::ATOMIC_CMP_SWAP_I64:
return emitAtomicCmpSwap(MI, BB);
+
+ case Mips::ATOMIC_LOAD_MIN_I8:
+ return emitAtomicBinaryPartword(MI, BB, 1);
+ case Mips::ATOMIC_LOAD_MIN_I16:
+ return emitAtomicBinaryPartword(MI, BB, 2);
+ case Mips::ATOMIC_LOAD_MIN_I32:
+ return emitAtomicBinary(MI, BB);
+ case Mips::ATOMIC_LOAD_MIN_I64:
+ return emitAtomicBinary(MI, BB);
+
+ case Mips::ATOMIC_LOAD_MAX_I8:
+ return emitAtomicBinaryPartword(MI, BB, 1);
+ case Mips::ATOMIC_LOAD_MAX_I16:
+ return emitAtomicBinaryPartword(MI, BB, 2);
+ case Mips::ATOMIC_LOAD_MAX_I32:
+ return emitAtomicBinary(MI, BB);
+ case Mips::ATOMIC_LOAD_MAX_I64:
+ return emitAtomicBinary(MI, BB);
+
+ case Mips::ATOMIC_LOAD_UMIN_I8:
+ return emitAtomicBinaryPartword(MI, BB, 1);
+ case Mips::ATOMIC_LOAD_UMIN_I16:
+ return emitAtomicBinaryPartword(MI, BB, 2);
+ case Mips::ATOMIC_LOAD_UMIN_I32:
+ return emitAtomicBinary(MI, BB);
+ case Mips::ATOMIC_LOAD_UMIN_I64:
+ return emitAtomicBinary(MI, BB);
+
+ case Mips::ATOMIC_LOAD_UMAX_I8:
+ return emitAtomicBinaryPartword(MI, BB, 1);
+ case Mips::ATOMIC_LOAD_UMAX_I16:
+ return emitAtomicBinaryPartword(MI, BB, 2);
+ case Mips::ATOMIC_LOAD_UMAX_I32:
+ return emitAtomicBinary(MI, BB);
+ case Mips::ATOMIC_LOAD_UMAX_I64:
+ return emitAtomicBinary(MI, BB);
+
case Mips::PseudoSDIV:
case Mips::PseudoUDIV:
case Mips::DIV:
@@ -1428,6 +1466,7 @@ MipsTargetLowering::emitAtomicBinary(MachineInstr &MI,
DebugLoc DL = MI.getDebugLoc();
unsigned AtomicOp;
+ bool NeedsAdditionalReg = false;
switch (MI.getOpcode()) {
case Mips::ATOMIC_LOAD_ADD_I32:
AtomicOp = Mips::ATOMIC_LOAD_ADD_I32_POSTRA;
@@ -1471,6 +1510,38 @@ MipsTargetLowering::emitAtomicBinary(MachineInstr &MI,
case Mips::ATOMIC_SWAP_I64:
AtomicOp = Mips::ATOMIC_SWAP_I64_POSTRA;
break;
+ case Mips::ATOMIC_LOAD_MIN_I32:
+ AtomicOp = Mips::ATOMIC_LOAD_MIN_I32_POSTRA;
+ NeedsAdditionalReg = true;
+ break;
+ case Mips::ATOMIC_LOAD_MAX_I32:
+ AtomicOp = Mips::ATOMIC_LOAD_MAX_I32_POSTRA;
+ NeedsAdditionalReg = true;
+ break;
+ case Mips::ATOMIC_LOAD_UMIN_I32:
+ AtomicOp = Mips::ATOMIC_LOAD_UMIN_I32_POSTRA;
+ NeedsAdditionalReg = true;
+ break;
+ case Mips::ATOMIC_LOAD_UMAX_I32:
+ AtomicOp = Mips::ATOMIC_LOAD_UMAX_I32_POSTRA;
+ NeedsAdditionalReg = true;
+ break;
+ case Mips::ATOMIC_LOAD_MIN_I64:
+ AtomicOp = Mips::ATOMIC_LOAD_MIN_I64_POSTRA;
+ NeedsAdditionalReg = true;
+ break;
+ case Mips::ATOMIC_LOAD_MAX_I64:
+ AtomicOp = Mips::ATOMIC_LOAD_MAX_I64_POSTRA;
+ NeedsAdditionalReg = true;
+ break;
+ case Mips::ATOMIC_LOAD_UMIN_I64:
+ AtomicOp = Mips::ATOMIC_LOAD_UMIN_I64_POSTRA;
+ NeedsAdditionalReg = true;
+ break;
+ case Mips::ATOMIC_LOAD_UMAX_I64:
+ AtomicOp = Mips::ATOMIC_LOAD_UMAX_I64_POSTRA;
+ NeedsAdditionalReg = true;
+ break;
default:
llvm_unreachable("Unknown pseudo atomic for replacement!");
}
@@ -1523,12 +1594,19 @@ MipsTargetLowering::emitAtomicBinary(MachineInstr &MI,
BuildMI(*BB, II, DL, TII->get(Mips::COPY), IncrCopy).addReg(Incr);
BuildMI(*BB, II, DL, TII->get(Mips::COPY), PtrCopy).addReg(Ptr);
- BuildMI(*BB, II, DL, TII->get(AtomicOp))
- .addReg(OldVal, RegState::Define | RegState::EarlyClobber)
- .addReg(PtrCopy)
- .addReg(IncrCopy)
- .addReg(Scratch, RegState::Define | RegState::EarlyClobber |
- RegState::Implicit | RegState::Dead);
+ MachineInstrBuilder MIB =
+ BuildMI(*BB, II, DL, TII->get(AtomicOp))
+ .addReg(OldVal, RegState::Define | RegState::EarlyClobber)
+ .addReg(PtrCopy)
+ .addReg(IncrCopy)
+ .addReg(Scratch, RegState::Define | RegState::EarlyClobber |
+ RegState::Implicit | RegState::Dead);
+ if (NeedsAdditionalReg) {
+ Register Scratch2 =
+ RegInfo.createVirtualRegister(RegInfo.getRegClass(OldVal));
+ MIB.addReg(Scratch2, RegState::Define | RegState::EarlyClobber |
+ RegState::Implicit | RegState::Dead);
+ }
MI.eraseFromParent();
@@ -1596,6 +1674,7 @@ MachineBasicBlock *MipsTargetLowering::emitAtomicBinaryPartword(
Register Scratch3 = RegInfo.createVirtualRegister(RC);
unsigned AtomicOp = 0;
+ bool NeedsAdditionalReg = false;
switch (MI.getOpcode()) {
case Mips::ATOMIC_LOAD_NAND_I8:
AtomicOp = Mips::ATOMIC_LOAD_NAND_I8_POSTRA;
@@ -1639,6 +1718,38 @@ MachineBasicBlock *MipsTargetLowering::emitAtomicBinaryPartword(
case Mips::ATOMIC_LOAD_XOR_I16:
AtomicOp = Mips::ATOMIC_LOAD_XOR_I16_POSTRA;
break;
+ case Mips::ATOMIC_LOAD_MIN_I8:
+ AtomicOp = Mips::ATOMIC_LOAD_MIN_I8_POSTRA;
+ NeedsAdditionalReg = true;
+ break;
+ case Mips::ATOMIC_LOAD_MIN_I16:
+ AtomicOp = Mips::ATOMIC_LOAD_MIN_I16_POSTRA;
+ NeedsAdditionalReg = true;
+ break;
+ case Mips::ATOMIC_LOAD_MAX_I8:
+ AtomicOp = Mips::ATOMIC_LOAD_MAX_I8_POSTRA;
+ NeedsAdditionalReg = true;
+ break;
+ case Mips::ATOMIC_LOAD_MAX_I16:
+ AtomicOp = Mips::ATOMIC_LOAD_MAX_I16_POSTRA;
+ NeedsAdditionalReg = true;
+ break;
+ case Mips::ATOMIC_LOAD_UMIN_I8:
+ AtomicOp = Mips::ATOMIC_LOAD_UMIN_I8_POSTRA;
+ NeedsAdditionalReg = true;
+ break;
+ case Mips::ATOMIC_LOAD_UMIN_I16:
+ AtomicOp = Mips::ATOMIC_LOAD_UMIN_I16_POSTRA;
+ NeedsAdditionalReg = true;
+ break;
+ case Mips::ATOMIC_LOAD_UMAX_I8:
+ AtomicOp = Mips::ATOMIC_LOAD_UMAX_I8_POSTRA;
+ NeedsAdditionalReg = true;
+ break;
+ case Mips::ATOMIC_LOAD_UMAX_I16:
+ AtomicOp = Mips::ATOMIC_LOAD_UMAX_I16_POSTRA;
+ NeedsAdditionalReg = true;
+ break;
default:
llvm_unreachable("Unknown subword atomic pseudo for expansion!");
}
@@ -1693,19 +1804,25 @@ MachineBasicBlock *MipsTargetLowering::emitAtomicBinaryPartword(
// emitAtomicBinary. In summary, we need a scratch register which is going to
// be undef, that is unique among registers chosen for the instruction.
- BuildMI(BB, DL, TII->get(AtomicOp))
- .addReg(Dest, RegState::Define | RegState::EarlyClobber)
- .addReg(AlignedAddr)
- .addReg(Incr2)
- .addReg(Mask)
- .addReg(Mask2)
- .addReg(ShiftAmt)
- .addReg(Scratch, RegState::EarlyClobber | RegState::Define |
- RegState::Dead | RegState::Implicit)
- .addReg(Scratch2, RegState::EarlyClobber | RegState::Define |
- RegState::Dead | RegState::Implicit)
- .addReg(Scratch3, RegState::EarlyClobber | RegState::Define |
- RegState::Dead | RegState::Implicit);
+ MachineInstrBuilder MIB =
+ BuildMI(BB, DL, TII->get(AtomicOp))
+ .addReg(Dest, RegState::Define | RegState::EarlyClobber)
+ .addReg(AlignedAddr)
+ .addReg(Incr2)
+ .addReg(Mask)
+ .addReg(Mask2)
+ .addReg(ShiftAmt)
+ .addReg(Scratch, RegState::EarlyClobber | RegState::Define |
+ RegState::Dead | RegState::Implicit)
+ .addReg(Scratch2, RegState::EarlyClobber | RegState::Define |
+ RegState::Dead | RegState::Implicit)
+ .addReg(Scratch3, RegState::EarlyClobber | RegState::Define |
+ RegState::Dead | RegState::Implicit);
+ if (NeedsAdditionalReg) {
+ Register Scratch4 = RegInfo.createVirtualRegister(RC);
+ MIB.addReg(Scratch4, RegState::EarlyClobber | RegState::Define |
+ RegState::Dead | RegState::Implicit);
+ }
MI.eraseFromParent(); // The instruction is gone now.
@@ -2804,7 +2921,8 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT,
// allocate a register directly.
Reg = State.AllocateReg(IntRegs);
}
- } else if (ValVT == MVT::i32 || (ValVT == MVT::f32 && AllocateFloatsInIntReg)) {
+ } else if (ValVT == MVT::i32 ||
+ (ValVT == MVT::f32 && AllocateFloatsInIntReg)) {
Reg = State.AllocateReg(IntRegs);
// If this is the first part of an i64 arg,
// the allocated register must be either A0 or A2.
@@ -2993,6 +3111,14 @@ void MipsTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI,
StringRef Sym;
if (const GlobalAddressSDNode *G =
dyn_cast_or_null<const GlobalAddressSDNode>(TargetAddr)) {
+ // We must not emit the R_MIPS_JALR relocation against data symbols
+ // since this will cause run-time crashes if the linker replaces the
+ // call instruction with a relative branch to the data symbol.
+ if (!isa<Function>(G->getGlobal())) {
+ LLVM_DEBUG(dbgs() << "Not adding R_MIPS_JALR against data symbol "
+ << G->getGlobal()->getName() << "\n");
+ return;
+ }
Sym = G->getGlobal()->getName();
}
else if (const ExternalSymbolSDNode *ES =
@@ -3005,6 +3131,7 @@ void MipsTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI,
MachineFunction *MF = MI.getParent()->getParent();
MCSymbol *S = MF->getContext().getOrCreateSymbol(Sym);
+ LLVM_DEBUG(dbgs() << "Adding R_MIPS_JALR against " << Sym << "\n");
MI.addOperand(MachineOperand::CreateMCSymbol(S, MipsII::MO_JALR));
}
}
@@ -3625,8 +3752,8 @@ MipsTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
return CCInfo.CheckReturn(Outs, RetCC_Mips);
}
-bool
-MipsTargetLowering::shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const {
+bool MipsTargetLowering::shouldSignExtendTypeInLibCall(EVT Type,
+ bool IsSigned) const {
if ((ABI.IsN32() || ABI.IsN64()) && Type == MVT::i32)
return true;
@@ -4006,11 +4133,13 @@ MipsTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
}
}
- std::pair<unsigned, const TargetRegisterClass *> R;
- R = parseRegForInlineAsmConstraint(Constraint, VT);
+ if (!Constraint.empty()) {
+ std::pair<unsigned, const TargetRegisterClass *> R;
+ R = parseRegForInlineAsmConstraint(Constraint, VT);
- if (R.second)
- return R;
+ if (R.second)
+ return R;
+ }
return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
}
@@ -4113,7 +4242,8 @@ void MipsTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
bool MipsTargetLowering::isLegalAddressingMode(const DataLayout &DL,
const AddrMode &AM, Type *Ty,
- unsigned AS, Instruction *I) const {
+ unsigned AS,
+ Instruction *I) const {
// No global is ever allowed as a base.
if (AM.BaseGV)
return false;
@@ -4489,8 +4619,9 @@ MachineBasicBlock *MipsTargetLowering::emitPseudoSELECT(MachineInstr &MI,
return BB;
}
-MachineBasicBlock *MipsTargetLowering::emitPseudoD_SELECT(MachineInstr &MI,
- MachineBasicBlock *BB) const {
+MachineBasicBlock *
+MipsTargetLowering::emitPseudoD_SELECT(MachineInstr &MI,
+ MachineBasicBlock *BB) const {
assert(!(Subtarget.hasMips4() || Subtarget.hasMips32()) &&
"Subtarget already supports SELECT nodes with the use of"
"conditional-move instructions.");
@@ -4566,8 +4697,9 @@ MachineBasicBlock *MipsTargetLowering::emitPseudoD_SELECT(MachineInstr &MI,
// FIXME? Maybe this could be a TableGen attribute on some registers and
// this table could be generated automatically from RegInfo.
-Register MipsTargetLowering::getRegisterByName(const char* RegName, EVT VT,
- const MachineFunction &MF) const {
+Register
+MipsTargetLowering::getRegisterByName(const char *RegName, LLT VT,
+ const MachineFunction &MF) const {
// Named registers is expected to be fairly rare. For now, just support $28
// since the linux kernel uses it.
if (Subtarget.isGP64bit()) {
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h
index 0a5cddd45afb..92cbe1d54c5b 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsISelLowering.h
@@ -348,7 +348,7 @@ class TargetRegisterClass;
void HandleByVal(CCState *, unsigned &, unsigned) const override;
- Register getRegisterByName(const char* RegName, EVT VT,
+ Register getRegisterByName(const char* RegName, LLT VT,
const MachineFunction &MF) const override;
/// If a physical register, this returns the register that receives the
diff --git a/llvm/lib/Target/Mips/MipsInstrFPU.td b/llvm/lib/Target/Mips/MipsInstrFPU.td
index e94e107e64c2..79776998463f 100644
--- a/llvm/lib/Target/Mips/MipsInstrFPU.td
+++ b/llvm/lib/Target/Mips/MipsInstrFPU.td
@@ -129,8 +129,9 @@ class ABSS_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC,
HARDFLOAT,
NeverHasSideEffects;
-class CVT_PS_S_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC, InstrItinClass Itin, bit IsComm,
- SDPatternOperator OpNode= null_frag> :
+class CVT_PS_S_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC,
+ InstrItinClass Itin, bit IsComm,
+ SDPatternOperator OpNode = null_frag> :
InstSE<(outs DstRC:$fd), (ins SrcRC:$fs, SrcRC:$ft),
!strconcat(opstr, "\t$fd, $fs, $ft"),
[(set DstRC:$fd, (OpNode SrcRC:$fs, SrcRC:$ft))], Itin, FrmFR, opstr>,
@@ -142,7 +143,8 @@ multiclass ABSS_M<string opstr, InstrItinClass Itin,
SDPatternOperator OpNode= null_frag> {
def _D32 : MMRel, ABSS_FT<opstr, AFGR64Opnd, AFGR64Opnd, Itin, OpNode>,
FGR_32;
- def _D64 : StdMMR6Rel, ABSS_FT<opstr, FGR64Opnd, FGR64Opnd, Itin, OpNode>, FGR_64 {
+ def _D64 : StdMMR6Rel, ABSS_FT<opstr, FGR64Opnd, FGR64Opnd, Itin, OpNode>,
+ FGR_64 {
string DecoderNamespace = "MipsFP64";
}
}
@@ -362,17 +364,21 @@ defm D64 : C_COND_M<"d", FGR64Opnd, 17, II_C_CC_D>, ISA_MIPS1_NOT_32R6_64R6,
// Floating Point Instructions
//===----------------------------------------------------------------------===//
let AdditionalPredicates = [NotInMicroMips] in {
- def ROUND_W_S : MMRel, StdMMR6Rel, ABSS_FT<"round.w.s", FGR32Opnd, FGR32Opnd, II_ROUND>,
- ABSS_FM<0xc, 16>, ISA_MIPS2;
- defm ROUND_W : ROUND_M<"round.w.d", II_ROUND>, ABSS_FM<0xc, 17>, ISA_MIPS2;
- def TRUNC_W_S : MMRel, StdMMR6Rel, ABSS_FT<"trunc.w.s", FGR32Opnd, FGR32Opnd, II_TRUNC>,
- ABSS_FM<0xd, 16>, ISA_MIPS2;
- def CEIL_W_S : MMRel, StdMMR6Rel, ABSS_FT<"ceil.w.s", FGR32Opnd, FGR32Opnd, II_CEIL>,
- ABSS_FM<0xe, 16>, ISA_MIPS2;
- def FLOOR_W_S : MMRel, StdMMR6Rel, ABSS_FT<"floor.w.s", FGR32Opnd, FGR32Opnd, II_FLOOR>,
- ABSS_FM<0xf, 16>, ISA_MIPS2;
- def CVT_W_S : MMRel, ABSS_FT<"cvt.w.s", FGR32Opnd, FGR32Opnd, II_CVT>,
- ABSS_FM<0x24, 16>, ISA_MIPS1;
+ def ROUND_W_S : MMRel, StdMMR6Rel,
+ ABSS_FT<"round.w.s", FGR32Opnd, FGR32Opnd, II_ROUND>,
+ ABSS_FM<0xc, 16>, ISA_MIPS2;
+ defm ROUND_W : ROUND_M<"round.w.d", II_ROUND>, ABSS_FM<0xc, 17>, ISA_MIPS2;
+ def TRUNC_W_S : MMRel, StdMMR6Rel,
+ ABSS_FT<"trunc.w.s", FGR32Opnd, FGR32Opnd, II_TRUNC>,
+ ABSS_FM<0xd, 16>, ISA_MIPS2;
+ def CEIL_W_S : MMRel, StdMMR6Rel,
+ ABSS_FT<"ceil.w.s", FGR32Opnd, FGR32Opnd, II_CEIL>,
+ ABSS_FM<0xe, 16>, ISA_MIPS2;
+ def FLOOR_W_S : MMRel, StdMMR6Rel,
+ ABSS_FT<"floor.w.s", FGR32Opnd, FGR32Opnd, II_FLOOR>,
+ ABSS_FM<0xf, 16>, ISA_MIPS2;
+ def CVT_W_S : MMRel, ABSS_FT<"cvt.w.s", FGR32Opnd, FGR32Opnd, II_CVT>,
+ ABSS_FM<0x24, 16>, ISA_MIPS1;
defm TRUNC_W : ROUND_M<"trunc.w.d", II_TRUNC>, ABSS_FM<0xd, 17>, ISA_MIPS2;
defm CEIL_W : ROUND_M<"ceil.w.d", II_CEIL>, ABSS_FM<0xe, 17>, ISA_MIPS2;
@@ -536,7 +542,8 @@ let AdditionalPredicates = [NotInMicroMips] in {
let DecoderNamespace = "MipsFP64";
}
- def MTHC1_D32 : MMRel, StdMMR6Rel, MTC1_64_FT<"mthc1", AFGR64Opnd, GPR32Opnd, II_MTHC1>,
+ def MTHC1_D32 : MMRel, StdMMR6Rel,
+ MTC1_64_FT<"mthc1", AFGR64Opnd, GPR32Opnd, II_MTHC1>,
MFC1_FM<7>, ISA_MIPS32R2, FGR_32;
def MTHC1_D64 : MTC1_64_FT<"mthc1", FGR64Opnd, GPR32Opnd, II_MTHC1>,
MFC1_FM<7>, ISA_MIPS32R2, FGR_64 {
@@ -621,7 +628,7 @@ let AdditionalPredicates = [IsNotNaCl, NotInMicroMips],
INSN_MIPS5_32R2_NOT_32R6_64R6, FGR_64;
}
-/// Floating-point Aritmetic
+/// Floating-point Arithmetic
let AdditionalPredicates = [NotInMicroMips] in {
def FADD_S : MMRel, ADDS_FT<"add.s", FGR32Opnd, II_ADD_S, 1, fadd>,
ADDS_FM<0x00, 16>, ISA_MIPS1;
@@ -950,9 +957,12 @@ multiclass NMADD_NMSUB<Instruction Nmadd, Instruction Nmsub, RegisterOperand RC>
}
let AdditionalPredicates = [NoNaNsFPMath, HasMadd4, NotInMicroMips] in {
- defm : NMADD_NMSUB<NMADD_S, NMSUB_S, FGR32Opnd>, INSN_MIPS4_32R2_NOT_32R6_64R6;
- defm : NMADD_NMSUB<NMADD_D32, NMSUB_D32, AFGR64Opnd>, FGR_32, INSN_MIPS4_32R2_NOT_32R6_64R6;
- defm : NMADD_NMSUB<NMADD_D64, NMSUB_D64, FGR64Opnd>, FGR_64, INSN_MIPS4_32R2_NOT_32R6_64R6;
+ defm : NMADD_NMSUB<NMADD_S, NMSUB_S, FGR32Opnd>,
+ INSN_MIPS4_32R2_NOT_32R6_64R6;
+ defm : NMADD_NMSUB<NMADD_D32, NMSUB_D32, AFGR64Opnd>,
+ FGR_32, INSN_MIPS4_32R2_NOT_32R6_64R6;
+ defm : NMADD_NMSUB<NMADD_D64, NMSUB_D64, FGR64Opnd>,
+ FGR_64, INSN_MIPS4_32R2_NOT_32R6_64R6;
}
// Patterns for loads/stores with a reg+imm operand.
diff --git a/llvm/lib/Target/Mips/MipsInstrFormats.td b/llvm/lib/Target/Mips/MipsInstrFormats.td
index 14f01514f33f..4624c1f2d04a 100644
--- a/llvm/lib/Target/Mips/MipsInstrFormats.td
+++ b/llvm/lib/Target/Mips/MipsInstrFormats.td
@@ -97,9 +97,6 @@ class MipsInst<dag outs, dag ins, string asmstr, list<dag> pattern,
bit isCTI = 0; // Any form of Control Transfer Instruction.
// Required for MIPSR6
bit hasForbiddenSlot = 0; // Instruction has a forbidden slot.
- bit IsPCRelativeLoad = 0; // Load instruction with implicit source register
- // ($pc) and with explicit offset and destination
- // register
bit hasFCCRegOperand = 0; // Instruction uses $fcc<X> register and is
// present in MIPS-I to MIPS-III.
@@ -107,8 +104,7 @@ class MipsInst<dag outs, dag ins, string asmstr, list<dag> pattern,
let TSFlags{3-0} = FormBits;
let TSFlags{4} = isCTI;
let TSFlags{5} = hasForbiddenSlot;
- let TSFlags{6} = IsPCRelativeLoad;
- let TSFlags{7} = hasFCCRegOperand;
+ let TSFlags{6} = hasFCCRegOperand;
let DecoderNamespace = "Mips";
@@ -626,6 +622,19 @@ class SEQI_FM<bits<6> funct> : StdArch {
let Inst{5-0} = funct;
}
+class SAA_FM<bits<6> funct> : StdArch {
+ bits<5> rt;
+ bits<5> rs;
+
+ bits<32> Inst;
+
+ let Inst{31-26} = 0x1c;
+ let Inst{25-21} = rs;
+ let Inst{20-16} = rt;
+ let Inst{15-6} = 0;
+ let Inst{5-0} = funct;
+}
+
//===----------------------------------------------------------------------===//
// System calls format <op|code_|funct>
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.cpp b/llvm/lib/Target/Mips/MipsInstrInfo.cpp
index 6bb25ee5754d..25bbe5990827 100644
--- a/llvm/lib/Target/Mips/MipsInstrInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsInstrInfo.cpp
@@ -275,7 +275,8 @@ MipsInstrInfo::BranchType MipsInstrInfo::analyzeBranch(
return BT_CondUncond;
}
-bool MipsInstrInfo::isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const {
+bool MipsInstrInfo::isBranchOffsetInRange(unsigned BranchOpc,
+ int64_t BrOffset) const {
switch (BranchOpc) {
case Mips::B:
case Mips::BAL:
@@ -433,7 +434,6 @@ bool MipsInstrInfo::isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset)
llvm_unreachable("Unknown branch instruction!");
}
-
/// Return the corresponding compact (no delay slot) form of a branch.
unsigned MipsInstrInfo::getEquivalentCompactForm(
const MachineBasicBlock::iterator I) const {
diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td
index 58167e0f344d..d9a3ff802708 100644
--- a/llvm/lib/Target/Mips/MipsInstrInfo.td
+++ b/llvm/lib/Target/Mips/MipsInstrInfo.td
@@ -211,6 +211,10 @@ def HasCnMips : Predicate<"Subtarget->hasCnMips()">,
AssemblerPredicate<"FeatureCnMips">;
def NotCnMips : Predicate<"!Subtarget->hasCnMips()">,
AssemblerPredicate<"!FeatureCnMips">;
+def HasCnMipsP : Predicate<"Subtarget->hasCnMipsP()">,
+ AssemblerPredicate<"FeatureCnMipsP">;
+def NotCnMipsP : Predicate<"!Subtarget->hasCnMipsP()">,
+ AssemblerPredicate<"!FeatureCnMipsP">;
def IsSym32 : Predicate<"Subtarget->hasSym32()">,
AssemblerPredicate<"FeatureSym32">;
def IsSym64 : Predicate<"!Subtarget->hasSym32()">,
@@ -439,6 +443,14 @@ class NOT_ASE_CNMIPS {
list<Predicate> ASEPredicate = [NotCnMips];
}
+class ASE_CNMIPSP {
+ list<Predicate> ASEPredicate = [HasCnMipsP];
+}
+
+class NOT_ASE_CNMIPSP {
+ list<Predicate> ASEPredicate = [NotCnMipsP];
+}
+
class ASE_MIPS64_CNMIPS {
list<Predicate> ASEPredicate = [HasMips64, HasCnMips];
}
@@ -947,8 +959,7 @@ foreach I = {16} in
// Like uimm16_64 but coerces simm16 to uimm16.
def uimm16_relaxed : Operand<i32> {
let PrintMethod = "printUImm<16>";
- let ParserMatchClass =
- !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass");
+ let ParserMatchClass = UImm16RelaxedAsmOperandClass;
}
foreach I = {5} in
@@ -968,14 +979,12 @@ foreach I = {16} in
// Like uimm16_64 but coerces simm16 to uimm16.
def uimm16_64_relaxed : Operand<i64> {
let PrintMethod = "printUImm<16>";
- let ParserMatchClass =
- !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass");
+ let ParserMatchClass = UImm16RelaxedAsmOperandClass;
}
def uimm16_altrelaxed : Operand<i32> {
let PrintMethod = "printUImm<16>";
- let ParserMatchClass =
- !cast<AsmOperandClass>("UImm16AltRelaxedAsmOperandClass");
+ let ParserMatchClass = UImm16AltRelaxedAsmOperandClass;
}
// Like uimm5 but reports a less confusing error for 32-63 when
// an instruction alias permits that.
@@ -1048,22 +1057,22 @@ foreach I = {16, 32} in
// Like simm16 but coerces uimm16 to simm16.
def simm16_relaxed : Operand<i32> {
let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
- let ParserMatchClass = !cast<AsmOperandClass>("SImm16RelaxedAsmOperandClass");
+ let ParserMatchClass = SImm16RelaxedAsmOperandClass;
}
def simm16_64 : Operand<i64> {
let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
- let ParserMatchClass = !cast<AsmOperandClass>("SImm16AsmOperandClass");
+ let ParserMatchClass = SImm16AsmOperandClass;
}
// like simm32 but coerces simm32 to uimm32.
def uimm32_coerced : Operand<i32> {
- let ParserMatchClass = !cast<AsmOperandClass>("UImm32CoercedAsmOperandClass");
+ let ParserMatchClass = UImm32CoercedAsmOperandClass;
}
// Like simm32 but coerces uimm32 to simm32.
def simm32_relaxed : Operand<i32> {
let DecoderMethod = "DecodeSImmWithOffsetAndScale<32>";
- let ParserMatchClass = !cast<AsmOperandClass>("SImm32RelaxedAsmOperandClass");
+ let ParserMatchClass = SImm32RelaxedAsmOperandClass;
}
// This is almost the same as a uimm7 but 0x7f is interpreted as -1.
@@ -1077,59 +1086,14 @@ def MipsMemAsmOperand : AsmOperandClass {
let ParserMethod = "parseMemOperand";
}
-def MipsMemSimm9AsmOperand : AsmOperandClass {
- let Name = "MemOffsetSimm9";
- let SuperClasses = [MipsMemAsmOperand];
- let RenderMethod = "addMemOperands";
- let ParserMethod = "parseMemOperand";
- let PredicateMethod = "isMemWithSimmOffset<9>";
- let DiagnosticType = "MemSImm9";
-}
-
-def MipsMemSimm10AsmOperand : AsmOperandClass {
- let Name = "MemOffsetSimm10";
- let SuperClasses = [MipsMemAsmOperand];
- let RenderMethod = "addMemOperands";
- let ParserMethod = "parseMemOperand";
- let PredicateMethod = "isMemWithSimmOffset<10>";
- let DiagnosticType = "MemSImm10";
-}
-
-def MipsMemSimm12AsmOperand : AsmOperandClass {
- let Name = "MemOffsetSimm12";
- let SuperClasses = [MipsMemAsmOperand];
- let RenderMethod = "addMemOperands";
- let ParserMethod = "parseMemOperand";
- let PredicateMethod = "isMemWithSimmOffset<12>";
- let DiagnosticType = "MemSImm12";
-}
-
-foreach I = {1, 2, 3} in
- def MipsMemSimm10Lsl # I # AsmOperand : AsmOperandClass {
- let Name = "MemOffsetSimm10_" # I;
- let SuperClasses = [MipsMemAsmOperand];
- let RenderMethod = "addMemOperands";
- let ParserMethod = "parseMemOperand";
- let PredicateMethod = "isMemWithSimmOffset<10, " # I # ">";
- let DiagnosticType = "MemSImm10Lsl" # I;
- }
-
-def MipsMemSimm11AsmOperand : AsmOperandClass {
- let Name = "MemOffsetSimm11";
- let SuperClasses = [MipsMemAsmOperand];
- let RenderMethod = "addMemOperands";
- let ParserMethod = "parseMemOperand";
- let PredicateMethod = "isMemWithSimmOffset<11>";
- let DiagnosticType = "MemSImm11";
-}
-
-def MipsMemSimm16AsmOperand : AsmOperandClass {
- let Name = "MemOffsetSimm16";
+class MipsMemSimmAsmOperand<int Width, int Shift = 0> : AsmOperandClass {
+ let Name = "MemOffsetSimm" # Width # "_" # Shift;
let SuperClasses = [MipsMemAsmOperand];
let RenderMethod = "addMemOperands";
let ParserMethod = "parseMemOperand";
- let PredicateMethod = "isMemWithSimmOffset<16>";
- let DiagnosticType = "MemSImm16";
+ let PredicateMethod = "isMemWithSimmOffset<" # Width # ", " # Shift # ">";
+ let DiagnosticType = !if(!eq(Shift, 0), "MemSImm" # Width,
+ "MemSImm" # Width # "Lsl" # Shift);
}
def MipsMemSimmPtrAsmOperand : AsmOperandClass {
@@ -1176,44 +1140,26 @@ def simm12 : Operand<i32> {
let DecoderMethod = "DecodeSimm12";
}
-def mem_simm9 : mem_generic {
+def mem_simm9_exp : mem_generic {
let MIOperandInfo = (ops ptr_rc, simm9);
- let EncoderMethod = "getMemEncoding";
- let ParserMatchClass = MipsMemSimm9AsmOperand;
+ let ParserMatchClass = MipsMemSimmPtrAsmOperand;
+ let OperandNamespace = "MipsII";
+ let OperandType = "OPERAND_MEM_SIMM9";
}
-def mem_simm10 : mem_generic {
- let MIOperandInfo = (ops ptr_rc, simm10);
- let EncoderMethod = "getMemEncoding";
- let ParserMatchClass = MipsMemSimm10AsmOperand;
-}
+foreach I = {9, 10, 11, 12, 16} in
+ def mem_simm # I : mem_generic {
+ let MIOperandInfo = (ops ptr_rc, !cast<Operand>("simm" # I));
+ let ParserMatchClass = MipsMemSimmAsmOperand<I>;
+ }
foreach I = {1, 2, 3} in
def mem_simm10_lsl # I : mem_generic {
let MIOperandInfo = (ops ptr_rc, !cast<Operand>("simm10_lsl" # I));
let EncoderMethod = "getMemEncoding<" # I # ">";
- let ParserMatchClass =
- !cast<AsmOperandClass>("MipsMemSimm10Lsl" # I # "AsmOperand");
+ let ParserMatchClass = MipsMemSimmAsmOperand<10, I>;
}
-def mem_simm11 : mem_generic {
- let MIOperandInfo = (ops ptr_rc, simm11);
- let EncoderMethod = "getMemEncoding";
- let ParserMatchClass = MipsMemSimm11AsmOperand;
-}
-
-def mem_simm12 : mem_generic {
- let MIOperandInfo = (ops ptr_rc, simm12);
- let EncoderMethod = "getMemEncoding";
- let ParserMatchClass = MipsMemSimm12AsmOperand;
-}
-
-def mem_simm16 : mem_generic {
- let MIOperandInfo = (ops ptr_rc, simm16);
- let EncoderMethod = "getMemEncoding";
- let ParserMatchClass = MipsMemSimm16AsmOperand;
-}
-
def mem_simmptr : mem_generic {
let ParserMatchClass = MipsMemSimmPtrAsmOperand;
}
@@ -1260,6 +1206,7 @@ def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
// Node immediate fits as 16-bit sign extended on target immediate.
// e.g. addi, andi
def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
+def imm32SExt16 : IntImmLeaf<i32, [{ return isInt<16>(Imm.getSExtValue()); }]>;
// Node immediate fits as 7-bit zero extended on target immediate.
def immZExt7 : PatLeaf<(imm), [{ return isUInt<7>(N->getZExtValue()); }]>;
@@ -1275,6 +1222,9 @@ def immZExt16 : PatLeaf<(imm), [{
else
return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
}], LO16>;
+def imm32ZExt16 : IntImmLeaf<i32, [{
+ return (uint32_t)Imm.getZExtValue() == (unsigned short)Imm.getZExtValue();
+}]>;
// Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
def immSExt32Low16Zero : PatLeaf<(imm), [{
@@ -1975,6 +1925,18 @@ let usesCustomInserter = 1 in {
def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
+ def ATOMIC_LOAD_MIN_I8 : Atomic2Ops<atomic_load_min_8, GPR32>;
+ def ATOMIC_LOAD_MIN_I16 : Atomic2Ops<atomic_load_min_16, GPR32>;
+ def ATOMIC_LOAD_MIN_I32 : Atomic2Ops<atomic_load_min_32, GPR32>;
+ def ATOMIC_LOAD_MAX_I8 : Atomic2Ops<atomic_load_max_8, GPR32>;
+ def ATOMIC_LOAD_MAX_I16 : Atomic2Ops<atomic_load_max_16, GPR32>;
+ def ATOMIC_LOAD_MAX_I32 : Atomic2Ops<atomic_load_max_32, GPR32>;
+ def ATOMIC_LOAD_UMIN_I8 : Atomic2Ops<atomic_load_umin_8, GPR32>;
+ def ATOMIC_LOAD_UMIN_I16 : Atomic2Ops<atomic_load_umin_16, GPR32>;
+ def ATOMIC_LOAD_UMIN_I32 : Atomic2Ops<atomic_load_umin_32, GPR32>;
+ def ATOMIC_LOAD_UMAX_I8 : Atomic2Ops<atomic_load_umax_8, GPR32>;
+ def ATOMIC_LOAD_UMAX_I16 : Atomic2Ops<atomic_load_umax_16, GPR32>;
+ def ATOMIC_LOAD_UMAX_I32 : Atomic2Ops<atomic_load_umax_32, GPR32>;
}
def ATOMIC_LOAD_ADD_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
@@ -2004,6 +1966,19 @@ def ATOMIC_CMP_SWAP_I8_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
def ATOMIC_CMP_SWAP_I16_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
def ATOMIC_CMP_SWAP_I32_POSTRA : AtomicCmpSwapPostRA<GPR32>;
+def ATOMIC_LOAD_MIN_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
+def ATOMIC_LOAD_MIN_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
+def ATOMIC_LOAD_MIN_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
+def ATOMIC_LOAD_MAX_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
+def ATOMIC_LOAD_MAX_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
+def ATOMIC_LOAD_MAX_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
+def ATOMIC_LOAD_UMIN_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
+def ATOMIC_LOAD_UMIN_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
+def ATOMIC_LOAD_UMIN_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
+def ATOMIC_LOAD_UMAX_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
+def ATOMIC_LOAD_UMAX_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
+def ATOMIC_LOAD_UMAX_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
+
/// Pseudo instructions for loading and storing accumulator registers.
let isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
def LOAD_ACC64 : Load<"", ACC64>;
@@ -2046,17 +2021,17 @@ def LONG_BRANCH_ADDiu2Op : PseudoSE<(outs GPR32Opnd:$dst),
/// Arithmetic Instructions (ALU Immediate)
let AdditionalPredicates = [NotInMicroMips] in {
def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16_relaxed, GPR32Opnd,
- II_ADDIU, immSExt16, add>,
+ II_ADDIU, imm32SExt16, add>,
ADDI_FM<0x9>, IsAsCheapAsAMove, ISA_MIPS1;
def ANDi : MMRel, StdMMR6Rel,
- ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>,
+ ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, imm32ZExt16, and>,
ADDI_FM<0xc>, ISA_MIPS1;
def ORi : MMRel, StdMMR6Rel,
- ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, or>,
+ ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, imm32ZExt16, or>,
ADDI_FM<0xd>, ISA_MIPS1;
def XORi : MMRel, StdMMR6Rel,
- ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>,
+ ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, imm32ZExt16, xor>,
ADDI_FM<0xe>, ISA_MIPS1;
def ADDi : MMRel, ArithLogicI<"addi", simm16_relaxed, GPR32Opnd, II_ADDI>,
ADDI_FM<0x8>, ISA_MIPS1_NOT_32R6_64R6;
@@ -2069,10 +2044,10 @@ let AdditionalPredicates = [NotInMicroMips] in {
ISA_MIPS1;
/// Arithmetic Instructions (3-Operand, R-Type)
- def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
- ADD_FM<0, 0x21>, ISA_MIPS1;
- def SUBu : MMRel, StdMMR6Rel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
- ADD_FM<0, 0x23>, ISA_MIPS1;
+ def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
+ ADD_FM<0, 0x21>, ISA_MIPS1;
+ def SUBu : MMRel, StdMMR6Rel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
+ ADD_FM<0, 0x23>, ISA_MIPS1;
let Defs = [HI0, LO0] in
def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
@@ -2137,7 +2112,8 @@ let AdditionalPredicates = [NotInMicroMips] in {
LW_FM<0x28>, ISA_MIPS1;
def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>,
ISA_MIPS1;
- def SW : StdMMR6Rel, Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>, ISA_MIPS1;
+ def SW : StdMMR6Rel, Store<"sw", GPR32Opnd, store, II_SW>,
+ MMRel, LW_FM<0x2b>, ISA_MIPS1;
}
/// load/store left/right
@@ -2238,7 +2214,8 @@ def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
IsBranch, ISA_MIPS1;
let AdditionalPredicates = [NotInMicroMips] in {
-def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>, ISA_MIPS1_NOT_32R6_64R6;
+def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>,
+ ISA_MIPS1_NOT_32R6_64R6;
def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>,
ISA_MIPS1;
def BEQL : MMRel, CBranchLikely<"beql", brtarget, GPR32Opnd>,
@@ -2396,7 +2373,8 @@ let AdditionalPredicates = [NotInMicroMips] in {
// add op with mem ComplexPattern is used and the stack address copy
// can be matched. It's similar to Sparc LEA_ADDRi
let AdditionalPredicates = [NotInMicroMips] in
- def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>, ISA_MIPS1;
+ def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>,
+ ISA_MIPS1;
// MADD*/MSUB*
def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
@@ -2572,9 +2550,11 @@ def DROLImm : MipsAsmPseudoInst<(outs),
(ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
"drol\t$rs, $rt, $imm">, ISA_MIPS64;
def : MipsInstAlias<"drol $rd, $rs",
- (DROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
+ (DROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
+ ISA_MIPS64;
def : MipsInstAlias<"drol $rd, $imm",
- (DROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
+ (DROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>,
+ ISA_MIPS64;
def DROR : MipsAsmPseudoInst<(outs),
(ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
@@ -2583,9 +2563,11 @@ def DRORImm : MipsAsmPseudoInst<(outs),
(ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
"dror\t$rs, $rt, $imm">, ISA_MIPS64;
def : MipsInstAlias<"dror $rd, $rs",
- (DROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
+ (DROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
+ ISA_MIPS64;
def : MipsInstAlias<"dror $rd, $imm",
- (DRORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
+ (DRORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>,
+ ISA_MIPS64;
def ABSMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
"abs\t$rd, $rs">;
@@ -2762,7 +2744,8 @@ let AdditionalPredicates = [NotInMicroMips] in {
def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>, ISA_MIPS1;
- defm : OneOrTwoOperandMacroImmediateAlias<"add", ADDi>, ISA_MIPS1_NOT_32R6_64R6;
+ defm : OneOrTwoOperandMacroImmediateAlias<"add", ADDi>,
+ ISA_MIPS1_NOT_32R6_64R6;
defm : OneOrTwoOperandMacroImmediateAlias<"addu", ADDiu>, ISA_MIPS1;
@@ -3089,7 +3072,8 @@ multiclass MaterializeImms<ValueType VT, Register ZEROReg,
// observed.
// Arbitrary immediates
-def : MipsPat<(VT LUiORiPred:$imm), (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>;
+def : MipsPat<(VT LUiORiPred:$imm),
+ (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>;
// Bits 32-16 set, sign/zero extended.
def : MipsPat<(VT LUiPred:$imm), (LUiOp (HI16 imm:$imm))>;
diff --git a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
index f8fc7cb0898b..2f4c9d74262e 100644
--- a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
+++ b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
@@ -18,6 +18,7 @@
#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/IR/IntrinsicsMips.h"
#define DEBUG_TYPE "mips-isel"
@@ -39,12 +40,13 @@ public:
private:
bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
+ bool isRegInGprb(Register Reg, MachineRegisterInfo &MRI) const;
+ bool isRegInFprb(Register Reg, MachineRegisterInfo &MRI) const;
bool materialize32BitImm(Register DestReg, APInt Imm,
MachineIRBuilder &B) const;
bool selectCopy(MachineInstr &I, MachineRegisterInfo &MRI) const;
const TargetRegisterClass *
- getRegClassForTypeOnBank(unsigned OpSize, const RegisterBank &RB,
- const RegisterBankInfo &RBI) const;
+ getRegClassForTypeOnBank(Register Reg, MachineRegisterInfo &MRI) const;
unsigned selectLoadStoreOpCode(MachineInstr &I,
MachineRegisterInfo &MRI) const;
@@ -84,24 +86,23 @@ MipsInstructionSelector::MipsInstructionSelector(
{
}
+bool MipsInstructionSelector::isRegInGprb(Register Reg,
+ MachineRegisterInfo &MRI) const {
+ return RBI.getRegBank(Reg, MRI, TRI)->getID() == Mips::GPRBRegBankID;
+}
+
+bool MipsInstructionSelector::isRegInFprb(Register Reg,
+ MachineRegisterInfo &MRI) const {
+ return RBI.getRegBank(Reg, MRI, TRI)->getID() == Mips::FPRBRegBankID;
+}
+
bool MipsInstructionSelector::selectCopy(MachineInstr &I,
MachineRegisterInfo &MRI) const {
Register DstReg = I.getOperand(0).getReg();
if (Register::isPhysicalRegister(DstReg))
return true;
- const RegisterBank *RegBank = RBI.getRegBank(DstReg, MRI, TRI);
- const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
-
- const TargetRegisterClass *RC = &Mips::GPR32RegClass;
- if (RegBank->getID() == Mips::FPRBRegBankID) {
- if (DstSize == 32)
- RC = &Mips::FGR32RegClass;
- else if (DstSize == 64)
- RC = STI.isFP64bit() ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
- else
- llvm_unreachable("Unsupported destination size");
- }
+ const TargetRegisterClass *RC = getRegClassForTypeOnBank(DstReg, MRI);
if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
<< " operand\n");
@@ -111,19 +112,27 @@ bool MipsInstructionSelector::selectCopy(MachineInstr &I,
}
const TargetRegisterClass *MipsInstructionSelector::getRegClassForTypeOnBank(
- unsigned OpSize, const RegisterBank &RB,
- const RegisterBankInfo &RBI) const {
- if (RB.getID() == Mips::GPRBRegBankID)
+ Register Reg, MachineRegisterInfo &MRI) const {
+ const LLT Ty = MRI.getType(Reg);
+ const unsigned TySize = Ty.getSizeInBits();
+
+ if (isRegInGprb(Reg, MRI)) {
+ assert((Ty.isScalar() || Ty.isPointer()) && TySize == 32 &&
+ "Register class not available for LLT, register bank combination");
return &Mips::GPR32RegClass;
+ }
- if (RB.getID() == Mips::FPRBRegBankID)
- return OpSize == 32
- ? &Mips::FGR32RegClass
- : STI.hasMips32r6() || STI.isFP64bit() ? &Mips::FGR64RegClass
- : &Mips::AFGR64RegClass;
+ if (isRegInFprb(Reg, MRI)) {
+ if (Ty.isScalar()) {
+ assert((TySize == 32 || TySize == 64) &&
+ "Register class not available for LLT, register bank combination");
+ if (TySize == 32)
+ return &Mips::FGR32RegClass;
+ return STI.isFP64bit() ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
+ }
+ }
- llvm_unreachable("getRegClassForTypeOnBank can't find register class.");
- return nullptr;
+ llvm_unreachable("Unsupported register bank.");
}
bool MipsInstructionSelector::materialize32BitImm(Register DestReg, APInt Imm,
@@ -131,8 +140,9 @@ bool MipsInstructionSelector::materialize32BitImm(Register DestReg, APInt Imm,
assert(Imm.getBitWidth() == 32 && "Unsupported immediate size.");
// Ori zero extends immediate. Used for values with zeros in high 16 bits.
if (Imm.getHiBits(16).isNullValue()) {
- MachineInstr *Inst = B.buildInstr(Mips::ORi, {DestReg}, {Register(Mips::ZERO)})
- .addImm(Imm.getLoBits(16).getLimitedValue());
+ MachineInstr *Inst =
+ B.buildInstr(Mips::ORi, {DestReg}, {Register(Mips::ZERO)})
+ .addImm(Imm.getLoBits(16).getLimitedValue());
return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI);
}
// Lui places immediate in high 16 bits and sets low 16 bits to zero.
@@ -143,8 +153,9 @@ bool MipsInstructionSelector::materialize32BitImm(Register DestReg, APInt Imm,
}
// ADDiu sign extends immediate. Used for values with 1s in high 17 bits.
if (Imm.isSignedIntN(16)) {
- MachineInstr *Inst = B.buildInstr(Mips::ADDiu, {DestReg}, {Register(Mips::ZERO)})
- .addImm(Imm.getLoBits(16).getLimitedValue());
+ MachineInstr *Inst =
+ B.buildInstr(Mips::ADDiu, {DestReg}, {Register(Mips::ZERO)})
+ .addImm(Imm.getLoBits(16).getLimitedValue());
return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI);
}
// Values that cannot be materialized with single immediate instruction.
@@ -160,17 +171,22 @@ bool MipsInstructionSelector::materialize32BitImm(Register DestReg, APInt Imm,
return true;
}
-/// Returning Opc indicates that we failed to select MIPS instruction opcode.
+/// When I.getOpcode() is returned, we failed to select MIPS instruction opcode.
unsigned
MipsInstructionSelector::selectLoadStoreOpCode(MachineInstr &I,
MachineRegisterInfo &MRI) const {
- STI.getRegisterInfo();
- const Register DestReg = I.getOperand(0).getReg();
- const unsigned RegBank = RBI.getRegBank(DestReg, MRI, TRI)->getID();
+ const Register ValueReg = I.getOperand(0).getReg();
+ const LLT Ty = MRI.getType(ValueReg);
+ const unsigned TySize = Ty.getSizeInBits();
const unsigned MemSizeInBytes = (*I.memoperands_begin())->getSize();
unsigned Opc = I.getOpcode();
const bool isStore = Opc == TargetOpcode::G_STORE;
- if (RegBank == Mips::GPRBRegBankID) {
+
+ if (isRegInGprb(ValueReg, MRI)) {
+ assert(((Ty.isScalar() && TySize == 32) ||
+ (Ty.isPointer() && TySize == 32 && MemSizeInBytes == 4)) &&
+ "Unsupported register bank, LLT, MemSizeInBytes combination");
+ (void)TySize;
if (isStore)
switch (MemSizeInBytes) {
case 4:
@@ -196,33 +212,39 @@ MipsInstructionSelector::selectLoadStoreOpCode(MachineInstr &I,
}
}
- if (RegBank == Mips::FPRBRegBankID) {
- switch (MemSizeInBytes) {
- case 4:
- return isStore ? Mips::SWC1 : Mips::LWC1;
- case 8:
+ if (isRegInFprb(ValueReg, MRI)) {
+ if (Ty.isScalar()) {
+ assert(((TySize == 32 && MemSizeInBytes == 4) ||
+ (TySize == 64 && MemSizeInBytes == 8)) &&
+ "Unsupported register bank, LLT, MemSizeInBytes combination");
+
+ if (MemSizeInBytes == 4)
+ return isStore ? Mips::SWC1 : Mips::LWC1;
+
if (STI.isFP64bit())
return isStore ? Mips::SDC164 : Mips::LDC164;
- else
- return isStore ? Mips::SDC1 : Mips::LDC1;
- case 16: {
+ return isStore ? Mips::SDC1 : Mips::LDC1;
+ }
+
+ if (Ty.isVector()) {
assert(STI.hasMSA() && "Vector instructions require target with MSA.");
- const unsigned VectorElementSizeInBytes =
- MRI.getType(DestReg).getElementType().getSizeInBytes();
- if (VectorElementSizeInBytes == 1)
+ assert((TySize == 128 && MemSizeInBytes == 16) &&
+ "Unsupported register bank, LLT, MemSizeInBytes combination");
+ switch (Ty.getElementType().getSizeInBits()) {
+ case 8:
return isStore ? Mips::ST_B : Mips::LD_B;
- if (VectorElementSizeInBytes == 2)
+ case 16:
return isStore ? Mips::ST_H : Mips::LD_H;
- if (VectorElementSizeInBytes == 4)
+ case 32:
return isStore ? Mips::ST_W : Mips::LD_W;
- if (VectorElementSizeInBytes == 8)
+ case 64:
return isStore ? Mips::ST_D : Mips::LD_D;
- return Opc;
- }
- default:
- return Opc;
+ default:
+ return Opc;
+ }
}
}
+
return Opc;
}
@@ -239,7 +261,8 @@ bool MipsInstructionSelector::select(MachineInstr &I) {
return true;
}
- if (I.getOpcode() == Mips::G_MUL) {
+ if (I.getOpcode() == Mips::G_MUL &&
+ isRegInGprb(I.getOperand(0).getReg(), MRI)) {
MachineInstr *Mul = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MUL))
.add(I.getOperand(0))
.add(I.getOperand(1))
@@ -280,7 +303,7 @@ bool MipsInstructionSelector::select(MachineInstr &I) {
I.eraseFromParent();
return true;
}
- case G_GEP: {
+ case G_PTR_ADD: {
MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDu))
.add(I.getOperand(0))
.add(I.getOperand(1))
@@ -367,14 +390,12 @@ bool MipsInstructionSelector::select(MachineInstr &I) {
}
case G_PHI: {
const Register DestReg = I.getOperand(0).getReg();
- const unsigned OpSize = MRI.getType(DestReg).getSizeInBits();
const TargetRegisterClass *DefRC = nullptr;
if (Register::isPhysicalRegister(DestReg))
DefRC = TRI.getRegClass(DestReg);
else
- DefRC = getRegClassForTypeOnBank(OpSize,
- *RBI.getRegBank(DestReg, MRI, TRI), RBI);
+ DefRC = getRegClassForTypeOnBank(DestReg, MRI);
I.setDesc(TII.get(TargetOpcode::PHI));
return RBI.constrainGenericRegister(DestReg, *DefRC, MRI);
@@ -389,15 +410,15 @@ bool MipsInstructionSelector::select(MachineInstr &I) {
MachineOperand BaseAddr = I.getOperand(1);
int64_t SignedOffset = 0;
- // Try to fold load/store + G_GEP + G_CONSTANT
+ // Try to fold load/store + G_PTR_ADD + G_CONSTANT
// %SignedOffset:(s32) = G_CONSTANT i32 16_bit_signed_immediate
- // %Addr:(p0) = G_GEP %BaseAddr, %SignedOffset
+ // %Addr:(p0) = G_PTR_ADD %BaseAddr, %SignedOffset
// %LoadResult/%StoreSrc = load/store %Addr(p0)
// into:
// %LoadResult/%StoreSrc = NewOpc %BaseAddr(p0), 16_bit_signed_immediate
MachineInstr *Addr = MRI.getVRegDef(I.getOperand(1).getReg());
- if (Addr->getOpcode() == G_GEP) {
+ if (Addr->getOpcode() == G_PTR_ADD) {
MachineInstr *Offset = MRI.getVRegDef(Addr->getOperand(2).getReg());
if (Offset->getOpcode() == G_CONSTANT) {
APInt OffsetValue = Offset->getOperand(1).getCImm()->getValue();
@@ -452,15 +473,12 @@ bool MipsInstructionSelector::select(MachineInstr &I) {
break;
}
case G_IMPLICIT_DEF: {
+ Register Dst = I.getOperand(0).getReg();
MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::IMPLICIT_DEF))
- .add(I.getOperand(0));
+ .addDef(Dst);
// Set class based on register bank, there can be fpr and gpr implicit def.
- MRI.setRegClass(MI->getOperand(0).getReg(),
- getRegClassForTypeOnBank(
- MRI.getType(I.getOperand(0).getReg()).getSizeInBits(),
- *RBI.getRegBank(I.getOperand(0).getReg(), MRI, TRI),
- RBI));
+ MRI.setRegClass(Dst, getRegClassForTypeOnBank(Dst, MRI));
break;
}
case G_CONSTANT: {
diff --git a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
index bb4a1d902d75..9645aa24dc05 100644
--- a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
@@ -13,6 +13,7 @@
#include "MipsLegalizerInfo.h"
#include "MipsTargetMachine.h"
#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
+#include "llvm/IR/IntrinsicsMips.h"
using namespace llvm;
@@ -61,11 +62,7 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) {
const LLT v2s64 = LLT::vector(2, 64);
const LLT p0 = LLT::pointer(0, 32);
- getActionDefinitionsBuilder({G_SUB, G_MUL})
- .legalFor({s32})
- .clampScalar(0, s32, s32);
-
- getActionDefinitionsBuilder(G_ADD)
+ getActionDefinitionsBuilder({G_ADD, G_SUB, G_MUL})
.legalIf([=, &ST](const LegalityQuery &Query) {
if (CheckTyN(0, Query, {s32}))
return true;
@@ -145,8 +142,14 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) {
.legalFor({s32})
.clampScalar(0, s32, s32);
- getActionDefinitionsBuilder({G_SDIV, G_SREM, G_UREM, G_UDIV})
- .legalFor({s32})
+ getActionDefinitionsBuilder({G_SDIV, G_SREM, G_UDIV, G_UREM})
+ .legalIf([=, &ST](const LegalityQuery &Query) {
+ if (CheckTyN(0, Query, {s32}))
+ return true;
+ if (ST.hasMSA() && CheckTyN(0, Query, {v16s8, v8s16, v4s32, v2s64}))
+ return true;
+ return false;
+ })
.minScalar(0, s32)
.libcallFor({s64});
@@ -164,7 +167,7 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) {
.legalFor({s32})
.clampScalar(0, s32, s32);
- getActionDefinitionsBuilder({G_GEP, G_INTTOPTR})
+ getActionDefinitionsBuilder({G_PTR_ADD, G_INTTOPTR})
.legalFor({{p0, s32}});
getActionDefinitionsBuilder(G_PTRTOINT)
@@ -182,12 +185,35 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) {
getActionDefinitionsBuilder(G_VASTART)
.legalFor({p0});
+ getActionDefinitionsBuilder(G_BSWAP)
+ .legalIf([=, &ST](const LegalityQuery &Query) {
+ if (ST.hasMips32r2() && CheckTyN(0, Query, {s32}))
+ return true;
+ return false;
+ })
+ .lowerIf([=, &ST](const LegalityQuery &Query) {
+ if (!ST.hasMips32r2() && CheckTyN(0, Query, {s32}))
+ return true;
+ return false;
+ })
+ .maxScalar(0, s32);
+
+ getActionDefinitionsBuilder(G_BITREVERSE)
+ .lowerFor({s32})
+ .maxScalar(0, s32);
+
// FP instructions
getActionDefinitionsBuilder(G_FCONSTANT)
.legalFor({s32, s64});
getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FABS, G_FSQRT})
- .legalFor({s32, s64});
+ .legalIf([=, &ST](const LegalityQuery &Query) {
+ if (CheckTyN(0, Query, {s32, s64}))
+ return true;
+ if (ST.hasMSA() && CheckTyN(0, Query, {v16s8, v8s16, v4s32, v2s64}))
+ return true;
+ return false;
+ });
getActionDefinitionsBuilder(G_FCMP)
.legalFor({{s32, s32}, {s32, s64}})
@@ -315,6 +341,17 @@ static bool MSA3OpIntrinsicToGeneric(MachineInstr &MI, unsigned Opcode,
return true;
}
+static bool MSA2OpIntrinsicToGeneric(MachineInstr &MI, unsigned Opcode,
+ MachineIRBuilder &MIRBuilder,
+ const MipsSubtarget &ST) {
+ assert(ST.hasMSA() && "MSA intrinsic not supported on target without MSA.");
+ MIRBuilder.buildInstr(Opcode)
+ .add(MI.getOperand(0))
+ .add(MI.getOperand(2));
+ MI.eraseFromParent();
+ return true;
+}
+
bool MipsLegalizerInfo::legalizeIntrinsic(MachineInstr &MI,
MachineRegisterInfo &MRI,
MachineIRBuilder &MIRBuilder) const {
@@ -364,6 +401,64 @@ bool MipsLegalizerInfo::legalizeIntrinsic(MachineInstr &MI,
return SelectMSA3OpIntrinsic(MI, Mips::ADDVI_W, MIRBuilder, ST);
case Intrinsic::mips_addvi_d:
return SelectMSA3OpIntrinsic(MI, Mips::ADDVI_D, MIRBuilder, ST);
+ case Intrinsic::mips_subv_b:
+ case Intrinsic::mips_subv_h:
+ case Intrinsic::mips_subv_w:
+ case Intrinsic::mips_subv_d:
+ return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_SUB, MIRBuilder, ST);
+ case Intrinsic::mips_subvi_b:
+ return SelectMSA3OpIntrinsic(MI, Mips::SUBVI_B, MIRBuilder, ST);
+ case Intrinsic::mips_subvi_h:
+ return SelectMSA3OpIntrinsic(MI, Mips::SUBVI_H, MIRBuilder, ST);
+ case Intrinsic::mips_subvi_w:
+ return SelectMSA3OpIntrinsic(MI, Mips::SUBVI_W, MIRBuilder, ST);
+ case Intrinsic::mips_subvi_d:
+ return SelectMSA3OpIntrinsic(MI, Mips::SUBVI_D, MIRBuilder, ST);
+ case Intrinsic::mips_mulv_b:
+ case Intrinsic::mips_mulv_h:
+ case Intrinsic::mips_mulv_w:
+ case Intrinsic::mips_mulv_d:
+ return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_MUL, MIRBuilder, ST);
+ case Intrinsic::mips_div_s_b:
+ case Intrinsic::mips_div_s_h:
+ case Intrinsic::mips_div_s_w:
+ case Intrinsic::mips_div_s_d:
+ return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_SDIV, MIRBuilder, ST);
+ case Intrinsic::mips_mod_s_b:
+ case Intrinsic::mips_mod_s_h:
+ case Intrinsic::mips_mod_s_w:
+ case Intrinsic::mips_mod_s_d:
+ return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_SREM, MIRBuilder, ST);
+ case Intrinsic::mips_div_u_b:
+ case Intrinsic::mips_div_u_h:
+ case Intrinsic::mips_div_u_w:
+ case Intrinsic::mips_div_u_d:
+ return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_UDIV, MIRBuilder, ST);
+ case Intrinsic::mips_mod_u_b:
+ case Intrinsic::mips_mod_u_h:
+ case Intrinsic::mips_mod_u_w:
+ case Intrinsic::mips_mod_u_d:
+ return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_UREM, MIRBuilder, ST);
+ case Intrinsic::mips_fadd_w:
+ case Intrinsic::mips_fadd_d:
+ return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_FADD, MIRBuilder, ST);
+ case Intrinsic::mips_fsub_w:
+ case Intrinsic::mips_fsub_d:
+ return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_FSUB, MIRBuilder, ST);
+ case Intrinsic::mips_fmul_w:
+ case Intrinsic::mips_fmul_d:
+ return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_FMUL, MIRBuilder, ST);
+ case Intrinsic::mips_fdiv_w:
+ case Intrinsic::mips_fdiv_d:
+ return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_FDIV, MIRBuilder, ST);
+ case Intrinsic::mips_fmax_a_w:
+ return SelectMSA3OpIntrinsic(MI, Mips::FMAX_A_W, MIRBuilder, ST);
+ case Intrinsic::mips_fmax_a_d:
+ return SelectMSA3OpIntrinsic(MI, Mips::FMAX_A_D, MIRBuilder, ST);
+ case Intrinsic::mips_fsqrt_w:
+ return MSA2OpIntrinsicToGeneric(MI, TargetOpcode::G_FSQRT, MIRBuilder, ST);
+ case Intrinsic::mips_fsqrt_d:
+ return MSA2OpIntrinsicToGeneric(MI, TargetOpcode::G_FSQRT, MIRBuilder, ST);
default:
break;
}
diff --git a/llvm/lib/Target/Mips/MipsMCInstLower.cpp b/llvm/lib/Target/Mips/MipsMCInstLower.cpp
index fd984058a2bf..66e04bda2af3 100644
--- a/llvm/lib/Target/Mips/MipsMCInstLower.cpp
+++ b/llvm/lib/Target/Mips/MipsMCInstLower.cpp
@@ -34,7 +34,7 @@ void MipsMCInstLower::Initialize(MCContext *C) {
MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
MachineOperandType MOTy,
- unsigned Offset) const {
+ int64_t Offset) const {
MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
MipsMCExpr::MipsExprKind TargetKind = MipsMCExpr::MEK_None;
bool IsGpOff = false;
@@ -161,9 +161,7 @@ MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, Kind, *Ctx);
if (Offset) {
- // Assume offset is never negative.
- assert(Offset > 0);
-
+ // Note: Offset can also be negative
Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Offset, *Ctx),
*Ctx);
}
@@ -177,7 +175,7 @@ MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
}
MCOperand MipsMCInstLower::LowerOperand(const MachineOperand &MO,
- unsigned offset) const {
+ int64_t offset) const {
MachineOperandType MOTy = MO.getType();
switch (MOTy) {
diff --git a/llvm/lib/Target/Mips/MipsMCInstLower.h b/llvm/lib/Target/Mips/MipsMCInstLower.h
index 29af6f21de82..605a124bf102 100644
--- a/llvm/lib/Target/Mips/MipsMCInstLower.h
+++ b/llvm/lib/Target/Mips/MipsMCInstLower.h
@@ -35,11 +35,11 @@ public:
void Initialize(MCContext *C);
void Lower(const MachineInstr *MI, MCInst &OutMI) const;
- MCOperand LowerOperand(const MachineOperand& MO, unsigned offset = 0) const;
+ MCOperand LowerOperand(const MachineOperand &MO, int64_t offset = 0) const;
private:
MCOperand LowerSymbolOperand(const MachineOperand &MO,
- MachineOperandType MOTy, unsigned Offset) const;
+ MachineOperandType MOTy, int64_t Offset) const;
MCOperand createSub(MachineBasicBlock *BB1, MachineBasicBlock *BB2,
MipsMCExpr::MipsExprKind Kind) const;
void lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI) const;
diff --git a/llvm/lib/Target/Mips/MipsMSAInstrInfo.td b/llvm/lib/Target/Mips/MipsMSAInstrInfo.td
index f585d9c1a148..0fef518c240e 100644
--- a/llvm/lib/Target/Mips/MipsMSAInstrInfo.td
+++ b/llvm/lib/Target/Mips/MipsMSAInstrInfo.td
@@ -1287,6 +1287,7 @@ class MSA_I10_LDI_DESC_BASE<string instr_asm, RegisterOperand ROWD,
// LDI is matched using custom matching code in MipsSEISelDAGToDAG.cpp
list<dag> Pattern = [];
bit hasSideEffects = 0;
+ bit isReMaterializable = 1;
InstrItinClass Itinerary = itin;
}
diff --git a/llvm/lib/Target/Mips/MipsPreLegalizerCombiner.cpp b/llvm/lib/Target/Mips/MipsPreLegalizerCombiner.cpp
index ace0735652bd..f9d93ca29658 100644
--- a/llvm/lib/Target/Mips/MipsPreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/Mips/MipsPreLegalizerCombiner.cpp
@@ -17,6 +17,7 @@
#include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/InitializePasses.h"
#define DEBUG_TYPE "mips-prelegalizer-combiner"
diff --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
index d334366e727c..2a3f5a05dfe0 100644
--- a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
@@ -76,8 +76,9 @@ using namespace llvm;
MipsRegisterBankInfo::MipsRegisterBankInfo(const TargetRegisterInfo &TRI)
: MipsGenRegisterBankInfo() {}
-const RegisterBank &MipsRegisterBankInfo::getRegBankFromRegClass(
- const TargetRegisterClass &RC) const {
+const RegisterBank &
+MipsRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
+ LLT) const {
using namespace Mips;
switch (RC.getID()) {
@@ -437,12 +438,10 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
switch (Opc) {
case G_TRUNC:
- case G_SUB:
- case G_MUL:
case G_UMULH:
case G_ZEXTLOAD:
case G_SEXTLOAD:
- case G_GEP:
+ case G_PTR_ADD:
case G_INTTOPTR:
case G_PTRTOINT:
case G_AND:
@@ -451,15 +450,18 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case G_SHL:
case G_ASHR:
case G_LSHR:
- case G_SDIV:
- case G_UDIV:
- case G_SREM:
- case G_UREM:
case G_BRINDIRECT:
case G_VASTART:
+ case G_BSWAP:
OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
break;
case G_ADD:
+ case G_SUB:
+ case G_MUL:
+ case G_SDIV:
+ case G_SREM:
+ case G_UDIV:
+ case G_UREM:
OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
if (Op0Size == 128)
OperandsMapping = getMSAMapping(MF);
@@ -546,6 +548,8 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case G_FABS:
case G_FSQRT:
OperandsMapping = getFprbMapping(Op0Size);
+ if (Op0Size == 128)
+ OperandsMapping = getMSAMapping(MF);
break;
case G_FCONSTANT:
OperandsMapping = getOperandsMapping({getFprbMapping(Op0Size), nullptr});
@@ -636,7 +640,7 @@ void MipsRegisterBankInfo::setRegBank(MachineInstr &MI,
MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID));
break;
}
- case TargetOpcode::G_GEP: {
+ case TargetOpcode::G_PTR_ADD: {
assert(MRI.getType(Dest).isPointer() && "Unexpected operand type.");
MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID));
break;
@@ -649,8 +653,9 @@ void MipsRegisterBankInfo::setRegBank(MachineInstr &MI,
static void
combineAwayG_UNMERGE_VALUES(LegalizationArtifactCombiner &ArtCombiner,
MachineInstr &MI) {
+ SmallVector<Register, 4> UpdatedDefs;
SmallVector<MachineInstr *, 2> DeadInstrs;
- ArtCombiner.tryCombineMerges(MI, DeadInstrs);
+ ArtCombiner.tryCombineMerges(MI, DeadInstrs, UpdatedDefs);
for (MachineInstr *DeadMI : DeadInstrs)
DeadMI->eraseFromParent();
}
diff --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.h b/llvm/lib/Target/Mips/MipsRegisterBankInfo.h
index fa0f1c7bc941..66267f8d794d 100644
--- a/llvm/lib/Target/Mips/MipsRegisterBankInfo.h
+++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.h
@@ -32,8 +32,8 @@ class MipsRegisterBankInfo final : public MipsGenRegisterBankInfo {
public:
MipsRegisterBankInfo(const TargetRegisterInfo &TRI);
- const RegisterBank &
- getRegBankFromRegClass(const TargetRegisterClass &RC) const override;
+ const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC,
+ LLT) const override;
const InstructionMapping &
getInstrMapping(const MachineInstr &MI) const override;
diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
index c8313240a678..bef1a3657ea5 100644
--- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
+++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
@@ -27,6 +27,7 @@
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsMips.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -234,8 +235,8 @@ void MipsSEDAGToDAGISel::selectAddE(SDNode *Node, const SDLoc &DL) const {
SDValue OuFlag = CurDAG->getTargetConstant(20, DL, MVT::i32);
- SDNode *DSPCtrlField =
- CurDAG->getMachineNode(Mips::RDDSP, DL, MVT::i32, MVT::Glue, CstOne, InFlag);
+ SDNode *DSPCtrlField = CurDAG->getMachineNode(Mips::RDDSP, DL, MVT::i32,
+ MVT::Glue, CstOne, InFlag);
SDNode *Carry = CurDAG->getMachineNode(
Mips::EXT, DL, MVT::i32, SDValue(DSPCtrlField, 0), OuFlag, CstOne);
@@ -253,7 +254,8 @@ void MipsSEDAGToDAGISel::selectAddE(SDNode *Node, const SDLoc &DL) const {
SDValue Zero = CurDAG->getRegister(Mips::ZERO, MVT::i32);
SDValue InsOps[4] = {Zero, OuFlag, CstOne, SDValue(DSPCFWithCarry, 0)};
- SDNode *DSPCtrlFinal = CurDAG->getMachineNode(Mips::INS, DL, MVT::i32, InsOps);
+ SDNode *DSPCtrlFinal =
+ CurDAG->getMachineNode(Mips::INS, DL, MVT::i32, InsOps);
SDNode *WrDSP = CurDAG->getMachineNode(Mips::WRDSP, DL, MVT::Glue,
SDValue(DSPCtrlFinal, 0), CstOne);
@@ -1074,7 +1076,8 @@ bool MipsSEDAGToDAGISel::trySelect(SDNode *Node) {
Hi ? SDValue(Res, 0) : ZeroVal, LoVal);
assert((Hi || Lo) && "Zero case reached 32 bit case splat synthesis!");
- Res = CurDAG->getMachineNode(Mips::FILL_W, DL, MVT::v4i32, SDValue(Res, 0));
+ Res =
+ CurDAG->getMachineNode(Mips::FILL_W, DL, MVT::v4i32, SDValue(Res, 0));
} else if (SplatValue.isSignedIntN(32) && SplatBitSize == 64 &&
(ABI.IsN32() || ABI.IsN64())) {
@@ -1117,8 +1120,8 @@ bool MipsSEDAGToDAGISel::trySelect(SDNode *Node) {
// $res4 = insert.w $res3[1], $res fill.d $res
// splat.d $res4, 0
//
- // The ability to use dinsu is guaranteed as MSA requires MIPSR5. This saves
- // having to materialize the value by shifts and ors.
+ // The ability to use dinsu is guaranteed as MSA requires MIPSR5.
+ // This saves having to materialize the value by shifts and ors.
//
// FIXME: Implement the preferred sequence for MIPS64R6:
//
@@ -1239,7 +1242,8 @@ bool MipsSEDAGToDAGISel::trySelect(SDNode *Node) {
llvm_unreachable(
"Zero splat value handled by non-zero 64bit splat synthesis!");
- Res = CurDAG->getMachineNode(Mips::FILL_D, DL, MVT::v2i64, SDValue(Res, 0));
+ Res = CurDAG->getMachineNode(Mips::FILL_D, DL, MVT::v2i64,
+ SDValue(Res, 0));
} else
llvm_unreachable("Unknown ABI in MipsISelDAGToDAG!");
@@ -1278,10 +1282,6 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
default:
llvm_unreachable("Unexpected asm memory constraint");
// All memory constraints can at least accept raw pointers.
- case InlineAsm::Constraint_i:
- OutOps.push_back(Op);
- OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32));
- return false;
case InlineAsm::Constraint_m:
case InlineAsm::Constraint_o:
if (selectAddrRegImm16(Op, Base, Offset)) {
diff --git a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
index 5bd234f955ba..798e8784405f 100644
--- a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
@@ -34,6 +34,7 @@
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsMips.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
index 2126a1bda493..d4f09a2f3586 100644
--- a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
@@ -82,8 +82,8 @@ unsigned MipsSEInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
- const DebugLoc &DL, unsigned DestReg,
- unsigned SrcReg, bool KillSrc) const {
+ const DebugLoc &DL, MCRegister DestReg,
+ MCRegister SrcReg, bool KillSrc) const {
unsigned Opc = 0, ZeroReg = 0;
bool isMicroMips = Subtarget.inMicroMipsMode();
@@ -221,29 +221,24 @@ static bool isReadOrWriteToDSPReg(const MachineInstr &MI, bool &isWrite) {
/// We check for the common case of 'or', as it's MIPS' preferred instruction
/// for GPRs but we have to check the operands to ensure that is the case.
/// Other move instructions for MIPS are directly identifiable.
-bool MipsSEInstrInfo::isCopyInstrImpl(const MachineInstr &MI,
- const MachineOperand *&Src,
- const MachineOperand *&Dest) const {
+Optional<DestSourcePair>
+MipsSEInstrInfo::isCopyInstrImpl(const MachineInstr &MI) const {
bool isDSPControlWrite = false;
// Condition is made to match the creation of WRDSP/RDDSP copy instruction
// from copyPhysReg function.
if (isReadOrWriteToDSPReg(MI, isDSPControlWrite)) {
- if (!MI.getOperand(1).isImm() || MI.getOperand(1).getImm() != (1<<4))
- return false;
+ if (!MI.getOperand(1).isImm() || MI.getOperand(1).getImm() != (1 << 4))
+ return None;
else if (isDSPControlWrite) {
- Src = &MI.getOperand(0);
- Dest = &MI.getOperand(2);
+ return DestSourcePair{MI.getOperand(2), MI.getOperand(0)};
+
} else {
- Dest = &MI.getOperand(0);
- Src = &MI.getOperand(2);
+ return DestSourcePair{MI.getOperand(0), MI.getOperand(2)};
}
- return true;
} else if (MI.isMoveReg() || isORCopyInst(MI)) {
- Dest = &MI.getOperand(0);
- Src = &MI.getOperand(1);
- return true;
+ return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
}
- return false;
+ return None;
}
void MipsSEInstrInfo::
diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.h b/llvm/lib/Target/Mips/MipsSEInstrInfo.h
index 3111d1c21a0a..08c00ec8ccef 100644
--- a/llvm/lib/Target/Mips/MipsSEInstrInfo.h
+++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.h
@@ -43,7 +43,7 @@ public:
int &FrameIndex) const override;
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
- const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
+ const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg,
bool KillSrc) const override;
void storeRegToStack(MachineBasicBlock &MBB,
@@ -77,10 +77,10 @@ public:
protected:
/// If the specific machine instruction is a instruction that moves/copies
- /// value from one register to another register return true along with
- /// @Source machine operand and @Destination machine operand.
- bool isCopyInstrImpl(const MachineInstr &MI, const MachineOperand *&Source,
- const MachineOperand *&Destination) const override;
+ /// value from one register to another register return destination and source
+ /// registers as machine operands.
+ Optional<DestSourcePair>
+ isCopyInstrImpl(const MachineInstr &MI) const override;
private:
unsigned getAnalyzableBrOpc(unsigned Opc) const override;
diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td
index e8a0a30b8e9b..faccb37c2361 100644
--- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td
+++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td
@@ -720,11 +720,16 @@ def : InstRW<[GenericWriteALU], (instrs BADDu, BBIT0, BBIT032, BBIT1, BBIT132,
CINS, CINS32, CINS64_32, CINS_i32,
DMFC2_OCTEON, DMTC2_OCTEON, DPOP, EXTS,
EXTS32, MTM0, MTM1, MTM2, MTP0, MTP1, MTP2,
- POP, SEQ, SEQi, SNE, SNEi, V3MULU, VMM0,
- VMULU)>;
+ POP, SEQ, SEQi, SNE, SNEi,
+ V3MULU, VMM0, VMULU)>;
def : InstRW<[GenericWriteMDUtoGPR], (instrs DMUL)>;
+// Cavium Networks MIPS (cnMIPSP) - Octeon+, HasCnMipsP
+// =================================================
+
+def : InstRW<[GenericWriteALU], (instrs SAA, SAAD)>;
+
// FPU Pipelines
// =============
@@ -1610,5 +1615,6 @@ def : InstRW<[GenericWriteAtomic],
def : InstRW<[GenericWriteAtomic],
(instregex "^ATOMIC_CMP_SWAP_I(8|16|32|64)_POSTRA$")>;
def : InstRW<[GenericWriteAtomic],
- (instregex "^ATOMIC_LOAD_(ADD|SUB|AND|OR|XOR|NAND)_I(8|16|32|64)_POSTRA$")>;
+ (instregex "^ATOMIC_LOAD_(ADD|SUB|AND|OR|XOR|NAND|MIN|MAX|UMIN|UMAX)"
+ "_I(8|16|32|64)_POSTRA$")>;
}
diff --git a/llvm/lib/Target/Mips/MipsScheduleP5600.td b/llvm/lib/Target/Mips/MipsScheduleP5600.td
index f97b03bff08e..7331917baa25 100644
--- a/llvm/lib/Target/Mips/MipsScheduleP5600.td
+++ b/llvm/lib/Target/Mips/MipsScheduleP5600.td
@@ -18,7 +18,8 @@ def MipsP5600Model : SchedMachineModel {
list<Predicate> UnsupportedFeatures = [HasMips3, HasMips32r6, HasMips64,
HasMips64r2, HasMips64r5, HasMips64r6,
IsGP64bit, IsPTR64bit,
- InMicroMips, InMips16Mode, HasCnMips,
+ InMicroMips, InMips16Mode,
+ HasCnMips, HasCnMipsP,
HasDSP, HasDSPR2, HasMT, HasCRC];
}
@@ -631,5 +632,6 @@ def : InstRW<[P5600WriteAtomic],
def : InstRW<[P5600WriteAtomic],
(instregex "^ATOMIC_CMP_SWAP_I(8|16|32|64)_POSTRA$")>;
def : InstRW<[P5600WriteAtomic],
- (instregex "^ATOMIC_LOAD_(ADD|SUB|AND|OR|XOR|NAND)_I(8|16|32|64)_POSTRA$")>;
+ (instregex "^ATOMIC_LOAD_(ADD|SUB|AND|OR|XOR|NAND|MIN|MAX|UMIN|UMAX)"
+ "_I(8|16|32|64)_POSTRA$")>;
}
diff --git a/llvm/lib/Target/Mips/MipsSubtarget.cpp b/llvm/lib/Target/Mips/MipsSubtarget.cpp
index b9245c9fc0eb..133b818114c8 100644
--- a/llvm/lib/Target/Mips/MipsSubtarget.cpp
+++ b/llvm/lib/Target/Mips/MipsSubtarget.cpp
@@ -74,16 +74,17 @@ MipsSubtarget::MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
IsLittle(little), IsSoftFloat(false), IsSingleFloat(false), IsFPXX(false),
NoABICalls(false), Abs2008(false), IsFP64bit(false), UseOddSPReg(true),
IsNaN2008bit(false), IsGP64bit(false), HasVFPU(false), HasCnMips(false),
- HasMips3_32(false), HasMips3_32r2(false), HasMips4_32(false),
- HasMips4_32r2(false), HasMips5_32r2(false), InMips16Mode(false),
- InMips16HardFloat(Mips16HardFloat), InMicroMipsMode(false), HasDSP(false),
- HasDSPR2(false), HasDSPR3(false), AllowMixed16_32(Mixed16_32 | Mips_Os16),
- Os16(Mips_Os16), HasMSA(false), UseTCCInDIV(false), HasSym32(false),
- HasEVA(false), DisableMadd4(false), HasMT(false), HasCRC(false),
- HasVirt(false), HasGINV(false), UseIndirectJumpsHazard(false),
- StackAlignOverride(StackAlignOverride), TM(TM), TargetTriple(TT),
- TSInfo(), InstrInfo(MipsInstrInfo::create(
- initializeSubtargetDependencies(CPU, FS, TM))),
+ HasCnMipsP(false), HasMips3_32(false), HasMips3_32r2(false),
+ HasMips4_32(false), HasMips4_32r2(false), HasMips5_32r2(false),
+ InMips16Mode(false), InMips16HardFloat(Mips16HardFloat),
+ InMicroMipsMode(false), HasDSP(false), HasDSPR2(false), HasDSPR3(false),
+ AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16), HasMSA(false),
+ UseTCCInDIV(false), HasSym32(false), HasEVA(false), DisableMadd4(false),
+ HasMT(false), HasCRC(false), HasVirt(false), HasGINV(false),
+ UseIndirectJumpsHazard(false), StackAlignOverride(StackAlignOverride),
+ TM(TM), TargetTriple(TT), TSInfo(),
+ InstrInfo(
+ MipsInstrInfo::create(initializeSubtargetDependencies(CPU, FS, TM))),
FrameLowering(MipsFrameLowering::create(*this)),
TLInfo(MipsTargetLowering::create(TM, *this)) {
@@ -255,6 +256,10 @@ MipsSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS,
stackAlignment = Align(8);
}
+ if ((isABI_N32() || isABI_N64()) && !isGP64bit())
+ report_fatal_error("64-bit code requested on a subtarget that doesn't "
+ "support it!");
+
return *this;
}
diff --git a/llvm/lib/Target/Mips/MipsSubtarget.h b/llvm/lib/Target/Mips/MipsSubtarget.h
index 0a8c2ef8ae5c..5a1dfec41a47 100644
--- a/llvm/lib/Target/Mips/MipsSubtarget.h
+++ b/llvm/lib/Target/Mips/MipsSubtarget.h
@@ -111,6 +111,9 @@ class MipsSubtarget : public MipsGenSubtargetInfo {
// CPU supports cnMIPS (Cavium Networks Octeon CPU).
bool HasCnMips;
+ // CPU supports cnMIPSP (Cavium Networks Octeon+ CPU).
+ bool HasCnMipsP;
+
// isLinux - Target system is Linux. Is false we consider ELFOS for now.
bool IsLinux;
@@ -270,6 +273,7 @@ public:
bool hasMips64r6() const { return MipsArchVersion >= Mips64r6; }
bool hasCnMips() const { return HasCnMips; }
+ bool hasCnMipsP() const { return HasCnMipsP; }
bool isLittle() const { return IsLittle; }
bool isABICalls() const { return !NoABICalls; }
diff --git a/llvm/lib/Target/Mips/MipsTargetMachine.cpp b/llvm/lib/Target/Mips/MipsTargetMachine.cpp
index e58f316791ba..8fec6db00cb9 100644
--- a/llvm/lib/Target/Mips/MipsTargetMachine.cpp
+++ b/llvm/lib/Target/Mips/MipsTargetMachine.cpp
@@ -23,16 +23,17 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/CodeGen/BasicTTIImpl.h"
#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
+#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
#include "llvm/CodeGen/GlobalISel/Legalizer.h"
#include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
-#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
-#include "llvm/CodeGen/BasicTTIImpl.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Function.h"
+#include "llvm/InitializePasses.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/TargetRegistry.h"
@@ -44,7 +45,7 @@ using namespace llvm;
#define DEBUG_TYPE "mips"
-extern "C" void LLVMInitializeMipsTarget() {
+extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsTarget() {
// Register the target.
RegisterTargetMachine<MipsebTargetMachine> X(getTheMipsTarget());
RegisterTargetMachine<MipselTargetMachine> Y(getTheMipselTarget());
diff --git a/llvm/lib/Target/Mips/MipsTargetStreamer.h b/llvm/lib/Target/Mips/MipsTargetStreamer.h
index 298d056ce2c3..b389ba8938c4 100644
--- a/llvm/lib/Target/Mips/MipsTargetStreamer.h
+++ b/llvm/lib/Target/Mips/MipsTargetStreamer.h
@@ -156,10 +156,6 @@ public:
unsigned BaseReg, int64_t Offset,
function_ref<unsigned()> GetATReg, SMLoc IDLoc,
const MCSubtargetInfo *STI);
- void emitSCWithSymOffset(unsigned Opcode, unsigned SrcReg, unsigned BaseReg,
- MCOperand &HiOperand, MCOperand &LoOperand,
- unsigned ATReg, SMLoc IDLoc,
- const MCSubtargetInfo *STI);
void emitLoadWithImmOffset(unsigned Opcode, unsigned DstReg, unsigned BaseReg,
int64_t Offset, unsigned TmpReg, SMLoc IDLoc,
const MCSubtargetInfo *STI);
diff --git a/llvm/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp b/llvm/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp
index 0082ca34cdbd..44041987ec76 100644
--- a/llvm/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp
+++ b/llvm/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp
@@ -27,7 +27,7 @@ Target &llvm::getTheMips64elTarget() {
return TheMips64elTarget;
}
-extern "C" void LLVMInitializeMipsTargetInfo() {
+extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsTargetInfo() {
RegisterTarget<Triple::mips,
/*HasJIT=*/true>
X(getTheMipsTarget(), "mips", "MIPS (32-bit big endian)", "Mips");