aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/Mips
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
commit044eb2f6afba375a914ac9d8024f8f5142bb912e (patch)
tree1475247dc9f9fe5be155ebd4c9069c75aadf8c20 /lib/Target/Mips
parenteb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff)
downloadsrc-044eb2f6afba375a914ac9d8024f8f5142bb912e.tar.gz
src-044eb2f6afba375a914ac9d8024f8f5142bb912e.zip
Vendor import of llvm trunk r321017:vendor/llvm/llvm-trunk-r321017
Notes
Notes: svn path=/vendor/llvm/dist/; revision=326938 svn path=/vendor/llvm/llvm-trunk-r321017/; revision=326939; tag=vendor/llvm/llvm-trunk-r321017
Diffstat (limited to 'lib/Target/Mips')
-rw-r--r--lib/Target/Mips/AsmParser/MipsAsmParser.cpp103
-rw-r--r--lib/Target/Mips/Disassembler/MipsDisassembler.cpp152
-rw-r--r--lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp1
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp41
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h16
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp30
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp23
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h16
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp4
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp70
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h3
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsMCNaCl.h6
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp27
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h25
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp17
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp6
-rw-r--r--lib/Target/Mips/MicroMips32r6InstrFormats.td17
-rw-r--r--lib/Target/Mips/MicroMips32r6InstrInfo.td29
-rw-r--r--lib/Target/Mips/MicroMips64r6InstrFormats.td267
-rw-r--r--lib/Target/Mips/MicroMips64r6InstrInfo.td562
-rw-r--r--lib/Target/Mips/MicroMipsInstrFPU.td452
-rw-r--r--lib/Target/Mips/MicroMipsInstrFormats.td3
-rw-r--r--lib/Target/Mips/MicroMipsInstrInfo.td66
-rw-r--r--lib/Target/Mips/MicroMipsSizeReduction.cpp158
-rw-r--r--lib/Target/Mips/Mips16FrameLowering.cpp7
-rw-r--r--lib/Target/Mips/Mips16FrameLowering.h2
-rw-r--r--lib/Target/Mips/Mips16HardFloat.cpp58
-rw-r--r--lib/Target/Mips/Mips16ISelLowering.cpp2
-rw-r--r--lib/Target/Mips/Mips16InstrInfo.cpp74
-rw-r--r--lib/Target/Mips/Mips16InstrInfo.h20
-rw-r--r--lib/Target/Mips/Mips16InstrInfo.td6
-rw-r--r--lib/Target/Mips/Mips16RegisterInfo.cpp4
-rw-r--r--lib/Target/Mips/Mips32r6InstrInfo.td42
-rw-r--r--lib/Target/Mips/Mips64InstrInfo.td213
-rw-r--r--lib/Target/Mips/Mips64r6InstrInfo.td12
-rw-r--r--lib/Target/Mips/MipsAnalyzeImmediate.cpp6
-rw-r--r--lib/Target/Mips/MipsAnalyzeImmediate.h16
-rw-r--r--lib/Target/Mips/MipsAsmPrinter.cpp71
-rw-r--r--lib/Target/Mips/MipsAsmPrinter.h54
-rw-r--r--lib/Target/Mips/MipsCCState.cpp8
-rw-r--r--lib/Target/Mips/MipsCondMov.td12
-rw-r--r--lib/Target/Mips/MipsConstantIslandPass.cpp52
-rw-r--r--lib/Target/Mips/MipsDSPInstrInfo.td4
-rw-r--r--lib/Target/Mips/MipsDelaySlotFiller.cpp41
-rw-r--r--lib/Target/Mips/MipsFastISel.cpp13
-rw-r--r--lib/Target/Mips/MipsFrameLowering.h2
-rw-r--r--lib/Target/Mips/MipsHazardSchedule.cpp22
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp186
-rw-r--r--lib/Target/Mips/MipsISelLowering.h97
-rw-r--r--lib/Target/Mips/MipsInstrFPU.td119
-rw-r--r--lib/Target/Mips/MipsInstrInfo.cpp192
-rw-r--r--lib/Target/Mips/MipsInstrInfo.h32
-rw-r--r--lib/Target/Mips/MipsInstrInfo.td168
-rw-r--r--lib/Target/Mips/MipsLongBranch.cpp175
-rw-r--r--lib/Target/Mips/MipsMCInstLower.cpp13
-rw-r--r--lib/Target/Mips/MipsMCInstLower.h28
-rw-r--r--lib/Target/Mips/MipsMachineFunction.cpp6
-rw-r--r--lib/Target/Mips/MipsOptimizePICCall.cpp43
-rw-r--r--lib/Target/Mips/MipsRegisterInfo.cpp32
-rw-r--r--lib/Target/Mips/MipsRegisterInfo.h10
-rw-r--r--lib/Target/Mips/MipsRegisterInfo.td7
-rw-r--r--lib/Target/Mips/MipsSEFrameLowering.cpp23
-rw-r--r--lib/Target/Mips/MipsSEFrameLowering.h9
-rw-r--r--lib/Target/Mips/MipsSEISelDAGToDAG.cpp69
-rw-r--r--lib/Target/Mips/MipsSEISelLowering.cpp85
-rw-r--r--lib/Target/Mips/MipsSEISelLowering.h25
-rw-r--r--lib/Target/Mips/MipsSEInstrInfo.cpp34
-rw-r--r--lib/Target/Mips/MipsSERegisterInfo.cpp4
-rw-r--r--lib/Target/Mips/MipsScheduleGeneric.td1
-rw-r--r--lib/Target/Mips/MipsScheduleP5600.td4
-rw-r--r--lib/Target/Mips/MipsSubtarget.cpp29
-rw-r--r--lib/Target/Mips/MipsSubtarget.h14
-rw-r--r--lib/Target/Mips/MipsTargetMachine.cpp53
-rw-r--r--lib/Target/Mips/MipsTargetMachine.h12
-rw-r--r--lib/Target/Mips/MipsTargetObjectFile.cpp33
-rw-r--r--lib/Target/Mips/MipsTargetStreamer.h2
-rw-r--r--lib/Target/Mips/Relocation.txt35
-rw-r--r--lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp8
78 files changed, 2231 insertions, 2152 deletions
diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index a294004b9f68..345b081500a4 100644
--- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -466,6 +466,9 @@ public:
Match_RequiresSameSrcAndDst,
Match_NoFCCRegisterForCurrentISA,
Match_NonZeroOperandForSync,
+ Match_RequiresPosSizeRange0_32,
+ Match_RequiresPosSizeRange33_64,
+ Match_RequiresPosSizeUImm6,
#define GET_OPERAND_DIAGNOSTIC_TYPES
#include "MipsGenAsmMatcher.inc"
#undef GET_OPERAND_DIAGNOSTIC_TYPES
@@ -473,7 +476,7 @@ public:
MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
const MCInstrInfo &MII, const MCTargetOptions &Options)
- : MCTargetAsmParser(Options, sti),
+ : MCTargetAsmParser(Options, sti, MII),
ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
sti.getCPU(), Options)) {
MCAsmParserExtension::Initialize(parser);
@@ -509,6 +512,9 @@ public:
IsLittleEndian = false;
else
IsLittleEndian = true;
+
+ if (getSTI().getCPU() == "mips64r6" && inMicroMipsMode())
+ report_fatal_error("microMIPS64R6 is not supported", false);
}
/// True if all of $fcc0 - $fcc7 exist for the current ISA.
@@ -1984,9 +1990,7 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
case Mips::DDIV:
case Mips::DDIVU:
case Mips::DIVU_MMR6:
- case Mips::DDIVU_MM64R6:
case Mips::DIV_MMR6:
- case Mips::DDIV_MM64R6:
if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
@@ -2270,8 +2274,10 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
// We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
// If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
- if (inMicroMipsMode())
+ if (inMicroMipsMode()) {
TOut.setUsesMicroMips();
+ TOut.updateABIInfo(*this);
+ }
// If this instruction has a delay slot and .set reorder is active,
// emit a NOP after it.
@@ -5109,8 +5115,6 @@ MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
return Match_Success;
case Mips::DATI:
case Mips::DAHI:
- case Mips::DATI_MM64R6:
- case Mips::DAHI_MM64R6:
if (static_cast<MipsOperand &>(*Operands[1])
.isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
return Match_Success;
@@ -5123,7 +5127,6 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
// As described by the MIPSR6 spec, daui must not use the zero operand for
// its source operand.
case Mips::DAUI:
- case Mips::DAUI_MM64R6:
if (Inst.getOperand(1).getReg() == Mips::ZERO ||
Inst.getOperand(1).getReg() == Mips::ZERO_64)
return Match_RequiresNoZeroRegister;
@@ -5196,6 +5199,44 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
return Match_RequiresDifferentOperands;
return Match_Success;
+ case Mips::DINS: {
+ assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
+ "Operands must be immediates for dins!");
+ const signed Pos = Inst.getOperand(2).getImm();
+ const signed Size = Inst.getOperand(3).getImm();
+ if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
+ return Match_RequiresPosSizeRange0_32;
+ return Match_Success;
+ }
+ case Mips::DINSM:
+ case Mips::DINSU: {
+ assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
+ "Operands must be immediates for dinsm/dinsu!");
+ const signed Pos = Inst.getOperand(2).getImm();
+ const signed Size = Inst.getOperand(3).getImm();
+ if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
+ return Match_RequiresPosSizeRange33_64;
+ return Match_Success;
+ }
+ case Mips::DEXT: {
+ assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
+ "Operands must be immediates for DEXTM!");
+ const signed Pos = Inst.getOperand(2).getImm();
+ const signed Size = Inst.getOperand(3).getImm();
+ if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
+ return Match_RequiresPosSizeUImm6;
+ return Match_Success;
+ }
+ case Mips::DEXTM:
+ case Mips::DEXTU: {
+ assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
+ "Operands must be immediates for dextm/dextu!");
+ const signed Pos = Inst.getOperand(2).getImm();
+ const signed Size = Inst.getOperand(3).getImm();
+ if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
+ return Match_RequiresPosSizeRange33_64;
+ return Match_Success;
+ }
}
uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
@@ -5341,6 +5382,7 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
"expected 11-bit signed immediate");
case Match_UImm16:
case Match_UImm16_Relaxed:
+ case Match_UImm16_AltRelaxed:
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
"expected 16-bit unsigned immediate");
case Match_SImm16:
@@ -5387,6 +5429,24 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_MemSImm16:
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
"expected memory with 16-bit signed offset");
+ case Match_RequiresPosSizeRange0_32: {
+ SMLoc ErrorStart = Operands[3]->getStartLoc();
+ SMLoc ErrorEnd = Operands[4]->getEndLoc();
+ return Error(ErrorStart, "size plus position are not in the range 0 .. 32",
+ SMRange(ErrorStart, ErrorEnd));
+ }
+ case Match_RequiresPosSizeUImm6: {
+ SMLoc ErrorStart = Operands[3]->getStartLoc();
+ SMLoc ErrorEnd = Operands[4]->getEndLoc();
+ return Error(ErrorStart, "size plus position are not in the range 1 .. 63",
+ SMRange(ErrorStart, ErrorEnd));
+ }
+ case Match_RequiresPosSizeRange33_64: {
+ SMLoc ErrorStart = Operands[3]->getStartLoc();
+ SMLoc ErrorEnd = Operands[4]->getEndLoc();
+ return Error(ErrorStart, "size plus position are not in the range 33 .. 64",
+ SMRange(ErrorStart, ErrorEnd));
+ }
}
llvm_unreachable("Implement any new match types added!");
@@ -5658,12 +5718,12 @@ bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
return true;
case MCExpr::SymbolRef:
return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
- case MCExpr::Binary:
- if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
- if (!isEvaluated(BE->getLHS()))
- return false;
- return isEvaluated(BE->getRHS());
- }
+ 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:
@@ -6726,6 +6786,9 @@ bool MipsAsmParser::parseSetArchDirective() {
if (ArchFeatureName.empty())
return reportParseError("unsupported architecture");
+ if (ArchFeatureName == "mips64r6" && inMicroMipsMode())
+ return reportParseError("mips64r6 does not support microMIPS");
+
selectArch(ArchFeatureName);
getTargetStreamer().emitDirectiveSetArch(Arch);
return false;
@@ -6744,6 +6807,10 @@ bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
setFeatureBits(Mips::FeatureDSP, "dsp");
getTargetStreamer().emitDirectiveSetDsp();
break;
+ case Mips::FeatureDSPR2:
+ setFeatureBits(Mips::FeatureDSPR2, "dspr2");
+ getTargetStreamer().emitDirectiveSetDspr2();
+ break;
case Mips::FeatureMicroMips:
setFeatureBits(Mips::FeatureMicroMips, "micromips");
getTargetStreamer().emitDirectiveSetMicroMips();
@@ -7053,6 +7120,10 @@ bool MipsAsmParser::parseDirectiveSet() {
Parser.eatToEndOfStatement();
return false;
} else if (Tok.getString() == "micromips") {
+ if (hasMips64r6()) {
+ Error(Tok.getLoc(), ".set micromips directive is not supported with MIPS64R6");
+ return false;
+ }
return parseSetFeature(Mips::FeatureMicroMips);
} else if (Tok.getString() == "mips0") {
return parseSetMips0Directive();
@@ -7085,9 +7156,15 @@ bool MipsAsmParser::parseDirectiveSet() {
} else if (Tok.getString() == "mips64r5") {
return parseSetFeature(Mips::FeatureMips64r5);
} else if (Tok.getString() == "mips64r6") {
+ if (inMicroMipsMode()) {
+ Error(Tok.getLoc(), "MIPS64R6 is not supported with microMIPS");
+ return false;
+ }
return parseSetFeature(Mips::FeatureMips64r6);
} else if (Tok.getString() == "dsp") {
return parseSetFeature(Mips::FeatureDSP);
+ } else if (Tok.getString() == "dspr2") {
+ return parseSetFeature(Mips::FeatureDSPR2);
} else if (Tok.getString() == "nodsp") {
return parseSetNoDspDirective();
} else if (Tok.getString() == "msa") {
diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
index b0b994323036..ef0f08b49850 100644
--- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
+++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+#include "MCTargetDesc/MipsMCTargetDesc.h"
#include "Mips.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/MC/MCContext.h"
@@ -32,7 +33,7 @@ using namespace llvm;
#define DEBUG_TYPE "mips-disassembler"
-typedef MCDisassembler::DecodeStatus DecodeStatus;
+using DecodeStatus = MCDisassembler::DecodeStatus;
namespace {
@@ -286,10 +287,8 @@ static DecodeStatus DecodeLoadByte15(MCInst &Inst,
uint64_t Address,
const void *Decoder);
-static DecodeStatus DecodeCacheOp(MCInst &Inst,
- unsigned Insn,
- uint64_t Address,
- const void *Decoder);
+static DecodeStatus DecodeCacheOp(MCInst &Inst, unsigned Insn, uint64_t Address,
+ const void *Decoder);
static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
unsigned Insn,
@@ -367,17 +366,14 @@ static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
uint64_t Address,
const void *Decoder);
-static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn,
- uint64_t Address,
- const void *Decoder);
+static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address,
+ const void *Decoder);
-static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn,
- uint64_t Address,
- const void *Decoder);
+static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, uint64_t Address,
+ const void *Decoder);
static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
- uint64_t Address,
- const void *Decoder);
+ uint64_t Address, const void *Decoder);
static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
uint64_t Address,
@@ -523,6 +519,14 @@ static DecodeStatus
DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
const void *Decoder);
+template <typename InsnType>
+static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
+ const void *Decoder);
+
+template <typename InsnType>
+static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
+ const void *Decoder);
+
static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
uint64_t Address,
const void *Decoder);
@@ -531,7 +535,7 @@ static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
uint64_t Address,
const void *Decoder);
-static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
+static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
uint64_t Address,
const void *Decoder);
@@ -581,7 +585,8 @@ static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
template <typename InsnType>
static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
const void *Decoder) {
- typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
+ using DecodeFN = DecodeStatus (*)(MCInst &, unsigned, uint64_t, const void *);
+
// The size of the n field depends on the element size
// The register class also depends on this.
InsnType tmp = fieldFromInstruction(insn, 17, 5);
@@ -1054,6 +1059,86 @@ static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
return MCDisassembler::Success;
}
+// Override the generated disassembler to produce DEXT all the time. This is
+// for feature / behaviour parity with binutils.
+template <typename InsnType>
+static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
+ const void *Decoder) {
+ unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
+ unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
+ unsigned Size = 0;
+ unsigned Pos = 0;
+
+ switch (MI.getOpcode()) {
+ case Mips::DEXT:
+ Pos = Lsb;
+ Size = Msbd + 1;
+ break;
+ case Mips::DEXTM:
+ Pos = Lsb;
+ Size = Msbd + 1 + 32;
+ break;
+ case Mips::DEXTU:
+ Pos = Lsb + 32;
+ Size = Msbd + 1;
+ break;
+ default:
+ llvm_unreachable("Unknown DEXT instruction!");
+ }
+
+ MI.setOpcode(Mips::DEXT);
+
+ 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::createImm(Pos));
+ MI.addOperand(MCOperand::createImm(Size));
+
+ return MCDisassembler::Success;
+}
+
+// Override the generated disassembler to produce DINS all the time. This is
+// for feature / behaviour parity with binutils.
+template <typename InsnType>
+static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
+ const void *Decoder) {
+ unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
+ unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
+ unsigned Size = 0;
+ unsigned Pos = 0;
+
+ switch (MI.getOpcode()) {
+ case Mips::DINS:
+ Pos = Lsb;
+ Size = Msbd + 1 - Pos;
+ break;
+ case Mips::DINSM:
+ Pos = Lsb;
+ Size = Msbd + 33 - Pos;
+ break;
+ case Mips::DINSU:
+ Pos = Lsb + 32;
+ // mbsd = pos + size - 33
+ // mbsd - pos + 33 = size
+ Size = Msbd + 33 - Pos;
+ break;
+ default:
+ llvm_unreachable("Unknown DINS instruction!");
+ }
+
+ InsnType Rs = fieldFromInstruction(Insn, 21, 5);
+ 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::createImm(Pos));
+ MI.addOperand(MCOperand::createImm(Size));
+
+ return MCDisassembler::Success;
+}
/// Read two bytes from the ArrayRef and return 16 bit halfword sorted
/// according to the given endianness.
static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
@@ -1127,7 +1212,7 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
if (hasMips32r6()) {
DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
// Calling the auto-generated decoder function for microMIPS32R6
- // (and microMIPS64R6) 16-bit instructions.
+ // 16-bit instructions.
Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
Address, this, STI);
if (Result != MCDisassembler::Fail) {
@@ -1170,9 +1255,9 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
return Result;
}
- if (hasMips32r6() && isFP64()) {
- DEBUG(dbgs() << "Trying MicroMips32r6FP64 table (32-bit opcodes):\n");
- Result = decodeInstruction(DecoderTableMicroMips32r6FP6432, Instr, Insn,
+ if (isFP64()) {
+ DEBUG(dbgs() << "Trying MicroMipsFP64 table (32-bit opcodes):\n");
+ Result = decodeInstruction(DecoderTableMicroMipsFP6432, Instr, Insn,
Address, this, STI);
if (Result != MCDisassembler::Fail) {
Size = 4;
@@ -1255,6 +1340,14 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
return Result;
}
+ if (isFP64()) {
+ DEBUG(dbgs() << "Trying MipsFP64 (64 bit FPU) table (32-bit opcodes):\n");
+ Result = decodeInstruction(DecoderTableMipsFP6432, Instr, Insn,
+ Address, this, STI);
+ if (Result != MCDisassembler::Fail)
+ return Result;
+ }
+
DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
// Calling the auto-generated decoder function.
Result =
@@ -2165,7 +2258,7 @@ static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
unsigned Offset,
uint64_t Address,
const void *Decoder) {
- int32_t BranchOffset = SignExtend32<7>(Offset) << 1;
+ int32_t BranchOffset = SignExtend32<8>(Offset << 1);
Inst.addOperand(MCOperand::createImm(BranchOffset));
return MCDisassembler::Success;
}
@@ -2174,7 +2267,7 @@ static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
unsigned Offset,
uint64_t Address,
const void *Decoder) {
- int32_t BranchOffset = SignExtend32<10>(Offset) << 1;
+ int32_t BranchOffset = SignExtend32<11>(Offset << 1);
Inst.addOperand(MCOperand::createImm(BranchOffset));
return MCDisassembler::Success;
}
@@ -2192,7 +2285,7 @@ static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
unsigned Offset,
uint64_t Address,
const void *Decoder) {
- int32_t BranchOffset = SignExtend32<26>(Offset) << 1;
+ int32_t BranchOffset = SignExtend32<27>(Offset << 1);
Inst.addOperand(MCOperand::createImm(BranchOffset));
return MCDisassembler::Success;
@@ -2263,15 +2356,10 @@ static DecodeStatus DecodeInsSize(MCInst &Inst,
uint64_t Address,
const void *Decoder) {
// First we need to grab the pos(lsb) from MCInst.
+ // This function only handles the 32 bit variants of ins, as dins
+ // variants are handled differently.
int Pos = Inst.getOperand(2).getImm();
- if (Inst.getOpcode() == Mips::DINSU)
- Pos += 32;
- int Size;
- if (Inst.getOpcode() == Mips::DINSM ||
- Inst.getOpcode() == Mips::DINSU)
- Size = (int) Insn - Pos + 33;
- else
- Size = (int) Insn - Pos + 1;
+ int Size = (int) Insn - Pos + 1;
Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
return MCDisassembler::Success;
}
@@ -2365,10 +2453,8 @@ static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
return MCDisassembler::Success;
}
-static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
+static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
uint64_t Address, const void *Decoder) {
- unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
-
switch (RegPair) {
default:
return MCDisassembler::Fail;
diff --git a/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp b/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
index 49c42fd1880c..1d125d0dbae6 100644
--- a/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
+++ b/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
@@ -188,7 +188,6 @@ printMemOperandEA(const MCInst *MI, int opNum, raw_ostream &O) {
printOperand(MI, opNum, O);
O << ", ";
printOperand(MI, opNum+1, O);
- return;
}
void MipsInstPrinter::
diff --git a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
index a1ed0ea4d7f3..1ad524c06969 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
+++ b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
@@ -24,6 +24,7 @@
#include "llvm/MC/MCFixupKindInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
@@ -209,10 +210,9 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
return Value;
}
-MCObjectWriter *
+std::unique_ptr<MCObjectWriter>
MipsAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {
- return createMipsELFObjectWriter(OS,
- MCELFObjectTargetWriter::getOSABI(OSType), IsLittle, Is64Bit);
+ return createMipsELFObjectWriter(OS, TheTriple, IsN32);
}
// Little-endian fixup data byte ordering:
@@ -475,34 +475,9 @@ bool MipsAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
return true;
}
-// MCAsmBackend
-MCAsmBackend *llvm::createMipsAsmBackendEL32(const Target &T,
- const MCRegisterInfo &MRI,
- const Triple &TT, StringRef CPU,
- const MCTargetOptions &Options) {
- return new MipsAsmBackend(T, TT.getOS(), /*IsLittle*/ true,
- /*Is64Bit*/ false);
-}
-
-MCAsmBackend *llvm::createMipsAsmBackendEB32(const Target &T,
- const MCRegisterInfo &MRI,
- const Triple &TT, StringRef CPU,
- const MCTargetOptions &Options) {
- return new MipsAsmBackend(T, TT.getOS(), /*IsLittle*/ false,
- /*Is64Bit*/ false);
-}
-
-MCAsmBackend *llvm::createMipsAsmBackendEL64(const Target &T,
- const MCRegisterInfo &MRI,
- const Triple &TT, StringRef CPU,
- const MCTargetOptions &Options) {
- return new MipsAsmBackend(T, TT.getOS(), /*IsLittle*/ true, /*Is64Bit*/ true);
-}
-
-MCAsmBackend *llvm::createMipsAsmBackendEB64(const Target &T,
- const MCRegisterInfo &MRI,
- const Triple &TT, StringRef CPU,
- const MCTargetOptions &Options) {
- return new MipsAsmBackend(T, TT.getOS(), /*IsLittle*/ false,
- /*Is64Bit*/ true);
+MCAsmBackend *llvm::createMipsAsmBackend(const Target &T,
+ const MCRegisterInfo &MRI,
+ const Triple &TT, StringRef CPU,
+ const MCTargetOptions &Options) {
+ return new MipsAsmBackend(T, MRI, TT, CPU, Options.ABIName == "n32");
}
diff --git a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h
index 8ebde3b9b7a4..406b820edae5 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h
+++ b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h
@@ -23,20 +23,22 @@ namespace llvm {
class MCAssembler;
struct MCFixupKindInfo;
-class Target;
class MCObjectWriter;
+class MCRegisterInfo;
+class Target;
class MipsAsmBackend : public MCAsmBackend {
- Triple::OSType OSType;
+ Triple TheTriple;
bool IsLittle; // Big or little endian
- bool Is64Bit; // 32 or 64 bit words
+ bool IsN32;
public:
- MipsAsmBackend(const Target &T, Triple::OSType OSType, bool IsLittle,
- bool Is64Bit)
- : MCAsmBackend(), OSType(OSType), IsLittle(IsLittle), Is64Bit(Is64Bit) {}
+ MipsAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT,
+ StringRef CPU, bool N32)
+ : TheTriple(TT), IsLittle(TT.isLittleEndian()), IsN32(N32) {}
- MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override;
+ std::unique_ptr<MCObjectWriter>
+ createObjectWriter(raw_pwrite_stream &OS) const override;
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target, MutableArrayRef<char> Data,
diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
index d116ac3471bc..6d2f098a6b32 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
+++ b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
@@ -13,6 +13,7 @@
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSymbolELF.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
@@ -55,7 +56,7 @@ raw_ostream &operator<<(raw_ostream &OS, const MipsRelocationEntry &RHS) {
class MipsELFObjectWriter : public MCELFObjectTargetWriter {
public:
- MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI, bool _isN64,
+ MipsELFObjectWriter(uint8_t OSABI, bool HasRelocationAddend, bool Is64,
bool IsLittleEndian);
~MipsELFObjectWriter() override = default;
@@ -209,11 +210,10 @@ static void dumpRelocs(const char *Prefix, const Container &Relocs) {
}
#endif
-MipsELFObjectWriter::MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI,
- bool _isN64, bool IsLittleEndian)
- : MCELFObjectTargetWriter(_is64Bit, OSABI, ELF::EM_MIPS,
- /*HasRelocationAddend*/ _isN64,
- /*IsN64*/ _isN64) {}
+MipsELFObjectWriter::MipsELFObjectWriter(uint8_t OSABI,
+ bool HasRelocationAddend, bool Is64,
+ bool IsLittleEndian)
+ : MCELFObjectTargetWriter(Is64, OSABI, ELF::EM_MIPS, HasRelocationAddend) {}
unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx,
const MCValue &Target,
@@ -282,7 +282,7 @@ unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx,
case FK_TPRel_8:
return ELF::R_MIPS_TLS_TPREL64;
case FK_GPRel_4:
- if (isN64()) {
+ if (is64Bit()) {
unsigned Type = (unsigned)ELF::R_MIPS_NONE;
Type = setRType((unsigned)ELF::R_MIPS_GPREL32, Type);
Type = setRType2((unsigned)ELF::R_MIPS_64, Type);
@@ -656,11 +656,13 @@ bool MipsELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
}
}
-MCObjectWriter *llvm::createMipsELFObjectWriter(raw_pwrite_stream &OS,
- uint8_t OSABI,
- bool IsLittleEndian,
- bool Is64Bit) {
- MCELFObjectTargetWriter *MOTW =
- new MipsELFObjectWriter(Is64Bit, OSABI, Is64Bit, IsLittleEndian);
- return createELFObjectWriter(MOTW, OS, IsLittleEndian);
+std::unique_ptr<MCObjectWriter>
+llvm::createMipsELFObjectWriter(raw_pwrite_stream &OS, const Triple &TT,
+ bool IsN32) {
+ uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
+ bool IsN64 = TT.isArch64Bit() && !IsN32;
+ bool HasRelocationAddend = TT.isArch64Bit();
+ auto MOTW = llvm::make_unique<MipsELFObjectWriter>(
+ OSABI, HasRelocationAddend, IsN64, TT.isLittleEndian());
+ return createELFObjectWriter(std::move(MOTW), OS, TT.isLittleEndian());
}
diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
index f658aadff22f..4b8f9c7a680c 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
+++ b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
@@ -11,7 +11,9 @@
#include "MipsOptionRecord.h"
#include "MipsTargetStreamer.h"
#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSymbolELF.h"
@@ -19,6 +21,16 @@
using namespace llvm;
+MipsELFStreamer::MipsELFStreamer(MCContext &Context,
+ std::unique_ptr<MCAsmBackend> MAB,
+ raw_pwrite_stream &OS,
+ std::unique_ptr<MCCodeEmitter> Emitter)
+ : MCELFStreamer(Context, std::move(MAB), OS, std::move(Emitter)) {
+ RegInfoRecord = new MipsRegInfoRecord(this, Context);
+ MipsOptionRecords.push_back(
+ std::unique_ptr<MipsRegInfoRecord>(RegInfoRecord));
+}
+
void MipsELFStreamer::EmitInstruction(const MCInst &Inst,
const MCSubtargetInfo &STI, bool) {
MCELFStreamer::EmitInstruction(Inst, STI);
@@ -77,10 +89,9 @@ void MipsELFStreamer::EmitMipsOptionRecords() {
I->EmitMipsOptionRecord();
}
-MCELFStreamer *llvm::createMipsELFStreamer(MCContext &Context,
- MCAsmBackend &MAB,
- raw_pwrite_stream &OS,
- MCCodeEmitter *Emitter,
- bool RelaxAll) {
- return new MipsELFStreamer(Context, MAB, OS, Emitter);
+MCELFStreamer *llvm::createMipsELFStreamer(
+ MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
+ raw_pwrite_stream &OS, std::unique_ptr<MCCodeEmitter> Emitter,
+ bool RelaxAll) {
+ return new MipsELFStreamer(Context, std::move(MAB), OS, std::move(Emitter));
}
diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
index f5eda112817e..2fe9b08b645a 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
+++ b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
@@ -33,13 +33,9 @@ class MipsELFStreamer : public MCELFStreamer {
SmallVector<MCSymbol*, 4> Labels;
public:
- MipsELFStreamer(MCContext &Context, MCAsmBackend &MAB, raw_pwrite_stream &OS,
- MCCodeEmitter *Emitter)
- : MCELFStreamer(Context, MAB, OS, Emitter) {
- RegInfoRecord = new MipsRegInfoRecord(this, Context);
- MipsOptionRecords.push_back(
- std::unique_ptr<MipsRegInfoRecord>(RegInfoRecord));
- }
+ MipsELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
+ raw_pwrite_stream &OS,
+ std::unique_ptr<MCCodeEmitter> Emitter);
/// Overriding this function allows us to add arbitrary behaviour before the
/// \p Inst is actually emitted. For example, we can inspect the operands and
@@ -69,9 +65,11 @@ public:
void createPendingLabelRelocs();
};
-MCELFStreamer *createMipsELFStreamer(MCContext &Context, MCAsmBackend &MAB,
+MCELFStreamer *createMipsELFStreamer(MCContext &Context,
+ std::unique_ptr<MCAsmBackend> MAB,
raw_pwrite_stream &OS,
- MCCodeEmitter *Emitter, bool RelaxAll);
+ std::unique_ptr<MCCodeEmitter> Emitter,
+ bool RelaxAll);
} // end namespace llvm
#endif // LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSELFSTREAMER_H
diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
index 11411d997bb3..e63304220ae5 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
+++ b/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
@@ -61,4 +61,8 @@ MipsMCAsmInfo::MipsMCAsmInfo(const Triple &TheTriple) {
// Enable IAS by default for Debian mips64/mips64el.
if (TheTriple.getEnvironment() == Triple::GNUABI64)
UseIntegratedAssembler = true;
+
+ // Enable IAS by default for Android mips64el that uses N64 ABI.
+ if (TheTriple.getArch() == Triple::mips64el && TheTriple.isAndroid())
+ UseIntegratedAssembler = true;
}
diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
index 0330824fd614..ac81e6207456 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
+++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
@@ -86,45 +86,6 @@ static void LowerLargeShift(MCInst& Inst) {
case Mips::DROTR:
Inst.setOpcode(Mips::DROTR32);
return;
- case Mips::DSLL_MM64R6:
- Inst.setOpcode(Mips::DSLL32_MM64R6);
- return;
- case Mips::DSRL_MM64R6:
- Inst.setOpcode(Mips::DSRL32_MM64R6);
- return;
- case Mips::DSRA_MM64R6:
- Inst.setOpcode(Mips::DSRA32_MM64R6);
- return;
- case Mips::DROTR_MM64R6:
- Inst.setOpcode(Mips::DROTR32_MM64R6);
- return;
- }
-}
-
-// Pick a DINS instruction variant based on the pos and size operands
-static void LowerDins(MCInst& InstIn) {
- assert(InstIn.getNumOperands() == 5 &&
- "Invalid no. of machine operands for DINS!");
-
- assert(InstIn.getOperand(2).isImm());
- int64_t pos = InstIn.getOperand(2).getImm();
- assert(InstIn.getOperand(3).isImm());
- int64_t size = InstIn.getOperand(3).getImm();
-
- assert((pos + size) <= 64 &&
- "DINS cannot have position plus size over 64");
- if (pos < 32) {
- if ((pos + size) > 0 && (pos + size) <= 32)
- return; // DINS, do nothing
- else if ((pos + size) > 32) {
- //DINSM
- InstIn.getOperand(3).setImm(size - 32);
- InstIn.setOpcode(Mips::DINSM);
- }
- } else if ((pos + size) > 32 && (pos + size) <= 64) {
- // DINSU
- InstIn.getOperand(2).setImm(pos - 32);
- InstIn.setOpcode(Mips::DINSU);
}
}
@@ -205,16 +166,8 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS,
case Mips::DSRL:
case Mips::DSRA:
case Mips::DROTR:
- case Mips::DSLL_MM64R6:
- case Mips::DSRL_MM64R6:
- case Mips::DSRA_MM64R6:
- case Mips::DROTR_MM64R6:
LowerLargeShift(TmpInst);
break;
- // Double extract instruction is chosen by pos and size operands
- case Mips::DINS:
- LowerDins(TmpInst);
- break;
// Compact branches, enforce encoding restrictions.
case Mips::BEQC:
case Mips::BNEC:
@@ -1146,6 +1099,29 @@ MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo,
}
unsigned
+MipsMCCodeEmitter::getMovePRegSingleOpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ assert(((OpNo == 2) || (OpNo == 3)) &&
+ "Unexpected OpNo for movep operand encoding!");
+
+ MCOperand Op = MI.getOperand(OpNo);
+ assert(Op.isReg() && "Operand of movep is not a register!");
+ switch (Op.getReg()) {
+ default:
+ llvm_unreachable("Unknown register for movep!");
+ case Mips::ZERO: return 0;
+ case Mips::S1: return 1;
+ case Mips::V0: return 2;
+ case Mips::V1: return 3;
+ case Mips::S0: return 4;
+ case Mips::S2: return 5;
+ case Mips::S3: return 6;
+ case Mips::S4: return 7;
+ }
+}
+
+unsigned
MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
index d12d3195521a..1e840114b2b3 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
+++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
@@ -252,6 +252,9 @@ public:
unsigned getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
+ unsigned getMovePRegSingleOpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
unsigned getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCNaCl.h b/lib/Target/Mips/MCTargetDesc/MipsMCNaCl.h
index 687b800c2409..dfacf4354516 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsMCNaCl.h
+++ b/lib/Target/Mips/MCTargetDesc/MipsMCNaCl.h
@@ -22,9 +22,11 @@ bool isBasePlusOffsetMemoryAccess(unsigned Opcode, unsigned *AddrIdx,
bool baseRegNeedsLoadStoreMask(unsigned Reg);
// This function creates an MCELFStreamer for Mips NaCl.
-MCELFStreamer *createMipsNaClELFStreamer(MCContext &Context, MCAsmBackend &TAB,
+MCELFStreamer *createMipsNaClELFStreamer(MCContext &Context,
+ std::unique_ptr<MCAsmBackend> TAB,
raw_pwrite_stream &OS,
- MCCodeEmitter *Emitter, bool RelaxAll);
+ std::unique_ptr<MCCodeEmitter> Emitter,
+ bool RelaxAll);
}
#endif
diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
index 56fe18572118..8fcd8aa4c19b 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
+++ b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
@@ -13,11 +13,13 @@
#include "MipsMCTargetDesc.h"
#include "InstPrinter/MipsInstPrinter.h"
+#include "MipsAsmBackend.h"
#include "MipsELFStreamer.h"
#include "MipsMCAsmInfo.h"
#include "MipsMCNaCl.h"
#include "MipsTargetStreamer.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
@@ -90,13 +92,17 @@ static MCInstPrinter *createMipsMCInstPrinter(const Triple &T,
}
static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context,
- MCAsmBackend &MAB, raw_pwrite_stream &OS,
- MCCodeEmitter *Emitter, bool RelaxAll) {
+ std::unique_ptr<MCAsmBackend> &&MAB,
+ raw_pwrite_stream &OS,
+ std::unique_ptr<MCCodeEmitter> &&Emitter,
+ bool RelaxAll) {
MCStreamer *S;
if (!T.isOSNaCl())
- S = createMipsELFStreamer(Context, MAB, OS, Emitter, RelaxAll);
+ S = createMipsELFStreamer(Context, std::move(MAB), OS, std::move(Emitter),
+ RelaxAll);
else
- S = createMipsNaClELFStreamer(Context, MAB, OS, Emitter, RelaxAll);
+ S = createMipsNaClELFStreamer(Context, std::move(MAB), OS,
+ std::move(Emitter), RelaxAll);
return S;
}
@@ -180,6 +186,9 @@ extern "C" void LLVMInitializeMipsTargetMC() {
TargetRegistry::RegisterObjectTargetStreamer(
*T, createMipsObjectTargetStreamer);
+
+ // Register the asm backend.
+ TargetRegistry::RegisterMCAsmBackend(*T, createMipsAsmBackend);
}
// Register the MC Code Emitter
@@ -188,14 +197,4 @@ extern "C" void LLVMInitializeMipsTargetMC() {
for (Target *T : {&getTheMipselTarget(), &getTheMips64elTarget()})
TargetRegistry::RegisterMCCodeEmitter(*T, createMipsMCCodeEmitterEL);
-
- // Register the asm backend.
- TargetRegistry::RegisterMCAsmBackend(getTheMipsTarget(),
- createMipsAsmBackendEB32);
- TargetRegistry::RegisterMCAsmBackend(getTheMipselTarget(),
- createMipsAsmBackendEL32);
- TargetRegistry::RegisterMCAsmBackend(getTheMips64Target(),
- createMipsAsmBackendEB64);
- TargetRegistry::RegisterMCAsmBackend(getTheMips64elTarget(),
- createMipsAsmBackendEL64);
}
diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h
index b28681f42ebe..abbf08ed212f 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h
+++ b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h
@@ -16,6 +16,8 @@
#include "llvm/Support/DataTypes.h"
+#include <memory>
+
namespace llvm {
class MCAsmBackend;
class MCCodeEmitter;
@@ -43,25 +45,12 @@ MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII,
const MCRegisterInfo &MRI,
MCContext &Ctx);
-MCAsmBackend *createMipsAsmBackendEB32(const Target &T,
- const MCRegisterInfo &MRI,
- const Triple &TT, StringRef CPU,
- const MCTargetOptions &Options);
-MCAsmBackend *createMipsAsmBackendEL32(const Target &T,
- const MCRegisterInfo &MRI,
- const Triple &TT, StringRef CPU,
- const MCTargetOptions &Options);
-MCAsmBackend *createMipsAsmBackendEB64(const Target &T,
- const MCRegisterInfo &MRI,
- const Triple &TT, StringRef CPU,
- const MCTargetOptions &Options);
-MCAsmBackend *createMipsAsmBackendEL64(const Target &T,
- const MCRegisterInfo &MRI,
- const Triple &TT, StringRef CPU,
- const MCTargetOptions &Options);
+MCAsmBackend *createMipsAsmBackend(const Target &T, const MCRegisterInfo &MRI,
+ const Triple &TT, StringRef CPU,
+ const MCTargetOptions &Options);
-MCObjectWriter *createMipsELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI,
- bool IsLittleEndian, bool Is64Bit);
+std::unique_ptr<MCObjectWriter>
+createMipsELFObjectWriter(raw_pwrite_stream &OS, const Triple &TT, bool IsN32);
namespace MIPS_MC {
StringRef selectMipsCPU(const Triple &TT, StringRef CPU);
diff --git a/lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp
index 9266f0e216d1..d878cf82e26d 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp
+++ b/lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp
@@ -20,7 +20,9 @@
#include "Mips.h"
#include "MipsELFStreamer.h"
#include "MipsMCNaCl.h"
+#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCInst.h"
#include "llvm/Support/ErrorHandling.h"
@@ -40,9 +42,10 @@ const unsigned LoadStoreStackMaskReg = Mips::T7;
class MipsNaClELFStreamer : public MipsELFStreamer {
public:
- MipsNaClELFStreamer(MCContext &Context, MCAsmBackend &TAB,
- raw_pwrite_stream &OS, MCCodeEmitter *Emitter)
- : MipsELFStreamer(Context, TAB, OS, Emitter) {}
+ MipsNaClELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
+ raw_pwrite_stream &OS,
+ std::unique_ptr<MCCodeEmitter> Emitter)
+ : MipsELFStreamer(Context, std::move(TAB), OS, std::move(Emitter)) {}
~MipsNaClELFStreamer() override = default;
@@ -255,11 +258,13 @@ bool baseRegNeedsLoadStoreMask(unsigned Reg) {
return Reg != Mips::SP && Reg != Mips::T8;
}
-MCELFStreamer *createMipsNaClELFStreamer(MCContext &Context, MCAsmBackend &TAB,
+MCELFStreamer *createMipsNaClELFStreamer(MCContext &Context,
+ std::unique_ptr<MCAsmBackend> TAB,
raw_pwrite_stream &OS,
- MCCodeEmitter *Emitter,
+ std::unique_ptr<MCCodeEmitter> Emitter,
bool RelaxAll) {
- MipsNaClELFStreamer *S = new MipsNaClELFStreamer(Context, TAB, OS, Emitter);
+ MipsNaClELFStreamer *S =
+ new MipsNaClELFStreamer(Context, std::move(TAB), OS, std::move(Emitter));
if (RelaxAll)
S->getAssembler().setRelaxAll(true);
diff --git a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
index 7caeb08589af..fb4e1ba0ded9 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
+++ b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
@@ -98,6 +98,7 @@ void MipsTargetStreamer::emitDirectiveSetHardFloat() {
forbidModuleDirective();
}
void MipsTargetStreamer::emitDirectiveSetDsp() { forbidModuleDirective(); }
+void MipsTargetStreamer::emitDirectiveSetDspr2() { forbidModuleDirective(); }
void MipsTargetStreamer::emitDirectiveSetNoDsp() { forbidModuleDirective(); }
void MipsTargetStreamer::emitDirectiveCpLoad(unsigned RegNo) {}
bool MipsTargetStreamer::emitDirectiveCpRestore(
@@ -562,6 +563,11 @@ void MipsTargetAsmStreamer::emitDirectiveSetDsp() {
MipsTargetStreamer::emitDirectiveSetDsp();
}
+void MipsTargetAsmStreamer::emitDirectiveSetDspr2() {
+ OS << "\t.set\tdspr2\n";
+ MipsTargetStreamer::emitDirectiveSetDspr2();
+}
+
void MipsTargetAsmStreamer::emitDirectiveSetNoDsp() {
OS << "\t.set\tnodsp\n";
MipsTargetStreamer::emitDirectiveSetNoDsp();
diff --git a/lib/Target/Mips/MicroMips32r6InstrFormats.td b/lib/Target/Mips/MicroMips32r6InstrFormats.td
index 2f0933277e81..25048293714d 100644
--- a/lib/Target/Mips/MicroMips32r6InstrFormats.td
+++ b/lib/Target/Mips/MicroMips32r6InstrFormats.td
@@ -17,7 +17,7 @@ class MMR6Arch<string opstr> {
string DecoderNamespace = "MicroMipsR6";
}
-// Class used for microMIPS32r6 and microMIPS64r6 instructions.
+// Class used for microMIPS32r6 instructions.
class MicroMipsR6Inst16 : PredicateControl {
string DecoderNamespace = "MicroMipsR6";
let InsnPredicates = [HasMicroMips32r6];
@@ -829,6 +829,21 @@ class POOL16C_NOT16_FM_MMR6 : MicroMipsR6Inst16 {
let Inst{3-0} = 0b0000;
}
+class POOL16C_MOVEP16_FM_MMR6 : MicroMipsR6Inst16 {
+ bits<3> dst_regs;
+ bits<3> rt;
+ bits<3> rs;
+
+ bits<16> Inst;
+
+ let Inst{15-10} = 0b010001;
+ let Inst{9-7} = dst_regs;
+ let Inst{6-4} = rt;
+ let Inst{3} = rs{2};
+ let Inst{2} = 0b1;
+ let Inst{1-0} = rs{1-0};
+}
+
class POOL16C_OR16_XOR16_FM_MMR6<bits<4> op> : MicroMipsR6Inst16 {
bits<3> rt;
bits<3> rs;
diff --git a/lib/Target/Mips/MicroMips32r6InstrInfo.td b/lib/Target/Mips/MicroMips32r6InstrInfo.td
index fd04f80dd566..3ff3f07654d9 100644
--- a/lib/Target/Mips/MicroMips32r6InstrInfo.td
+++ b/lib/Target/Mips/MicroMips32r6InstrInfo.td
@@ -229,6 +229,7 @@ class SRL16_MMR6_ENC : SHIFT_FM_MM16<1>, MicroMipsR6Inst16;
class BREAK16_MMR6_ENC : POOL16C_BREAKPOINT_FM_MMR6<0b011011>;
class LI16_MMR6_ENC : LI_FM_MM16;
class MOVE16_MMR6_ENC : MOVE_FM_MM16<0b000011>;
+class MOVEP_MMR6_ENC : POOL16C_MOVEP16_FM_MMR6;
class SDBBP16_MMR6_ENC : POOL16C_BREAKPOINT_FM_MMR6<0b111011>;
class SUBU16_MMR6_ENC : POOL16A_SUBU16_FM_MMR6;
class XOR16_MMR6_ENC : POOL16C_OR16_XOR16_FM_MMR6<0b1000>;
@@ -382,7 +383,9 @@ class BALC_MMR6_DESC : BC_MMR6_DESC_BASE<"balc", brtarget26_mm, II_BALC> {
bit isCall = 1;
list<Register> Defs = [RA];
}
-class BC_MMR6_DESC : BC_MMR6_DESC_BASE<"bc", brtarget26_mm, II_BC>;
+class BC_MMR6_DESC : BC_MMR6_DESC_BASE<"bc", brtarget26_mm, II_BC> {
+ list<dag> Pattern = [(br bb:$offset)];
+}
class BC16_MMR6_DESC : MicroMipsInst16<(outs), (ins brtarget10_mm:$offset),
!strconcat("bc16", "\t$offset"), [],
@@ -1124,10 +1127,7 @@ class ROUND_W_D_MMR6_DESC : ABSS_FT_MMR6_DESC_BASE<"round.w.d", FGR64Opnd,
FGR64Opnd, II_ROUND>;
class SEL_S_MMR6_DESC : COP1_SEL_DESC_BASE<"sel.s", FGR32Opnd, II_SEL_S>;
-class SEL_D_MMR6_DESC : COP1_SEL_DESC_BASE<"sel.d", FGR64Opnd, II_SEL_D> {
- // We must insert a SUBREG_TO_REG around $fd_in
- bit usesCustomInserter = 1;
-}
+class SEL_D_MMR6_DESC : COP1_SEL_D_DESC_BASE<"sel.d", FGR64Opnd, II_SEL_D>;
class SELEQZ_S_MMR6_DESC : SELEQNEZ_DESC_BASE<"seleqz.s", FGR32Opnd,
II_SELCCZ_S>;
@@ -1207,6 +1207,7 @@ class LI16_MMR6_DESC : LoadImmMM16<"li16", li16_imm, GPRMM16Opnd>,
MMR6Arch<"li16">, MicroMipsR6Inst16, IsAsCheapAsAMove;
class MOVE16_MMR6_DESC : MoveMM16<"move16", GPR32Opnd>, MMR6Arch<"move16">,
MicroMipsR6Inst16;
+class MOVEP_MMR6_DESC : MovePMM16<"movep", GPRMM16OpndMoveP>, MMR6Arch<"movep">;
class SDBBP16_MMR6_DESC : BrkSdbbp16MM<"sdbbp16", II_SDBBP>, MMR6Arch<"sdbbp16">,
MicroMipsR6Inst16;
class SUBU16_MMR6_DESC : ArithRMM16<"subu16", GPRMM16Opnd, 0, II_SUBU, sub>,
@@ -1488,7 +1489,7 @@ def MTC1_MMR6 : StdMMR6Rel, MTC1_MMR6_DESC, MTC1_MMR6_ENC, ISA_MICROMIPS32R6;
def MTC2_MMR6 : StdMMR6Rel, MTC2_MMR6_ENC, MTC2_MMR6_DESC, ISA_MICROMIPS32R6;
def MTHC0_MMR6 : R6MMR6Rel, MTHC0_MMR6_ENC, MTHC0_MMR6_DESC, ISA_MICROMIPS32R6;
def MTHC1_D32_MMR6 : StdMMR6Rel, MTHC1_D32_MMR6_DESC, MTHC1_MMR6_ENC, ISA_MICROMIPS32R6;
-let DecoderNamespace = "MicroMips32r6FP64" in {
+let DecoderNamespace = "MicroMipsFP64" in {
def MTHC1_D64_MMR6 : R6MMR6Rel, MTHC1_D64_MMR6_DESC, MTHC1_MMR6_ENC,
ISA_MICROMIPS32R6;
}
@@ -1499,7 +1500,7 @@ def MFC2_MMR6 : StdMMR6Rel, MFC2_MMR6_ENC, MFC2_MMR6_DESC, ISA_MICROMIPS32R6;
def MFHC0_MMR6 : R6MMR6Rel, MFHC0_MMR6_ENC, MFHC0_MMR6_DESC, ISA_MICROMIPS32R6;
def MFHC1_D32_MMR6 : StdMMR6Rel, MFHC1_D32_MMR6_DESC, MFHC1_MMR6_ENC,
ISA_MICROMIPS32R6;
-let DecoderNamespace = "MicroMips32r6FP64" in {
+let DecoderNamespace = "MicroMipsFP64" in {
def MFHC1_D64_MMR6 : StdMMR6Rel, MFHC1_D64_MMR6_DESC, MFHC1_MMR6_ENC,
ISA_MICROMIPS32R6;
}
@@ -1682,6 +1683,8 @@ def LI16_MMR6 : StdMMR6Rel, LI16_MMR6_DESC, LI16_MMR6_ENC,
ISA_MICROMIPS32R6;
def MOVE16_MMR6 : StdMMR6Rel, MOVE16_MMR6_DESC, MOVE16_MMR6_ENC,
ISA_MICROMIPS32R6;
+def MOVEP_MMR6 : StdMMR6Rel, MOVEP_MMR6_DESC, MOVEP_MMR6_ENC,
+ ISA_MICROMIPS32R6;
def SDBBP16_MMR6 : StdMMR6Rel, SDBBP16_MMR6_DESC, SDBBP16_MMR6_ENC,
ISA_MICROMIPS32R6;
def SUBU16_MMR6 : StdMMR6Rel, SUBU16_MMR6_DESC, SUBU16_MMR6_ENC,
@@ -1732,7 +1735,7 @@ def BC2EQZC_MMR6 : R6MMR6Rel, MipsR6Inst, BC2EQZC_MMR6_ENC, BC2EQZC_MMR6_DESC,
ISA_MICROMIPS32R6;
def BC2NEZC_MMR6 : R6MMR6Rel, MipsR6Inst, BC2NEZC_MMR6_ENC, BC2NEZC_MMR6_DESC,
ISA_MICROMIPS32R6;
-let DecoderNamespace = "MicroMips32r6FP64" in {
+let DecoderNamespace = "MicroMipsFP64" in {
def LDC1_D64_MMR6 : StdMMR6Rel, LDC1_D64_MMR6_DESC, LDC1_MMR6_ENC,
ISA_MICROMIPS32R6 {
let BaseOpcode = "LDC164";
@@ -1832,6 +1835,9 @@ def : MipsInstAlias<"seh $rd", (SEH_MMR6 GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
ISA_MICROMIPS32R6;
def : MipsInstAlias<"seb $rd", (SEB_MMR6 GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
ISA_MICROMIPS32R6;
+def : MipsInstAlias<"lapc $rd, $imm",
+ (ADDIUPC_MMR6 GPR32Opnd:$rd, simm19_lsl2:$imm)>,
+ ISA_MICROMIPS32R6;
//===----------------------------------------------------------------------===//
//
@@ -1879,3 +1885,10 @@ let AddedComplexity = 41 in {
}
def TAILCALL_MMR6 : TailCall<BC_MMR6, brtarget26_mm>, ISA_MICROMIPS32R6;
+
+def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
+ (TAILCALL_MMR6 tglobaladdr:$dst)>, ISA_MICROMIPS32R6;
+
+def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
+ (TAILCALL_MMR6 texternalsym:$dst)>, ISA_MICROMIPS32R6;
+
diff --git a/lib/Target/Mips/MicroMips64r6InstrFormats.td b/lib/Target/Mips/MicroMips64r6InstrFormats.td
deleted file mode 100644
index 26062bfb2b8e..000000000000
--- a/lib/Target/Mips/MicroMips64r6InstrFormats.td
+++ /dev/null
@@ -1,267 +0,0 @@
-//=- MicroMips64r6InstrFormats.td - Instruction Formats -*- tablegen -* -=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file describes microMIPS64r6 instruction formats.
-//
-//===----------------------------------------------------------------------===//
-
-class DAUI_FM_MMR6 {
- bits<5> rt;
- bits<5> rs;
- bits<16> imm;
-
- bits<32> Inst;
-
- let Inst{31-26} = 0b111100;
- let Inst{25-21} = rt;
- let Inst{20-16} = rs;
- let Inst{15-0} = imm;
-}
-
-class POOL32I_ADD_IMM_FM_MMR6<bits<5> funct> {
- bits<5> rs;
- bits<16> imm;
-
- bits<32> Inst;
-
- let Inst{31-26} = 0b010000;
- let Inst{25-21} = funct;
- let Inst{20-16} = rs;
- let Inst{15-0} = imm;
-}
-
-class POOL32S_EXTBITS_FM_MMR6<bits<6> funct> {
- bits<5> rt;
- bits<5> rs;
- bits<5> size;
- bits<5> pos;
-
- bits<32> Inst;
-
- let Inst{31-26} = 0b010110;
- let Inst{25-21} = rt;
- let Inst{20-16} = rs;
- let Inst{15-11} = size;
- let Inst{10-6} = pos;
- let Inst{5-0} = funct;
-}
-
-class POOL32S_DALIGN_FM_MMR6 {
- bits<5> rs;
- bits<5> rt;
- bits<5> rd;
- bits<3> bp;
-
- bits<32> Inst;
-
- let Inst{31-26} = 0b010110;
- let Inst{25-21} = rs;
- let Inst{20-16} = rt;
- let Inst{15-11} = rd;
- let Inst{10-8} = bp;
- let Inst{7-6} = 0b00;
- let Inst{5-0} = 0b011100;
-}
-
-class POOL32A_DIVMOD_FM_MMR6<string instr_asm, bits<9> funct>
- : MMR6Arch<instr_asm> {
- bits<5> rt;
- bits<5> rs;
- bits<5> rd;
-
- bits<32> Inst;
-
- let Inst{31-26} = 0b010110;
- let Inst{25-21} = rt;
- let Inst{20-16} = rs;
- let Inst{15-11} = rd;
- let Inst{10-9} = 0b00;
- let Inst{8-0} = funct;
-}
-
-class POOL32S_DMFTC0_FM_MMR6<string instr_asm, bits<5> funct>
- : MMR6Arch<instr_asm>, MipsR6Inst {
- bits<5> rt;
- bits<5> rs;
- bits<3> sel;
-
- bits<32> Inst;
-
- let Inst{31-26} = 0b010110;
- let Inst{25-21} = rt;
- let Inst{20-16} = rs;
- let Inst{15-14} = 0;
- let Inst{13-11} = sel;
- let Inst{10-6} = funct;
- let Inst{5-0} = 0b111100;
-}
-
-class POOL32S_ARITH_FM_MMR6<string opstr, bits<9> funct>
- : MMR6Arch<opstr> {
- bits<5> rt;
- bits<5> rs;
- bits<5> rd;
-
- bits<32> Inst;
-
- let Inst{31-26} = 0b010110;
- let Inst{25-21} = rt;
- let Inst{20-16} = rs;
- let Inst{15-11} = rd;
- let Inst{10-9} = 0b00;
- let Inst{8-0} = funct;
-}
-
-class DADDIU_FM_MMR6<string opstr> : MMR6Arch<opstr> {
- bits<5> rt;
- bits<5> rs;
- bits<16> imm16;
-
- bits<32> Inst;
-
- let Inst{31-26} = 0b010111;
- let Inst{25-21} = rt;
- let Inst{20-16} = rs;
- let Inst{15-0} = imm16;
-}
-
-class PCREL18_FM_MMR6<bits<3> funct> : MipsR6Inst {
- bits<5> rt;
- bits<18> imm;
-
- bits<32> Inst;
-
- let Inst{31-26} = 0b011110;
- let Inst{25-21} = rt;
- let Inst{20-18} = funct;
- let Inst{17-0} = imm;
-}
-
-class POOL32S_2R_FM_MMR6<string instr_asm, bits<10> funct>
- : MMR6Arch<instr_asm>, MipsR6Inst {
- bits<5> rt;
- bits<5> rs;
-
- bits<32> Inst;
-
- let Inst{31-26} = 0b010110;
- let Inst{25-21} = rt;
- let Inst{20-16} = rs;
- let Inst{15-6} = funct;
- let Inst{5-0} = 0b111100;
-}
-
-class POOL32S_2RSA5B0_FM_MMR6<string instr_asm, bits<9> funct>
- : MMR6Arch<instr_asm>, MipsR6Inst {
- bits<5> rt;
- bits<5> rs;
- bits<5> sa;
-
- bits<32> Inst;
-
- let Inst{31-26} = 0b010110;
- let Inst{25-21} = rt;
- let Inst{20-16} = rs;
- let Inst{15-11} = sa;
- let Inst{10-9} = 0b00;
- let Inst{8-0} = funct;
-}
-
-class LD_SD_32_2R_OFFSET16_FM_MMR6<string instr_asm, bits<6> op>
- : MMR6Arch<instr_asm>, MipsR6Inst {
- bits<5> rt;
- bits<21> addr;
- bits<5> base = addr{20-16};
- bits<16> offset = addr{15-0};
-
- bits<32> Inst;
-
- let Inst{31-26} = op;
- let Inst{25-21} = rt;
- let Inst{20-16} = base;
- let Inst{15-0} = offset;
-}
-
-class POOL32C_2R_OFFSET12_FM_MMR6<string instr_asm, bits<4> funct>
- : MMR6Arch<instr_asm>, MipsR6Inst {
- bits<5> rt;
- bits<21> addr;
- bits<5> base = addr{20-16};
- bits<12> offset = addr{11-0};
-
- bits<32> Inst;
-
- let Inst{31-26} = 0b011000;
- let Inst{25-21} = rt;
- let Inst{20-16} = base;
- let Inst{15-12} = funct;
- let Inst{11-0} = offset;
-}
-
-class POOL32S_3R_FM_MMR6<string instr_asm, bits<9> funct>
- : MMR6Arch<instr_asm>, MipsR6Inst {
- bits<5> rt;
- bits<5> rs;
- bits<5> rd;
-
- bits<32> Inst;
-
- let Inst{31-26} = 0b010110;
- let Inst{25-21} = rt;
- let Inst{20-16} = rs;
- let Inst{15-11} = rd;
- let Inst{10-9} = 0b00;
- let Inst{8-0} = funct;
-}
-
-class POOL32S_DBITSWAP_FM_MMR6<string instr_asm> : MMR6Arch<instr_asm>,
- MipsR6Inst {
- bits<5> rt;
- bits<5> rd;
-
- bits<32> Inst;
-
- let Inst{31-26} = 0b010110;
- let Inst{25-21} = rt;
- let Inst{20-16} = rd;
- let Inst{15-12} = 0b0000;
- let Inst{11-6} = 0b101100;
- let Inst{5-0} = 0b111100;
-}
-
-class POOL32S_3RSA_FM_MMR6<string instr_asm> : MMR6Arch<instr_asm>,
- MipsR6Inst {
- bits<5> rt;
- bits<5> rs;
- bits<5> rd;
- bits<2> sa;
-
- bits<32> Inst;
-
- let Inst{31-26} = 0b010110;
- let Inst{25-21} = rt;
- let Inst{20-16} = rs;
- let Inst{15-11} = rd;
- let Inst{10-9} = sa;
- let Inst{8-6} = 0b100;
- let Inst{5-0} = 0b000100;
-}
-
-class PCREL_1ROFFSET19_FM_MMR6<string instr_asm> : MMR6Arch<instr_asm>,
- MipsR6Inst {
- bits<5> rt;
- bits<19> offset;
-
- bits<32> Inst;
-
- let Inst{31-26} = 0b011110;
- let Inst{25-21} = rt;
- let Inst{20-19} = 0b10;
- let Inst{18-0} = offset;
-}
diff --git a/lib/Target/Mips/MicroMips64r6InstrInfo.td b/lib/Target/Mips/MicroMips64r6InstrInfo.td
deleted file mode 100644
index 38b09d105ddd..000000000000
--- a/lib/Target/Mips/MicroMips64r6InstrInfo.td
+++ /dev/null
@@ -1,562 +0,0 @@
-//=- MicroMips64r6InstrInfo.td - Instruction Information -*- tablegen -*- -=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file describes MicroMips64r6 instructions.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-//
-// Instruction Encodings
-//
-//===----------------------------------------------------------------------===//
-
-class DAUI_MMR6_ENC : DAUI_FM_MMR6;
-class DAHI_MMR6_ENC : POOL32I_ADD_IMM_FM_MMR6<0b10001>;
-class DATI_MMR6_ENC : POOL32I_ADD_IMM_FM_MMR6<0b10000>;
-class DEXT_MMR6_ENC : POOL32S_EXTBITS_FM_MMR6<0b101100>;
-class DEXTM_MMR6_ENC : POOL32S_EXTBITS_FM_MMR6<0b100100>;
-class DEXTU_MMR6_ENC : POOL32S_EXTBITS_FM_MMR6<0b010100>;
-class DALIGN_MMR6_ENC : POOL32S_DALIGN_FM_MMR6;
-class DDIV_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"ddiv", 0b100011000>;
-class DMOD_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"dmod", 0b101011000>;
-class DDIVU_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"ddivu", 0b110011000>;
-class DMODU_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"dmodu", 0b111011000>;
-class DINSU_MM64R6_ENC : POOL32S_EXTBITS_FM_MMR6<0b110100>;
-class DINSM_MM64R6_ENC : POOL32S_EXTBITS_FM_MMR6<0b000100>;
-class DINS_MM64R6_ENC : POOL32S_EXTBITS_FM_MMR6<0b001100>;
-class DMTC0_MM64R6_ENC : POOL32S_DMFTC0_FM_MMR6<"dmtc0", 0b01011>;
-class DMTC1_MM64R6_ENC : POOL32F_MFTC1_FM_MMR6<"dmtc1", 0b10110000>;
-class DMTC2_MM64R6_ENC : POOL32A_MFTC2_FM_MMR6<"dmtc2", 0b0111110100>;
-class DMFC0_MM64R6_ENC : POOL32S_DMFTC0_FM_MMR6<"dmfc0", 0b00011>;
-class DMFC1_MM64R6_ENC : POOL32F_MFTC1_FM_MMR6<"dmfc1", 0b10010000>;
-class DMFC2_MM64R6_ENC : POOL32A_MFTC2_FM_MMR6<"dmfc2", 0b0110110100>;
-class DADD_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dadd", 0b100010000>;
-class DADDIU_MM64R6_ENC : DADDIU_FM_MMR6<"daddiu">;
-class DADDU_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"daddu", 0b101010000>;
-class LDPC_MMR646_ENC : PCREL18_FM_MMR6<0b110>;
-class DSUB_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dsub", 0b110010000>;
-class DSUBU_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dsubu", 0b111010000>;
-class DMUL_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dmul", 0b000011000>;
-class DMUH_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dmuh", 0b001011000>;
-class DMULU_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dmulu", 0b010011000>;
-class DMUHU_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dmuhu", 0b011011000>;
-class DSBH_MM64R6_ENC : POOL32S_2R_FM_MMR6<"dsbh", 0b0111101100>;
-class DSHD_MM64R6_ENC : POOL32S_2R_FM_MMR6<"dshd", 0b1111101100>;
-class DSLL_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<"dsll", 0b000000000>;
-class DSLL32_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<"dsll32", 0b000001000>;
-class DSLLV_MM64R6_ENC : POOL32S_3R_FM_MMR6<"dsllv", 0b000010000>;
-class DSRAV_MM64R6_ENC : POOL32S_3R_FM_MMR6<"dsrav", 0b010010000>;
-class DSRA_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<"dsra", 0b010000000>;
-class DSRA32_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<"dsra32", 0b010000100>;
-class DCLO_MM64R6_ENC : POOL32S_2R_FM_MMR6<"dclo", 0b0100101100>;
-class DCLZ_MM64R6_ENC : POOL32S_2R_FM_MMR6<"dclz", 0b0101101100>;
-class DROTR_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<"drotr", 0b011000000>;
-class DROTR32_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<"drotr32", 0b011001000>;
-class DROTRV_MM64R6_ENC : POOL32S_3R_FM_MMR6<"drotrv", 0b011010000>;
-class LD_MM64R6_ENC : LD_SD_32_2R_OFFSET16_FM_MMR6<"ld", 0b110111>;
-class LLD_MM64R6_ENC : POOL32C_2R_OFFSET12_FM_MMR6<"lld", 0b0111>;
-class LWU_MM64R6_ENC : POOL32C_2R_OFFSET12_FM_MMR6<"lwu", 0b1110>;
-class SD_MM64R6_ENC : LD_SD_32_2R_OFFSET16_FM_MMR6<"sd", 0b110110>;
-class DSRL_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<"dsrl", 0b001000000>;
-class DSRL32_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<"dsrl32", 0b001001000>;
-class DSRLV_MM64R6_ENC : POOL32S_3R_FM_MMR6<"dsrlv", 0b001010000>;
-class DBITSWAP_MM64R6_ENC : POOL32S_DBITSWAP_FM_MMR6<"dbitswap">;
-class DLSA_MM64R6_ENC : POOL32S_3RSA_FM_MMR6<"dlsa">;
-class LWUPC_MM64R6_ENC : PCREL_1ROFFSET19_FM_MMR6<"lwupc">;
-
-//===----------------------------------------------------------------------===//
-//
-// Instruction Descriptions
-//
-//===----------------------------------------------------------------------===//
-
-class DAUI_MMR6_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
- InstrItinClass Itin>
- : MMR6Arch<instr_asm>, MipsR6Inst {
- dag OutOperandList = (outs GPROpnd:$rt);
- dag InOperandList = (ins GPROpnd:$rs, uimm16:$imm);
- string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $imm");
- list<dag> Pattern = [];
- InstrItinClass Itinerary = Itin;
-}
-class DAUI_MMR6_DESC : DAUI_MMR6_DESC_BASE<"daui", GPR64Opnd, II_DAUI>;
-
-class DAHI_DATI_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
- InstrItinClass Itin>
- : MMR6Arch<instr_asm>, MipsR6Inst {
- dag OutOperandList = (outs GPROpnd:$rs);
- dag InOperandList = (ins GPROpnd:$rt, uimm16:$imm);
- string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $imm");
- string Constraints = "$rs = $rt";
- InstrItinClass Itinerary = Itin;
-}
-class DAHI_MMR6_DESC : DAHI_DATI_DESC_BASE<"dahi", GPR64Opnd, II_DAHI>;
-class DATI_MMR6_DESC : DAHI_DATI_DESC_BASE<"dati", GPR64Opnd, II_DATI>;
-
-class EXTBITS_DESC_BASE<string instr_asm, RegisterOperand RO, Operand PosOpnd,
- Operand SizeOpnd, SDPatternOperator Op = null_frag>
- : MMR6Arch<instr_asm>, MipsR6Inst {
- dag OutOperandList = (outs RO:$rt);
- dag InOperandList = (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size);
- string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $pos, $size");
- list<dag> Pattern = [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size))];
- InstrItinClass Itinerary = II_EXT;
- Format Form = FrmR;
- string BaseOpcode = instr_asm;
-}
-// TODO: Add 'pos + size' constraint check to dext* instructions
-// DEXT: 0 < pos + size <= 63
-// DEXTM, DEXTU: 32 < pos + size <= 64
-class DEXT_MMR6_DESC : EXTBITS_DESC_BASE<"dext", GPR64Opnd, uimm5_report_uimm6,
- uimm5_plus1, MipsExt>;
-class DEXTM_MMR6_DESC : EXTBITS_DESC_BASE<"dextm", GPR64Opnd, uimm5,
- uimm5_plus33, MipsExt>;
-class DEXTU_MMR6_DESC : EXTBITS_DESC_BASE<"dextu", GPR64Opnd, uimm5_plus32,
- uimm5_plus1, MipsExt>;
-
-class DALIGN_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
- Operand ImmOpnd, InstrItinClass itin>
- : MMR6Arch<instr_asm>, MipsR6Inst {
- dag OutOperandList = (outs GPROpnd:$rd);
- dag InOperandList = (ins GPROpnd:$rs, GPROpnd:$rt, ImmOpnd:$bp);
- string AsmString = !strconcat(instr_asm, "\t$rd, $rs, $rt, $bp");
- list<dag> Pattern = [];
- InstrItinClass Itinerary = itin;
-}
-
-class DALIGN_MMR6_DESC : DALIGN_DESC_BASE<"dalign", GPR64Opnd, uimm3,
- II_DALIGN>;
-
-class DDIV_MM64R6_DESC : DIVMOD_MMR6_DESC_BASE<"ddiv", GPR64Opnd, II_DDIV,
- sdiv>;
-class DMOD_MM64R6_DESC : DIVMOD_MMR6_DESC_BASE<"dmod", GPR64Opnd, II_DMOD,
- srem>;
-class DDIVU_MM64R6_DESC : DIVMOD_MMR6_DESC_BASE<"ddivu", GPR64Opnd, II_DDIVU,
- udiv>;
-class DMODU_MM64R6_DESC : DIVMOD_MMR6_DESC_BASE<"dmodu", GPR64Opnd, II_DMODU,
- urem>;
-
-class DCLO_MM64R6_DESC {
- dag OutOperandList = (outs GPR64Opnd:$rt);
- dag InOperandList = (ins GPR64Opnd:$rs);
- string AsmString = !strconcat("dclo", "\t$rt, $rs");
- list<dag> Pattern = [(set GPR64Opnd:$rt, (ctlz (not GPR64Opnd:$rs)))];
- InstrItinClass Itinerary = II_DCLO;
- Format Form = FrmR;
- string BaseOpcode = "dclo";
-}
-
-class DCLZ_MM64R6_DESC {
- dag OutOperandList = (outs GPR64Opnd:$rt);
- dag InOperandList = (ins GPR64Opnd:$rs);
- string AsmString = !strconcat("dclz", "\t$rt, $rs");
- list<dag> Pattern = [(set GPR64Opnd:$rt, (ctlz GPR64Opnd:$rs))];
- InstrItinClass Itinerary = II_DCLZ;
- Format Form = FrmR;
- string BaseOpcode = "dclz";
-}
-
-class DINSU_MM64R6_DESC : InsBase<"dinsu", GPR64Opnd, uimm5_plus32,
- uimm5_inssize_plus1, MipsIns>;
-class DINSM_MM64R6_DESC : InsBase<"dinsm", GPR64Opnd, uimm5, uimm_range_2_64>;
-class DINS_MM64R6_DESC : InsBase<"dins", GPR64Opnd, uimm5, uimm5_inssize_plus1,
- MipsIns>;
-class DMTC0_MM64R6_DESC : MTC0_MMR6_DESC_BASE<"dmtc0", COP0Opnd, GPR64Opnd,
- II_DMTC0>;
-class DMTC1_MM64R6_DESC : MTC1_MMR6_DESC_BASE<"dmtc1", FGR64Opnd, GPR64Opnd,
- II_DMTC1, bitconvert>;
-class DMTC2_MM64R6_DESC : MTC2_MMR6_DESC_BASE<"dmtc2", COP2Opnd, GPR64Opnd,
- II_DMTC2>;
-class DMFC0_MM64R6_DESC : MFC0_MMR6_DESC_BASE<"dmfc0", GPR64Opnd, COP0Opnd,
- II_DMFC0>;
-class DMFC1_MM64R6_DESC : MFC1_MMR6_DESC_BASE<"dmfc1", GPR64Opnd, FGR64Opnd,
- II_DMFC1, bitconvert>;
-class DMFC2_MM64R6_DESC : MFC2_MMR6_DESC_BASE<"dmfc2", GPR64Opnd, COP2Opnd,
- II_DMFC2>;
-class DADD_MM64R6_DESC : ArithLogicR<"dadd", GPR64Opnd, 1, II_DADD>;
-class DADDIU_MM64R6_DESC : ArithLogicI<"daddiu", simm16_64, GPR64Opnd,
- II_DADDIU, immSExt16, add>,
- IsAsCheapAsAMove;
-class DADDU_MM64R6_DESC : ArithLogicR<"daddu", GPR64Opnd, 1, II_DADDU, add>;
-
-class DSUB_DESC_BASE<string instr_asm, RegisterOperand RO,
- InstrItinClass Itin = NoItinerary,
- SDPatternOperator OpNode = null_frag>
- : MipsR6Inst {
- dag OutOperandList = (outs RO:$rd);
- dag InOperandList = (ins RO:$rs, RO:$rt);
- string AsmString = !strconcat(instr_asm, "\t$rd, $rs, $rt");
- list<dag> Pattern = [(set RO:$rd, (OpNode RO:$rs, RO:$rt))];
- InstrItinClass Itinerary = Itin;
- Format Form = FrmR;
- string BaseOpcode = instr_asm;
- let isCommutable = 0;
- let isReMaterializable = 1;
- let TwoOperandAliasConstraint = "$rd = $rs";
-}
-class DSUB_MM64R6_DESC : DSUB_DESC_BASE<"dsub", GPR64Opnd, II_DSUB>;
-class DSUBU_MM64R6_DESC : DSUB_DESC_BASE<"dsubu", GPR64Opnd, II_DSUBU, sub>;
-
-class LDPC_MM64R6_DESC : PCREL_MMR6_DESC_BASE<"ldpc", GPR64Opnd, simm18_lsl3,
- II_LDPC>;
-
-class MUL_MM64R6_DESC_BASE<string opstr, RegisterOperand GPROpnd,
- InstrItinClass Itin = NoItinerary,
- SDPatternOperator Op = null_frag> : MipsR6Inst {
- dag OutOperandList = (outs GPROpnd:$rd);
- dag InOperandList = (ins GPROpnd:$rs, GPROpnd:$rt);
- string AsmString = !strconcat(opstr, "\t$rd, $rs, $rt");
- InstrItinClass Itinerary = Itin;
- list<dag> Pattern = [(set GPROpnd:$rd, (Op GPROpnd:$rs, GPROpnd:$rt))];
-}
-
-class DMUL_MM64R6_DESC : MUL_MM64R6_DESC_BASE<"dmul", GPR64Opnd, II_DMUL, mul>;
-class DMUH_MM64R6_DESC : MUL_MM64R6_DESC_BASE<"dmuh", GPR64Opnd, II_DMUH,
- mulhs>;
-class DMULU_MM64R6_DESC : MUL_MM64R6_DESC_BASE<"dmulu", GPR64Opnd, II_DMULU>;
-class DMUHU_MM64R6_DESC : MUL_MM64R6_DESC_BASE<"dmuhu", GPR64Opnd, II_DMUHU,
- mulhu>;
-
-class DSBH_DSHD_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
- InstrItinClass Itin> {
- dag OutOperandList = (outs GPROpnd:$rt);
- dag InOperandList = (ins GPROpnd:$rs);
- string AsmString = !strconcat(instr_asm, "\t$rt, $rs");
- bit hasSideEffects = 0;
- list<dag> Pattern = [];
- InstrItinClass Itinerary = Itin;
- Format Form = FrmR;
- string BaseOpcode = instr_asm;
-}
-
-class DSBH_MM64R6_DESC : DSBH_DSHD_DESC_BASE<"dsbh", GPR64Opnd, II_DSBH>;
-class DSHD_MM64R6_DESC : DSBH_DSHD_DESC_BASE<"dshd", GPR64Opnd, II_DSHD>;
-
-class SHIFT_ROTATE_IMM_MM64R6<string instr_asm, Operand ImmOpnd,
- InstrItinClass itin,
- SDPatternOperator OpNode = null_frag,
- SDPatternOperator PO = null_frag> {
- dag OutOperandList = (outs GPR64Opnd:$rt);
- dag InOperandList = (ins GPR64Opnd:$rs, ImmOpnd:$sa);
- string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $sa");
- list<dag> Pattern = [(set GPR64Opnd:$rt, (OpNode GPR64Opnd:$rs, PO:$sa))];
- InstrItinClass Itinerary = itin;
- Format Form = FrmR;
- string TwoOperandAliasConstraint = "$rs = $rt";
- string BaseOpcode = instr_asm;
-}
-
-class SHIFT_ROTATE_REG_MM64R6<string instr_asm, InstrItinClass itin,
- SDPatternOperator OpNode = null_frag> {
- dag OutOperandList = (outs GPR64Opnd:$rd);
- dag InOperandList = (ins GPR64Opnd:$rt, GPR32Opnd:$rs);
- string AsmString = !strconcat(instr_asm, "\t$rd, $rt, $rs");
- list<dag> Pattern = [(set GPR64Opnd:$rd,
- (OpNode GPR64Opnd:$rt, GPR32Opnd:$rs))];
- InstrItinClass Itinerary = itin;
- Format Form = FrmR;
- string BaseOpcode = instr_asm;
-}
-
-class DSLL_MM64R6_DESC : SHIFT_ROTATE_IMM_MM64R6<"dsll", uimm6, II_DSLL, shl,
- immZExt6>;
-class DSLL32_MM64R6_DESC : SHIFT_ROTATE_IMM_MM64R6<"dsll32", uimm5, II_DSLL32>;
-class DSLLV_MM64R6_DESC : SHIFT_ROTATE_REG_MM64R6<"dsllv", II_DSLLV, shl>;
-class DSRAV_MM64R6_DESC : SHIFT_ROTATE_REG_MM64R6<"dsrav", II_DSRAV, sra>;
-class DSRA_MM64R6_DESC : SHIFT_ROTATE_IMM_MM64R6<"dsra", uimm6, II_DSRA, sra,
- immZExt6>;
-class DSRA32_MM64R6_DESC : SHIFT_ROTATE_IMM_MM64R6<"dsra32", uimm5, II_DSRA32>;
-class DROTR_MM64R6_DESC : SHIFT_ROTATE_IMM_MM64R6<"drotr", uimm6, II_DROTR,
- rotr, immZExt6>;
-class DROTR32_MM64R6_DESC : SHIFT_ROTATE_IMM_MM64R6<"drotr32", uimm5,
- II_DROTR32>;
-class DROTRV_MM64R6_DESC : SHIFT_ROTATE_REG_MM64R6<"drotrv", II_DROTRV, rotr>;
-class DSRL_MM64R6_DESC : SHIFT_ROTATE_IMM_MM64R6<"dsrl", uimm6, II_DSRL, srl,
- immZExt6>;
-class DSRL32_MM64R6_DESC : SHIFT_ROTATE_IMM_MM64R6<"dsrl32", uimm5, II_DSRL32>;
-class DSRLV_MM64R6_DESC : SHIFT_ROTATE_REG_MM64R6<"dsrlv", II_DSRLV, srl>;
-
-class Load_MM64R6<string instr_asm, Operand MemOpnd, InstrItinClass itin,
- SDPatternOperator OpNode = null_frag> {
- dag OutOperandList = (outs GPR64Opnd:$rt);
- dag InOperandList = (ins MemOpnd:$addr);
- string AsmString = !strconcat(instr_asm, "\t$rt, $addr");
- list<dag> Pattern = [(set GPR64Opnd:$rt, (OpNode addr:$addr))];
- InstrItinClass Itinerary = itin;
- Format Form = FrmI;
- bit mayLoad = 1;
- bit canFoldAsLoad = 1;
- string BaseOpcode = instr_asm;
-}
-
-class LD_MM64R6_DESC : Load_MM64R6<"ld", mem_simm16, II_LD, load> {
- string DecoderMethod = "DecodeMemMMImm16";
-}
-class LWU_MM64R6_DESC : Load_MM64R6<"lwu", mem_simm12, II_LWU, zextloadi32>{
- string DecoderMethod = "DecodeMemMMImm12";
-}
-
-class LLD_MM64R6_DESC {
- dag OutOperandList = (outs GPR64Opnd:$rt);
- dag InOperandList = (ins mem_simm12:$addr);
- string AsmString = "lld\t$rt, $addr";
- list<dag> Pattern = [];
- bit mayLoad = 1;
- InstrItinClass Itinerary = II_LLD;
- string BaseOpcode = "lld";
- string DecoderMethod = "DecodeMemMMImm12";
-}
-
-class SD_MM64R6_DESC {
- dag OutOperandList = (outs);
- dag InOperandList = (ins GPR64Opnd:$rt, mem_simm16:$addr);
- string AsmString = "sd\t$rt, $addr";
- list<dag> Pattern = [(store GPR64Opnd:$rt, addr:$addr)];
- InstrItinClass Itinerary = II_SD;
- Format Form = FrmI;
- bit mayStore = 1;
- string BaseOpcode = "sd";
- string DecoderMethod = "DecodeMemMMImm16";
-}
-
-class DBITSWAP_MM64R6_DESC {
- dag OutOperandList = (outs GPR64Opnd:$rd);
- dag InOperandList = (ins GPR64Opnd:$rt);
- string AsmString = !strconcat("dbitswap", "\t$rd, $rt");
- list<dag> Pattern = [];
- InstrItinClass Itinerary = II_DBITSWAP;
-}
-
-class DLSA_MM64R6_DESC {
- dag OutOperandList = (outs GPR64Opnd:$rd);
- dag InOperandList = (ins GPR64Opnd:$rt, GPR64Opnd:$rs, uimm2_plus1:$sa);
- string AsmString = "dlsa\t$rt, $rs, $rd, $sa";
- list<dag> Pattern = [];
- InstrItinClass Itinerary = II_DLSA;
-}
-
-class LWUPC_MM64R6_DESC {
- dag OutOperandList = (outs GPR64Opnd:$rt);
- dag InOperandList = (ins simm19_lsl2:$offset);
- string AsmString = "lwupc\t$rt, $offset";
- list<dag> Pattern = [];
- InstrItinClass Itinerary = II_LWUPC;
- bit mayLoad = 1;
- bit IsPCRelativeLoad = 1;
-}
-
-//===----------------------------------------------------------------------===//
-//
-// Instruction Definitions
-//
-//===----------------------------------------------------------------------===//
-
-let DecoderNamespace = "MicroMipsR6" in {
- def DAUI_MM64R6 : StdMMR6Rel, DAUI_MMR6_DESC, DAUI_MMR6_ENC, ISA_MICROMIPS64R6;
- let DecoderMethod = "DecodeDAHIDATIMMR6" in {
- def DAHI_MM64R6 : StdMMR6Rel, DAHI_MMR6_DESC, DAHI_MMR6_ENC, ISA_MICROMIPS64R6;
- def DATI_MM64R6 : StdMMR6Rel, DATI_MMR6_DESC, DATI_MMR6_ENC, ISA_MICROMIPS64R6;
- }
- def DEXT_MM64R6 : StdMMR6Rel, DEXT_MMR6_DESC, DEXT_MMR6_ENC,
- ISA_MICROMIPS64R6;
- def DEXTM_MM64R6 : StdMMR6Rel, DEXTM_MMR6_DESC, DEXTM_MMR6_ENC,
- ISA_MICROMIPS64R6;
- def DEXTU_MM64R6 : StdMMR6Rel, DEXTU_MMR6_DESC, DEXTU_MMR6_ENC,
- ISA_MICROMIPS64R6;
- def DALIGN_MM64R6 : StdMMR6Rel, DALIGN_MMR6_DESC, DALIGN_MMR6_ENC,
- ISA_MICROMIPS64R6;
- def DDIV_MM64R6 : R6MMR6Rel, DDIV_MM64R6_DESC, DDIV_MM64R6_ENC,
- ISA_MICROMIPS64R6;
- def DMOD_MM64R6 : R6MMR6Rel, DMOD_MM64R6_DESC, DMOD_MM64R6_ENC,
- ISA_MICROMIPS64R6;
- def DDIVU_MM64R6 : R6MMR6Rel, DDIVU_MM64R6_DESC, DDIVU_MM64R6_ENC,
- ISA_MICROMIPS64R6;
- def DMODU_MM64R6 : R6MMR6Rel, DMODU_MM64R6_DESC, DMODU_MM64R6_ENC,
- ISA_MICROMIPS64R6;
- def DINSU_MM64R6: R6MMR6Rel, DINSU_MM64R6_DESC, DINSU_MM64R6_ENC,
- ISA_MICROMIPS64R6;
- def DINSM_MM64R6: R6MMR6Rel, DINSM_MM64R6_DESC, DINSM_MM64R6_ENC,
- ISA_MICROMIPS64R6;
- def DINS_MM64R6: R6MMR6Rel, DINS_MM64R6_DESC, DINS_MM64R6_ENC,
- ISA_MICROMIPS64R6;
- def DMTC0_MM64R6 : StdMMR6Rel, DMTC0_MM64R6_ENC, DMTC0_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DMTC1_MM64R6 : StdMMR6Rel, DMTC1_MM64R6_DESC, DMTC1_MM64R6_ENC,
- ISA_MICROMIPS64R6;
- def DMTC2_MM64R6 : StdMMR6Rel, DMTC2_MM64R6_ENC, DMTC2_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DMFC0_MM64R6 : StdMMR6Rel, DMFC0_MM64R6_ENC, DMFC0_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DMFC1_MM64R6 : StdMMR6Rel, DMFC1_MM64R6_DESC, DMFC1_MM64R6_ENC,
- ISA_MICROMIPS64R6;
- def DMFC2_MM64R6 : StdMMR6Rel, DMFC2_MM64R6_ENC, DMFC2_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DADD_MM64R6: StdMMR6Rel, DADD_MM64R6_DESC, DADD_MM64R6_ENC,
- ISA_MICROMIPS64R6;
- def DADDIU_MM64R6: StdMMR6Rel, DADDIU_MM64R6_DESC, DADDIU_MM64R6_ENC,
- ISA_MICROMIPS64R6;
- def DADDU_MM64R6: StdMMR6Rel, DADDU_MM64R6_DESC, DADDU_MM64R6_ENC,
- ISA_MICROMIPS64R6;
- def LDPC_MM64R6 : R6MMR6Rel, LDPC_MMR646_ENC, LDPC_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DSUB_MM64R6 : StdMMR6Rel, DSUB_MM64R6_DESC, DSUB_MM64R6_ENC,
- ISA_MICROMIPS64R6;
- def DSUBU_MM64R6 : StdMMR6Rel, DSUBU_MM64R6_DESC, DSUBU_MM64R6_ENC,
- ISA_MICROMIPS64R6;
- def DMUL_MM64R6 : R6MMR6Rel, DMUL_MM64R6_DESC, DMUL_MM64R6_ENC,
- ISA_MICROMIPS64R6;
- def DMUH_MM64R6 : R6MMR6Rel, DMUH_MM64R6_DESC, DMUH_MM64R6_ENC,
- ISA_MICROMIPS64R6;
- def DMULU_MM64R6 : R6MMR6Rel, DMULU_MM64R6_DESC, DMULU_MM64R6_ENC,
- ISA_MICROMIPS64R6;
- def DMUHU_MM64R6 : R6MMR6Rel, DMUHU_MM64R6_DESC, DMUHU_MM64R6_ENC,
- ISA_MICROMIPS64R6;
- def DSBH_MM64R6 : R6MMR6Rel, DSBH_MM64R6_ENC, DSBH_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DSHD_MM64R6 : R6MMR6Rel, DSHD_MM64R6_ENC, DSHD_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DSLL_MM64R6 : StdMMR6Rel, DSLL_MM64R6_ENC, DSLL_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DSLL32_MM64R6 : StdMMR6Rel, DSLL32_MM64R6_ENC, DSLL32_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DSLLV_MM64R6 : StdMMR6Rel, DSLLV_MM64R6_ENC, DSLLV_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DSRAV_MM64R6 : StdMMR6Rel, DSRAV_MM64R6_ENC, DSRAV_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DSRA_MM64R6 : StdMMR6Rel, DSRA_MM64R6_ENC, DSRA_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DSRA32_MM64R6 : StdMMR6Rel, DSRA32_MM64R6_ENC, DSRA32_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DCLO_MM64R6 : StdMMR6Rel, R6MMR6Rel, DCLO_MM64R6_ENC, DCLO_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DCLZ_MM64R6 : StdMMR6Rel, R6MMR6Rel, DCLZ_MM64R6_ENC, DCLZ_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DROTR_MM64R6 : StdMMR6Rel, DROTR_MM64R6_ENC, DROTR_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DROTR32_MM64R6 : StdMMR6Rel, DROTR32_MM64R6_ENC, DROTR32_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DROTRV_MM64R6 : StdMMR6Rel, DROTRV_MM64R6_ENC, DROTRV_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def LD_MM64R6 : StdMMR6Rel, LD_MM64R6_ENC, LD_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def LLD_MM64R6 : StdMMR6Rel, R6MMR6Rel, LLD_MM64R6_ENC, LLD_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def LWU_MM64R6 : StdMMR6Rel, LWU_MM64R6_ENC, LWU_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def SD_MM64R6 : StdMMR6Rel, SD_MM64R6_ENC, SD_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DSRL_MM64R6 : StdMMR6Rel, DSRL_MM64R6_ENC, DSRL_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DSRL32_MM64R6 : StdMMR6Rel, DSRL32_MM64R6_ENC, DSRL32_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DSRLV_MM64R6 : StdMMR6Rel, DSRLV_MM64R6_ENC, DSRLV_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DBITSWAP_MM64R6 : R6MMR6Rel, DBITSWAP_MM64R6_ENC, DBITSWAP_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def DLSA_MM64R6 : R6MMR6Rel, DLSA_MM64R6_ENC, DLSA_MM64R6_DESC,
- ISA_MICROMIPS64R6;
- def LWUPC_MM64R6 : R6MMR6Rel, LWUPC_MM64R6_ENC, LWUPC_MM64R6_DESC,
- ISA_MICROMIPS64R6;
-}
-
-let AdditionalPredicates = [InMicroMips] in
-defm : MaterializeImms<i64, ZERO_64, DADDIU_MM64R6, LUi64, ORi64>;
-
-//===----------------------------------------------------------------------===//
-//
-// Arbitrary patterns that map to one or more instructions
-//
-//===----------------------------------------------------------------------===//
-
-defm : MipsHiLoRelocs<LUi64, DADDIU_MM64R6, ZERO_64, GPR64Opnd>, SYM_32,
- ISA_MICROMIPS64R6;
-
-defm : MipsHighestHigherHiLoRelocs<LUi64, DADDIU_MM64R6>, SYM_64,
- ISA_MICROMIPS64R6;
-
-def : MipsPat<(addc GPR64:$lhs, GPR64:$rhs),
- (DADDU_MM64R6 GPR64:$lhs, GPR64:$rhs)>, ISA_MICROMIPS64R6;
-def : MipsPat<(addc GPR64:$lhs, immSExt16:$imm),
- (DADDIU_MM64R6 GPR64:$lhs, imm:$imm)>, ISA_MICROMIPS64R6;
-
-
-def : MipsPat<(rotr GPR64:$rt, (i32 (trunc GPR64:$rs))),
- (DROTRV_MM64R6 GPR64:$rt, (EXTRACT_SUBREG GPR64:$rs, sub_32))>,
- ISA_MICROMIPS64R6;
-
-
-def : WrapperPat<tglobaladdr, DADDIU_MM64R6, GPR64>, ISA_MICROMIPS64R6;
-def : WrapperPat<tconstpool, DADDIU_MM64R6, GPR64>, ISA_MICROMIPS64R6;
-def : WrapperPat<texternalsym, DADDIU_MM64R6, GPR64>, ISA_MICROMIPS64R6;
-def : WrapperPat<tblockaddress, DADDIU_MM64R6, GPR64>, ISA_MICROMIPS64R6;
-def : WrapperPat<tjumptable, DADDIU_MM64R6, GPR64>, ISA_MICROMIPS64R6;
-def : WrapperPat<tglobaltlsaddr, DADDIU_MM64R6, GPR64>, ISA_MICROMIPS64R6;
-
-// Carry pattern
-def : MipsPat<(subc GPR64:$lhs, GPR64:$rhs),
- (DSUBU_MM64R6 GPR64:$lhs, GPR64:$rhs)>, ISA_MICROMIPS64R6;
-
-def : MipsPat<(atomic_load_64 addr:$a), (LD_MM64R6 addr:$a)>, ISA_MICROMIPS64R6;
-
-//===----------------------------------------------------------------------===//
-//
-// Instruction aliases
-//
-//===----------------------------------------------------------------------===//
-
-def : MipsInstAlias<"dmtc0 $rt, $rd",
- (DMTC0_MM64R6 COP0Opnd:$rd, GPR64Opnd:$rt, 0), 0>;
-def : MipsInstAlias<"dmfc0 $rt, $rd",
- (DMFC0_MM64R6 GPR64Opnd:$rt, COP0Opnd:$rd, 0), 0>,
- ISA_MICROMIPS64R6;
-def : MipsInstAlias<"daddu $rs, $rt, $imm",
- (DADDIU_MM64R6 GPR64Opnd:$rs,
- GPR64Opnd:$rt,
- simm16_64:$imm),
- 0>, ISA_MICROMIPS64R6;
-def : MipsInstAlias<"daddu $rs, $imm",
- (DADDIU_MM64R6 GPR64Opnd:$rs,
- GPR64Opnd:$rs,
- simm16_64:$imm),
- 0>, ISA_MICROMIPS64R6;
-def : MipsInstAlias<"dsubu $rt, $rs, $imm",
- (DADDIU_MM64R6 GPR64Opnd:$rt,
- GPR64Opnd:$rs,
- InvertedImOperand64:$imm),
- 0>, ISA_MICROMIPS64R6;
-def : MipsInstAlias<"dsubu $rs, $imm",
- (DADDIU_MM64R6 GPR64Opnd:$rs,
- GPR64Opnd:$rs,
- InvertedImOperand64:$imm),
- 0>, ISA_MICROMIPS64R6;
-def : MipsInstAlias<"dneg $rt, $rs",
- (DSUB_MM64R6 GPR64Opnd:$rt, ZERO_64, GPR64Opnd:$rs), 1>,
- ISA_MICROMIPS64R6;
-def : MipsInstAlias<"dneg $rt",
- (DSUB_MM64R6 GPR64Opnd:$rt, ZERO_64, GPR64Opnd:$rt), 1>,
- ISA_MICROMIPS64R6;
-def : MipsInstAlias<"dnegu $rt, $rs",
- (DSUBU_MM64R6 GPR64Opnd:$rt, ZERO_64, GPR64Opnd:$rs), 1>,
- ISA_MICROMIPS64R6;
-def : MipsInstAlias<"dnegu $rt",
- (DSUBU_MM64R6 GPR64Opnd:$rt, ZERO_64, GPR64Opnd:$rt), 1>,
- ISA_MICROMIPS64R6;
-def : MipsInstAlias<"dsll $rd, $rt, $rs",
- (DSLLV_MM64R6 GPR64Opnd:$rd, GPR64Opnd:$rt,
- GPR32Opnd:$rs), 0>, ISA_MICROMIPS64R6;
-def : MipsInstAlias<"dsrl $rd, $rt, $rs",
- (DSRLV_MM64R6 GPR64Opnd:$rd, GPR64Opnd:$rt,
- GPR32Opnd:$rs), 0>, ISA_MICROMIPS64R6;
-def : MipsInstAlias<"dsrl $rd, $rt",
- (DSRLV_MM64R6 GPR64Opnd:$rd, GPR64Opnd:$rd,
- GPR32Opnd:$rt), 0>, ISA_MICROMIPS64R6;
-def : MipsInstAlias<"dsll $rd, $rt",
- (DSLLV_MM64R6 GPR64Opnd:$rd, GPR64Opnd:$rd,
- GPR32Opnd:$rt), 0>, ISA_MICROMIPS64R6;
diff --git a/lib/Target/Mips/MicroMipsInstrFPU.td b/lib/Target/Mips/MicroMipsInstrFPU.td
index 5600f71ff68e..49025cc1570a 100644
--- a/lib/Target/Mips/MicroMipsInstrFPU.td
+++ b/lib/Target/Mips/MicroMipsInstrFPU.td
@@ -1,33 +1,49 @@
-let isCodeGenOnly = 1, Predicates = [InMicroMips] in {
+//==- MicroMipsInstrFPU.td - microMIPS FPU Instruction Info -*- tablegen -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the microMIPS FPU instruction set.
+//
+//===----------------------------------------------------------------------===//
+
+let isCodeGenOnly = 1 in {
def FADD_S_MM : MMRel, ADDS_FT<"add.s", FGR32Opnd, II_ADD_S, 1, fadd>,
- ADDS_FM_MM<0, 0x30>;
+ ADDS_FM_MM<0, 0x30>, ISA_MICROMIPS;
def FDIV_S_MM : MMRel, ADDS_FT<"div.s", FGR32Opnd, II_DIV_S, 0, fdiv>,
- ADDS_FM_MM<0, 0xf0>;
+ ADDS_FM_MM<0, 0xf0>, ISA_MICROMIPS;
def FMUL_S_MM : MMRel, ADDS_FT<"mul.s", FGR32Opnd, II_MUL_S, 1, fmul>,
- ADDS_FM_MM<0, 0xb0>;
+ ADDS_FM_MM<0, 0xb0>, ISA_MICROMIPS;
def FSUB_S_MM : MMRel, ADDS_FT<"sub.s", FGR32Opnd, II_SUB_S, 0, fsub>,
- ADDS_FM_MM<0, 0x70>;
+ ADDS_FM_MM<0, 0x70>, ISA_MICROMIPS;
def FADD_MM : MMRel, ADDS_FT<"add.d", AFGR64Opnd, II_ADD_D, 1, fadd>,
- ADDS_FM_MM<1, 0x30>;
+ ADDS_FM_MM<1, 0x30>, ISA_MICROMIPS;
def FDIV_MM : MMRel, ADDS_FT<"div.d", AFGR64Opnd, II_DIV_D, 0, fdiv>,
- ADDS_FM_MM<1, 0xf0>;
+ ADDS_FM_MM<1, 0xf0>, ISA_MICROMIPS;
def FMUL_MM : MMRel, ADDS_FT<"mul.d", AFGR64Opnd, II_MUL_D, 1, fmul>,
- ADDS_FM_MM<1, 0xb0>;
+ ADDS_FM_MM<1, 0xb0>, ISA_MICROMIPS;
def FSUB_MM : MMRel, ADDS_FT<"sub.d", AFGR64Opnd, II_SUB_D, 0, fsub>,
- ADDS_FM_MM<1, 0x70>;
+ ADDS_FM_MM<1, 0x70>, ISA_MICROMIPS;
def LWXC1_MM : MMRel, LWXC1_FT<"lwxc1", FGR32Opnd, II_LWXC1, load>,
- LWXC1_FM_MM<0x48>, INSN_MIPS4_32R2_NOT_32R6_64R6;
+ LWXC1_FM_MM<0x48>, ISA_MICROMIPS32_NOT_MIPS32R6;
def SWXC1_MM : MMRel, SWXC1_FT<"swxc1", FGR32Opnd, II_SWXC1, store>,
- SWXC1_FM_MM<0x88>, INSN_MIPS4_32R2_NOT_32R6_64R6;
+ SWXC1_FM_MM<0x88>, ISA_MICROMIPS32_NOT_MIPS32R6;
+
+// FIXME: These instruction definitions are incorrect. They should be 64-bit
+// FPU only.
def LUXC1_MM : MMRel, LWXC1_FT<"luxc1", AFGR64Opnd, II_LUXC1>,
- LWXC1_FM_MM<0x148>, INSN_MIPS5_32R2_NOT_32R6_64R6;
+ LWXC1_FM_MM<0x148>, ISA_MICROMIPS32_NOT_MIPS32R6;
def SUXC1_MM : MMRel, SWXC1_FT<"suxc1", AFGR64Opnd, II_SUXC1>,
- SWXC1_FM_MM<0x188>, INSN_MIPS5_32R2_NOT_32R6_64R6;
+ SWXC1_FM_MM<0x188>, ISA_MICROMIPS32_NOT_MIPS32R6;
def FCMP_S32_MM : MMRel, CEQS_FT<"s", FGR32, II_C_CC_S, MipsFPCmp>,
- CEQS_FM_MM<0> {
+ CEQS_FM_MM<0>, ISA_MICROMIPS32_NOT_MIPS32R6 {
// FIXME: This is a required to work around the fact that these instructions
// only use $fcc0. Ideally, MipsFPCmp nodes could be removed and the
// fcc register set is used directly.
@@ -35,249 +51,299 @@ def FCMP_S32_MM : MMRel, CEQS_FT<"s", FGR32, II_C_CC_S, MipsFPCmp>,
}
def FCMP_D32_MM : MMRel, CEQS_FT<"d", AFGR64, II_C_CC_D, MipsFPCmp>,
- CEQS_FM_MM<1> {
+ CEQS_FM_MM<1>, ISA_MICROMIPS32_NOT_MIPS32R6 {
// FIXME: This is a required to work around the fact that these instructions
// only use $fcc0. Ideally, MipsFPCmp nodes could be removed and the
// fcc register set is used directly.
bits<3> fcc = 0;
}
-def BC1F_MM : MMRel, BC1F_FT<"bc1f", brtarget_mm, II_BC1F, MIPS_BRANCH_F>,
- BC1F_FM_MM<0x1c>, ISA_MIPS1_NOT_32R6_64R6;
-def BC1T_MM : MMRel, BC1F_FT<"bc1t", brtarget_mm, II_BC1T, MIPS_BRANCH_T>,
- BC1F_FM_MM<0x1d>, ISA_MIPS1_NOT_32R6_64R6;
+}
+
+let DecoderNamespace = "MicroMips" in {
+ def BC1F_MM : MMRel, BC1F_FT<"bc1f", brtarget_mm, II_BC1F, MIPS_BRANCH_F>,
+ BC1F_FM_MM<0x1c>, ISA_MICROMIPS32_NOT_MIPS32R6;
+ def BC1T_MM : MMRel, BC1F_FT<"bc1t", brtarget_mm, II_BC1T, MIPS_BRANCH_T>,
+ BC1F_FM_MM<0x1d>, ISA_MICROMIPS32_NOT_MIPS32R6;
+}
+
+let isCodeGenOnly = 1 in {
def CVT_W_S_MM : MMRel, ABSS_FT<"cvt.w.s", FGR32Opnd, FGR32Opnd, II_CVT>,
- ROUND_W_FM_MM<0, 0x24>;
-def ROUND_W_S_MM : MMRel, StdMMR6Rel, ABSS_FT<"round.w.s", FGR32Opnd, FGR32Opnd, II_ROUND>,
- ROUND_W_FM_MM<0, 0xec>;
+ ROUND_W_FM_MM<0, 0x24>, ISA_MICROMIPS;
+def ROUND_W_S_MM : MMRel, StdMMR6Rel, ABSS_FT<"round.w.s", FGR32Opnd, FGR32Opnd,
+ II_ROUND>, ROUND_W_FM_MM<0, 0xec>,
+ ISA_MICROMIPS;
def CEIL_W_MM : MMRel, ABSS_FT<"ceil.w.d", FGR32Opnd, AFGR64Opnd, II_CEIL>,
- ROUND_W_FM_MM<1, 0x6c>;
+ ROUND_W_FM_MM<1, 0x6c>, ISA_MICROMIPS, FGR_32;
def CVT_W_MM : MMRel, ABSS_FT<"cvt.w.d", FGR32Opnd, AFGR64Opnd, II_CVT>,
- ROUND_W_FM_MM<1, 0x24>;
+ ROUND_W_FM_MM<1, 0x24>, ISA_MICROMIPS, FGR_32;
def FLOOR_W_MM : MMRel, ABSS_FT<"floor.w.d", FGR32Opnd, AFGR64Opnd, II_FLOOR>,
- ROUND_W_FM_MM<1, 0x2c>;
-def ROUND_W_MM : MMRel, StdMMR6Rel, ABSS_FT<"round.w.d", FGR32Opnd, AFGR64Opnd, II_ROUND>,
- ROUND_W_FM_MM<1, 0xec>;
+ ROUND_W_FM_MM<1, 0x2c>, ISA_MICROMIPS, FGR_32;
+def ROUND_W_MM : MMRel, StdMMR6Rel, ABSS_FT<"round.w.d", FGR32Opnd, AFGR64Opnd,
+ II_ROUND>, ROUND_W_FM_MM<1, 0xec>,
+ ISA_MICROMIPS, FGR_32;
def TRUNC_W_MM : MMRel, ABSS_FT<"trunc.w.d", FGR32Opnd, AFGR64Opnd, II_TRUNC>,
- ROUND_W_FM_MM<1, 0xac>;
+ ROUND_W_FM_MM<1, 0xac>, ISA_MICROMIPS, FGR_32;
def FSQRT_MM : MMRel, ABSS_FT<"sqrt.d", AFGR64Opnd, AFGR64Opnd, II_SQRT_D,
- fsqrt>, ROUND_W_FM_MM<1, 0x28>;
+ fsqrt>, ROUND_W_FM_MM<1, 0x28>,
+ ISA_MICROMIPS, FGR_32;
def CVT_L_S_MM : MMRel, ABSS_FT<"cvt.l.s", FGR64Opnd, FGR32Opnd, II_CVT>,
- ROUND_W_FM_MM<0, 0x4>, INSN_MIPS3_32R2;
+ ROUND_W_FM_MM<0, 0x4>, ISA_MICROMIPS, FGR_64;
def CVT_L_D64_MM : MMRel, ABSS_FT<"cvt.l.d", FGR64Opnd, FGR64Opnd, II_CVT>,
- ROUND_W_FM_MM<1, 0x4>, INSN_MIPS3_32R2;
+ ROUND_W_FM_MM<1, 0x4>, ISA_MICROMIPS, FGR_64;
+
+}
-def FABS_S_MM : MMRel, ABSS_FT<"abs.s", FGR32Opnd, FGR32Opnd, II_ABS, fabs>,
- ABS_FM_MM<0, 0xd>;
+let DecoderNamespace = "MicroMips" in {
+ def FABS_S_MM : MMRel, ABSS_FT<"abs.s", FGR32Opnd, FGR32Opnd, II_ABS, fabs>,
+ ABS_FM_MM<0, 0xd>, ISA_MICROMIPS;
+ def FABS_MM : MMRel, ABSS_FT<"abs.d", AFGR64Opnd, AFGR64Opnd, II_ABS, fabs>,
+ ABS_FM_MM<1, 0xd>, ISA_MICROMIPS, FGR_32;
+}
+
+let isCodeGenOnly = 1 in {
def FMOV_S_MM : MMRel, ABSS_FT<"mov.s", FGR32Opnd, FGR32Opnd, II_MOV_S>,
- ABS_FM_MM<0, 0x1>;
+ ABS_FM_MM<0, 0x1>, ISA_MICROMIPS;
def FNEG_S_MM : MMRel, ABSS_FT<"neg.s", FGR32Opnd, FGR32Opnd, II_NEG, fneg>,
- ABS_FM_MM<0, 0x2d>;
+ ABS_FM_MM<0, 0x2d>, ISA_MICROMIPS;
def CVT_D_S_MM : MMRel, ABSS_FT<"cvt.d.s", AFGR64Opnd, FGR32Opnd, II_CVT>,
- ABS_FM_MM<0, 0x4d>;
+ ABS_FM_MM<0, 0x4d>, ISA_MICROMIPS, FGR_32;
def CVT_D32_W_MM : MMRel, ABSS_FT<"cvt.d.w", AFGR64Opnd, FGR32Opnd, II_CVT>,
- ABS_FM_MM<1, 0x4d>;
+ ABS_FM_MM<1, 0x4d>, ISA_MICROMIPS, FGR_32;
def CVT_S_D32_MM : MMRel, ABSS_FT<"cvt.s.d", FGR32Opnd, AFGR64Opnd, II_CVT>,
- ABS_FM_MM<0, 0x6d>;
+ ABS_FM_MM<0, 0x6d>, ISA_MICROMIPS, FGR_32;
def CVT_S_W_MM : MMRel, ABSS_FT<"cvt.s.w", FGR32Opnd, FGR32Opnd, II_CVT>,
- ABS_FM_MM<1, 0x6d>;
+ ABS_FM_MM<1, 0x6d>, ISA_MICROMIPS;
-def FABS_MM : MMRel, ABSS_FT<"abs.d", AFGR64Opnd, AFGR64Opnd, II_ABS, fabs>,
- ABS_FM_MM<1, 0xd>;
def FNEG_MM : MMRel, ABSS_FT<"neg.d", AFGR64Opnd, AFGR64Opnd, II_NEG, fneg>,
- ABS_FM_MM<1, 0x2d>;
+ ABS_FM_MM<1, 0x2d>, ISA_MICROMIPS, FGR_32;
def FMOV_D32_MM : MMRel, ABSS_FT<"mov.d", AFGR64Opnd, AFGR64Opnd, II_MOV_D>,
- ABS_FM_MM<1, 0x1>, FGR_32;
+ ABS_FM_MM<1, 0x1>, ISA_MICROMIPS, FGR_32;
def MOVZ_I_S_MM : MMRel, CMov_I_F_FT<"movz.s", GPR32Opnd, FGR32Opnd,
- II_MOVZ_S>, CMov_I_F_FM_MM<0x78, 0>;
+ II_MOVZ_S>, CMov_I_F_FM_MM<0x78, 0>,
+ ISA_MICROMIPS32_NOT_MIPS32R6;
def MOVN_I_S_MM : MMRel, CMov_I_F_FT<"movn.s", GPR32Opnd, FGR32Opnd,
- II_MOVN_S>, CMov_I_F_FM_MM<0x38, 0>;
+ II_MOVN_S>, CMov_I_F_FM_MM<0x38, 0>,
+ ISA_MICROMIPS32_NOT_MIPS32R6;
def MOVZ_I_D32_MM : MMRel, CMov_I_F_FT<"movz.d", GPR32Opnd, AFGR64Opnd,
- II_MOVZ_D>, CMov_I_F_FM_MM<0x78, 1>;
+ II_MOVZ_D>, CMov_I_F_FM_MM<0x78, 1>,
+ ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32;
def MOVN_I_D32_MM : MMRel, CMov_I_F_FT<"movn.d", GPR32Opnd, AFGR64Opnd,
- II_MOVN_D>, CMov_I_F_FM_MM<0x38, 1>;
+ II_MOVN_D>, CMov_I_F_FM_MM<0x38, 1>,
+ ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32;
def MOVT_S_MM : MMRel, CMov_F_F_FT<"movt.s", FGR32Opnd, II_MOVT_S,
- MipsCMovFP_T>, CMov_F_F_FM_MM<0x60, 0>;
+ MipsCMovFP_T>, CMov_F_F_FM_MM<0x60, 0>,
+ ISA_MICROMIPS32_NOT_MIPS32R6;
def MOVF_S_MM : MMRel, CMov_F_F_FT<"movf.s", FGR32Opnd, II_MOVF_S,
- MipsCMovFP_F>, CMov_F_F_FM_MM<0x20, 0>;
+ MipsCMovFP_F>, CMov_F_F_FM_MM<0x20, 0>,
+ ISA_MICROMIPS32_NOT_MIPS32R6;
def MOVT_D32_MM : MMRel, CMov_F_F_FT<"movt.d", AFGR64Opnd, II_MOVT_D,
- MipsCMovFP_T>, CMov_F_F_FM_MM<0x60, 1>;
+ MipsCMovFP_T>, CMov_F_F_FM_MM<0x60, 1>,
+ ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32;
def MOVF_D32_MM : MMRel, CMov_F_F_FT<"movf.d", AFGR64Opnd, II_MOVF_D,
- MipsCMovFP_F>, CMov_F_F_FM_MM<0x20, 1>;
+ MipsCMovFP_F>, CMov_F_F_FM_MM<0x20, 1>,
+ ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32;
def MFC1_MM : MMRel, MFC1_FT<"mfc1", GPR32Opnd, FGR32Opnd,
- II_MFC1, bitconvert>, MFC1_FM_MM<0x80>;
+ II_MFC1, bitconvert>, MFC1_FM_MM<0x80>,
+ ISA_MICROMIPS;
def MTC1_MM : MMRel, MTC1_FT<"mtc1", FGR32Opnd, GPR32Opnd,
- II_MTC1, bitconvert>, MFC1_FM_MM<0xa0>;
+ II_MTC1, bitconvert>, MFC1_FM_MM<0xa0>,
+ ISA_MICROMIPS;
def MADD_S_MM : MMRel, MADDS_FT<"madd.s", FGR32Opnd, II_MADD_S, fadd>,
- MADDS_FM_MM<0x1>;
+ MADDS_FM_MM<0x1>, ISA_MICROMIPS32_NOT_MIPS32R6;
def MSUB_S_MM : MMRel, MADDS_FT<"msub.s", FGR32Opnd, II_MSUB_S, fsub>,
- MADDS_FM_MM<0x21>;
+ MADDS_FM_MM<0x21>, ISA_MICROMIPS32_NOT_MIPS32R6;
def NMADD_S_MM : MMRel, NMADDS_FT<"nmadd.s", FGR32Opnd, II_NMADD_S, fadd>,
- MADDS_FM_MM<0x2>;
+ MADDS_FM_MM<0x2>, ISA_MICROMIPS32_NOT_MIPS32R6;
def NMSUB_S_MM : MMRel, NMADDS_FT<"nmsub.s", FGR32Opnd, II_NMSUB_S, fsub>,
- MADDS_FM_MM<0x22>;
+ MADDS_FM_MM<0x22>, ISA_MICROMIPS32_NOT_MIPS32R6;
def MADD_D32_MM : MMRel, MADDS_FT<"madd.d", AFGR64Opnd, II_MADD_D, fadd>,
- MADDS_FM_MM<0x9>;
+ MADDS_FM_MM<0x9>, ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32;
def MSUB_D32_MM : MMRel, MADDS_FT<"msub.d", AFGR64Opnd, II_MSUB_D, fsub>,
- MADDS_FM_MM<0x29>;
+ MADDS_FM_MM<0x29>, ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32;
def NMADD_D32_MM : MMRel, NMADDS_FT<"nmadd.d", AFGR64Opnd, II_NMADD_D, fadd>,
- MADDS_FM_MM<0xa>;
+ MADDS_FM_MM<0xa>, ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32;
def NMSUB_D32_MM : MMRel, NMADDS_FT<"nmsub.d", AFGR64Opnd, II_NMSUB_D, fsub>,
- MADDS_FM_MM<0x2a>;
+ MADDS_FM_MM<0x2a>, ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32;
}
-let AdditionalPredicates = [InMicroMips] in {
- def FLOOR_W_S_MM : MMRel, ABSS_FT<"floor.w.s", FGR32Opnd, FGR32Opnd,
- II_FLOOR>, ROUND_W_FM_MM<0, 0x2c>;
- def TRUNC_W_S_MM : MMRel, StdMMR6Rel, ABSS_FT<"trunc.w.s", FGR32Opnd,
- FGR32Opnd, II_TRUNC>, ROUND_W_FM_MM<0, 0xac>;
- def CEIL_W_S_MM : MMRel, ABSS_FT<"ceil.w.s", FGR32Opnd, FGR32Opnd, II_CEIL>,
- ROUND_W_FM_MM<0, 0x6c>;
- def FSQRT_S_MM : MMRel, ABSS_FT<"sqrt.s", FGR32Opnd, FGR32Opnd, II_SQRT_S,
- fsqrt>, ROUND_W_FM_MM<0, 0x28>;
- def MTHC1_MM : MMRel, MTC1_64_FT<"mthc1", AFGR64Opnd, GPR32Opnd, II_MTHC1>,
- MFC1_FM_MM<0xe0>, ISA_MIPS32R2, FGR_32;
- def MFHC1_MM : MMRel, MFC1_FT<"mfhc1", GPR32Opnd, AFGR64Opnd, II_MFHC1>,
- MFC1_FM_MM<0xc0>, ISA_MIPS32R2, FGR_32;
- let DecoderNamespace = "MicroMips" in {
- def CFC1_MM : MMRel, MFC1_FT<"cfc1", GPR32Opnd, CCROpnd, II_CFC1>,
- MFC1_FM_MM<0x40>;
- def CTC1_MM : MMRel, MTC1_FT<"ctc1", CCROpnd, GPR32Opnd, II_CTC1>,
- MFC1_FM_MM<0x60>;
- def RECIP_S_MM : MMRel, ABSS_FT<"recip.s", FGR32Opnd, FGR32Opnd,
- II_RECIP_S>,
- ROUND_W_FM_MM<0b0, 0b01001000>;
- def RECIP_D_MM : MMRel, ABSS_FT<"recip.d", AFGR64Opnd, AFGR64Opnd,
- II_RECIP_D>, ROUND_W_FM_MM<0b1, 0b01001000>;
- def RSQRT_S_MM : MMRel, ABSS_FT<"rsqrt.s", FGR32Opnd, FGR32Opnd,
+def FLOOR_W_S_MM : MMRel, ABSS_FT<"floor.w.s", FGR32Opnd, FGR32Opnd,
+ II_FLOOR>, ROUND_W_FM_MM<0, 0x2c>,
+ ISA_MICROMIPS;
+def TRUNC_W_S_MM : MMRel, StdMMR6Rel, ABSS_FT<"trunc.w.s", FGR32Opnd,
+ FGR32Opnd, II_TRUNC>,
+ ROUND_W_FM_MM<0, 0xac>, ISA_MICROMIPS;
+def CEIL_W_S_MM : MMRel, ABSS_FT<"ceil.w.s", FGR32Opnd, FGR32Opnd, II_CEIL>,
+ ROUND_W_FM_MM<0, 0x6c>, ISA_MICROMIPS;
+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_MM : MMRel, MTC1_64_FT<"mthc1", AFGR64Opnd, GPR32Opnd, II_MTHC1>,
+ MFC1_FM_MM<0xe0>, ISA_MICROMIPS, FGR_32;
+def MFHC1_MM : MMRel, MFC1_FT<"mfhc1", GPR32Opnd, AFGR64Opnd, II_MFHC1>,
+ MFC1_FM_MM<0xc0>, ISA_MICROMIPS, FGR_32;
+
+let DecoderNamespace = "MicroMips" in {
+ def CFC1_MM : MMRel, MFC1_FT<"cfc1", GPR32Opnd, CCROpnd, II_CFC1>,
+ MFC1_FM_MM<0x40>, ISA_MICROMIPS;
+ def CTC1_MM : MMRel, MTC1_FT<"ctc1", CCROpnd, GPR32Opnd, II_CTC1>,
+ MFC1_FM_MM<0x60>, ISA_MICROMIPS;
+ def RECIP_S_MM : MMRel, ABSS_FT<"recip.s", FGR32Opnd, FGR32Opnd,
II_RECIP_S>,
- ROUND_W_FM_MM<0b0, 0b00001000>;
- def RSQRT_D_MM : MMRel, ABSS_FT<"rsqrt.d", AFGR64Opnd, AFGR64Opnd,
- II_RECIP_D>, ROUND_W_FM_MM<0b1, 0b00001000>;
+ ROUND_W_FM_MM<0b0, 0b01001000>, ISA_MICROMIPS;
+ def RECIP_D32_MM : MMRel, ABSS_FT<"recip.d", AFGR64Opnd, AFGR64Opnd,
+ II_RECIP_D>,
+ ROUND_W_FM_MM<0b1, 0b01001000>, ISA_MICROMIPS, FGR_32 {
+ let BaseOpcode = "RECIP_D32";
}
- let DecoderNamespace = "MicroMips", DecoderMethod = "DecodeFMemMMR2" in {
- def LDC1_MM : MMRel, LW_FT<"ldc1", AFGR64Opnd, mem_mm_16, II_LDC1, load>,
- LW_FM_MM<0x2f>, FGR_32 {
- let BaseOpcode = "LDC132";
- }
- def SDC1_MM : MMRel, SW_FT<"sdc1", AFGR64Opnd, mem_mm_16, II_SDC1, store>,
- LW_FM_MM<0x2e>, FGR_32;
- def LWC1_MM : MMRel, LW_FT<"lwc1", FGR32Opnd, mem_mm_16, II_LWC1, load>,
- LW_FM_MM<0x27>;
- def SWC1_MM : MMRel, SW_FT<"swc1", FGR32Opnd, mem_mm_16, II_SWC1, store>,
- LW_FM_MM<0x26>;
+ let DecoderNamespace = "MicroMipsFP64" in
+ def RECIP_D64_MM : MMRel, ABSS_FT<"recip.d", FGR64Opnd, FGR64Opnd,
+ II_RECIP_D>,
+ ROUND_W_FM_MM<0b1, 0b01001000>, ISA_MICROMIPS, FGR_64;
+ def RSQRT_S_MM : MMRel, ABSS_FT<"rsqrt.s", FGR32Opnd, FGR32Opnd,
+ II_RECIP_S>,
+ ROUND_W_FM_MM<0b0, 0b00001000>;
+ def RSQRT_D32_MM : MMRel, ABSS_FT<"rsqrt.d", AFGR64Opnd, AFGR64Opnd,
+ II_RECIP_D>,
+ ROUND_W_FM_MM<0b1, 0b00001000>, ISA_MICROMIPS, FGR_32 {
+ let BaseOpcode = "RSQRT_D32";
}
+ let DecoderNamespace = "MicroMipsFP64" in
+ def RSQRT_D64_MM : MMRel, ABSS_FT<"rsqrt.d", FGR64Opnd, FGR64Opnd,
+ II_RECIP_D>,
+ ROUND_W_FM_MM<0b1, 0b00001000>, ISA_MICROMIPS, FGR_64;
+}
- multiclass C_COND_MM<string TypeStr, RegisterOperand RC, bits<2> fmt,
- InstrItinClass itin> {
- def C_F_#NAME#_MM : MMRel, C_COND_FT<"f", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 0> {
- let BaseOpcode = "c.f."#NAME;
- let isCommutable = 1;
- }
- def C_UN_#NAME#_MM : MMRel, C_COND_FT<"un", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 1> {
- let BaseOpcode = "c.un."#NAME;
- let isCommutable = 1;
- }
- def C_EQ_#NAME#_MM : MMRel, C_COND_FT<"eq", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 2> {
- let BaseOpcode = "c.eq."#NAME;
- let isCommutable = 1;
- }
- def C_UEQ_#NAME#_MM : MMRel, C_COND_FT<"ueq", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 3> {
- let BaseOpcode = "c.ueq."#NAME;
- let isCommutable = 1;
- }
- def C_OLT_#NAME#_MM : MMRel, C_COND_FT<"olt", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 4> {
- let BaseOpcode = "c.olt."#NAME;
- }
- def C_ULT_#NAME#_MM : MMRel, C_COND_FT<"ult", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 5> {
- let BaseOpcode = "c.ult."#NAME;
- }
- def C_OLE_#NAME#_MM : MMRel, C_COND_FT<"ole", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 6> {
- let BaseOpcode = "c.ole."#NAME;
- }
- def C_ULE_#NAME#_MM : MMRel, C_COND_FT<"ule", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 7> {
- let BaseOpcode = "c.ule."#NAME;
- }
- def C_SF_#NAME#_MM : MMRel, C_COND_FT<"sf", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 8> {
- let BaseOpcode = "c.sf."#NAME;
- let isCommutable = 1;
- }
- def C_NGLE_#NAME#_MM : MMRel, C_COND_FT<"ngle", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 9> {
- let BaseOpcode = "c.ngle."#NAME;
- }
- def C_SEQ_#NAME#_MM : MMRel, C_COND_FT<"seq", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 10> {
- let BaseOpcode = "c.seq."#NAME;
- let isCommutable = 1;
- }
- def C_NGL_#NAME#_MM : MMRel, C_COND_FT<"ngl", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 11> {
- let BaseOpcode = "c.ngl."#NAME;
- }
- def C_LT_#NAME#_MM : MMRel, C_COND_FT<"lt", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 12> {
- let BaseOpcode = "c.lt."#NAME;
- }
- def C_NGE_#NAME#_MM : MMRel, C_COND_FT<"nge", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 13> {
- let BaseOpcode = "c.nge."#NAME;
- }
- def C_LE_#NAME#_MM : MMRel, C_COND_FT<"le", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 14> {
- let BaseOpcode = "c.le."#NAME;
- }
- def C_NGT_#NAME#_MM : MMRel, C_COND_FT<"ngt", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 15> {
- let BaseOpcode = "c.ngt."#NAME;
- }
+let DecoderNamespace = "MicroMips", DecoderMethod = "DecodeFMemMMR2" in {
+ def LDC1_MM : MMRel, LW_FT<"ldc1", AFGR64Opnd, mem_mm_16, II_LDC1, load>,
+ LW_FM_MM<0x2f>, ISA_MICROMIPS, FGR_32 {
+ let BaseOpcode = "LDC132";
+ }
+ def SDC1_MM : MMRel, SW_FT<"sdc1", AFGR64Opnd, mem_mm_16, II_SDC1, store>,
+ LW_FM_MM<0x2e>, ISA_MICROMIPS, FGR_32;
+ def LWC1_MM : MMRel, LW_FT<"lwc1", FGR32Opnd, mem_mm_16, II_LWC1, load>,
+ LW_FM_MM<0x27>, ISA_MICROMIPS;
+ def SWC1_MM : MMRel, SW_FT<"swc1", FGR32Opnd, mem_mm_16, II_SWC1, store>,
+ LW_FM_MM<0x26>, ISA_MICROMIPS;
+}
+
+multiclass C_COND_MM<string TypeStr, RegisterOperand RC, bits<2> fmt,
+ InstrItinClass itin> {
+ def C_F_#NAME#_MM : MMRel, C_COND_FT<"f", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 0> {
+ let BaseOpcode = "c.f."#NAME;
+ let isCommutable = 1;
+ }
+ def C_UN_#NAME#_MM : MMRel, C_COND_FT<"un", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 1> {
+ let BaseOpcode = "c.un."#NAME;
+ let isCommutable = 1;
}
+ def C_EQ_#NAME#_MM : MMRel, C_COND_FT<"eq", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 2> {
+ let BaseOpcode = "c.eq."#NAME;
+ let isCommutable = 1;
+ }
+ def C_UEQ_#NAME#_MM : MMRel, C_COND_FT<"ueq", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 3> {
+ let BaseOpcode = "c.ueq."#NAME;
+ let isCommutable = 1;
+ }
+ def C_OLT_#NAME#_MM : MMRel, C_COND_FT<"olt", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 4> {
+ let BaseOpcode = "c.olt."#NAME;
+ }
+ def C_ULT_#NAME#_MM : MMRel, C_COND_FT<"ult", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 5> {
+ let BaseOpcode = "c.ult."#NAME;
+ }
+ def C_OLE_#NAME#_MM : MMRel, C_COND_FT<"ole", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 6> {
+ let BaseOpcode = "c.ole."#NAME;
+ }
+ def C_ULE_#NAME#_MM : MMRel, C_COND_FT<"ule", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 7> {
+ let BaseOpcode = "c.ule."#NAME;
+ }
+ def C_SF_#NAME#_MM : MMRel, C_COND_FT<"sf", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 8> {
+ let BaseOpcode = "c.sf."#NAME;
+ let isCommutable = 1;
+ }
+ def C_NGLE_#NAME#_MM : MMRel, C_COND_FT<"ngle", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 9> {
+ let BaseOpcode = "c.ngle."#NAME;
+ }
+ def C_SEQ_#NAME#_MM : MMRel, C_COND_FT<"seq", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 10> {
+ let BaseOpcode = "c.seq."#NAME;
+ let isCommutable = 1;
+ }
+ def C_NGL_#NAME#_MM : MMRel, C_COND_FT<"ngl", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 11> {
+ let BaseOpcode = "c.ngl."#NAME;
+ }
+ def C_LT_#NAME#_MM : MMRel, C_COND_FT<"lt", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 12> {
+ let BaseOpcode = "c.lt."#NAME;
+ }
+ def C_NGE_#NAME#_MM : MMRel, C_COND_FT<"nge", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 13> {
+ let BaseOpcode = "c.nge."#NAME;
+ }
+ def C_LE_#NAME#_MM : MMRel, C_COND_FT<"le", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 14> {
+ let BaseOpcode = "c.le."#NAME;
+ }
+ def C_NGT_#NAME#_MM : MMRel, C_COND_FT<"ngt", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 15> {
+ let BaseOpcode = "c.ngt."#NAME;
+ }
+}
- defm S : C_COND_MM<"s", FGR32Opnd, 0b00, II_C_CC_S>,
- ISA_MIPS1_NOT_32R6_64R6;
- defm D32 : C_COND_MM<"d", AFGR64Opnd, 0b01, II_C_CC_D>,
- ISA_MIPS1_NOT_32R6_64R6, FGR_32;
- let DecoderNamespace = "Mips64" in
+defm S : C_COND_MM<"s", FGR32Opnd, 0b00, II_C_CC_S>,
+ ISA_MICROMIPS32_NOT_MIPS32R6;
+defm D32 : C_COND_MM<"d", AFGR64Opnd, 0b01, II_C_CC_D>,
+ ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32;
+let DecoderNamespace = "Mips64" in
defm D64 : C_COND_MM<"d", FGR64Opnd, 0b01, II_C_CC_D>,
- ISA_MIPS1_NOT_32R6_64R6, FGR_64;
+ ISA_MICROMIPS32_NOT_MIPS32R6, FGR_64;
- defm S_MM : C_COND_ALIASES<"s", FGR32Opnd>, HARDFLOAT,
- ISA_MIPS1_NOT_32R6_64R6;
- defm D32_MM : C_COND_ALIASES<"d", AFGR64Opnd>, HARDFLOAT,
- ISA_MIPS1_NOT_32R6_64R6, FGR_32;
- defm D64_MM : C_COND_ALIASES<"d", FGR64Opnd>, HARDFLOAT,
- ISA_MIPS1_NOT_32R6_64R6, FGR_64;
+defm S_MM : C_COND_ALIASES<"s", FGR32Opnd>, HARDFLOAT,
+ ISA_MICROMIPS32_NOT_MIPS32R6;
+defm D32_MM : C_COND_ALIASES<"d", AFGR64Opnd>, HARDFLOAT,
+ ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32;
+defm D64_MM : C_COND_ALIASES<"d", FGR64Opnd>, HARDFLOAT,
+ ISA_MICROMIPS32_NOT_MIPS32R6, FGR_64;
- defm : BC1_ALIASES<BC1T_MM, "bc1t", BC1F_MM, "bc1f">,
- ISA_MIPS1_NOT_32R6_64R6, HARDFLOAT;
+defm : BC1_ALIASES<BC1T_MM, "bc1t", BC1F_MM, "bc1f">,
+ ISA_MICROMIPS32_NOT_MIPS32R6, HARDFLOAT;
+
+
+// To generate NMADD and NMSUB instructions when fneg node is present
+let AdditionalPredicates = [NoNaNsFPMath, HasMadd4,
+ InMicroMips, NotMips32r6] in {
+ defm : NMADD_NMSUB<NMADD_S_MM, NMSUB_S_MM, FGR32Opnd>,
+ ISA_MICROMIPS32_NOT_MIPS32R6;
+ defm : NMADD_NMSUB<NMADD_D32_MM, NMSUB_D32_MM, AFGR64Opnd>,
+ ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32;
}
//===----------------------------------------------------------------------===//
// Floating Point Patterns
//===----------------------------------------------------------------------===//
-let AdditionalPredicates = [InMicroMips] in {
- // Patterns for loads/stores with a reg+imm operand.
- let AddedComplexity = 40 in {
- def : LoadRegImmPat<LDC1_MM, f64, load>, FGR_32;
- def : StoreRegImmPat<SDC1_MM, f64>, FGR_32;
- def : LoadRegImmPat<LWC1_MM, f32, load>;
- def : StoreRegImmPat<SWC1_MM, f32>;
- }
+
+// Patterns for loads/stores with a reg+imm operand.
+let AddedComplexity = 40 in {
+ def : LoadRegImmPat<LDC1_MM, f64, load>, ISA_MICROMIPS, FGR_32;
+ def : StoreRegImmPat<SDC1_MM, f64>, ISA_MICROMIPS, FGR_32;
+ def : LoadRegImmPat<LWC1_MM, f32, load>, ISA_MICROMIPS;
+ def : StoreRegImmPat<SWC1_MM, f32>, ISA_MICROMIPS;
}
diff --git a/lib/Target/Mips/MicroMipsInstrFormats.td b/lib/Target/Mips/MicroMipsInstrFormats.td
index 774976828a0c..bc0045dad21e 100644
--- a/lib/Target/Mips/MicroMipsInstrFormats.td
+++ b/lib/Target/Mips/MicroMipsInstrFormats.td
@@ -786,13 +786,14 @@ class C_COND_FM_MM<bits <2> fmt, bits<4> c> : CEQS_FM_MM<fmt> {
}
class BC1F_FM_MM<bits<5> tf> : MMArch {
+ bits<3> fcc;
bits<16> offset;
bits<32> Inst;
let Inst{31-26} = 0x10;
let Inst{25-21} = tf;
- let Inst{20-18} = 0x0; // cc
+ let Inst{20-18} = fcc; // cc
let Inst{17-16} = 0x0;
let Inst{15-0} = offset;
}
diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td
index ee554bc7f69a..64fe55e9776b 100644
--- a/lib/Target/Mips/MicroMipsInstrInfo.td
+++ b/lib/Target/Mips/MicroMipsInstrInfo.td
@@ -587,24 +587,24 @@ class UncondBranchMM16<string opstr> :
}
def ADDU16_MM : ArithRMM16<"addu16", GPRMM16Opnd, 1, II_ADDU, add>,
- ARITH_FM_MM16<0>, ISA_MICROMIPS_NOT_32R6_64R6;
+ ARITH_FM_MM16<0>, ISA_MICROMIPS_NOT_32R6;
def AND16_MM : LogicRMM16<"and16", GPRMM16Opnd, II_AND, and>,
- LOGIC_FM_MM16<0x2>, ISA_MICROMIPS_NOT_32R6_64R6;
+ LOGIC_FM_MM16<0x2>, ISA_MICROMIPS_NOT_32R6;
def ANDI16_MM : AndImmMM16<"andi16", GPRMM16Opnd, II_AND>, ANDI_FM_MM16<0x0b>,
- ISA_MICROMIPS_NOT_32R6_64R6;
+ ISA_MICROMIPS_NOT_32R6;
def NOT16_MM : NotMM16<"not16", GPRMM16Opnd>, LOGIC_FM_MM16<0x0>,
- ISA_MICROMIPS_NOT_32R6_64R6;
+ ISA_MICROMIPS_NOT_32R6;
def OR16_MM : LogicRMM16<"or16", GPRMM16Opnd, II_OR, or>, LOGIC_FM_MM16<0x3>,
- ISA_MICROMIPS_NOT_32R6_64R6;
+ ISA_MICROMIPS_NOT_32R6;
def SLL16_MM : ShiftIMM16<"sll16", uimm3_shift, GPRMM16Opnd, II_SLL>,
- SHIFT_FM_MM16<0>, ISA_MICROMIPS_NOT_32R6_64R6;
+ SHIFT_FM_MM16<0>, ISA_MICROMIPS_NOT_32R6;
def SRL16_MM : ShiftIMM16<"srl16", uimm3_shift, GPRMM16Opnd, II_SRL>,
- SHIFT_FM_MM16<1>, ISA_MICROMIPS_NOT_32R6_64R6;
+ SHIFT_FM_MM16<1>, ISA_MICROMIPS_NOT_32R6;
def SUBU16_MM : ArithRMM16<"subu16", GPRMM16Opnd, 0, II_SUBU, sub>,
- ARITH_FM_MM16<1>, ISA_MICROMIPS_NOT_32R6_64R6;
+ ARITH_FM_MM16<1>, ISA_MICROMIPS_NOT_32R6;
def XOR16_MM : LogicRMM16<"xor16", GPRMM16Opnd, II_XOR, xor>,
- LOGIC_FM_MM16<0x1>, ISA_MICROMIPS_NOT_32R6_64R6;
+ LOGIC_FM_MM16<0x1>, ISA_MICROMIPS_NOT_32R6;
def LBU16_MM : LoadMM16<"lbu16", GPRMM16Opnd, zextloadi8, II_LBU,
mem_mm_4>, LOAD_STORE_FM_MM16<0x02>;
def LHU16_MM : LoadMM16<"lhu16", GPRMM16Opnd, zextloadi16, II_LHU,
@@ -631,7 +631,8 @@ def ADDIUSP_MM : AddImmUSP<"addiusp">, ADDIUSP_FM_MM16;
def MFHI16_MM : MoveFromHILOMM<"mfhi", GPR32Opnd, AC0>, MFHILO_FM_MM16<0x10>;
def MFLO16_MM : MoveFromHILOMM<"mflo", GPR32Opnd, AC0>, MFHILO_FM_MM16<0x12>;
def MOVE16_MM : MoveMM16<"move", GPR32Opnd>, MOVE_FM_MM16<0x03>;
-def MOVEP_MM : MovePMM16<"movep", GPRMM16OpndMoveP>, MOVEP_FM_MM16;
+def MOVEP_MM : MovePMM16<"movep", GPRMM16OpndMoveP>, MOVEP_FM_MM16,
+ ISA_MICROMIPS_NOT_32R6;
def LI16_MM : LoadImmMM16<"li16", li16_imm, GPRMM16Opnd>, LI_FM_MM16,
IsAsCheapAsAMove;
def JALR16_MM : JumpLinkRegMM16<"jalr", GPR32Opnd>, JALR_FM_MM16<0x0e>,
@@ -646,9 +647,9 @@ def BNEZ16_MM : CBranchZeroMM<"bnez16", brtarget7_mm, GPRMM16Opnd>,
BEQNEZ_FM_MM16<0x2b>;
def B16_MM : UncondBranchMM16<"b16">, B16_FM;
def BREAK16_MM : BrkSdbbp16MM<"break16", II_BREAK>, BRKSDBBP16_FM_MM<0x28>,
- ISA_MICROMIPS_NOT_32R6_64R6;
+ ISA_MICROMIPS_NOT_32R6;
def SDBBP16_MM : BrkSdbbp16MM<"sdbbp16", II_SDBBP>, BRKSDBBP16_FM_MM<0x2C>,
- ISA_MICROMIPS_NOT_32R6_64R6;
+ ISA_MICROMIPS_NOT_32R6;
let DecoderNamespace = "MicroMips" in {
/// Load and Store Instructions - multiple
@@ -884,12 +885,18 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
def EXT_MM : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1, immZExt5,
immZExt5Plus1, MipsExt>, EXT_FM_MM<0x2c>;
def INS_MM : MMRel, InsBase<"ins", GPR32Opnd, uimm5, uimm5_inssize_plus1,
- MipsIns>, EXT_FM_MM<0x0c>;
+ immZExt5, immZExt5Plus1>,
+ EXT_FM_MM<0x0c>;
/// Jump Instructions
+}
+let DecoderNamespace = "MicroMips", DecoderMethod = "DecodeJumpTargetMM" in
+ def J_MM : MMRel, JumpFJ<jmptarget_mm, "j", br, bb, "j">,
+ J_FM_MM<0x35>, AdditionalRequires<[RelocNotPIC]>,
+ IsBranch, ISA_MICROMIPS32_NOT_MIPS32R6;
+
+let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
let DecoderMethod = "DecodeJumpTargetMM" in {
- def J_MM : MMRel, JumpFJ<jmptarget_mm, "j", br, bb, "j">,
- J_FM_MM<0x35>;
def JAL_MM : MMRel, JumpLink<"jal", calltarget_mm>, J_FM_MM<0x3d>;
def JALX_MM : MMRel, JumpLink<"jalx", calltarget>, J_FM_MM<0x3c>;
}
@@ -924,6 +931,9 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
GPR32Opnd>, BGEZAL_FM_MM<0x13>;
def BLTZALS_MM : BranchCompareToZeroLinkMM<"bltzals", brtarget_mm,
GPR32Opnd>, BGEZAL_FM_MM<0x11>;
+}
+def B_MM : UncondBranch<BEQ_MM, brtarget_mm>, IsBranch, ISA_MICROMIPS;
+let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
/// Control Instructions
def SYNC_MM : MMRel, SYNC_FT<"sync">, SYNC_FM_MM;
@@ -1005,20 +1015,14 @@ let DecoderNamespace = "MicroMips" in {
// MicroMips arbitrary patterns that map to one or more instructions
//===----------------------------------------------------------------------===//
-def : MipsPat<(i32 immLi16:$imm),
- (LI16_MM immLi16:$imm)>;
-
-let AdditionalPredicates = [InMicroMips] in
-defm : MaterializeImms<i32, ZERO, ADDiu_MM, LUi_MM, ORi_MM>;
-
-let Predicates = [InMicroMips] in {
+let AdditionalPredicates = [InMicroMips] in {
def : MipsPat<(i32 immLi16:$imm),
(LI16_MM immLi16:$imm)>;
- def : MipsPat<(i32 immSExt16:$imm),
- (ADDiu_MM ZERO, immSExt16:$imm)>;
- def : MipsPat<(i32 immZExt16:$imm),
- (ORi_MM ZERO, immZExt16:$imm)>;
+ defm : MaterializeImms<i32, ZERO, ADDiu_MM, LUi_MM, ORi_MM>;
+}
+
+let Predicates = [InMicroMips] in {
def : MipsPat<(not GPRMM16:$in),
(NOT16_MM GPRMM16:$in)>;
def : MipsPat<(not GPR32:$in),
@@ -1066,13 +1070,13 @@ let Predicates = [InMicroMips] in {
(LW_MM addr:$addr)>;
def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
(SUBu_MM GPR32:$lhs, GPR32:$rhs)>;
-
- def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
- (TAILCALL_MM tglobaladdr:$dst)>, ISA_MIPS1_NOT_32R6_64R6;
- def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
- (TAILCALL_MM texternalsym:$dst)>, ISA_MIPS1_NOT_32R6_64R6;
}
+def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
+ (TAILCALL_MM tglobaladdr:$dst)>, ISA_MICROMIPS32_NOT_MIPS32R6;
+def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
+ (TAILCALL_MM texternalsym:$dst)>, ISA_MICROMIPS32_NOT_MIPS32R6;
+
let AddedComplexity = 40 in {
def : MipsPat<(i32 (sextloadi16 addrRegImm:$a)),
(LH_MM addrRegImm:$a)>;
diff --git a/lib/Target/Mips/MicroMipsSizeReduction.cpp b/lib/Target/Mips/MicroMipsSizeReduction.cpp
index 35948e36ad91..f2e014084e46 100644
--- a/lib/Target/Mips/MicroMipsSizeReduction.cpp
+++ b/lib/Target/Mips/MicroMipsSizeReduction.cpp
@@ -32,6 +32,9 @@ namespace {
enum OperandTransfer {
OT_NA, ///< Not applicable
OT_OperandsAll, ///< Transfer all operands
+ OT_Operands02, ///< Transfer operands 0 and 2
+ OT_Operand2, ///< Transfer just operand 2
+ OT_OperandsXOR, ///< Transfer operands for XOR16
};
/// Reduction type
@@ -143,14 +146,27 @@ private:
// returns true on success.
static bool ReduceSXtoSX16(MachineInstr *MI, const ReduceEntry &Entry);
- // Attempts to reduce arithmetic instructions, returns true on success
+ // Attempts to reduce arithmetic instructions, returns true on success.
static bool ReduceArithmeticInstructions(MachineInstr *MI,
const ReduceEntry &Entry);
- // Changes opcode of an instruction
+ // Attempts to reduce ADDIU into ADDIUSP instruction,
+ // returns true on success.
+ static bool ReduceADDIUToADDIUSP(MachineInstr *MI, const ReduceEntry &Entry);
+
+ // Attempts to reduce ADDIU into ADDIUR1SP instruction,
+ // returns true on success.
+ static bool ReduceADDIUToADDIUR1SP(MachineInstr *MI,
+ const ReduceEntry &Entry);
+
+ // Attempts to reduce XOR into XOR16 instruction,
+ // returns true on success.
+ static bool ReduceXORtoXOR16(MachineInstr *MI, const ReduceEntry &Entry);
+
+ // Changes opcode of an instruction.
static bool ReplaceInstruction(MachineInstr *MI, const ReduceEntry &Entry);
- // Table with transformation rules for each instruction
+ // Table with transformation rules for each instruction.
static llvm::SmallVector<ReduceEntry, 16> ReduceTable;
};
@@ -158,12 +174,20 @@ char MicroMipsSizeReduce::ID = 0;
const MipsInstrInfo *MicroMipsSizeReduce::MipsII;
// This table must be sorted by WideOpc as a main criterion and
-// ReduceType as a sub-criterion (when wide opcodes are the same)
+// ReduceType as a sub-criterion (when wide opcodes are the same).
llvm::SmallVector<ReduceEntry, 16> MicroMipsSizeReduce::ReduceTable = {
// ReduceType, OpCodes, ReduceFunction,
// OpInfo(TransferOperands),
// ImmField(Shift, LBound, HBound, ImmFieldPosition)
+ {RT_OneInstr, OpCodes(Mips::ADDiu, Mips::ADDIUR1SP_MM),
+ ReduceADDIUToADDIUR1SP, OpInfo(OT_Operands02), ImmField(2, 0, 64, 2)},
+ {RT_OneInstr, OpCodes(Mips::ADDiu, Mips::ADDIUSP_MM), ReduceADDIUToADDIUSP,
+ OpInfo(OT_Operand2), ImmField(0, 0, 0, 2)},
+ {RT_OneInstr, OpCodes(Mips::ADDiu_MM, Mips::ADDIUR1SP_MM),
+ ReduceADDIUToADDIUR1SP, OpInfo(OT_Operands02), ImmField(2, 0, 64, 2)},
+ {RT_OneInstr, OpCodes(Mips::ADDiu_MM, Mips::ADDIUSP_MM),
+ ReduceADDIUToADDIUSP, OpInfo(OT_Operand2), ImmField(0, 0, 0, 2)},
{RT_OneInstr, OpCodes(Mips::ADDu, Mips::ADDU16_MM),
ReduceArithmeticInstructions, OpInfo(OT_OperandsAll),
ImmField(0, 0, 0, -1)},
@@ -174,6 +198,8 @@ llvm::SmallVector<ReduceEntry, 16> MicroMipsSizeReduce::ReduceTable = {
OpInfo(OT_OperandsAll), ImmField(0, -1, 15, 2)},
{RT_OneInstr, OpCodes(Mips::LBu_MM, Mips::LBU16_MM), ReduceLXUtoLXU16,
OpInfo(OT_OperandsAll), ImmField(0, -1, 15, 2)},
+ {RT_OneInstr, OpCodes(Mips::LEA_ADDiu, Mips::ADDIUR1SP_MM),
+ ReduceADDIUToADDIUR1SP, OpInfo(OT_Operands02), ImmField(2, 0, 64, 2)},
{RT_OneInstr, OpCodes(Mips::LHu, Mips::LHU16_MM), ReduceLXUtoLXU16,
OpInfo(OT_OperandsAll), ImmField(1, 0, 16, 2)},
{RT_OneInstr, OpCodes(Mips::LHu_MM, Mips::LHU16_MM), ReduceLXUtoLXU16,
@@ -200,10 +226,13 @@ llvm::SmallVector<ReduceEntry, 16> MicroMipsSizeReduce::ReduceTable = {
OpInfo(OT_OperandsAll), ImmField(2, 0, 32, 2)},
{RT_OneInstr, OpCodes(Mips::SW_MM, Mips::SWSP_MM), ReduceXWtoXWSP,
OpInfo(OT_OperandsAll), ImmField(2, 0, 32, 2)},
-};
-}
+ {RT_OneInstr, OpCodes(Mips::XOR, Mips::XOR16_MM), ReduceXORtoXOR16,
+ OpInfo(OT_OperandsXOR), ImmField(0, 0, 0, -1)},
+ {RT_OneInstr, OpCodes(Mips::XOR_MM, Mips::XOR16_MM), ReduceXORtoXOR16,
+ OpInfo(OT_OperandsXOR), ImmField(0, 0, 0, -1)}};
+} // namespace
-// Returns true if the machine operand MO is register SP
+// Returns true if the machine operand MO is register SP.
static bool IsSP(const MachineOperand &MO) {
if (MO.isReg() && ((MO.getReg() == Mips::SP)))
return true;
@@ -225,7 +254,7 @@ static bool isMMSourceRegister(const MachineOperand &MO) {
}
// Returns true if the operand Op is an immediate value
-// and writes the immediate value into variable Imm
+// and writes the immediate value into variable Imm.
static bool GetImm(MachineInstr *MI, unsigned Op, int64_t &Imm) {
if (!MI->getOperand(Op).isImm())
@@ -234,17 +263,27 @@ static bool GetImm(MachineInstr *MI, unsigned Op, int64_t &Imm) {
return true;
}
+// Returns true if the value is a valid immediate for ADDIUSP.
+static bool AddiuspImmValue(int64_t Value) {
+ int64_t Value2 = Value >> 2;
+ if (((Value & (int64_t)maskTrailingZeros<uint64_t>(2)) == Value) &&
+ ((Value2 >= 2 && Value2 <= 257) || (Value2 >= -258 && Value2 <= -3)))
+ return true;
+ return false;
+}
+
// Returns true if the variable Value has the number of least-significant zero
-// bits equal to Shift and if the shifted value is between the bounds
+// bits equal to Shift and if the shifted value is between the bounds.
static bool InRange(int64_t Value, unsigned short Shift, int LBound,
int HBound) {
int64_t Value2 = Value >> Shift;
- if ((Value2 << Shift) == Value && (Value2 >= LBound) && (Value2 < HBound))
+ if (((Value & (int64_t)maskTrailingZeros<uint64_t>(Shift)) == Value) &&
+ (Value2 >= LBound) && (Value2 < HBound))
return true;
return false;
}
-// Returns true if immediate operand is in range
+// Returns true if immediate operand is in range.
static bool ImmInRange(MachineInstr *MI, const ReduceEntry &Entry) {
int64_t offset;
@@ -310,6 +349,34 @@ bool MicroMipsSizeReduce::ReduceArithmeticInstructions(
return ReplaceInstruction(MI, Entry);
}
+bool MicroMipsSizeReduce::ReduceADDIUToADDIUR1SP(MachineInstr *MI,
+ const ReduceEntry &Entry) {
+
+ if (!ImmInRange(MI, Entry))
+ return false;
+
+ if (!isMMThreeBitGPRegister(MI->getOperand(0)) || !IsSP(MI->getOperand(1)))
+ return false;
+
+ return ReplaceInstruction(MI, Entry);
+}
+
+bool MicroMipsSizeReduce::ReduceADDIUToADDIUSP(MachineInstr *MI,
+ const ReduceEntry &Entry) {
+
+ int64_t ImmValue;
+ if (!GetImm(MI, Entry.ImmField(), ImmValue))
+ return false;
+
+ if (!AddiuspImmValue(ImmValue))
+ return false;
+
+ if (!IsSP(MI->getOperand(0)) || !IsSP(MI->getOperand(1)))
+ return false;
+
+ return ReplaceInstruction(MI, Entry);
+}
+
bool MicroMipsSizeReduce::ReduceLXUtoLXU16(MachineInstr *MI,
const ReduceEntry &Entry) {
@@ -336,6 +403,20 @@ bool MicroMipsSizeReduce::ReduceSXtoSX16(MachineInstr *MI,
return ReplaceInstruction(MI, Entry);
}
+bool MicroMipsSizeReduce::ReduceXORtoXOR16(MachineInstr *MI,
+ const ReduceEntry &Entry) {
+ if (!isMMThreeBitGPRegister(MI->getOperand(0)) ||
+ !isMMThreeBitGPRegister(MI->getOperand(1)) ||
+ !isMMThreeBitGPRegister(MI->getOperand(2)))
+ return false;
+
+ if (!(MI->getOperand(0).getReg() == MI->getOperand(2).getReg()) &&
+ !(MI->getOperand(0).getReg() == MI->getOperand(1).getReg()))
+ return false;
+
+ return ReplaceInstruction(MI, Entry);
+}
+
bool MicroMipsSizeReduce::ReduceMBB(MachineBasicBlock &MBB) {
bool Modified = false;
MachineBasicBlock::instr_iterator MII = MBB.instr_begin(),
@@ -361,19 +442,62 @@ bool MicroMipsSizeReduce::ReduceMBB(MachineBasicBlock &MBB) {
bool MicroMipsSizeReduce::ReplaceInstruction(MachineInstr *MI,
const ReduceEntry &Entry) {
- MI->setDesc(MipsII->get(Entry.NarrowOpc()));
- DEBUG(dbgs() << "Converted into 16-bit: " << *MI);
+ enum OperandTransfer OpTransfer = Entry.TransferOperands();
+
+ DEBUG(dbgs() << "Converting 32-bit: " << *MI);
++NumReduced;
- return true;
+
+ if (OpTransfer == OT_OperandsAll) {
+ MI->setDesc(MipsII->get(Entry.NarrowOpc()));
+ DEBUG(dbgs() << " to 16-bit: " << *MI);
+ return true;
+ } else {
+ MachineBasicBlock &MBB = *MI->getParent();
+ const MCInstrDesc &NewMCID = MipsII->get(Entry.NarrowOpc());
+ DebugLoc dl = MI->getDebugLoc();
+ MachineInstrBuilder MIB = BuildMI(MBB, MI, dl, NewMCID);
+ switch (OpTransfer) {
+ case OT_Operand2:
+ MIB.add(MI->getOperand(2));
+ break;
+ case OT_Operands02: {
+ MIB.add(MI->getOperand(0));
+ MIB.add(MI->getOperand(2));
+ break;
+ }
+ case OT_OperandsXOR: {
+ if (MI->getOperand(0).getReg() == MI->getOperand(2).getReg()) {
+ MIB.add(MI->getOperand(0));
+ MIB.add(MI->getOperand(1));
+ MIB.add(MI->getOperand(2));
+ } else {
+ MIB.add(MI->getOperand(0));
+ MIB.add(MI->getOperand(2));
+ MIB.add(MI->getOperand(1));
+ }
+ break;
+ }
+ default:
+ llvm_unreachable("Unknown operand transfer!");
+ }
+
+ // Transfer MI flags.
+ MIB.setMIFlags(MI->getFlags());
+
+ DEBUG(dbgs() << " to 16-bit: " << *MIB);
+ MBB.erase_instr(MI);
+ return true;
+ }
+ return false;
}
bool MicroMipsSizeReduce::runOnMachineFunction(MachineFunction &MF) {
Subtarget = &static_cast<const MipsSubtarget &>(MF.getSubtarget());
- // TODO: Add support for other subtargets:
- // microMIPS32r6 and microMIPS64r6
- if (!Subtarget->inMicroMipsMode() || !Subtarget->hasMips32r2())
+ // TODO: Add support for the subtarget microMIPS32R6.
+ if (!Subtarget->inMicroMipsMode() || !Subtarget->hasMips32r2() ||
+ Subtarget->hasMips32r6())
return false;
MipsII = static_cast<const MipsInstrInfo *>(Subtarget->getInstrInfo());
diff --git a/lib/Target/Mips/Mips16FrameLowering.cpp b/lib/Target/Mips/Mips16FrameLowering.cpp
index 09e41e1423ae..cb59e2ddb1c6 100644
--- a/lib/Target/Mips/Mips16FrameLowering.cpp
+++ b/lib/Target/Mips/Mips16FrameLowering.cpp
@@ -30,7 +30,7 @@
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MachineLocation.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/Target/TargetFrameLowering.h"
+#include "llvm/CodeGen/TargetFrameLowering.h"
#include <cassert>
#include <cstdint>
#include <vector>
@@ -38,7 +38,7 @@
using namespace llvm;
Mips16FrameLowering::Mips16FrameLowering(const MipsSubtarget &STI)
- : MipsFrameLowering(STI, STI.stackAlignment()) {}
+ : MipsFrameLowering(STI, STI.getStackAlignment()) {}
void Mips16FrameLowering::emitPrologue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
@@ -59,7 +59,6 @@ void Mips16FrameLowering::emitPrologue(MachineFunction &MF,
MachineModuleInfo &MMI = MF.getMMI();
const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
- MachineLocation DstML, SrcML;
// Adjust stack.
TII.makeFrame(Mips::SP, StackSize, MBB, MBBI);
@@ -143,7 +142,7 @@ spillCalleeSavedRegisters(MachineBasicBlock &MBB,
bool Mips16FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
- const std::vector<CalleeSavedInfo> &CSI,
+ std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const {
//
// Registers RA,S0,S1 are the callee saved registers and they will be restored
diff --git a/lib/Target/Mips/Mips16FrameLowering.h b/lib/Target/Mips/Mips16FrameLowering.h
index b48ed4641ea7..f7fa4dc3d86d 100644
--- a/lib/Target/Mips/Mips16FrameLowering.h
+++ b/lib/Target/Mips/Mips16FrameLowering.h
@@ -33,7 +33,7 @@ public:
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
- const std::vector<CalleeSavedInfo> &CSI,
+ std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const override;
bool hasReservedCallFrame(const MachineFunction &MF) const override;
diff --git a/lib/Target/Mips/Mips16HardFloat.cpp b/lib/Target/Mips/Mips16HardFloat.cpp
index 3c2426129e49..682ea5c4ed7f 100644
--- a/lib/Target/Mips/Mips16HardFloat.cpp
+++ b/lib/Target/Mips/Mips16HardFloat.cpp
@@ -1,4 +1,4 @@
-//===---- Mips16HardFloat.cpp for Mips16 Hard Float --------===//
+//===- Mips16HardFloat.cpp for Mips16 Hard Float --------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -25,6 +25,7 @@ using namespace llvm;
#define DEBUG_TYPE "mips16-hard-float"
namespace {
+
class Mips16HardFloat : public ModulePass {
public:
static char ID;
@@ -41,21 +42,21 @@ namespace {
bool runOnModule(Module &M) override;
};
- static void EmitInlineAsm(LLVMContext &C, BasicBlock *BB, StringRef AsmText) {
- std::vector<llvm::Type *> AsmArgTypes;
- std::vector<llvm::Value *> AsmArgs;
+} // end anonymous namespace
- llvm::FunctionType *AsmFTy =
- llvm::FunctionType::get(Type::getVoidTy(C), AsmArgTypes, false);
- llvm::InlineAsm *IA =
- llvm::InlineAsm::get(AsmFTy, AsmText, "", true,
- /* IsAlignStack */ false, llvm::InlineAsm::AD_ATT);
- CallInst::Create(IA, AsmArgs, "", BB);
- }
+static void EmitInlineAsm(LLVMContext &C, BasicBlock *BB, StringRef AsmText) {
+ std::vector<Type *> AsmArgTypes;
+ std::vector<Value *> AsmArgs;
- char Mips16HardFloat::ID = 0;
+ FunctionType *AsmFTy =
+ FunctionType::get(Type::getVoidTy(C), AsmArgTypes, false);
+ InlineAsm *IA = InlineAsm::get(AsmFTy, AsmText, "", true,
+ /* IsAlignStack */ false, InlineAsm::AD_ATT);
+ CallInst::Create(IA, AsmArgs, "", BB);
}
+char Mips16HardFloat::ID = 0;
+
//
// Return types that matter for hard float are:
// float, double, complex float, and complex double
@@ -89,18 +90,15 @@ static FPReturnVariant whichFPReturnVariant(Type *T) {
return NoFPRet;
}
-//
// Parameter type that matter are float, (float, float), (float, double),
// double, (double, double), (double, float)
-//
enum FPParamVariant {
FSig, FFSig, FDSig,
DSig, DDSig, DFSig, NoSig
};
// which floating point parameter signature variant we are dealing with
-//
-typedef Type::TypeID TypeID;
+using TypeID = Type::TypeID;
const Type::TypeID FloatTyID = Type::FloatTyID;
const Type::TypeID DoubleTyID = Type::DoubleTyID;
@@ -154,7 +152,6 @@ static FPParamVariant whichFPParamVariantNeeded(Function &F) {
// Figure out if we need float point based on the function parameters.
// We need to move variables in and/or out of floating point
// registers because of the ABI
-//
static bool needsFPStubFromParams(Function &F) {
if (F.arg_size() >=1) {
Type *ArgType = F.getFunctionType()->getParamType(0);
@@ -183,10 +180,8 @@ static bool needsFPHelperFromSig(Function &F) {
return needsFPStubFromParams(F) || needsFPReturnHelper(F);
}
-//
// We swap between FP and Integer registers to allow Mips16 and Mips32 to
// interoperate
-//
static std::string swapFPIntParams(FPParamVariant PV, Module *M, bool LE,
bool ToFP) {
std::string MI = ToFP ? "mtc1 ": "mfc1 ";
@@ -255,10 +250,8 @@ static std::string swapFPIntParams(FPParamVariant PV, Module *M, bool LE,
return AsmText;
}
-//
// Make sure that we know we already need a stub for this function.
// Having called needsFPHelperFromSig
-//
static void assureFPCallStub(Function &F, Module *M,
const MipsTargetMachine &TM) {
// for now we only need them for static relocation
@@ -277,9 +270,9 @@ static void assureFPCallStub(Function &F, Module *M,
FStub = Function::Create(F.getFunctionType(),
Function::InternalLinkage, StubName, M);
FStub->addFnAttr("mips16_fp_stub");
- FStub->addFnAttr(llvm::Attribute::Naked);
- FStub->addFnAttr(llvm::Attribute::NoInline);
- FStub->addFnAttr(llvm::Attribute::NoUnwind);
+ FStub->addFnAttr(Attribute::Naked);
+ FStub->addFnAttr(Attribute::NoInline);
+ FStub->addFnAttr(Attribute::NoUnwind);
FStub->addFnAttr("nomips16");
FStub->setSection(SectionName);
BasicBlock *BB = BasicBlock::Create(Context, "entry", FStub);
@@ -350,9 +343,7 @@ static void assureFPCallStub(Function &F, Module *M,
new UnreachableInst(Context, BB);
}
-//
// Functions that are llvm intrinsics and don't need helpers.
-//
static const char *const IntrinsicInline[] = {
"fabs", "fabsf",
"llvm.ceil.f32", "llvm.ceil.f64",
@@ -379,10 +370,9 @@ static bool isIntrinsicInline(Function *F) {
return std::binary_search(std::begin(IntrinsicInline),
std::end(IntrinsicInline), F->getName());
}
-//
+
// Returns of float, double and complex need to be handled with a helper
// function.
-//
static bool fixupFPReturnAndCall(Function &F, Module *M,
const MipsTargetMachine &TM) {
bool Modified = false;
@@ -465,9 +455,9 @@ static void createFPFnStub(Function *F, Module *M, FPParamVariant PV,
(F->getFunctionType(),
Function::InternalLinkage, StubName, M);
FStub->addFnAttr("mips16_fp_stub");
- FStub->addFnAttr(llvm::Attribute::Naked);
- FStub->addFnAttr(llvm::Attribute::NoUnwind);
- FStub->addFnAttr(llvm::Attribute::NoInline);
+ FStub->addFnAttr(Attribute::Naked);
+ FStub->addFnAttr(Attribute::NoUnwind);
+ FStub->addFnAttr(Attribute::NoInline);
FStub->addFnAttr("nomips16");
FStub->setSection(SectionName);
BasicBlock *BB = BasicBlock::Create(Context, "entry", FStub);
@@ -489,9 +479,7 @@ static void createFPFnStub(Function *F, Module *M, FPParamVariant PV,
new UnreachableInst(FStub->getContext(), BB);
}
-//
// remove the use-soft-float attribute
-//
static void removeUseSoftFloat(Function &F) {
AttrBuilder B;
DEBUG(errs() << "removing -use-soft-float\n");
@@ -503,8 +491,6 @@ static void removeUseSoftFloat(Function &F) {
F.addAttributes(AttributeList::FunctionIndex, B);
}
-
-//
// This pass only makes sense when the underlying chip has floating point but
// we are compiling as mips16.
// For all mips16 functions (that are not stubs we have already generated), or
@@ -521,7 +507,6 @@ static void removeUseSoftFloat(Function &F) {
// 4) TBD. For pic, calls to extern functions of unknown type are handled by
// predefined helper functions in libc but this work is currently done
// during call lowering but it should be moved here in the future.
-//
bool Mips16HardFloat::runOnModule(Module &M) {
auto &TM = static_cast<const MipsTargetMachine &>(
getAnalysis<TargetPassConfig>().getTM<TargetMachine>());
@@ -545,7 +530,6 @@ bool Mips16HardFloat::runOnModule(Module &M) {
return Modified;
}
-
ModulePass *llvm::createMips16HardFloatPass() {
return new Mips16HardFloat();
}
diff --git a/lib/Target/Mips/Mips16ISelLowering.cpp b/lib/Target/Mips/Mips16ISelLowering.cpp
index bdb9eec4cc5a..8ce47e3f669d 100644
--- a/lib/Target/Mips/Mips16ISelLowering.cpp
+++ b/lib/Target/Mips/Mips16ISelLowering.cpp
@@ -17,8 +17,8 @@
#include "MipsRegisterInfo.h"
#include "MipsTargetMachine.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Target/TargetInstrInfo.h"
using namespace llvm;
diff --git a/lib/Target/Mips/Mips16InstrInfo.cpp b/lib/Target/Mips/Mips16InstrInfo.cpp
index 35ef31749f40..e11023b4d272 100644
--- a/lib/Target/Mips/Mips16InstrInfo.cpp
+++ b/lib/Target/Mips/Mips16InstrInfo.cpp
@@ -1,4 +1,4 @@
-//===-- Mips16InstrInfo.cpp - Mips16 Instruction Information --------------===//
+//===- Mips16InstrInfo.cpp - Mips16 Instruction Information ---------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,27 +10,38 @@
// This file contains the Mips16 implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//
+
#include "Mips16InstrInfo.h"
-#include "InstPrinter/MipsInstPrinter.h"
-#include "MipsMachineFunction.h"
-#include "MipsTargetMachine.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/RegisterScavenging.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/IR/DebugLoc.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
+#include <cassert>
#include <cctype>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <iterator>
+#include <vector>
using namespace llvm;
#define DEBUG_TYPE "mips16-instrinfo"
Mips16InstrInfo::Mips16InstrInfo(const MipsSubtarget &STI)
- : MipsInstrInfo(STI, Mips::Bimm16), RI() {}
+ : MipsInstrInfo(STI, Mips::Bimm16) {}
const MipsRegisterInfo &Mips16InstrInfo::getRegisterInfo() const {
return RI;
@@ -71,12 +82,10 @@ void Mips16InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
else if ((SrcReg == Mips::HI0) &&
(Mips::CPU16RegsRegClass.contains(DestReg)))
Opc = Mips::Mfhi16, SrcReg = 0;
-
else if ((SrcReg == Mips::LO0) &&
(Mips::CPU16RegsRegClass.contains(DestReg)))
Opc = Mips::Mflo16, SrcReg = 0;
-
assert(Opc && "Cannot copy registers");
MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc));
@@ -190,6 +199,7 @@ static void addSaveRestoreRegs(MachineInstrBuilder &MIB,
}
}
}
+
// Adjust SP by FrameSize bytes. Save RA, S0, S1
void Mips16InstrInfo::makeFrame(unsigned SP, int64_t FrameSize,
MachineBasicBlock &MBB,
@@ -256,7 +266,6 @@ void Mips16InstrInfo::restoreFrame(unsigned SP, int64_t FrameSize,
// This can only be called at times that we know that there is at least one free
// register.
// This is clearly safe at prologue and epilogue.
-//
void Mips16InstrInfo::adjustStackPtrBig(unsigned SP, int64_t Amount,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
@@ -474,46 +483,3 @@ bool Mips16InstrInfo::validImmediate(unsigned Opcode, unsigned Reg,
}
llvm_unreachable("unexpected Opcode in validImmediate");
}
-
-/// Measure the specified inline asm to determine an approximation of its
-/// length.
-/// Comments (which run till the next SeparatorString or newline) do not
-/// count as an instruction.
-/// Any other non-whitespace text is considered an instruction, with
-/// multiple instructions separated by SeparatorString or newlines.
-/// Variable-length instructions are not handled here; this function
-/// may be overloaded in the target code to do that.
-/// We implement the special case of the .space directive taking only an
-/// integer argument, which is the size in bytes. This is used for creating
-/// inline code spacing for testing purposes using inline assembly.
-///
-unsigned Mips16InstrInfo::getInlineAsmLength(const char *Str,
- const MCAsmInfo &MAI) const {
-
- // Count the number of instructions in the asm.
- bool atInsnStart = true;
- unsigned Length = 0;
- for (; *Str; ++Str) {
- if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(),
- strlen(MAI.getSeparatorString())) == 0)
- atInsnStart = true;
- if (atInsnStart && !std::isspace(static_cast<unsigned char>(*Str))) {
- if (strncmp(Str, ".space", 6)==0) {
- char *EStr; int Sz;
- Sz = strtol(Str+6, &EStr, 10);
- while (isspace(*EStr)) ++EStr;
- if (*EStr=='\0') {
- DEBUG(dbgs() << "parsed .space " << Sz << '\n');
- return Sz;
- }
- }
- Length += MAI.getMaxInstLength();
- atInsnStart = false;
- }
- if (atInsnStart && strncmp(Str, MAI.getCommentString().data(),
- MAI.getCommentString().size()) == 0)
- atInsnStart = false;
- }
-
- return Length;
-}
diff --git a/lib/Target/Mips/Mips16InstrInfo.h b/lib/Target/Mips/Mips16InstrInfo.h
index ab559799f00b..ffdd4728c8cb 100644
--- a/lib/Target/Mips/Mips16InstrInfo.h
+++ b/lib/Target/Mips/Mips16InstrInfo.h
@@ -1,4 +1,4 @@
-//===-- Mips16InstrInfo.h - Mips16 Instruction Information ------*- C++ -*-===//
+//===- Mips16InstrInfo.h - Mips16 Instruction Information -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,9 +16,15 @@
#include "Mips16RegisterInfo.h"
#include "MipsInstrInfo.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/Support/MathExtras.h"
+#include <cstdint>
namespace llvm {
+
+class MCInstrDesc;
class MipsSubtarget;
+
class Mips16InstrInfo : public MipsInstrInfo {
const Mips16RegisterInfo RI;
@@ -73,7 +79,6 @@ public:
void restoreFrame(unsigned SP, int64_t FrameSize, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
-
/// Adjust SP by Amount bytes.
void adjustStackPtr(unsigned SP, int64_t Amount, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;
@@ -81,7 +86,6 @@ public:
/// Emit a series of instructions to load an immediate.
// This is to adjust some FrameReg. We return the new register to be used
// in place of FrameReg and the adjusted immediate field (&NewImm)
- //
unsigned loadImmediate(unsigned FrameReg, int64_t Imm, MachineBasicBlock &MBB,
MachineBasicBlock::iterator II, const DebugLoc &DL,
unsigned &NewImm) const;
@@ -92,17 +96,12 @@ public:
return ((offset & 7) == 0) && isInt<11>(offset);
}
- //
// build the proper one based on the Imm field
- //
const MCInstrDesc& AddiuSpImm(int64_t Imm) const;
void BuildAddiuSpImm
(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, int64_t Imm) const;
-
- unsigned getInlineAsmLength(const char *Str,
- const MCAsmInfo &MAI) const override;
private:
unsigned getAnalyzableBrOpc(unsigned Opc) const override;
@@ -118,9 +117,8 @@ private:
void adjustStackPtrBigUnrestricted(unsigned SP, int64_t Amount,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
-
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_LIB_TARGET_MIPS_MIPS16INSTRINFO_H
diff --git a/lib/Target/Mips/Mips16InstrInfo.td b/lib/Target/Mips/Mips16InstrInfo.td
index 52bf690a8083..b91c94288582 100644
--- a/lib/Target/Mips/Mips16InstrInfo.td
+++ b/lib/Target/Mips/Mips16InstrInfo.td
@@ -369,14 +369,14 @@ class FRxRxRy16_ins<bits<5> f, string asmstr,
let rx=0 in
class FRR16_JALRC_RA_only_ins<bits<1> nd_, bits<1> l_,
string asmstr, InstrItinClass itin>:
- FRR16_JALRC<nd_, l_, 1, (outs), (ins), !strconcat(asmstr, "\t $$ra"),
+ FRR16_JALRC<nd_, l_, 1, (outs), (ins), !strconcat(asmstr, "\t$$ra"),
[], itin> ;
class FRR16_JALRC_ins<bits<1> nd, bits<1> l, bits<1> ra,
string asmstr, InstrItinClass itin>:
FRR16_JALRC<nd, l, ra, (outs), (ins CPU16Regs:$rx),
- !strconcat(asmstr, "\t $rx"), [], itin> ;
+ !strconcat(asmstr, "\t$rx"), [], itin> ;
class FRR_SF16_ins
<bits<5> _funct, bits<3> _subfunc,
@@ -1376,7 +1376,7 @@ def: Mips16Pat<(brind CPU16Regs:$rs), (JrcRx16 CPU16Regs:$rs)> {
let isCall=1, hasDelaySlot=0 in
def JumpLinkReg16:
FRR16_JALRC<0, 0, 0, (outs), (ins CPU16Regs:$rs),
- "jalrc \t$rs", [(MipsJmpLink CPU16Regs:$rs)], II_JALRC> {
+ "jalrc\t$rs", [(MipsJmpLink CPU16Regs:$rs)], II_JALRC> {
let Defs = [RA];
}
diff --git a/lib/Target/Mips/Mips16RegisterInfo.cpp b/lib/Target/Mips/Mips16RegisterInfo.cpp
index 44771cbe8be1..ff95f3c72282 100644
--- a/lib/Target/Mips/Mips16RegisterInfo.cpp
+++ b/lib/Target/Mips/Mips16RegisterInfo.cpp
@@ -22,6 +22,8 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/TargetFrameLowering.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/Function.h"
@@ -29,8 +31,6 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetFrameLowering.h"
-#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
diff --git a/lib/Target/Mips/Mips32r6InstrInfo.td b/lib/Target/Mips/Mips32r6InstrInfo.td
index 7daea163b8a6..62f045e77fdb 100644
--- a/lib/Target/Mips/Mips32r6InstrInfo.td
+++ b/lib/Target/Mips/Mips32r6InstrInfo.td
@@ -13,6 +13,24 @@
include "Mips32r6InstrFormats.td"
+//===----------------------------------------------------------------------===//
+//
+// Mips profiles and nodes
+//
+//===----------------------------------------------------------------------===//
+
+def SDT_MipsFSelect : SDTypeProfile<1, 3, [SDTCisFP<1>,
+ SDTCisSameAs<0,2>,
+ SDTCisSameAs<2,3>]>;
+
+def MipsFSelect : SDNode<"MipsISD::FSELECT", SDT_MipsFSelect>;
+
+//===----------------------------------------------------------------------===//
+//
+// Mips Operands
+//
+//===----------------------------------------------------------------------===//
+
// Notes about removals/changes from MIPS32r6:
// Reencoded: jr -> jalr
// Reencoded: jr.hb -> jalr.hb
@@ -578,11 +596,20 @@ class COP1_SEL_DESC_BASE<string instr_asm, RegisterOperand FGROpnd,
InstrItinClass Itinerary = itin;
}
-class SEL_D_DESC : COP1_SEL_DESC_BASE<"sel.d", FGR64Opnd, II_SEL_D>,
- MipsR6Arch<"sel.d"> {
- // We must insert a SUBREG_TO_REG around $fd_in
- bit usesCustomInserter = 1;
+class COP1_SEL_D_DESC_BASE<string instr_asm, RegisterOperand FGROpnd,
+ InstrItinClass itin> {
+ dag OutOperandList = (outs FGROpnd:$fd);
+ dag InOperandList = (ins FGROpnd:$fd_in, FGROpnd:$fs, FGROpnd:$ft);
+ string AsmString = !strconcat(instr_asm, "\t$fd, $fs, $ft");
+ list<dag> Pattern = [(set FGROpnd:$fd, (MipsFSelect FGROpnd:$fd_in,
+ FGROpnd:$ft,
+ FGROpnd:$fs))];
+ string Constraints = "$fd_in = $fd";
+ InstrItinClass Itinerary = itin;
}
+
+class SEL_D_DESC : COP1_SEL_D_DESC_BASE<"sel.d", FGR64Opnd, II_SEL_D>,
+ MipsR6Arch<"sel.d">;
class SEL_S_DESC : COP1_SEL_DESC_BASE<"sel.s", FGR32Opnd, II_SEL_S>,
MipsR6Arch<"sel.s">;
@@ -795,9 +822,7 @@ let AdditionalPredicates = [NotInMicroMips] in {
def BC1NEZ : BC1NEZ_ENC, BC1NEZ_DESC, ISA_MIPS32R6, HARDFLOAT;
def BC2EQZ : BC2EQZ_ENC, BC2EQZ_DESC, ISA_MIPS32R6;
def BC2NEZ : BC2NEZ_ENC, BC2NEZ_DESC, ISA_MIPS32R6;
-}
-def BC : R6MMR6Rel, BC_ENC, BC_DESC, ISA_MIPS32R6;
-let AdditionalPredicates = [NotInMicroMips] in {
+ def BC : R6MMR6Rel, BC_ENC, BC_DESC, ISA_MIPS32R6;
def BEQC : R6MMR6Rel, BEQC_ENC, BEQC_DESC, ISA_MIPS32R6;
def BEQZALC : R6MMR6Rel, BEQZALC_ENC, BEQZALC_DESC, ISA_MIPS32R6;
def BEQZC : R6MMR6Rel, BEQZC_ENC, BEQZC_DESC, ISA_MIPS32R6;
@@ -923,6 +948,9 @@ def : MipsInstAlias<"div $rs, $rt", (DIV GPR32Opnd:$rs, GPR32Opnd:$rs,
def : MipsInstAlias<"divu $rs, $rt", (DIVU GPR32Opnd:$rs, GPR32Opnd:$rs,
GPR32Opnd:$rt)>, ISA_MIPS32R6;
+def : MipsInstAlias<"lapc $rd, $imm",
+ (ADDIUPC GPR32Opnd:$rd, simm19_lsl2:$imm)>, ISA_MIPS32R6;
+
//===----------------------------------------------------------------------===//
//
// Patterns and Pseudo Instructions
diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td
index 3dba7ce30cad..e008aeafaa2b 100644
--- a/lib/Target/Mips/Mips64InstrInfo.td
+++ b/lib/Target/Mips/Mips64InstrInfo.td
@@ -58,6 +58,15 @@ def PowerOf2HI : PatLeaf<(imm), [{
return false;
}]>;
+def PowerOf2LO_i32 : PatLeaf<(imm), [{
+ if (N->getValueType(0) == MVT::i32) {
+ uint64_t Imm = N->getZExtValue();
+ return isPowerOf2_32(Imm) && isUInt<32>(Imm);
+ }
+ else
+ return false;
+}]>;
+
def assertzext_lt_i32 : PatFrag<(ops node:$src), (assertzext node:$src), [{
return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLT(MVT::i32);
}]>;
@@ -90,8 +99,8 @@ let DecoderNamespace = "Mips64" in {
def DADDi : ArithLogicI<"daddi", simm16_64, GPR64Opnd, II_DADDI>,
ADDI_FM<0x18>, ISA_MIPS3_NOT_32R6_64R6;
let AdditionalPredicates = [NotInMicroMips] in {
- def DADDiu : StdMMR6Rel, ArithLogicI<"daddiu", simm16_64, GPR64Opnd,
- II_DADDIU, immSExt16, add>,
+ def DADDiu : ArithLogicI<"daddiu", simm16_64, GPR64Opnd, II_DADDIU,
+ immSExt16, add>,
ADDI_FM<0x19>, IsAsCheapAsAMove, ISA_MIPS3;
}
@@ -111,13 +120,13 @@ def LUi64 : LoadUpper<"lui", GPR64Opnd, uimm16_64_relaxed>, LUI_FM;
/// Arithmetic Instructions (3-Operand, R-Type)
let AdditionalPredicates = [NotInMicroMips] in {
- def DADD : StdMMR6Rel, ArithLogicR<"dadd", GPR64Opnd, 1, II_DADD>,
- ADD_FM<0, 0x2c>, ISA_MIPS3;
- def DADDu : StdMMR6Rel, ArithLogicR<"daddu", GPR64Opnd, 1, II_DADDU, add>,
- ADD_FM<0, 0x2d>, ISA_MIPS3;
- def DSUBu : StdMMR6Rel, ArithLogicR<"dsubu", GPR64Opnd, 0, II_DSUBU, sub>, ADD_FM<0, 0x2f>,
+ def DADD : ArithLogicR<"dadd", GPR64Opnd, 1, II_DADD>, ADD_FM<0, 0x2c>,
ISA_MIPS3;
- def DSUB : StdMMR6Rel, ArithLogicR<"dsub", GPR64Opnd, 0, II_DSUB>, ADD_FM<0, 0x2e>,
+ def DADDu : ArithLogicR<"daddu", GPR64Opnd, 1, II_DADDU, add>,
+ ADD_FM<0, 0x2d>, ISA_MIPS3;
+ def DSUBu : ArithLogicR<"dsubu", GPR64Opnd, 0, II_DSUBU, sub>,
+ ADD_FM<0, 0x2f>, ISA_MIPS3;
+ def DSUB : ArithLogicR<"dsub", GPR64Opnd, 0, II_DSUB>, ADD_FM<0, 0x2e>,
ISA_MIPS3;
}
@@ -132,40 +141,35 @@ def NOR64 : LogicNOR<"nor", GPR64Opnd>, ADD_FM<0, 0x27>;
/// Shift Instructions
let AdditionalPredicates = [NotInMicroMips] in {
- def DSLL : StdMMR6Rel, shift_rotate_imm<"dsll", uimm6, GPR64Opnd, II_DSLL,
- shl, immZExt6>,
+ def DSLL : shift_rotate_imm<"dsll", uimm6, GPR64Opnd, II_DSLL, shl,
+ immZExt6>,
SRA_FM<0x38, 0>, ISA_MIPS3;
- def DSRL : StdMMR6Rel, shift_rotate_imm<"dsrl", uimm6, GPR64Opnd, II_DSRL,
- srl, immZExt6>,
+ def DSRL : shift_rotate_imm<"dsrl", uimm6, GPR64Opnd, II_DSRL, srl,
+ immZExt6>,
SRA_FM<0x3a, 0>, ISA_MIPS3;
- def DSRA : StdMMR6Rel, shift_rotate_imm<"dsra", uimm6, GPR64Opnd, II_DSRA,
- sra, immZExt6>,
+ def DSRA : shift_rotate_imm<"dsra", uimm6, GPR64Opnd, II_DSRA, sra,
+ immZExt6>,
SRA_FM<0x3b, 0>, ISA_MIPS3;
- def DSLLV : StdMMR6Rel, shift_rotate_reg<"dsllv", GPR64Opnd, II_DSLLV, shl>,
+ def DSLLV : shift_rotate_reg<"dsllv", GPR64Opnd, II_DSLLV, shl>,
SRLV_FM<0x14, 0>, ISA_MIPS3;
- def DSRAV : StdMMR6Rel, shift_rotate_reg<"dsrav", GPR64Opnd, II_DSRAV, sra>,
+ def DSRAV : shift_rotate_reg<"dsrav", GPR64Opnd, II_DSRAV, sra>,
SRLV_FM<0x17, 0>, ISA_MIPS3;
- def DSRLV : StdMMR6Rel, shift_rotate_reg<"dsrlv", GPR64Opnd, II_DSRLV, srl>,
+ def DSRLV : shift_rotate_reg<"dsrlv", GPR64Opnd, II_DSRLV, srl>,
SRLV_FM<0x16, 0>, ISA_MIPS3;
- def DSLL32 : StdMMR6Rel, shift_rotate_imm<"dsll32", uimm5, GPR64Opnd,
- II_DSLL32>,
+ def DSLL32 : shift_rotate_imm<"dsll32", uimm5, GPR64Opnd, II_DSLL32>,
SRA_FM<0x3c, 0>, ISA_MIPS3;
- def DSRL32 : StdMMR6Rel, shift_rotate_imm<"dsrl32", uimm5, GPR64Opnd,
- II_DSRL32>,
+ def DSRL32 : shift_rotate_imm<"dsrl32", uimm5, GPR64Opnd, II_DSRL32>,
SRA_FM<0x3e, 0>, ISA_MIPS3;
- def DSRA32 : StdMMR6Rel, shift_rotate_imm<"dsra32", uimm5, GPR64Opnd,
- II_DSRA32>,
+ def DSRA32 : shift_rotate_imm<"dsra32", uimm5, GPR64Opnd, II_DSRA32>,
SRA_FM<0x3f, 0>, ISA_MIPS3;
// Rotate Instructions
- def DROTR : StdMMR6Rel, shift_rotate_imm<"drotr", uimm6, GPR64Opnd, II_DROTR,
- rotr, immZExt6>,
+ def DROTR : shift_rotate_imm<"drotr", uimm6, GPR64Opnd, II_DROTR, rotr,
+ immZExt6>,
SRA_FM<0x3a, 1>, ISA_MIPS64R2;
- def DROTRV : StdMMR6Rel, shift_rotate_reg<"drotrv", GPR64Opnd, II_DROTRV,
- rotr>,
+ def DROTRV : shift_rotate_reg<"drotrv", GPR64Opnd, II_DROTRV, rotr>,
SRLV_FM<0x16, 1>, ISA_MIPS64R2;
- def DROTR32 : StdMMR6Rel, shift_rotate_imm<"drotr32", uimm5, GPR64Opnd,
- II_DROTR32>,
+ def DROTR32 : shift_rotate_imm<"drotr32", uimm5, GPR64Opnd, II_DROTR32>,
SRA_FM<0x3e, 1>, ISA_MIPS64R2;
}
@@ -183,11 +187,11 @@ def SW64 : Store<"sw", GPR64Opnd, truncstorei32, II_SW>, LW_FM<0x2b>;
}
let AdditionalPredicates = [NotInMicroMips] in {
- def LWu : StdMMR6Rel, MMRel, Load<"lwu", GPR64Opnd, zextloadi32, II_LWU>,
+ def LWu : MMRel, Load<"lwu", GPR64Opnd, zextloadi32, II_LWU>,
LW_FM<0x27>, ISA_MIPS3;
- def LD : StdMMR6Rel, LoadMemory<"ld", GPR64Opnd, mem_simm16, load, II_LD>,
+ def LD : LoadMemory<"ld", GPR64Opnd, mem_simm16, load, II_LD>,
LW_FM<0x37>, ISA_MIPS3;
- def SD : StdMMR6Rel, StoreMemory<"sd", GPR64Opnd, mem_simm16, store, II_SD>,
+ def SD : StoreMemory<"sd", GPR64Opnd, mem_simm16, store, II_SD>,
LW_FM<0x3f>, ISA_MIPS3;
}
@@ -212,7 +216,7 @@ def SDR : StoreLeftRight<"sdr", MipsSDR, GPR64Opnd, II_SDR>, LW_FM<0x2d>,
/// Load-linked, Store-conditional
let AdditionalPredicates = [NotInMicroMips] in {
- def LLD : StdMMR6Rel, LLBase<"lld", GPR64Opnd, mem_simm16>, LW_FM<0x34>,
+ def LLD : LLBase<"lld", GPR64Opnd, mem_simm16>, LW_FM<0x34>,
ISA_MIPS3_NOT_32R6_64R6;
}
def SCD : SCBase<"scd", GPR64Opnd>, LW_FM<0x3c>, ISA_MIPS3_NOT_32R6_64R6;
@@ -290,10 +294,10 @@ def SEH64 : SignExtInReg<"seh", i16, GPR64Opnd, II_SEH>, SEB_FM<0x18, 0x20>,
/// Count Leading
let AdditionalPredicates = [NotInMicroMips] in {
- def DCLZ : StdMMR6Rel, CountLeading0<"dclz", GPR64Opnd, II_DCLZ>,
- CLO_FM<0x24>, ISA_MIPS64_NOT_64R6;
- def DCLO : StdMMR6Rel, CountLeading1<"dclo", GPR64Opnd, II_DCLO>,
- CLO_FM<0x25>, ISA_MIPS64_NOT_64R6;
+ def DCLZ : CountLeading0<"dclz", GPR64Opnd, II_DCLZ>, CLO_FM<0x24>,
+ ISA_MIPS64_NOT_64R6;
+ def DCLO : CountLeading1<"dclo", GPR64Opnd, II_DCLO>, CLO_FM<0x25>,
+ ISA_MIPS64_NOT_64R6;
/// Double Word Swap Bytes/HalfWords
def DSBH : SubwordSwap<"dsbh", GPR64Opnd, II_DSBH>, SEB_FM<2, 0x24>,
@@ -308,22 +312,39 @@ let isCodeGenOnly = 1 in
def RDHWR64 : ReadHardware<GPR64Opnd, HWRegsOpnd>, RDHWR_FM;
let AdditionalPredicates = [NotInMicroMips] in {
- // The 'pos + size' constraints are enforced by the code that lowers into
- // MipsISD::Ext.
- def DEXT : ExtBase<"dext", GPR64Opnd, uimm5_report_uimm6, uimm5_plus1,
- immZExt5, immZExt5Plus1, MipsExt>, EXT_FM<3>,
- ISA_MIPS64R2;
- def DEXTM : ExtBase<"dextm", GPR64Opnd, uimm5, uimm5_plus33, immZExt5,
- immZExt5Plus33, MipsExt>, EXT_FM<1>, ISA_MIPS64R2;
- def DEXTU : ExtBase<"dextu", GPR64Opnd, uimm5_plus32, uimm5_plus1,
- immZExt5Plus32, immZExt5Plus1, MipsExt>, EXT_FM<2>,
- ISA_MIPS64R2;
- def DINS : InsBase<"dins", GPR64Opnd, uimm6, uimm5_inssize_plus1, MipsIns>,
- EXT_FM<7>, ISA_MIPS64R2;
- def DINSU : InsBase<"dinsu", GPR64Opnd, uimm5_plus32, uimm5_inssize_plus1>,
- EXT_FM<6>, ISA_MIPS64R2;
- def DINSM : InsBase<"dinsm", GPR64Opnd, uimm5, uimm5_inssize_plus1>,
- EXT_FM<5>, ISA_MIPS64R2;
+ // The 'pos + size' constraints for code generation are enforced by the
+ // code that lowers into MipsISD::Ext.
+ // For assembly parsing, we alias dextu and dextm to dext, and match by
+ // operand were possible then check the 'pos + size' in MipsAsmParser.
+ // We override the generated decoder to enforce that dext always comes out
+ // for dextm and dextu like binutils.
+ let DecoderMethod = "DecodeDEXT" in {
+ def DEXT : ExtBase<"dext", GPR64Opnd, uimm5_report_uimm6,
+ uimm5_plus1_report_uimm6, immZExt5, immZExt5Plus1,
+ MipsExt>, EXT_FM<3>, ISA_MIPS64R2;
+ def DEXTM : ExtBase<"dextm", GPR64Opnd, uimm5, uimm5_plus33, immZExt5,
+ immZExt5Plus33, MipsExt>, EXT_FM<1>, ISA_MIPS64R2;
+ def DEXTU : ExtBase<"dextu", GPR64Opnd, uimm5_plus32, uimm5_plus1,
+ immZExt5Plus32, immZExt5Plus1, MipsExt>, EXT_FM<2>,
+ ISA_MIPS64R2;
+ }
+ // The 'pos + size' constraints for code generation are enforced by the
+ // code that lowers into MipsISD::Ins.
+ // For assembly parsing, we alias dinsu and dinsm to dins, and match by
+ // operand were possible then check the 'pos + size' in MipsAsmParser.
+ // We override the generated decoder to enforce that dins always comes out
+ // for dinsm and dinsu like binutils.
+ let DecoderMethod = "DecodeDINS" in {
+ def DINS : InsBase<"dins", GPR64Opnd, uimm6, uimm5_inssize_plus1,
+ immZExt5, immZExt5Plus1>, EXT_FM<7>,
+ ISA_MIPS64R2;
+ def DINSU : InsBase<"dinsu", GPR64Opnd, uimm5_plus32, uimm5_inssize_plus1,
+ immZExt5Plus32, immZExt5Plus1>,
+ EXT_FM<6>, ISA_MIPS64R2;
+ def DINSM : InsBase<"dinsm", GPR64Opnd, uimm5, uimm_range_2_64,
+ immZExt5, immZExtRange2To64>,
+ EXT_FM<5>, ISA_MIPS64R2;
+ }
}
let isCodeGenOnly = 1, AdditionalPredicates = [NotInMicroMips] in {
@@ -542,73 +563,75 @@ defm : MipsHiLoRelocs<LUi64, DADDiu, ZERO_64, GPR64Opnd>, SYM_32;
def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi64 tglobaladdr:$in)>;
def : MipsPat<(MipsGotHi texternalsym:$in), (LUi64 texternalsym:$in)>;
-multiclass MipsHighestHigherHiLoRelocs<Instruction Lui, Instruction Daddiu> {
+// highest/higher/hi/lo relocs
+let AdditionalPredicates = [NotInMicroMips] in {
def : MipsPat<(MipsJmpLink (i64 texternalsym:$dst)),
- (JAL texternalsym:$dst)>;
+ (JAL texternalsym:$dst)>, SYM_64;
def : MipsPat<(MipsHighest (i64 tglobaladdr:$in)),
- (Lui tglobaladdr:$in)>;
+ (LUi64 tglobaladdr:$in)>, SYM_64;
def : MipsPat<(MipsHighest (i64 tblockaddress:$in)),
- (Lui tblockaddress:$in)>;
+ (LUi64 tblockaddress:$in)>, SYM_64;
def : MipsPat<(MipsHighest (i64 tjumptable:$in)),
- (Lui tjumptable:$in)>;
+ (LUi64 tjumptable:$in)>, SYM_64;
def : MipsPat<(MipsHighest (i64 tconstpool:$in)),
- (Lui tconstpool:$in)>;
+ (LUi64 tconstpool:$in)>, SYM_64;
def : MipsPat<(MipsHighest (i64 tglobaltlsaddr:$in)),
- (Lui tglobaltlsaddr:$in)>;
+ (LUi64 tglobaltlsaddr:$in)>, SYM_64;
def : MipsPat<(MipsHighest (i64 texternalsym:$in)),
- (Lui texternalsym:$in)>;
+ (LUi64 texternalsym:$in)>, SYM_64;
def : MipsPat<(MipsHigher (i64 tglobaladdr:$in)),
- (Daddiu ZERO_64, tglobaladdr:$in)>;
+ (DADDiu ZERO_64, tglobaladdr:$in)>, SYM_64;
def : MipsPat<(MipsHigher (i64 tblockaddress:$in)),
- (Daddiu ZERO_64, tblockaddress:$in)>;
+ (DADDiu ZERO_64, tblockaddress:$in)>, SYM_64;
def : MipsPat<(MipsHigher (i64 tjumptable:$in)),
- (Daddiu ZERO_64, tjumptable:$in)>;
+ (DADDiu ZERO_64, tjumptable:$in)>, SYM_64;
def : MipsPat<(MipsHigher (i64 tconstpool:$in)),
- (Daddiu ZERO_64, tconstpool:$in)>;
+ (DADDiu ZERO_64, tconstpool:$in)>, SYM_64;
def : MipsPat<(MipsHigher (i64 tglobaltlsaddr:$in)),
- (Daddiu ZERO_64, tglobaltlsaddr:$in)>;
+ (DADDiu ZERO_64, tglobaltlsaddr:$in)>, SYM_64;
def : MipsPat<(MipsHigher (i64 texternalsym:$in)),
- (Daddiu ZERO_64, texternalsym:$in)>;
+ (DADDiu ZERO_64, texternalsym:$in)>, SYM_64;
def : MipsPat<(add GPR64:$hi, (MipsHigher (i64 tglobaladdr:$lo))),
- (Daddiu GPR64:$hi, tglobaladdr:$lo)>;
+ (DADDiu GPR64:$hi, tglobaladdr:$lo)>, SYM_64;
def : MipsPat<(add GPR64:$hi, (MipsHigher (i64 tblockaddress:$lo))),
- (Daddiu GPR64:$hi, tblockaddress:$lo)>;
+ (DADDiu GPR64:$hi, tblockaddress:$lo)>, SYM_64;
def : MipsPat<(add GPR64:$hi, (MipsHigher (i64 tjumptable:$lo))),
- (Daddiu GPR64:$hi, tjumptable:$lo)>;
+ (DADDiu GPR64:$hi, tjumptable:$lo)>, SYM_64;
def : MipsPat<(add GPR64:$hi, (MipsHigher (i64 tconstpool:$lo))),
- (Daddiu GPR64:$hi, tconstpool:$lo)>;
+ (DADDiu GPR64:$hi, tconstpool:$lo)>, SYM_64;
def : MipsPat<(add GPR64:$hi, (MipsHigher (i64 tglobaltlsaddr:$lo))),
- (Daddiu GPR64:$hi, tglobaltlsaddr:$lo)>;
+ (DADDiu GPR64:$hi, tglobaltlsaddr:$lo)>, SYM_64;
def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tglobaladdr:$lo))),
- (Daddiu GPR64:$hi, tglobaladdr:$lo)>;
+ (DADDiu GPR64:$hi, tglobaladdr:$lo)>, SYM_64;
def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tblockaddress:$lo))),
- (Daddiu GPR64:$hi, tblockaddress:$lo)>;
+ (DADDiu GPR64:$hi, tblockaddress:$lo)>, SYM_64;
def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tjumptable:$lo))),
- (Daddiu GPR64:$hi, tjumptable:$lo)>;
+ (DADDiu GPR64:$hi, tjumptable:$lo)>, SYM_64;
def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tconstpool:$lo))),
- (Daddiu GPR64:$hi, tconstpool:$lo)>;
+ (DADDiu GPR64:$hi, tconstpool:$lo)>, SYM_64;
def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tglobaltlsaddr:$lo))),
- (Daddiu GPR64:$hi, tglobaltlsaddr:$lo)>;
+ (DADDiu GPR64:$hi, tglobaltlsaddr:$lo)>, SYM_64;
def : MipsPat<(add GPR64:$hi, (MipsLo (i64 tglobaladdr:$lo))),
- (Daddiu GPR64:$hi, tglobaladdr:$lo)>;
+ (DADDiu GPR64:$hi, tglobaladdr:$lo)>, SYM_64;
def : MipsPat<(add GPR64:$hi, (MipsLo (i64 tblockaddress:$lo))),
- (Daddiu GPR64:$hi, tblockaddress:$lo)>;
+ (DADDiu GPR64:$hi, tblockaddress:$lo)>, SYM_64;
def : MipsPat<(add GPR64:$hi, (MipsLo (i64 tjumptable:$lo))),
- (Daddiu GPR64:$hi, tjumptable:$lo)>;
+ (DADDiu GPR64:$hi, tjumptable:$lo)>, SYM_64;
def : MipsPat<(add GPR64:$hi, (MipsLo (i64 tconstpool:$lo))),
- (Daddiu GPR64:$hi, tconstpool:$lo)>;
+ (DADDiu GPR64:$hi, tconstpool:$lo)>, SYM_64;
def : MipsPat<(add GPR64:$hi, (MipsLo (i64 tglobaltlsaddr:$lo))),
- (Daddiu GPR64:$hi, tglobaltlsaddr:$lo)>;
-
+ (DADDiu GPR64:$hi, tglobaltlsaddr:$lo)>, SYM_64;
}
-// highest/higher/hi/lo relocs
-let AdditionalPredicates = [NotInMicroMips] in
-defm : MipsHighestHigherHiLoRelocs<LUi64, DADDiu>, SYM_64;
+// gp_rel relocs
+def : MipsPat<(add GPR64:$gp, (MipsGPRel tglobaladdr:$in)),
+ (DADDiu GPR64:$gp, tglobaladdr:$in)>, ABI_N64;
+def : MipsPat<(add GPR64:$gp, (MipsGPRel tconstpool:$in)),
+ (DADDiu GPR64:$gp, tconstpool:$in)>, ABI_N64;
def : WrapperPat<tglobaladdr, DADDiu, GPR64>;
def : WrapperPat<tconstpool, DADDiu, GPR64>;
@@ -703,6 +726,12 @@ def : MipsPat<(brcond (i32 (setne (and i64:$lhs, PowerOf2LO:$mask), 0)), bb:$dst
(BBIT1 i64:$lhs, (Log2LO PowerOf2LO:$mask), bb:$dst)>, ASE_MIPS64_CNMIPS;
def : MipsPat<(brcond (i32 (setne (and i64:$lhs, PowerOf2HI:$mask), 0)), bb:$dst),
(BBIT132 i64:$lhs, (Log2HI PowerOf2HI:$mask), bb:$dst)>, ASE_MIPS64_CNMIPS;
+def : MipsPat<(brcond (i32 (seteq (and i32:$lhs, PowerOf2LO_i32:$mask), 0)), bb:$dst),
+ (BBIT0 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), i32:$lhs, sub_32),
+ (Log2LO PowerOf2LO_i32:$mask), bb:$dst)>, ASE_MIPS64_CNMIPS;
+def : MipsPat<(brcond (i32 (setne (and i32:$lhs, PowerOf2LO_i32:$mask), 0)), bb:$dst),
+ (BBIT1 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), i32:$lhs, sub_32),
+ (Log2LO PowerOf2LO_i32:$mask), bb:$dst)>, ASE_MIPS64_CNMIPS;
// Atomic load patterns.
def : MipsPat<(atomic_load_8 addr:$a), (LB64 addr:$a)>;
@@ -802,6 +831,18 @@ let AdditionalPredicates = [NotInMicroMips] in {
def : MipsInstAlias<"dsll $rd, $rt",
(DSLLV GPR64Opnd:$rd, GPR64Opnd:$rd, GPR32Opnd:$rt), 0>,
ISA_MIPS3;
+ def : MipsInstAlias<"dins $rt, $rs, $pos, $size",
+ (DINSM GPR64Opnd:$rt, GPR64Opnd:$rs, uimm5:$pos,
+ uimm_range_2_64:$size), 0>, ISA_MIPS64R2;
+ def : MipsInstAlias<"dins $rt, $rs, $pos, $size",
+ (DINSU GPR64Opnd:$rt, GPR64Opnd:$rs, uimm5_plus32:$pos,
+ uimm5_plus1:$size), 0>, ISA_MIPS64R2;
+ def : MipsInstAlias<"dext $rt, $rs, $pos, $size",
+ (DEXTM GPR64Opnd:$rt, GPR64Opnd:$rs, uimm5:$pos,
+ uimm5_plus33:$size), 0>, ISA_MIPS64R2;
+ def : MipsInstAlias<"dext $rt, $rs, $pos, $size",
+ (DEXTU GPR64Opnd:$rt, GPR64Opnd:$rs, uimm5_plus32:$pos,
+ uimm5_plus1:$size), 0>, ISA_MIPS64R2;
// Two operand (implicit 0 selector) versions:
def : MipsInstAlias<"dmtc0 $rt, $rd",
diff --git a/lib/Target/Mips/Mips64r6InstrInfo.td b/lib/Target/Mips/Mips64r6InstrInfo.td
index dabf4e0a52e2..1cd43ee6f1c3 100644
--- a/lib/Target/Mips/Mips64r6InstrInfo.td
+++ b/lib/Target/Mips/Mips64r6InstrInfo.td
@@ -117,21 +117,21 @@ let AdditionalPredicates = [NotInMicroMips] in {
}
def DAUI : DAUI_ENC, DAUI_DESC, ISA_MIPS64R6;
def DALIGN : DALIGN_ENC, DALIGN_DESC, ISA_MIPS64R6;
- def DBITSWAP : R6MMR6Rel, DBITSWAP_ENC, DBITSWAP_DESC, ISA_MIPS64R6;
- def DCLO_R6 : R6MMR6Rel, DCLO_R6_ENC, DCLO_R6_DESC, ISA_MIPS64R6;
- def DCLZ_R6 : R6MMR6Rel, DCLZ_R6_ENC, DCLZ_R6_DESC, ISA_MIPS64R6;
+ def DBITSWAP : DBITSWAP_ENC, DBITSWAP_DESC, ISA_MIPS64R6;
+ def DCLO_R6 : DCLO_R6_ENC, DCLO_R6_DESC, ISA_MIPS64R6;
+ def DCLZ_R6 : DCLZ_R6_ENC, DCLZ_R6_DESC, ISA_MIPS64R6;
def DDIV : DDIV_ENC, DDIV_DESC, ISA_MIPS64R6;
def DDIVU : DDIVU_ENC, DDIVU_DESC, ISA_MIPS64R6;
def DMOD : DMOD_ENC, DMOD_DESC, ISA_MIPS64R6;
def DMODU : DMODU_ENC, DMODU_DESC, ISA_MIPS64R6;
- def DLSA_R6 : R6MMR6Rel, DLSA_R6_ENC, DLSA_R6_DESC, ISA_MIPS64R6;
+ def DLSA_R6 : DLSA_R6_ENC, DLSA_R6_DESC, ISA_MIPS64R6;
def DMUH: DMUH_ENC, DMUH_DESC, ISA_MIPS64R6;
def DMUHU: DMUHU_ENC, DMUHU_DESC, ISA_MIPS64R6;
def DMUL_R6: DMUL_R6_ENC, DMUL_R6_DESC, ISA_MIPS64R6;
def DMULU: DMULU_ENC, DMULU_DESC, ISA_MIPS64R6;
- def LLD_R6 : R6MMR6Rel, LLD_R6_ENC, LLD_R6_DESC, ISA_MIPS64R6;
+ def LLD_R6 : LLD_R6_ENC, LLD_R6_DESC, ISA_MIPS64R6;
}
-def LDPC: R6MMR6Rel, LDPC_ENC, LDPC_DESC, ISA_MIPS64R6;
+def LDPC: LDPC_ENC, LDPC_DESC, ISA_MIPS64R6;
def SCD_R6 : SCD_R6_ENC, SCD_R6_DESC, ISA_MIPS32R6;
let DecoderNamespace = "Mips32r6_64r6_GP64" in {
def SELEQZ64 : SELEQZ_ENC, SELEQZ64_DESC, ISA_MIPS32R6, GPR_64;
diff --git a/lib/Target/Mips/MipsAnalyzeImmediate.cpp b/lib/Target/Mips/MipsAnalyzeImmediate.cpp
index 161345d2a845..4e17ee327ab6 100644
--- a/lib/Target/Mips/MipsAnalyzeImmediate.cpp
+++ b/lib/Target/Mips/MipsAnalyzeImmediate.cpp
@@ -1,4 +1,4 @@
-//===-- MipsAnalyzeImmediate.cpp - Analyze Immediates ---------------------===//
+//===- MipsAnalyzeImmediate.cpp - Analyze Immediates ----------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,9 +6,13 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+
#include "MipsAnalyzeImmediate.h"
#include "Mips.h"
#include "llvm/Support/MathExtras.h"
+#include <cassert>
+#include <cstdint>
+#include <iterator>
using namespace llvm;
diff --git a/lib/Target/Mips/MipsAnalyzeImmediate.h b/lib/Target/Mips/MipsAnalyzeImmediate.h
index ae3c38ced80b..1c520242fb8d 100644
--- a/lib/Target/Mips/MipsAnalyzeImmediate.h
+++ b/lib/Target/Mips/MipsAnalyzeImmediate.h
@@ -1,4 +1,4 @@
-//===-- MipsAnalyzeImmediate.h - Analyze Immediates ------------*- C++ -*--===//
+//===- MipsAnalyzeImmediate.h - Analyze Immediates -------------*- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,11 +6,12 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_LIB_TARGET_MIPS_MIPSANALYZEIMMEDIATE_H
#define LLVM_LIB_TARGET_MIPS_MIPSANALYZEIMMEDIATE_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/DataTypes.h"
+#include <cstdint>
namespace llvm {
@@ -18,16 +19,18 @@ namespace llvm {
public:
struct Inst {
unsigned Opc, ImmOpnd;
+
Inst(unsigned Opc, unsigned ImmOpnd);
};
- typedef SmallVector<Inst, 7 > InstSeq;
+ using InstSeq = SmallVector<Inst, 7>;
/// Analyze - Get an instruction sequence to load immediate Imm. The last
/// instruction in the sequence must be an ADDiu if LastInstrIsADDiu is
/// true;
const InstSeq &Analyze(uint64_t Imm, unsigned Size, bool LastInstrIsADDiu);
+
private:
- typedef SmallVector<InstSeq, 5> InstSeqLs;
+ using InstSeqLs = SmallVector<InstSeq, 5>;
/// AddInstr - Add I to all instruction sequences in SeqLs.
void AddInstr(InstSeqLs &SeqLs, const Inst &I);
@@ -58,6 +61,7 @@ namespace llvm {
unsigned ADDiu, ORi, SLL, LUi;
InstSeq Insts;
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_LIB_TARGET_MIPS_MIPSANALYZEIMMEDIATE_H
diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp
index f7ff7c3dc7bb..f9de78dc281f 100644
--- a/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -1,4 +1,4 @@
-//===-- MipsAsmPrinter.cpp - Mips LLVM Assembly Printer -------------------===//
+//===- MipsAsmPrinter.cpp - Mips LLVM Assembly Printer --------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,41 +14,55 @@
#include "MipsAsmPrinter.h"
#include "InstPrinter/MipsInstPrinter.h"
+#include "MCTargetDesc/MipsABIInfo.h"
#include "MCTargetDesc/MipsBaseInfo.h"
#include "MCTargetDesc/MipsMCNaCl.h"
+#include "MCTargetDesc/MipsMCTargetDesc.h"
#include "Mips.h"
-#include "MipsInstrInfo.h"
#include "MipsMCInstLower.h"
+#include "MipsMachineFunction.h"
+#include "MipsSubtarget.h"
#include "MipsTargetMachine.h"
#include "MipsTargetStreamer.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
-#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Mangler.h"
-#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstBuilder.h"
-#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCSectionELF.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCSymbolELF.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
-#include "llvm/Target/TargetOptions.h"
+#include "llvm/Target/TargetMachine.h"
+#include <cassert>
+#include <cstdint>
+#include <map>
+#include <memory>
#include <string>
+#include <vector>
using namespace llvm;
@@ -65,11 +79,11 @@ bool MipsAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
if (Subtarget->inMips16Mode())
for (std::map<
const char *,
- const llvm::Mips16HardFloatInfo::FuncSignature *>::const_iterator
+ const Mips16HardFloatInfo::FuncSignature *>::const_iterator
it = MipsFI->StubsNeeded.begin();
it != MipsFI->StubsNeeded.end(); ++it) {
const char *Symbol = it->first;
- const llvm::Mips16HardFloatInfo::FuncSignature *Signature = it->second;
+ const Mips16HardFloatInfo::FuncSignature *Signature = it->second;
if (StubsNeeded.find(Symbol) == StubsNeeded.end())
StubsNeeded[Symbol] = Signature;
}
@@ -94,7 +108,7 @@ bool MipsAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) {
#include "MipsGenMCPseudoLowering.inc"
// Lower PseudoReturn/PseudoIndirectBranch/PseudoIndirectBranch64 to JR, JR_MM,
-// JALR, or JALR64 as appropriate for the target
+// JALR, or JALR64 as appropriate for the target.
void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer,
const MachineInstr *MI) {
bool HasLinkReg = false;
@@ -347,6 +361,7 @@ void MipsAsmPrinter::EmitFunctionEntryLabel() {
if (Subtarget->inMicroMipsMode()) {
TS.emitDirectiveSetMicroMips();
TS.setUsesMicroMips();
+ TS.updateABIInfo(*Subtarget);
} else
TS.emitDirectiveSetNoMicroMips();
@@ -366,7 +381,7 @@ void MipsAsmPrinter::EmitFunctionBodyStart() {
MCInstLowering.Initialize(&MF->getContext());
- bool IsNakedFunction = MF->getFunction()->hasFnAttribute(Attribute::Naked);
+ bool IsNakedFunction = MF->getFunction().hasFnAttribute(Attribute::Naked);
if (!IsNakedFunction)
emitFrameDirective();
@@ -403,8 +418,9 @@ void MipsAsmPrinter::EmitFunctionBodyEnd() {
}
void MipsAsmPrinter::EmitBasicBlockEnd(const MachineBasicBlock &MBB) {
+ AsmPrinter::EmitBasicBlockEnd(MBB);
MipsTargetStreamer &TS = getTargetStreamer();
- if (MBB.size() == 0)
+ if (MBB.empty())
TS.emitDirectiveInsn();
}
@@ -483,7 +499,7 @@ bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
return true;
O << MO.getImm() - 1;
return false;
- case 'z': {
+ case 'z':
// $0 if zero, regular printing otherwise
if (MO.getType() == MachineOperand::MO_Immediate && MO.getImm() == 0) {
O << "$0";
@@ -491,7 +507,6 @@ bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
}
// If not, call printOperand as normal.
break;
- }
case 'D': // Second part of a double word register operand
case 'L': // Low order register of a double word register operand
case 'M': // High order register of a double word register operand
@@ -671,7 +686,6 @@ printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O) {
printOperand(MI, opNum, O);
O << ", ";
printOperand(MI, opNum+1, O);
- return;
}
void MipsAsmPrinter::
@@ -706,7 +720,7 @@ void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) {
StringRef CPU = MIPS_MC::selectMipsCPU(TT, TM.getTargetCPU());
StringRef FS = TM.getTargetFeatureString();
const MipsTargetMachine &MTM = static_cast<const MipsTargetMachine &>(TM);
- const MipsSubtarget STI(TT, CPU, FS, MTM.isLittleEndian(), MTM);
+ const MipsSubtarget STI(TT, CPU, FS, MTM.isLittleEndian(), MTM, 0);
bool IsABICalls = STI.isABICalls();
const MipsABIInfo &ABI = MTM.getABI();
@@ -834,6 +848,7 @@ void MipsAsmPrinter::EmitSwapFPIntParams(const MCSubtargetInfo &STI,
Mips16HardFloatInfo::FPParamVariant PV,
bool LE, bool ToFP) {
using namespace Mips16HardFloatInfo;
+
unsigned MovOpc = ToFP ? Mips::MTC1 : Mips::MFC1;
switch (PV) {
case FSig:
@@ -866,6 +881,7 @@ void MipsAsmPrinter::EmitSwapFPIntRetval(
const MCSubtargetInfo &STI, Mips16HardFloatInfo::FPReturnVariant RV,
bool LE) {
using namespace Mips16HardFloatInfo;
+
unsigned MovOpc = Mips::MFC1;
switch (RV) {
case FRet:
@@ -888,8 +904,9 @@ void MipsAsmPrinter::EmitSwapFPIntRetval(
void MipsAsmPrinter::EmitFPCallStub(
const char *Symbol, const Mips16HardFloatInfo::FuncSignature *Signature) {
- MCSymbol *MSymbol = OutContext.getOrCreateSymbol(StringRef(Symbol));
using namespace Mips16HardFloatInfo;
+
+ MCSymbol *MSymbol = OutContext.getOrCreateSymbol(StringRef(Symbol));
bool LE = getDataLayout().isLittleEndian();
// Construct a local MCSubtargetInfo here.
// This is because the MachineFunction won't exist (but have not yet been
@@ -1039,11 +1056,11 @@ void MipsAsmPrinter::EmitEndOfAsmFile(Module &M) {
//
for (std::map<
const char *,
- const llvm::Mips16HardFloatInfo::FuncSignature *>::const_iterator
+ const Mips16HardFloatInfo::FuncSignature *>::const_iterator
it = StubsNeeded.begin();
it != StubsNeeded.end(); ++it) {
const char *Symbol = it->first;
- const llvm::Mips16HardFloatInfo::FuncSignature *Signature = it->second;
+ const Mips16HardFloatInfo::FuncSignature *Signature = it->second;
EmitFPCallStub(Symbol, Signature);
}
// return to the text section
@@ -1065,16 +1082,16 @@ void MipsAsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind) {
// be patching over the full 48 bytes (12 instructions) with the following
// pattern:
//
- // ADDIU SP, SP, -8
+ // ADDIU SP, SP, -8
// NOP
- // SW RA, 4(SP)
+ // SW RA, 4(SP)
// SW T9, 0(SP)
// LUI T9, %hi(__xray_FunctionEntry/Exit)
// ORI T9, T9, %lo(__xray_FunctionEntry/Exit)
// LUI T0, %hi(function_id)
- // JALR T9
- // ORI T0, T0, %lo(function_id)
- // LW T9, 0(SP)
+ // JALR T9
+ // ORI T0, T0, %lo(function_id)
+ // LW T9, 0(SP)
// LW RA, 4(SP)
// ADDIU SP, SP, 8
//
diff --git a/lib/Target/Mips/MipsAsmPrinter.h b/lib/Target/Mips/MipsAsmPrinter.h
index 4699e1b0bd3b..999b6f896bae 100644
--- a/lib/Target/Mips/MipsAsmPrinter.h
+++ b/lib/Target/Mips/MipsAsmPrinter.h
@@ -1,4 +1,4 @@
-//===-- MipsAsmPrinter.h - Mips LLVM Assembly Printer ----------*- C++ -*--===//
+//===- MipsAsmPrinter.h - Mips LLVM Assembly Printer -----------*- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,19 +16,29 @@
#include "Mips16HardFloatInfo.h"
#include "MipsMCInstLower.h"
-#include "MipsMachineFunction.h"
#include "MipsSubtarget.h"
#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Target/TargetMachine.h"
+#include <algorithm>
+#include <map>
+#include <memory>
namespace llvm {
-class MCStreamer;
-class MachineInstr;
+
+class MCOperand;
+class MCSubtargetInfo;
+class MCSymbol;
class MachineBasicBlock;
+class MachineConstantPool;
+class MachineFunction;
+class MachineInstr;
+class MachineOperand;
+class MipsFunctionInfo;
class MipsTargetStreamer;
class Module;
class raw_ostream;
+class TargetMachine;
class LLVM_LIBRARY_VISIBILITY MipsAsmPrinter : public AsmPrinter {
MipsTargetStreamer &getTargetStreamer() const;
@@ -38,16 +48,25 @@ class LLVM_LIBRARY_VISIBILITY MipsAsmPrinter : public AsmPrinter {
//===------------------------------------------------------------------===//
// XRay implementation
//===------------------------------------------------------------------===//
+
public:
// XRay-specific lowering for Mips.
void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI);
void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI);
void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI);
- // Helper function that emits the XRay sleds we've collected for a particular
- // function.
- void EmitXRayTable();
private:
+ /// MCP - Keep a pointer to constantpool entries of the current
+ /// MachineFunction.
+ const MachineConstantPool *MCP = nullptr;
+
+ /// InConstantPool - Maintain state when emitting a sequence of constant
+ /// pool entries so we can properly mark them as data regions.
+ bool InConstantPool = false;
+
+ std::map<const char *, const Mips16HardFloatInfo::FuncSignature *>
+ StubsNeeded;
+
void EmitSled(const MachineInstr &MI, SledKind Kind);
// tblgen'erated function.
@@ -63,17 +82,6 @@ private:
// lowerOperand - Convert a MachineOperand into the equivalent MCOperand.
bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp);
- /// MCP - Keep a pointer to constantpool entries of the current
- /// MachineFunction.
- const MachineConstantPool *MCP;
-
- /// InConstantPool - Maintain state when emitting a sequence of constant
- /// pool entries so we can properly mark them as data regions.
- bool InConstantPool;
-
- std::map<const char *, const llvm::Mips16HardFloatInfo::FuncSignature *>
- StubsNeeded;
-
void emitInlineAsmStart() const override;
void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
@@ -107,15 +115,13 @@ private:
bool isLongBranchPseudo(int Opcode) const;
public:
-
const MipsSubtarget *Subtarget;
const MipsFunctionInfo *MipsFI;
MipsMCInstLower MCInstLowering;
explicit MipsAsmPrinter(TargetMachine &TM,
std::unique_ptr<MCStreamer> Streamer)
- : AsmPrinter(TM, std::move(Streamer)), MCP(nullptr),
- InConstantPool(false), MCInstLowering(*this) {}
+ : AsmPrinter(TM, std::move(Streamer)), MCInstLowering(*this) {}
StringRef getPassName() const override { return "Mips Assembly Printer"; }
@@ -156,7 +162,7 @@ public:
void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
void EmitDebugThreadLocal(const MCExpr *Value, unsigned Size) const override;
};
-}
-#endif
+} // end namespace llvm
+#endif // LLVM_LIB_TARGET_MIPS_MIPSASMPRINTER_H
diff --git a/lib/Target/Mips/MipsCCState.cpp b/lib/Target/Mips/MipsCCState.cpp
index 6a03ee9927d7..81a1cced93b7 100644
--- a/lib/Target/Mips/MipsCCState.cpp
+++ b/lib/Target/Mips/MipsCCState.cpp
@@ -101,9 +101,9 @@ void MipsCCState::PreAnalyzeReturnForF128(
const MachineFunction &MF = getMachineFunction();
for (unsigned i = 0; i < Outs.size(); ++i) {
OriginalArgWasF128.push_back(
- originalTypeIsF128(MF.getFunction()->getReturnType(), nullptr));
+ originalTypeIsF128(MF.getFunction().getReturnType(), nullptr));
OriginalArgWasFloat.push_back(
- MF.getFunction()->getReturnType()->isFloatingPointTy());
+ MF.getFunction().getReturnType()->isFloatingPointTy());
}
}
@@ -149,7 +149,7 @@ void MipsCCState::PreAnalyzeFormalArgumentsForF128(
const SmallVectorImpl<ISD::InputArg> &Ins) {
const MachineFunction &MF = getMachineFunction();
for (unsigned i = 0; i < Ins.size(); ++i) {
- Function::const_arg_iterator FuncArg = MF.getFunction()->arg_begin();
+ Function::const_arg_iterator FuncArg = MF.getFunction().arg_begin();
// SRet arguments cannot originate from f128 or {f128} returns so we just
// push false. We have to handle this specially since SRet arguments
@@ -161,7 +161,7 @@ void MipsCCState::PreAnalyzeFormalArgumentsForF128(
continue;
}
- assert(Ins[i].getOrigArgIndex() < MF.getFunction()->arg_size());
+ assert(Ins[i].getOrigArgIndex() < MF.getFunction().arg_size());
std::advance(FuncArg, Ins[i].getOrigArgIndex());
OriginalArgWasF128.push_back(
diff --git a/lib/Target/Mips/MipsCondMov.td b/lib/Target/Mips/MipsCondMov.td
index fd4517f25335..a0039d159248 100644
--- a/lib/Target/Mips/MipsCondMov.td
+++ b/lib/Target/Mips/MipsCondMov.td
@@ -149,7 +149,7 @@ def MOVN_I_D32 : MMRel, CMov_I_F_FT<"movn.d", GPR32Opnd, AFGR64Opnd,
II_MOVN_D>, CMov_I_F_FM<19, 17>,
INSN_MIPS4_32_NOT_32R6_64R6, FGR_32;
-let DecoderNamespace = "Mips64" in {
+let DecoderNamespace = "MipsFP64" in {
def MOVZ_I_D64 : CMov_I_F_FT<"movz.d", GPR32Opnd, FGR64Opnd, II_MOVZ_D>,
CMov_I_F_FM<18, 17>, INSN_MIPS4_32_NOT_32R6_64R6, FGR_64;
def MOVN_I_D64 : CMov_I_F_FT<"movn.d", GPR32Opnd, FGR64Opnd, II_MOVN_D>,
@@ -188,7 +188,7 @@ def MOVF_D32 : MMRel, CMov_F_F_FT<"movf.d", AFGR64Opnd, II_MOVF_D,
MipsCMovFP_F>, CMov_F_F_FM<17, 0>,
INSN_MIPS4_32_NOT_32R6_64R6, FGR_32;
-let DecoderNamespace = "Mips64" in {
+let DecoderNamespace = "MipsFP64" in {
def MOVT_D64 : CMov_F_F_FT<"movt.d", FGR64Opnd, II_MOVT_D, MipsCMovFP_T>,
CMov_F_F_FM<17, 1>, INSN_MIPS4_32_NOT_32R6_64R6, FGR_64;
def MOVF_D64 : CMov_F_F_FT<"movf.d", FGR64Opnd, II_MOVF_D, MipsCMovFP_F>,
@@ -270,13 +270,13 @@ let usesCustomInserter = 1 in {
ISA_MIPS1_NOT_4_32;
class SelectFP_Pseudo_T<RegisterOperand RC> :
- PseudoSE<(outs RC:$dst), (ins GPR32Opnd:$cond, RC:$T, RC:$F),
- [(set RC:$dst, (MipsCMovFP_T RC:$T, GPR32Opnd:$cond, RC:$F))]>,
+ PseudoSE<(outs RC:$dst), (ins FCCRegsOpnd:$cond, RC:$T, RC:$F),
+ [(set RC:$dst, (MipsCMovFP_T RC:$T, FCCRegsOpnd:$cond, RC:$F))]>,
ISA_MIPS1_NOT_4_32;
class SelectFP_Pseudo_F<RegisterOperand RC> :
- PseudoSE<(outs RC:$dst), (ins GPR32Opnd:$cond, RC:$T, RC:$F),
- [(set RC:$dst, (MipsCMovFP_F RC:$T, GPR32Opnd:$cond, RC:$F))]>,
+ PseudoSE<(outs RC:$dst), (ins FCCRegsOpnd:$cond, RC:$T, RC:$F),
+ [(set RC:$dst, (MipsCMovFP_F RC:$T, FCCRegsOpnd:$cond, RC:$F))]>,
ISA_MIPS1_NOT_4_32;
}
diff --git a/lib/Target/Mips/MipsConstantIslandPass.cpp b/lib/Target/Mips/MipsConstantIslandPass.cpp
index ff43a3950610..a9abc171b423 100644
--- a/lib/Target/Mips/MipsConstantIslandPass.cpp
+++ b/lib/Target/Mips/MipsConstantIslandPass.cpp
@@ -1,4 +1,4 @@
-//===-- MipsConstantIslandPass.cpp - Emit Pc Relative loads----------------===//
+//===- MipsConstantIslandPass.cpp - Emit Pc Relative loads ----------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -53,7 +53,6 @@
#include <cassert>
#include <cstdint>
#include <iterator>
-#include <new>
#include <vector>
using namespace llvm;
@@ -72,17 +71,14 @@ AlignConstantIslands("mips-align-constant-islands", cl::Hidden, cl::init(true),
// Rather than do make check tests with huge amounts of code, we force
// the test to use this amount.
-//
static cl::opt<int> ConstantIslandsSmallOffset(
"mips-constant-islands-small-offset",
cl::init(0),
cl::desc("Make small offsets be this amount for testing purposes"),
cl::Hidden);
-//
// For testing purposes we tell it to not use relaxed load forms so that it
// will split blocks.
-//
static cl::opt<bool> NoLoadRelaxation(
"mips-constant-islands-no-load-relaxation",
cl::init(false),
@@ -131,12 +127,10 @@ 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.
// Need to refactor some of the code to call this routine.
-//
static unsigned int branchMaxOffsets(unsigned int Opcode) {
unsigned Bits, Scale;
switch (Opcode) {
@@ -189,8 +183,8 @@ static unsigned int branchMaxOffsets(unsigned int Opcode) {
namespace {
- typedef MachineBasicBlock::iterator Iter;
- typedef MachineBasicBlock::reverse_iterator ReverseIter;
+ using Iter = MachineBasicBlock::iterator;
+ using ReverseIter = MachineBasicBlock::reverse_iterator;
/// MipsConstantIslands - Due to limited PC-relative displacements, Mips
/// requires constant pool entries to be scattered among the instructions
@@ -247,7 +241,7 @@ namespace {
/// previous iteration by inserting unconditional branches.
SmallSet<MachineBasicBlock*, 4> NewWaterList;
- typedef std::vector<MachineBasicBlock*>::iterator water_iterator;
+ using water_iterator = std::vector<MachineBasicBlock *>::iterator;
/// CPUser - One user of a constant pool, keeping the machine instruction
/// pointer, the constant pool being referenced, and the max displacement
@@ -420,10 +414,10 @@ namespace {
void prescanForConstants();
};
- char MipsConstantIslands::ID = 0;
-
} // end anonymous namespace
+char MipsConstantIslands::ID = 0;
+
bool MipsConstantIslands::isOffsetInRange
(unsigned UserOffset, unsigned TrialOffset,
const CPUser &U) {
@@ -436,7 +430,7 @@ bool MipsConstantIslands::isOffsetInRange
LLVM_DUMP_METHOD void MipsConstantIslands::dumpBBs() {
for (unsigned J = 0, E = BBInfo.size(); J !=E; ++J) {
const BasicBlockInfo &BBI = BBInfo[J];
- dbgs() << format("%08x BB#%u\t", BBI.Offset, J)
+ dbgs() << format("%08x %bb.%u\t", BBI.Offset, J)
<< format(" size=%#x\n", BBInfo[J].Size);
}
}
@@ -748,7 +742,6 @@ initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {
// Scan the instructions for constant pool operands.
for (unsigned op = 0, e = MI.getNumOperands(); op != e; ++op)
if (MI.getOperand(op).isCPI()) {
-
// We found one. The addressing mode tells us the max displacement
// from the PC that this instruction permits.
@@ -998,11 +991,11 @@ bool MipsConstantIslands::isCPEntryInRange
const BasicBlockInfo &BBI = BBInfo[Block];
dbgs() << "User of CPE#" << CPEMI->getOperand(0).getImm()
<< " max delta=" << MaxDisp
- << format(" insn address=%#x", UserOffset)
- << " in BB#" << Block << ": "
+ << format(" insn address=%#x", UserOffset) << " in "
+ << printMBBReference(*MI->getParent()) << ": "
<< format("%#x-%x\t", BBI.Offset, BBI.postOffset()) << *MI
<< format("CPE address=%#x offset=%+d: ", CPEOffset,
- int(CPEOffset-UserOffset));
+ int(CPEOffset - UserOffset));
});
}
@@ -1038,7 +1031,6 @@ void MipsConstantIslands::adjustBBOffsetsAfter(MachineBasicBlock *BB) {
/// and instruction CPEMI, and decrement its refcount. If the refcount
/// becomes 0 remove the entry and instruction. Returns true if we removed
/// the entry, false if we didn't.
-
bool MipsConstantIslands::decrementCPEReferenceCount(unsigned CPI,
MachineInstr *CPEMI) {
// Find the old entry. Eliminate it if it is no longer used.
@@ -1205,7 +1197,7 @@ bool MipsConstantIslands::findAvailableWater(CPUser &U, unsigned UserOffset,
// This is the least amount of required padding seen so far.
BestGrowth = Growth;
WaterIter = IP;
- DEBUG(dbgs() << "Found water after BB#" << WaterBB->getNumber()
+ DEBUG(dbgs() << "Found water after " << printMBBReference(*WaterBB)
<< " Growth=" << Growth << '\n');
// Keep looking unless it is perfect.
@@ -1244,8 +1236,8 @@ void MipsConstantIslands::createNewWater(unsigned CPUserIndex,
unsigned CPEOffset = UserBBI.postOffset(CPELogAlign) + Delta;
if (isOffsetInRange(UserOffset, CPEOffset, U)) {
- DEBUG(dbgs() << "Split at end of BB#" << UserMBB->getNumber()
- << format(", expected CPE offset %#x\n", CPEOffset));
+ DEBUG(dbgs() << "Split at end of " << printMBBReference(*UserMBB)
+ << format(", expected CPE offset %#x\n", CPEOffset));
NewMBB = &*++UserMBB->getIterator();
// Add an unconditional branch from UserMBB to fallthrough block. Record
// it for branch lengthening; this new branch will not get out of range,
@@ -1478,11 +1470,11 @@ bool MipsConstantIslands::isBBInRange
unsigned BrOffset = getOffsetOf(MI) + PCAdj;
unsigned DestOffset = BBInfo[DestBB->getNumber()].Offset;
- DEBUG(dbgs() << "Branch of destination BB#" << DestBB->getNumber()
- << " from BB#" << MI->getParent()->getNumber()
- << " max delta=" << MaxDisp
- << " from " << getOffsetOf(MI) << " to " << DestOffset
- << " offset " << int(DestOffset-BrOffset) << "\t" << *MI);
+ DEBUG(dbgs() << "Branch of destination " << printMBBReference(*DestBB)
+ << " from " << printMBBReference(*MI->getParent())
+ << " max delta=" << MaxDisp << " from " << getOffsetOf(MI)
+ << " to " << DestOffset << " offset "
+ << int(DestOffset - BrOffset) << "\t" << *MI);
if (BrOffset <= DestOffset) {
// Branch before the Dest.
@@ -1623,9 +1615,9 @@ MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {
}
MachineBasicBlock *NextBB = &*++MBB->getIterator();
- DEBUG(dbgs() << " Insert B to BB#" << DestBB->getNumber()
- << " also invert condition and change dest. to BB#"
- << NextBB->getNumber() << "\n");
+ DEBUG(dbgs() << " Insert B to " << printMBBReference(*DestBB)
+ << " also invert condition and change dest. to "
+ << printMBBReference(*NextBB) << "\n");
// Insert a new conditional branch and a new unconditional branch.
// Also update the ImmBranch as well as adding a new entry for the new branch.
@@ -1669,7 +1661,7 @@ void MipsConstantIslands::prescanForConstants() {
int64_t V = Literal.getImm();
DEBUG(dbgs() << "literal " << V << "\n");
Type *Int32Ty =
- Type::getInt32Ty(MF->getFunction()->getContext());
+ Type::getInt32Ty(MF->getFunction().getContext());
const Constant *C = ConstantInt::get(Int32Ty, V);
unsigned index = MCP->getConstantPoolIndex(C, 4);
I->getOperand(2).ChangeToImmediate(index);
diff --git a/lib/Target/Mips/MipsDSPInstrInfo.td b/lib/Target/Mips/MipsDSPInstrInfo.td
index 2595333188a4..871135e3a22b 100644
--- a/lib/Target/Mips/MipsDSPInstrInfo.td
+++ b/lib/Target/Mips/MipsDSPInstrInfo.td
@@ -1325,6 +1325,10 @@ def : BitconvertPat<i32, v2i16, GPR32, DSPR>;
def : BitconvertPat<i32, v4i8, GPR32, DSPR>;
def : BitconvertPat<v2i16, i32, DSPR, GPR32>;
def : BitconvertPat<v4i8, i32, DSPR, GPR32>;
+def : BitconvertPat<f32, v2i16, FGR32, DSPR>;
+def : BitconvertPat<f32, v4i8, FGR32, DSPR>;
+def : BitconvertPat<v2i16, f32, DSPR, FGR32>;
+def : BitconvertPat<v4i8, f32, DSPR, FGR32>;
def : DSPPat<(v2i16 (load addr:$a)),
(v2i16 (COPY_TO_REGCLASS (LW addr:$a), DSPR))>;
diff --git a/lib/Target/Mips/MipsDelaySlotFiller.cpp b/lib/Target/Mips/MipsDelaySlotFiller.cpp
index 4a34e3101cb8..e06b57e41834 100644
--- a/lib/Target/Mips/MipsDelaySlotFiller.cpp
+++ b/lib/Target/Mips/MipsDelaySlotFiller.cpp
@@ -1,4 +1,4 @@
-//===-- MipsDelaySlotFiller.cpp - Mips Delay Slot Filler ------------------===//
+//===- MipsDelaySlotFiller.cpp - Mips Delay Slot Filler -------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,8 +14,8 @@
#include "MCTargetDesc/MipsMCNaCl.h"
#include "Mips.h"
#include "MipsInstrInfo.h"
+#include "MipsRegisterInfo.h"
#include "MipsSubtarget.h"
-#include "MipsTargetMachine.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerUnion.h"
@@ -34,6 +34,8 @@
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/Casting.h"
@@ -41,7 +43,6 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegisterInfo.h"
#include <algorithm>
#include <cassert>
#include <iterator>
@@ -103,9 +104,9 @@ static cl::opt<CompactBranchPolicy> MipsCompactBranchPolicy(
namespace {
- typedef MachineBasicBlock::iterator Iter;
- typedef MachineBasicBlock::reverse_iterator ReverseIter;
- typedef SmallDenseMap<MachineBasicBlock*, MachineInstr*, 2> BB2BrMap;
+ using Iter = MachineBasicBlock::iterator;
+ using ReverseIter = MachineBasicBlock::reverse_iterator;
+ using BB2BrMap = SmallDenseMap<MachineBasicBlock *, MachineInstr *, 2>;
class RegDefsUses {
public:
@@ -186,7 +187,7 @@ namespace {
MemDefsUses(const DataLayout &DL, const MachineFrameInfo *MFI);
private:
- typedef PointerUnion<const Value *, const PseudoSourceValue *> ValueType;
+ using ValueType = PointerUnion<const Value *, const PseudoSourceValue *>;
bool hasHazard_(const MachineInstr &MI) override;
@@ -211,7 +212,7 @@ namespace {
class Filler : public MachineFunctionPass {
public:
- Filler() : MachineFunctionPass(ID), TM(nullptr) {}
+ Filler() : MachineFunctionPass(ID) {}
StringRef getPassName() const override { return "Mips Delay Slot Filler"; }
@@ -290,15 +291,15 @@ namespace {
bool terminateSearch(const MachineInstr &Candidate) const;
- const TargetMachine *TM;
+ const TargetMachine *TM = nullptr;
static char ID;
};
- char Filler::ID = 0;
-
} // end anonymous namespace
+char Filler::ID = 0;
+
static bool hasUnoccupiedSlot(const MachineInstr *MI) {
return MI->hasDelaySlot() && !MI->isBundledWithSucc();
}
@@ -596,21 +597,14 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
bool InMicroMipsMode = STI.inMicroMipsMode();
const MipsInstrInfo *TII = STI.getInstrInfo();
- if (InMicroMipsMode && STI.hasMips32r6()) {
- // This is microMIPS32r6 or microMIPS64r6 processor. Delay slot for
- // branching instructions is not needed.
- return Changed;
- }
-
for (Iter I = MBB.begin(); I != MBB.end(); ++I) {
if (!hasUnoccupiedSlot(&*I))
continue;
- ++FilledSlots;
- Changed = true;
+ // Delay slot filling is disabled at -O0, or in microMIPS32R6.
+ if (!DisableDelaySlotFiller && (TM->getOptLevel() != CodeGenOpt::None) &&
+ !(InMicroMipsMode && STI.hasMips32r6())) {
- // Delay slot filling is disabled at -O0.
- if (!DisableDelaySlotFiller && (TM->getOptLevel() != CodeGenOpt::None)) {
bool Filled = false;
if (MipsCompactBranchPolicy.getValue() != CB_Always ||
@@ -642,6 +636,8 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
// if it is in range.
DSI->setDesc(TII->get(getEquivalentCallShort(DSI->getOpcode())));
}
+ ++FilledSlots;
+ Changed = true;
continue;
}
}
@@ -659,12 +655,15 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
(STI.hasMips32r6() && MipsCompactBranchPolicy != CB_Never)) &&
TII->getEquivalentCompactForm(I)) {
I = replaceWithCompactBranch(MBB, I, I->getDebugLoc());
+ Changed = true;
continue;
}
// Bundle the NOP to the instruction with the delay slot.
BuildMI(MBB, std::next(I), I->getDebugLoc(), TII->get(Mips::NOP));
MIBundleBuilder(MBB, I, std::next(I, 2));
+ ++FilledSlots;
+ Changed = true;
}
return Changed;
diff --git a/lib/Target/Mips/MipsFastISel.cpp b/lib/Target/Mips/MipsFastISel.cpp
index f79cb0e67200..8bbac3ed7cfb 100644
--- a/lib/Target/Mips/MipsFastISel.cpp
+++ b/lib/Target/Mips/MipsFastISel.cpp
@@ -1,4 +1,4 @@
-//===-- MipsFastISel.cpp - Mips FastISel implementation -------------------===//
+//===- MipsFastISel.cpp - Mips FastISel implementation --------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -37,6 +37,8 @@
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MachineValueType.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/CallingConv.h"
@@ -64,12 +66,9 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetLowering.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
-#include <new>
#define DEBUG_TYPE "mips-fastisel"
@@ -82,7 +81,7 @@ class MipsFastISel final : public FastISel {
// All possible address modes.
class Address {
public:
- typedef enum { RegBase, FrameIndexBase } BaseKind;
+ using BaseKind = enum { RegBase, FrameIndexBase };
private:
BaseKind Kind = RegBase;
@@ -231,7 +230,6 @@ private:
// for some reason, this default is not generated by tablegen
// so we explicitly generate it here.
- //
unsigned fastEmitInst_riir(uint64_t inst, const TargetRegisterClass *RC,
unsigned Op0, bool Op0IsKill, uint64_t imm1,
uint64_t imm2, unsigned Op3, bool Op3IsKill) {
@@ -629,6 +627,7 @@ bool MipsFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) {
return true;
return false;
}
+
// Because of how EmitCmp is called with fast-isel, you can
// end up with redundant "andi" instructions after the sequences emitted below.
// We should try and solve this issue in the future.
@@ -937,10 +936,8 @@ bool MipsFastISel::selectStore(const Instruction *I) {
return true;
}
-//
// This can cause a redundant sltiu to be generated.
// FIXME: try and eliminate this in a future patch.
-//
bool MipsFastISel::selectBranch(const Instruction *I) {
const BranchInst *BI = cast<BranchInst>(I);
MachineBasicBlock *BrBB = FuncInfo.MBB;
diff --git a/lib/Target/Mips/MipsFrameLowering.h b/lib/Target/Mips/MipsFrameLowering.h
index 8c4214c4c21d..883c3267d51a 100644
--- a/lib/Target/Mips/MipsFrameLowering.h
+++ b/lib/Target/Mips/MipsFrameLowering.h
@@ -15,7 +15,7 @@
#define LLVM_LIB_TARGET_MIPS_MIPSFRAMELOWERING_H
#include "Mips.h"
-#include "llvm/Target/TargetFrameLowering.h"
+#include "llvm/CodeGen/TargetFrameLowering.h"
namespace llvm {
class MipsSubtarget;
diff --git a/lib/Target/Mips/MipsHazardSchedule.cpp b/lib/Target/Mips/MipsHazardSchedule.cpp
index f6fcf6ec9385..da67c1bcea99 100644
--- a/lib/Target/Mips/MipsHazardSchedule.cpp
+++ b/lib/Target/Mips/MipsHazardSchedule.cpp
@@ -1,4 +1,4 @@
-//===-- MipsHazardSchedule.cpp - Workaround pipeline hazards --------------===//
+//===- MipsHazardSchedule.cpp - Workaround pipeline hazards ---------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -44,15 +44,15 @@
#include "Mips.h"
#include "MipsInstrInfo.h"
-#include "MipsSEInstrInfo.h"
-#include "MipsTargetMachine.h"
+#include "MipsSubtarget.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/IR/Function.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegisterInfo.h"
+#include <algorithm>
+#include <iterator>
+#include <utility>
using namespace llvm;
@@ -62,11 +62,10 @@ STATISTIC(NumInsertedNops, "Number of nops inserted");
namespace {
-typedef MachineBasicBlock::iterator Iter;
-typedef MachineBasicBlock::reverse_iterator ReverseIter;
+using Iter = MachineBasicBlock::iterator;
+using ReverseIter = MachineBasicBlock::reverse_iterator;
class MipsHazardSchedule : public MachineFunctionPass {
-
public:
MipsHazardSchedule() : MachineFunctionPass(ID) {}
@@ -83,9 +82,10 @@ private:
static char ID;
};
-char MipsHazardSchedule::ID = 0;
} // end of anonymous namespace
+char MipsHazardSchedule::ID = 0;
+
/// Returns a pass that clears pipeline hazards.
FunctionPass *llvm::createMipsHazardSchedule() {
return new MipsHazardSchedule();
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index 20319f85696c..6448fd917560 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -1,4 +1,4 @@
-//===-- MipsISelLowering.cpp - Mips DAG Lowering Implementation -----------===//
+//===- MipsISelLowering.cpp - Mips DAG Lowering Implementation ------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,33 +11,70 @@
// selection DAG.
//
//===----------------------------------------------------------------------===//
+
#include "MipsISelLowering.h"
#include "InstPrinter/MipsInstPrinter.h"
#include "MCTargetDesc/MipsBaseInfo.h"
+#include "MCTargetDesc/MipsMCTargetDesc.h"
#include "MipsCCState.h"
+#include "MipsInstrInfo.h"
#include "MipsMachineFunction.h"
+#include "MipsRegisterInfo.h"
#include "MipsSubtarget.h"
#include "MipsTargetMachine.h"
#include "MipsTargetObjectFile.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/FunctionLoweringInfo.h"
+#include "llvm/CodeGen/ISDOpcodes.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/CodeGen/MachineValueType.h"
+#include "llvm/CodeGen/RuntimeLibcalls.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/TargetFrameLowering.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Value.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/CodeGen.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
+#include <algorithm>
+#include <cassert>
#include <cctype>
+#include <cstdint>
+#include <deque>
+#include <iterator>
+#include <utility>
+#include <vector>
using namespace llvm;
@@ -102,7 +139,6 @@ unsigned MipsTargetLowering::getNumRegistersForCallingConv(LLVMContext &Context,
unsigned MipsTargetLowering::getVectorTypeBreakdownForCallingConv(
LLVMContext &Context, EVT VT, EVT &IntermediateVT,
unsigned &NumIntermediates, MVT &RegisterVT) const {
-
// Break down vector types to either 2 i64s or 4 i32s.
RegisterVT = getRegisterTypeForCallingConv(Context, VT) ;
IntermediateVT = RegisterVT;
@@ -166,6 +202,8 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const {
case MipsISD::EH_RETURN: return "MipsISD::EH_RETURN";
case MipsISD::FPBrcond: return "MipsISD::FPBrcond";
case MipsISD::FPCmp: return "MipsISD::FPCmp";
+ case MipsISD::FSELECT: return "MipsISD::FSELECT";
+ case MipsISD::MTC1_D64: return "MipsISD::MTC1_D64";
case MipsISD::CMovFP_T: return "MipsISD::CMovFP_T";
case MipsISD::CMovFP_F: return "MipsISD::CMovFP_F";
case MipsISD::TruncIntFP: return "MipsISD::TruncIntFP";
@@ -449,7 +487,6 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
setOperationAction(ISD::ATOMIC_STORE, MVT::i64, Expand);
}
-
if (!Subtarget.hasMips32r2()) {
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8, Expand);
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);
@@ -508,9 +545,9 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
const MipsTargetLowering *MipsTargetLowering::create(const MipsTargetMachine &TM,
const MipsSubtarget &STI) {
if (STI.inMips16Mode())
- return llvm::createMips16TargetLowering(TM, STI);
+ return createMips16TargetLowering(TM, STI);
- return llvm::createMipsSETargetLowering(TM, STI);
+ return createMipsSETargetLowering(TM, STI);
}
// Create a fast isel object.
@@ -603,7 +640,6 @@ static Mips::CondCode condCodeToFCC(ISD::CondCode CC) {
}
}
-
/// This function returns true if the floating point conditional branches and
/// conditional moves which use condition code CC should be inverted.
static bool invertFPCondCodeUser(Mips::CondCode CC) {
@@ -1076,38 +1112,6 @@ static SDValue performADDCombine(SDNode *N, SelectionDAG &DAG,
return DAG.getNode(ISD::ADD, DL, ValTy, Add1, Lo);
}
-static SDValue performAssertZextCombine(SDNode *N, SelectionDAG &DAG,
- TargetLowering::DAGCombinerInfo &DCI,
- const MipsSubtarget &Subtarget) {
- SDValue N0 = N->getOperand(0);
- EVT NarrowerVT = cast<VTSDNode>(N->getOperand(1))->getVT();
-
- if (N0.getOpcode() != ISD::TRUNCATE)
- return SDValue();
-
- if (N0.getOperand(0).getOpcode() != ISD::AssertZext)
- return SDValue();
-
- // fold (AssertZext (trunc (AssertZext x))) -> (trunc (AssertZext x))
- // if the type of the extension of the innermost AssertZext node is
- // smaller from that of the outermost node, eg:
- // (AssertZext:i32 (trunc:i32 (AssertZext:i64 X, i32)), i8)
- // -> (trunc:i32 (AssertZext X, i8))
- SDValue WiderAssertZext = N0.getOperand(0);
- EVT WiderVT = cast<VTSDNode>(WiderAssertZext->getOperand(1))->getVT();
-
- if (NarrowerVT.bitsLT(WiderVT)) {
- SDValue NewAssertZext = DAG.getNode(
- ISD::AssertZext, SDLoc(N), WiderAssertZext.getValueType(),
- WiderAssertZext.getOperand(0), DAG.getValueType(NarrowerVT));
- return DAG.getNode(ISD::TRUNCATE, SDLoc(N), N->getValueType(0),
- NewAssertZext);
- }
-
- return SDValue();
-}
-
-
static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const MipsSubtarget &Subtarget) {
@@ -1180,8 +1184,6 @@ SDValue MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
return performORCombine(N, DAG, DCI, Subtarget);
case ISD::ADD:
return performADDCombine(N, DAG, DCI, Subtarget);
- case ISD::AssertZext:
- return performAssertZextCombine(N, DAG, DCI, Subtarget);
case ISD::SHL:
return performSHLCombine(N, DAG, DCI, Subtarget);
case ISD::SUB:
@@ -1393,14 +1395,6 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
case Mips::DMOD:
case Mips::DMODU:
return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), true, false);
- case Mips::DDIV_MM64R6:
- case Mips::DDIVU_MM64R6:
- case Mips::DMOD_MM64R6:
- case Mips::DMODU_MM64R6:
- return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), true, true);
- case Mips::SEL_D:
- case Mips::SEL_D_MMR6:
- return emitSEL_D(MI, BB);
case Mips::PseudoSELECT_I:
case Mips::PseudoSELECT_I64:
@@ -1960,32 +1954,6 @@ MachineBasicBlock *MipsTargetLowering::emitAtomicCmpSwapPartword(
return exitMBB;
}
-MachineBasicBlock *MipsTargetLowering::emitSEL_D(MachineInstr &MI,
- MachineBasicBlock *BB) const {
- MachineFunction *MF = BB->getParent();
- const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
- const TargetInstrInfo *TII = Subtarget.getInstrInfo();
- MachineRegisterInfo &RegInfo = MF->getRegInfo();
- DebugLoc DL = MI.getDebugLoc();
- MachineBasicBlock::iterator II(MI);
-
- unsigned Fc = MI.getOperand(1).getReg();
- const auto &FGR64RegClass = TRI->getRegClass(Mips::FGR64RegClassID);
-
- unsigned Fc2 = RegInfo.createVirtualRegister(FGR64RegClass);
-
- BuildMI(*BB, II, DL, TII->get(Mips::SUBREG_TO_REG), Fc2)
- .addImm(0)
- .addReg(Fc)
- .addImm(Mips::sub_lo);
-
- // We don't erase the original instruction, we just replace the condition
- // register with the 64-bit super-register.
- MI.getOperand(1).setReg(Fc2);
-
- return BB;
-}
-
SDValue MipsTargetLowering::lowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
// The first operand is the chain, the second is the condition, the third is
// the block to branch to if the condition is true.
@@ -2051,7 +2019,7 @@ SDValue MipsTargetLowering::lowerGlobalAddress(SDValue Op,
const GlobalObject *GO = GV->getBaseObject();
if (GO && TLOF->IsGlobalInSmallSection(GO, getTargetMachine()))
// %gp_rel relocation
- return getAddrGPRel(N, SDLoc(N), Ty, DAG);
+ return getAddrGPRel(N, SDLoc(N), Ty, DAG, ABI.IsN64());
// %hi/%lo relocation
return Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG)
@@ -2206,7 +2174,7 @@ lowerConstantPool(SDValue Op, SelectionDAG &DAG) const
if (TLOF->IsConstantInSmallSection(DAG.getDataLayout(), N->getConstVal(),
getTargetMachine()))
// %gp_rel relocation
- return getAddrGPRel(N, SDLoc(N), Ty, DAG);
+ return getAddrGPRel(N, SDLoc(N), Ty, DAG, ABI.IsN64());
return Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG)
: getAddrNonPICSym64(N, SDLoc(N), Ty, DAG);
@@ -2839,8 +2807,7 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT,
llvm_unreachable("Cannot handle this ValVT.");
if (!Reg) {
- unsigned Offset = State.AllocateStack(ValVT.getSizeInBits() >> 3,
- OrigAlign);
+ unsigned Offset = State.AllocateStack(ValVT.getStoreSize(), OrigAlign);
State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
} else
State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
@@ -2900,7 +2867,7 @@ SDValue MipsTargetLowering::passArgOnStack(SDValue StackPtr, unsigned Offset,
void MipsTargetLowering::
getOpndList(SmallVectorImpl<SDValue> &Ops,
- std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
+ std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
SDValue Chain) const {
@@ -2945,7 +2912,7 @@ getOpndList(SmallVectorImpl<SDValue> &Ops,
assert(Mask && "Missing call preserved mask for calling convention");
if (Subtarget.inMips16HardFloat()) {
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {
- llvm::StringRef Sym = G->getGlobal()->getName();
+ StringRef Sym = G->getGlobal()->getName();
Function *F = G->getGlobal()->getParent()->getFunction(Sym);
if (F && F->hasFnAttribute("__Mips16RetHelper")) {
Mask = MipsRegisterInfo::getMips16RetHelperMask();
@@ -3012,7 +2979,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
G->getGlobal()->hasProtectedVisibility());
}
}
- if (!IsTailCall && CLI.CS && CLI.CS->isMustTailCall())
+ if (!IsTailCall && CLI.CS && CLI.CS.isMustTailCall())
report_fatal_error("failed to perform tail call elimination on a call "
"site marked musttail");
@@ -3033,7 +3000,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
DAG.getCopyFromReg(Chain, DL, ABI.IsN64() ? Mips::SP_64 : Mips::SP,
getPointerTy(DAG.getDataLayout()));
- std::deque< std::pair<unsigned, SDValue> > RegsToPass;
+ std::deque<std::pair<unsigned, SDValue>> RegsToPass;
SmallVector<SDValue, 8> MemOpChains;
CCInfo.rewindByValRegsInfo();
@@ -3145,22 +3112,36 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
// node so that legalize doesn't hack it.
- SDValue CalleeLo;
EVT Ty = Callee.getValueType();
bool GlobalOrExternal = false, IsCallReloc = false;
// The long-calls feature is ignored in case of PIC.
// While we do not support -mshared / -mno-shared properly,
// ignore long-calls in case of -mabicalls too.
- if (Subtarget.useLongCalls() && !Subtarget.isABICalls() && !IsPIC) {
- // Get the address of the callee into a register to prevent
- // using of the `jal` instruction for the direct call.
- if (auto *N = dyn_cast<GlobalAddressSDNode>(Callee))
- Callee = Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG)
- : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG);
- else if (auto *N = dyn_cast<ExternalSymbolSDNode>(Callee))
- Callee = Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG)
- : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG);
+ if (!Subtarget.isABICalls() && !IsPIC) {
+ // If the function should be called using "long call",
+ // get its address into a register to prevent using
+ // of the `jal` instruction for the direct call.
+ if (auto *N = dyn_cast<ExternalSymbolSDNode>(Callee)) {
+ if (Subtarget.useLongCalls())
+ Callee = Subtarget.hasSym32()
+ ? getAddrNonPIC(N, SDLoc(N), Ty, DAG)
+ : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG);
+ } else if (auto *N = dyn_cast<GlobalAddressSDNode>(Callee)) {
+ bool UseLongCalls = Subtarget.useLongCalls();
+ // If the function has long-call/far/near attribute
+ // it overrides command line switch pased to the backend.
+ if (auto *F = dyn_cast<Function>(N->getGlobal())) {
+ if (F->hasFnAttribute("long-call"))
+ UseLongCalls = true;
+ else if (F->hasFnAttribute("short-call"))
+ UseLongCalls = false;
+ }
+ if (UseLongCalls)
+ Callee = Subtarget.hasSym32()
+ ? getAddrNonPIC(N, SDLoc(N), Ty, DAG)
+ : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG);
+ }
}
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
@@ -3378,10 +3359,10 @@ SDValue MipsTargetLowering::LowerFormalArguments(
MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
*DAG.getContext());
CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(CallConv), 1);
- const Function *Func = DAG.getMachineFunction().getFunction();
- Function::const_arg_iterator FuncArg = Func->arg_begin();
+ const Function &Func = DAG.getMachineFunction().getFunction();
+ Function::const_arg_iterator FuncArg = Func.arg_begin();
- if (Func->hasFnAttribute("interrupt") && !Func->arg_empty())
+ if (Func.hasFnAttribute("interrupt") && !Func.arg_empty())
report_fatal_error(
"Functions with the interrupt attribute cannot have arguments!");
@@ -3537,7 +3518,6 @@ SDValue
MipsTargetLowering::LowerInterruptReturn(SmallVectorImpl<SDValue> &RetOps,
const SDLoc &DL,
SelectionDAG &DAG) const {
-
MachineFunction &MF = DAG.getMachineFunction();
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
@@ -3620,7 +3600,7 @@ MipsTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
// the sret argument into $v0 for the return. We saved the argument into
// a virtual register in the entry block, so now we copy the value out
// and into $v0.
- if (MF.getFunction()->hasStructRetAttr()) {
+ if (MF.getFunction().hasStructRetAttr()) {
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
unsigned Reg = MipsFI->getSRetReturnReg();
@@ -3642,7 +3622,7 @@ MipsTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
RetOps.push_back(Flag);
// ISRs must use "eret".
- if (DAG.getMachineFunction().getFunction()->hasFnAttribute("interrupt"))
+ if (DAG.getMachineFunction().getFunction().hasFnAttribute("interrupt"))
return LowerInterruptReturn(RetOps, DL, DAG);
// Standard return on Mips is a "jr $ra"
@@ -4003,7 +3983,7 @@ void MipsTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
bool MipsTargetLowering::isLegalAddressingMode(const DataLayout &DL,
const AddrMode &AM, Type *Ty,
- unsigned AS) const {
+ unsigned AS, Instruction *I) const {
// No global is ever allowed as a base.
if (AM.BaseGV)
return false;
diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h
index 0e47ed38f420..ce4f0376ca9b 100644
--- a/lib/Target/Mips/MipsISelLowering.h
+++ b/lib/Target/Mips/MipsISelLowering.h
@@ -1,4 +1,4 @@
-//===-- MipsISelLowering.h - Mips DAG Lowering Interface --------*- C++ -*-===//
+//===- MipsISelLowering.h - Mips DAG Lowering Interface ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,16 +17,45 @@
#include "MCTargetDesc/MipsABIInfo.h"
#include "MCTargetDesc/MipsBaseInfo.h"
+#include "MCTargetDesc/MipsMCTargetDesc.h"
#include "Mips.h"
-#include "llvm/CodeGen/CallingConvLower.h"
+#include "llvm/CodeGen/ISDOpcodes.h"
+#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/CodeGen/MachineValueType.h"
#include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/IR/Function.h"
-#include "llvm/Target/TargetLowering.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/TargetLowering.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Target/TargetMachine.h"
+#include <algorithm>
+#include <cassert>
#include <deque>
#include <string>
+#include <utility>
+#include <vector>
namespace llvm {
+
+class Argument;
+class CCState;
+class CCValAssign;
+class FastISel;
+class FunctionLoweringInfo;
+class MachineBasicBlock;
+class MachineFrameInfo;
+class MachineInstr;
+class MipsCCState;
+class MipsFunctionInfo;
+class MipsSubtarget;
+class MipsTargetMachine;
+class TargetLibraryInfo;
+class TargetRegisterClass;
+
namespace MipsISD {
+
enum NodeType : unsigned {
// Start the numbering from where ISD NodeType finishes.
FIRST_NUMBER = ISD::BUILTIN_OP_END,
@@ -66,6 +95,12 @@ namespace llvm {
// Floating Point Compare
FPCmp,
+ // Floating point select
+ FSELECT,
+
+ // Node used to generate an MTC1 i32 to f64 instruction
+ MTC1_D64,
+
// Floating Point Conditional Moves
CMovFP_T,
CMovFP_F,
@@ -218,17 +253,16 @@ namespace llvm {
SDL,
SDR
};
- }
+
+ } // ene namespace MipsISD
//===--------------------------------------------------------------------===//
// TargetLowering Implementation
//===--------------------------------------------------------------------===//
- class MipsFunctionInfo;
- class MipsSubtarget;
- class MipsCCState;
class MipsTargetLowering : public TargetLowering {
bool isMicroMips;
+
public:
explicit MipsTargetLowering(const MipsTargetMachine &TM,
const MipsSubtarget &STI);
@@ -250,26 +284,26 @@ namespace llvm {
/// Return the register type for a given MVT, ensuring vectors are treated
/// as a series of gpr sized integers.
- virtual MVT getRegisterTypeForCallingConv(MVT VT) const override;
+ MVT getRegisterTypeForCallingConv(MVT VT) const override;
/// Return the register type for a given MVT, ensuring vectors are treated
/// as a series of gpr sized integers.
- virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context,
- EVT VT) const override;
+ MVT getRegisterTypeForCallingConv(LLVMContext &Context,
+ EVT VT) const override;
/// Return the number of registers for a given MVT, ensuring vectors are
/// treated as a series of gpr sized integers.
- virtual unsigned getNumRegistersForCallingConv(LLVMContext &Context,
- EVT VT) const override;
+ unsigned getNumRegistersForCallingConv(LLVMContext &Context,
+ EVT VT) const override;
/// Break down vectors to the correct number of gpr sized integers.
- virtual unsigned getVectorTypeBreakdownForCallingConv(
+ unsigned getVectorTypeBreakdownForCallingConv(
LLVMContext &Context, EVT VT, EVT &IntermediateVT,
unsigned &NumIntermediates, MVT &RegisterVT) const override;
/// Return the correct alignment for the current calling convention.
- virtual unsigned
- getABIAlignmentForCallingConv(Type *ArgTy, DataLayout DL) const override {
+ unsigned getABIAlignmentForCallingConv(Type *ArgTy,
+ DataLayout DL) const override {
if (ArgTy->isVectorTy())
return std::min(DL.getABITypeAlignment(ArgTy), 8U);
return DL.getABITypeAlignment(ArgTy);
@@ -441,13 +475,12 @@ namespace llvm {
// (add $gp, %gp_rel(sym))
template <class NodeTy>
SDValue getAddrGPRel(NodeTy *N, const SDLoc &DL, EVT Ty,
- SelectionDAG &DAG) const {
- assert(Ty == MVT::i32);
+ SelectionDAG &DAG, bool IsN64) const {
SDValue GPRel = getTargetNode(N, Ty, DAG, MipsII::MO_GPREL);
- return DAG.getNode(ISD::ADD, DL, Ty,
- DAG.getRegister(Mips::GP, Ty),
- DAG.getNode(MipsISD::GPRel, DL, DAG.getVTList(Ty),
- GPRel));
+ return DAG.getNode(
+ ISD::ADD, DL, Ty,
+ DAG.getRegister(IsN64 ? Mips::GP_64 : Mips::GP, Ty),
+ DAG.getNode(MipsISD::GPRel, DL, DAG.getVTList(Ty), GPRel));
}
/// This function fills Ops, which is the list of operands that will later
@@ -455,7 +488,7 @@ namespace llvm {
/// copyToReg nodes to set up argument registers.
virtual void
getOpndList(SmallVectorImpl<SDValue> &Ops,
- std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
+ std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
SDValue Chain) const;
@@ -619,7 +652,8 @@ namespace llvm {
}
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
- Type *Ty, unsigned AS) const override;
+ Type *Ty, unsigned AS,
+ Instruction *I = nullptr) const override;
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
@@ -674,10 +708,13 @@ namespace llvm {
createMipsSETargetLowering(const MipsTargetMachine &TM,
const MipsSubtarget &STI);
- namespace Mips {
- FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
- const TargetLibraryInfo *libInfo);
- }
-}
+namespace Mips {
+
+FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
+ const TargetLibraryInfo *libInfo);
+
+} // end namespace Mips
+
+} // end namespace llvm
-#endif
+#endif // LLVM_LIB_TARGET_MIPS_MIPSISELLOWERING_H
diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td
index 0333fe6520fa..c81739115373 100644
--- a/lib/Target/Mips/MipsInstrFPU.td
+++ b/lib/Target/Mips/MipsInstrFPU.td
@@ -39,6 +39,9 @@ def SDT_MipsExtractElementF64 : SDTypeProfile<1, 2, [SDTCisVT<0, i32>,
SDTCisVT<1, f64>,
SDTCisVT<2, i32>]>;
+def SDT_MipsMTC1_D64 : SDTypeProfile<1, 1, [SDTCisVT<0, f64>,
+ SDTCisVT<1, i32>]>;
+
def MipsFPCmp : SDNode<"MipsISD::FPCmp", SDT_MipsFPCmp, [SDNPOutGlue]>;
def MipsCMovFP_T : SDNode<"MipsISD::CMovFP_T", SDT_MipsCMovFP, [SDNPInGlue]>;
def MipsCMovFP_F : SDNode<"MipsISD::CMovFP_F", SDT_MipsCMovFP, [SDNPInGlue]>;
@@ -49,6 +52,8 @@ def MipsBuildPairF64 : SDNode<"MipsISD::BuildPairF64", SDT_MipsBuildPairF64>;
def MipsExtractElementF64 : SDNode<"MipsISD::ExtractElementF64",
SDT_MipsExtractElementF64>;
+def MipsMTC1_D64 : SDNode<"MipsISD::MTC1_D64", SDT_MipsMTC1_D64>;
+
// Operand for printing out a condition code.
let PrintMethod = "printFCCOperand", DecoderMethod = "DecodeCondCode" in
def condcode : Operand<i32>;
@@ -114,7 +119,7 @@ multiclass ADDS_M<string opstr, InstrItinClass Itin, bit IsComm,
SDPatternOperator OpNode = null_frag> {
def _D32 : MMRel, ADDS_FT<opstr, AFGR64Opnd, Itin, IsComm, OpNode>, FGR_32;
def _D64 : ADDS_FT<opstr, FGR64Opnd, Itin, IsComm, OpNode>, FGR_64 {
- string DecoderNamespace = "Mips64";
+ string DecoderNamespace = "MipsFP64";
}
}
@@ -130,14 +135,14 @@ multiclass ABSS_M<string opstr, InstrItinClass Itin,
def _D32 : MMRel, ABSS_FT<opstr, AFGR64Opnd, AFGR64Opnd, Itin, OpNode>,
FGR_32;
def _D64 : ABSS_FT<opstr, FGR64Opnd, FGR64Opnd, Itin, OpNode>, FGR_64 {
- string DecoderNamespace = "Mips64";
+ string DecoderNamespace = "MipsFP64";
}
}
multiclass ROUND_M<string opstr, InstrItinClass Itin> {
def _D32 : MMRel, ABSS_FT<opstr, FGR32Opnd, AFGR64Opnd, Itin>, FGR_32;
def _D64 : StdMMR6Rel, ABSS_FT<opstr, FGR32Opnd, FGR64Opnd, Itin>, FGR_64 {
- let DecoderNamespace = "Mips64";
+ let DecoderNamespace = "MipsFP64";
}
}
@@ -210,14 +215,25 @@ class SWXC1_FT<string opstr, RegisterOperand DRC,
}
class BC1F_FT<string opstr, DAGOperand opnd, InstrItinClass Itin,
- SDPatternOperator Op = null_frag, bit DelaySlot = 1> :
+ SDPatternOperator Op = null_frag> :
InstSE<(outs), (ins FCCRegsOpnd:$fcc, opnd:$offset),
!strconcat(opstr, "\t$fcc, $offset"),
[(MipsFPBrcond Op, FCCRegsOpnd:$fcc, bb:$offset)], Itin,
FrmFI, opstr>, HARDFLOAT {
let isBranch = 1;
let isTerminator = 1;
- let hasDelaySlot = DelaySlot;
+ let hasDelaySlot = 1;
+ let Defs = [AT];
+ let hasFCCRegOperand = 1;
+}
+
+class BC1XL_FT<string opstr, DAGOperand opnd, InstrItinClass Itin> :
+ InstSE<(outs), (ins FCCRegsOpnd:$fcc, opnd:$offset),
+ !strconcat(opstr, "\t$fcc, $offset"), [], Itin,
+ FrmFI, opstr>, HARDFLOAT {
+ let isBranch = 1;
+ let isTerminator = 1;
+ let hasDelaySlot = 1;
let Defs = [AT];
let hasFCCRegOperand = 1;
}
@@ -326,7 +342,7 @@ let AdditionalPredicates = [NotInMicroMips] in {
defm S : C_COND_M<"s", FGR32Opnd, 16, II_C_CC_S>, ISA_MIPS1_NOT_32R6_64R6;
defm D32 : C_COND_M<"d", AFGR64Opnd, 17, II_C_CC_D>, ISA_MIPS1_NOT_32R6_64R6,
FGR_32;
-let DecoderNamespace = "Mips64" in
+let DecoderNamespace = "MipsFP64" in
defm D64 : C_COND_M<"d", FGR64Opnd, 17, II_C_CC_D>, ISA_MIPS1_NOT_32R6_64R6,
FGR_64;
}
@@ -353,14 +369,26 @@ defm CVT_W : ROUND_M<"cvt.w.d", II_CVT>, ABSS_FM<0x24, 17>;
let AdditionalPredicates = [NotInMicroMips] in {
def RECIP_S : MMRel, ABSS_FT<"recip.s", FGR32Opnd, FGR32Opnd, II_RECIP_S>,
ABSS_FM<0b010101, 0x10>, INSN_MIPS4_32R2;
- def RECIP_D : MMRel, ABSS_FT<"recip.d", FGR64Opnd, FGR64Opnd, II_RECIP_D>,
- ABSS_FM<0b010101, 0x11>, INSN_MIPS4_32R2;
+ def RECIP_D32 : MMRel, ABSS_FT<"recip.d", AFGR64Opnd, AFGR64Opnd, II_RECIP_D>,
+ ABSS_FM<0b010101, 0x11>, INSN_MIPS4_32R2, FGR_32 {
+ let BaseOpcode = "RECIP_D32";
+ }
+ let DecoderNamespace = "MipsFP64" in
+ def RECIP_D64 : MMRel, ABSS_FT<"recip.d", FGR64Opnd, FGR64Opnd,
+ II_RECIP_D>, ABSS_FM<0b010101, 0x11>,
+ INSN_MIPS4_32R2, FGR_64;
def RSQRT_S : MMRel, ABSS_FT<"rsqrt.s", FGR32Opnd, FGR32Opnd, II_RSQRT_S>,
ABSS_FM<0b010110, 0x10>, INSN_MIPS4_32R2;
- def RSQRT_D : MMRel, ABSS_FT<"rsqrt.d", FGR64Opnd, FGR64Opnd, II_RSQRT_D>,
- ABSS_FM<0b010110, 0x11>, INSN_MIPS4_32R2;
+ def RSQRT_D32 : MMRel, ABSS_FT<"rsqrt.d", AFGR64Opnd, AFGR64Opnd, II_RSQRT_D>,
+ ABSS_FM<0b010110, 0x11>, INSN_MIPS4_32R2, FGR_32 {
+ let BaseOpcode = "RSQRT_D32";
+ }
+ let DecoderNamespace = "MipsFP64" in
+ def RSQRT_D64 : MMRel, ABSS_FT<"rsqrt.d", FGR64Opnd, FGR64Opnd,
+ II_RSQRT_D>, ABSS_FM<0b010110, 0x11>,
+ INSN_MIPS4_32R2, FGR_64;
}
-let DecoderNamespace = "Mips64" in {
+let DecoderNamespace = "MipsFP64" in {
let AdditionalPredicates = [NotInMicroMips] in {
def ROUND_L_S : ABSS_FT<"round.l.s", FGR64Opnd, FGR32Opnd, II_ROUND>,
ABSS_FM<0x8, 16>, FGR_64;
@@ -397,7 +425,7 @@ def CVT_D32_W : MMRel, ABSS_FT<"cvt.d.w", AFGR64Opnd, FGR32Opnd, II_CVT>,
def CVT_D32_S : MMRel, ABSS_FT<"cvt.d.s", AFGR64Opnd, FGR32Opnd, II_CVT>,
ABSS_FM<0x21, 16>, FGR_32;
-let DecoderNamespace = "Mips64" in {
+let DecoderNamespace = "MipsFP64" in {
def CVT_S_D64 : ABSS_FT<"cvt.s.d", FGR32Opnd, FGR64Opnd, II_CVT>,
ABSS_FM<0x20, 17>, FGR_64;
let AdditionalPredicates = [NotInMicroMips] in{
@@ -420,11 +448,14 @@ let isPseudo = 1, isCodeGenOnly = 1 in {
def PseudoCVT_D64_L : ABSS_FT<"", FGR64Opnd, GPR64Opnd, II_CVT>;
}
-def FABS_S : MMRel, ABSS_FT<"abs.s", FGR32Opnd, FGR32Opnd, II_ABS, fabs>,
- ABSS_FM<0x5, 16>;
+let AdditionalPredicates = [NotInMicroMips] in {
+ def FABS_S : MMRel, ABSS_FT<"abs.s", FGR32Opnd, FGR32Opnd, II_ABS, fabs>,
+ ABSS_FM<0x5, 16>;
+ defm FABS : ABSS_M<"abs.d", II_ABS, fabs>, ABSS_FM<0x5, 17>;
+}
+
def FNEG_S : MMRel, ABSS_FT<"neg.s", FGR32Opnd, FGR32Opnd, II_NEG, fneg>,
ABSS_FM<0x7, 16>;
-defm FABS : ABSS_M<"abs.d", II_ABS, fabs>, ABSS_FM<0x5, 17>;
defm FNEG : ABSS_M<"neg.d", II_NEG, fneg>, ABSS_FM<0x7, 17>;
def FSQRT_S : MMRel, StdMMR6Rel, ABSS_FT<"sqrt.s", FGR32Opnd, FGR32Opnd,
@@ -445,13 +476,13 @@ def MFC1 : MMRel, MFC1_FT<"mfc1", GPR32Opnd, FGR32Opnd, II_MFC1,
bitconvert>, MFC1_FM<0>;
def MFC1_D64 : MFC1_FT<"mfc1", GPR32Opnd, FGR64Opnd, II_MFC1>, MFC1_FM<0>,
FGR_64 {
- let DecoderNamespace = "Mips64";
+ let DecoderNamespace = "MipsFP64";
}
def MTC1 : MMRel, MTC1_FT<"mtc1", FGR32Opnd, GPR32Opnd, II_MTC1,
bitconvert>, MFC1_FM<4>;
def MTC1_D64 : MTC1_FT<"mtc1", FGR64Opnd, GPR32Opnd, II_MTC1>, MFC1_FM<4>,
FGR_64 {
- let DecoderNamespace = "Mips64";
+ let DecoderNamespace = "MipsFP64";
}
let AdditionalPredicates = [NotInMicroMips] in {
@@ -459,7 +490,7 @@ let AdditionalPredicates = [NotInMicroMips] in {
MFC1_FM<3>, ISA_MIPS32R2, FGR_32;
def MFHC1_D64 : MFC1_FT<"mfhc1", GPR32Opnd, FGR64Opnd, II_MFHC1>,
MFC1_FM<3>, ISA_MIPS32R2, FGR_64 {
- let DecoderNamespace = "Mips64";
+ let DecoderNamespace = "MipsFP64";
}
}
let AdditionalPredicates = [NotInMicroMips] in {
@@ -467,7 +498,7 @@ let AdditionalPredicates = [NotInMicroMips] in {
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 {
- let DecoderNamespace = "Mips64";
+ let DecoderNamespace = "MipsFP64";
}
}
let AdditionalPredicates = [NotInMicroMips] in {
@@ -483,7 +514,7 @@ def FMOV_D32 : MMRel, ABSS_FT<"mov.d", AFGR64Opnd, AFGR64Opnd, II_MOV_D>,
ABSS_FM<0x6, 17>, FGR_32;
def FMOV_D64 : ABSS_FT<"mov.d", FGR64Opnd, FGR64Opnd, II_MOV_D>,
ABSS_FM<0x6, 17>, FGR_64 {
- let DecoderNamespace = "Mips64";
+ let DecoderNamespace = "MipsFP64";
}
/// Floating Point Memory Instructions
@@ -494,7 +525,7 @@ let AdditionalPredicates = [NotInMicroMips] in {
LW_FM<0x39>;
}
-let DecoderNamespace = "Mips64", AdditionalPredicates = [NotInMicroMips] in {
+let DecoderNamespace = "MipsFP64", AdditionalPredicates = [NotInMicroMips] in {
def LDC164 : StdMMR6Rel, LW_FT<"ldc1", FGR64Opnd, mem_simm16, II_LDC1, load>,
LW_FM<0x35>, ISA_MIPS2, FGR_64 {
let BaseOpcode = "LDC164";
@@ -529,7 +560,7 @@ let AdditionalPredicates = [NotInMicroMips, IsNotNaCl] in {
INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_32;
}
-let DecoderNamespace="Mips64" in {
+let DecoderNamespace="MipsFP64" in {
def LDXC164 : LWXC1_FT<"ldxc1", FGR64Opnd, II_LDXC1, load>, LWXC1_FM<1>,
INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_64;
def SDXC164 : SWXC1_FT<"sdxc1", FGR64Opnd, II_SDXC1, store>, SWXC1_FM<9>,
@@ -537,6 +568,7 @@ let DecoderNamespace="Mips64" in {
}
// Load/store doubleword indexed unaligned.
+// FIXME: This instruction should not be defined for FGR_32.
let AdditionalPredicates = [IsNotNaCl] in {
def LUXC1 : MMRel, LWXC1_FT<"luxc1", AFGR64Opnd, II_LUXC1>, LWXC1_FM<0x5>,
INSN_MIPS5_32R2_NOT_32R6_64R6, FGR_32;
@@ -544,7 +576,7 @@ let AdditionalPredicates = [IsNotNaCl] in {
INSN_MIPS5_32R2_NOT_32R6_64R6, FGR_32;
}
-let DecoderNamespace="Mips64" in {
+let DecoderNamespace="MipsFP64" in {
def LUXC164 : LWXC1_FT<"luxc1", FGR64Opnd, II_LUXC1>, LWXC1_FM<0x5>,
INSN_MIPS5_32R2_NOT_32R6_64R6, FGR_64;
def SUXC164 : SWXC1_FT<"suxc1", FGR64Opnd, II_SUXC1>, SWXC1_FM<0xd>,
@@ -589,7 +621,7 @@ let AdditionalPredicates = [NoNaNsFPMath, HasMadd4] in {
MADDS_FM<7, 1>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_32;
}
-let DecoderNamespace = "Mips64" in {
+let DecoderNamespace = "MipsFP64" in {
def MADD_D64 : MADDS_FT<"madd.d", FGR64Opnd, II_MADD_D, fadd>,
MADDS_FM<4, 1>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_64, MADD4;
def MSUB_D64 : MADDS_FT<"msub.d", FGR64Opnd, II_MSUB_D, fsub>,
@@ -597,7 +629,7 @@ let DecoderNamespace = "Mips64" in {
}
let AdditionalPredicates = [NoNaNsFPMath, HasMadd4],
- DecoderNamespace = "Mips64" in {
+ DecoderNamespace = "MipsFP64" in {
def NMADD_D64 : NMADDS_FT<"nmadd.d", FGR64Opnd, II_NMADD_D, fadd>,
MADDS_FM<6, 1>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_64;
def NMSUB_D64 : NMADDS_FT<"nmsub.d", FGR64Opnd, II_NMSUB_D, fsub>,
@@ -612,17 +644,17 @@ let AdditionalPredicates = [NoNaNsFPMath, HasMadd4],
def MIPS_BRANCH_F : PatLeaf<(i32 0)>;
def MIPS_BRANCH_T : PatLeaf<(i32 1)>;
-def BC1F : MMRel, BC1F_FT<"bc1f", brtarget, II_BC1F, MIPS_BRANCH_F>,
- BC1F_FM<0, 0>, ISA_MIPS1_NOT_32R6_64R6;
-def BC1FL : MMRel, BC1F_FT<"bc1fl", brtarget, II_BC1FL, MIPS_BRANCH_F, 0>,
- BC1F_FM<1, 0>, ISA_MIPS2_NOT_32R6_64R6;
-def BC1T : MMRel, BC1F_FT<"bc1t", brtarget, II_BC1T, MIPS_BRANCH_T>,
- BC1F_FM<0, 1>, ISA_MIPS1_NOT_32R6_64R6;
-def BC1TL : MMRel, BC1F_FT<"bc1tl", brtarget, II_BC1TL, MIPS_BRANCH_T, 0>,
- BC1F_FM<1, 1>, ISA_MIPS2_NOT_32R6_64R6;
+let AdditionalPredicates = [NotInMicroMips] in {
+ def BC1F : MMRel, BC1F_FT<"bc1f", brtarget, II_BC1F, MIPS_BRANCH_F>,
+ BC1F_FM<0, 0>, ISA_MIPS1_NOT_32R6_64R6;
+ def BC1FL : MMRel, BC1XL_FT<"bc1fl", brtarget, II_BC1FL>,
+ BC1F_FM<1, 0>, ISA_MIPS2_NOT_32R6_64R6;
+ def BC1T : MMRel, BC1F_FT<"bc1t", brtarget, II_BC1T, MIPS_BRANCH_T>,
+ BC1F_FM<0, 1>, ISA_MIPS1_NOT_32R6_64R6;
+ def BC1TL : MMRel, BC1XL_FT<"bc1tl", brtarget, II_BC1TL>,
+ BC1F_FM<1, 1>, ISA_MIPS2_NOT_32R6_64R6;
/// Floating Point Compare
-let AdditionalPredicates = [NotInMicroMips] in {
def FCMP_S32 : MMRel, CEQS_FT<"s", FGR32, II_C_CC_S, MipsFPCmp>, CEQS_FM<16>,
ISA_MIPS1_NOT_32R6_64R6 {
@@ -639,7 +671,7 @@ let AdditionalPredicates = [NotInMicroMips] in {
bits<3> fcc = 0;
}
}
-let DecoderNamespace = "Mips64" in
+let DecoderNamespace = "MipsFP64" in
def FCMP_D64 : CEQS_FT<"d", FGR64, II_C_CC_D, MipsFPCmp>, CEQS_FM<17>,
ISA_MIPS1_NOT_32R6_64R6, FGR_64 {
// FIXME: This is a required to work around the fact that thiese instructions
@@ -820,6 +852,9 @@ def : MipsPat<(f32 (sint_to_fp GPR32Opnd:$src)),
def : MipsPat<(MipsTruncIntFP FGR32Opnd:$src),
(TRUNC_W_S FGR32Opnd:$src)>;
+def : MipsPat<(MipsMTC1_D64 GPR32Opnd:$src),
+ (MTC1_D64 GPR32Opnd:$src)>, FGR_64;
+
def : MipsPat<(f64 (sint_to_fp GPR32Opnd:$src)),
(PseudoCVT_D32_W GPR32Opnd:$src)>, FGR_32;
def : MipsPat<(MipsTruncIntFP AFGR64Opnd:$src),
@@ -851,6 +886,20 @@ def : MipsPat<(f32 (fpround FGR64Opnd:$src)),
def : MipsPat<(f64 (fpextend FGR32Opnd:$src)),
(CVT_D64_S FGR32Opnd:$src)>, FGR_64;
+// To generate NMADD and NMSUB instructions when fneg node is present
+multiclass NMADD_NMSUB<Instruction Nmadd, Instruction Nmsub, RegisterOperand RC> {
+ def : MipsPat<(fneg (fadd (fmul RC:$fs, RC:$ft), RC:$fr)),
+ (Nmadd RC:$fr, RC:$fs, RC:$ft)>;
+ def : MipsPat<(fneg (fsub (fmul RC:$fs, RC:$ft), RC:$fr)),
+ (Nmsub RC:$fr, RC:$fs, RC:$ft)>;
+}
+
+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;
+}
+
// Patterns for loads/stores with a reg+imm operand.
let AdditionalPredicates = [NotInMicroMips] in {
let AddedComplexity = 40 in {
diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp
index 4adf77f8d9a9..51ddc0d44c00 100644
--- a/lib/Target/Mips/MipsInstrInfo.cpp
+++ b/lib/Target/Mips/MipsInstrInfo.cpp
@@ -1,4 +1,4 @@
-//===-- MipsInstrInfo.cpp - Mips Instruction Information ------------------===//
+//===- MipsInstrInfo.cpp - Mips Instruction Information -------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,14 +12,22 @@
//===----------------------------------------------------------------------===//
#include "MipsInstrInfo.h"
-#include "InstPrinter/MipsInstPrinter.h"
-#include "MipsMachineFunction.h"
+#include "MCTargetDesc/MipsBaseInfo.h"
+#include "MCTargetDesc/MipsMCTargetDesc.h"
#include "MipsSubtarget.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/TargetRegistry.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/TargetOpcodes.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/MC/MCInstrDesc.h"
+#include "llvm/Target/TargetMachine.h"
+#include <cassert>
using namespace llvm;
@@ -35,9 +43,9 @@ MipsInstrInfo::MipsInstrInfo(const MipsSubtarget &STI, unsigned UncondBr)
const MipsInstrInfo *MipsInstrInfo::create(MipsSubtarget &STI) {
if (STI.inMips16Mode())
- return llvm::createMips16InstrInfo(STI);
+ return createMips16InstrInfo(STI);
- return llvm::createMipsSEInstrInfo(STI);
+ return createMipsSEInstrInfo(STI);
}
bool MipsInstrInfo::isZeroImm(const MachineOperand &op) const {
@@ -80,7 +88,7 @@ void MipsInstrInfo::AnalyzeCondBr(const MachineInstr *Inst, unsigned Opc,
BB = Inst->getOperand(NumOp-1).getMBB();
Cond.push_back(MachineOperand::CreateImm(Opc));
- for (int i=0; i<NumOp-1; i++)
+ for (int i = 0; i < NumOp-1; i++)
Cond.push_back(Inst->getOperand(i));
}
@@ -149,24 +157,23 @@ unsigned MipsInstrInfo::removeBranch(MachineBasicBlock &MBB,
assert(!BytesRemoved && "code size not handled");
MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();
- unsigned removed;
-
- // Skip all the debug instructions.
- while (I != REnd && I->isDebugValue())
- ++I;
-
- if (I == REnd)
- return 0;
-
- MachineBasicBlock::iterator FirstBr = ++I.getReverse();
+ unsigned removed = 0;
// Up to 2 branches are removed.
// Note that indirect branches are not removed.
- for (removed = 0; I != REnd && removed < 2; ++I, ++removed)
+ while (I != REnd && removed < 2) {
+ // Skip past debug instructions.
+ if (I->isDebugValue()) {
+ ++I;
+ continue;
+ }
if (!getAnalyzableBrOpc(I->getOpcode()))
break;
-
- MBB.erase((--I).getReverse(), FirstBr);
+ // Remove the branch.
+ I->eraseFromParent();
+ I = MBB.rbegin();
+ ++removed;
+ }
return removed;
}
@@ -185,7 +192,6 @@ MipsInstrInfo::BranchType MipsInstrInfo::analyzeBranch(
MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond, bool AllowModify,
SmallVectorImpl<MachineInstr *> &BranchInstrs) const {
-
MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();
// Skip all the debug instructions.
@@ -211,7 +217,13 @@ MipsInstrInfo::BranchType MipsInstrInfo::analyzeBranch(
unsigned SecondLastOpc = 0;
MachineInstr *SecondLastInst = nullptr;
- if (++I != REnd) {
+ // Skip past any debug instruction to see if the second last actual
+ // is a branch.
+ ++I;
+ while (I != REnd && I->isDebugValue())
+ ++I;
+
+ if (I != REnd) {
SecondLastInst = &*I;
SecondLastOpc = getAnalyzableBrOpc(SecondLastInst->getOpcode());
@@ -396,7 +408,6 @@ bool MipsInstrInfo::SafeInForbiddenSlot(const MachineInstr &MI) const {
return false;
return (MI.getDesc().TSFlags & MipsII::IsCTI) == 0;
-
}
/// Predicate for distingushing instructions that have forbidden slots.
@@ -469,7 +480,7 @@ MipsInstrInfo::genInstrWithNewOpc(unsigned NewOpc,
MIB = BuildMI(*I->getParent(), I, I->getDebugLoc(), get(NewOpc));
// For MIPSR6 JI*C requires an immediate 0 as an operand, JIALC(64) an
- // immediate 0 as an operand and requires the removal of it's %RA<imp-def>
+ // immediate 0 as an operand and requires the removal of it's implicit-def %ra
// implicit operand as copying the implicit operations of the instructio we're
// looking at will give us the correct flags.
if (NewOpc == Mips::JIC || NewOpc == Mips::JIALC || NewOpc == Mips::JIC64 ||
@@ -514,7 +525,7 @@ bool MipsInstrInfo::findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1,
case Mips::DPADD_U_D:
case Mips::DPADD_S_H:
case Mips::DPADD_S_W:
- case Mips::DPADD_S_D: {
+ case Mips::DPADD_S_D:
// The first operand is both input and output, so it should not commute
if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3))
return false;
@@ -523,6 +534,129 @@ bool MipsInstrInfo::findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1,
return false;
return true;
}
- }
return TargetInstrInfo::findCommutedOpIndices(MI, SrcOpIdx1, SrcOpIdx2);
}
+
+// ins, ext, dext*, dins have the following constraints:
+// X <= pos < Y
+// X < size <= Y
+// X < pos+size <= Y
+//
+// dinsm and dinsu have the following constraints:
+// X <= pos < Y
+// X <= size <= Y
+// X < pos+size <= Y
+//
+// The callee of verifyInsExtInstruction however gives the bounds of
+// dins[um] like the other (d)ins (d)ext(um) instructions, so that this
+// function doesn't have to vary it's behaviour based on the instruction
+// being checked.
+static bool verifyInsExtInstruction(const MachineInstr &MI, StringRef &ErrInfo,
+ const int64_t PosLow, const int64_t PosHigh,
+ const int64_t SizeLow,
+ const int64_t SizeHigh,
+ const int64_t BothLow,
+ const int64_t BothHigh) {
+ MachineOperand MOPos = MI.getOperand(2);
+ if (!MOPos.isImm()) {
+ ErrInfo = "Position is not an immediate!";
+ return false;
+ }
+ int64_t Pos = MOPos.getImm();
+ if (!((PosLow <= Pos) && (Pos < PosHigh))) {
+ ErrInfo = "Position operand is out of range!";
+ return false;
+ }
+
+ MachineOperand MOSize = MI.getOperand(3);
+ if (!MOSize.isImm()) {
+ ErrInfo = "Size operand is not an immediate!";
+ return false;
+ }
+ int64_t Size = MOSize.getImm();
+ if (!((SizeLow < Size) && (Size <= SizeHigh))) {
+ ErrInfo = "Size operand is out of range!";
+ return false;
+ }
+
+ if (!((BothLow < (Pos + Size)) && ((Pos + Size) <= BothHigh))) {
+ ErrInfo = "Position + Size is out of range!";
+ return false;
+ }
+
+ return true;
+}
+
+// Perform target specific instruction verification.
+bool MipsInstrInfo::verifyInstruction(const MachineInstr &MI,
+ StringRef &ErrInfo) const {
+ // Verify that ins and ext instructions are well formed.
+ switch (MI.getOpcode()) {
+ case Mips::EXT:
+ case Mips::EXT_MM:
+ case Mips::INS:
+ case Mips::INS_MM:
+ case Mips::DINS:
+ return verifyInsExtInstruction(MI, ErrInfo, 0, 32, 0, 32, 0, 32);
+ case Mips::DINSM:
+ // The ISA spec has a subtle difference difference between dinsm and dextm
+ // in that it says:
+ // 2 <= size <= 64 for 'dinsm' but 'dextm' has 32 < size <= 64.
+ // To make the bounds checks similar, the range 1 < size <= 64 is checked
+ // for 'dinsm'.
+ return verifyInsExtInstruction(MI, ErrInfo, 0, 32, 1, 64, 32, 64);
+ case Mips::DINSU:
+ // The ISA spec has a subtle difference between dinsu and dextu in that
+ // the size range of dinsu is specified as 1 <= size <= 32 whereas size
+ // for dextu is 0 < size <= 32. The range checked for dinsu here is
+ // 0 < size <= 32, which is equivalent and similar to dextu.
+ return verifyInsExtInstruction(MI, ErrInfo, 32, 64, 0, 32, 32, 64);
+ case Mips::DEXT:
+ return verifyInsExtInstruction(MI, ErrInfo, 0, 32, 0, 32, 0, 63);
+ case Mips::DEXTM:
+ return verifyInsExtInstruction(MI, ErrInfo, 0, 32, 32, 64, 32, 64);
+ case Mips::DEXTU:
+ return verifyInsExtInstruction(MI, ErrInfo, 32, 64, 0, 32, 32, 64);
+ default:
+ return true;
+ }
+
+ return true;
+}
+
+std::pair<unsigned, unsigned>
+MipsInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {
+ return std::make_pair(TF, 0u);
+}
+
+ArrayRef<std::pair<unsigned, const char*>>
+MipsInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
+ using namespace MipsII;
+
+ static const std::pair<unsigned, const char*> Flags[] = {
+ {MO_GOT, "mips-got"},
+ {MO_GOT_CALL, "mips-got-call"},
+ {MO_GPREL, "mips-gprel"},
+ {MO_ABS_HI, "mips-abs-hi"},
+ {MO_ABS_LO, "mips-abs-lo"},
+ {MO_TLSGD, "mips-tlsgd"},
+ {MO_TLSLDM, "mips-tlsldm"},
+ {MO_DTPREL_HI, "mips-dtprel-hi"},
+ {MO_DTPREL_LO, "mips-dtprel-lo"},
+ {MO_GOTTPREL, "mips-gottprel"},
+ {MO_TPREL_HI, "mips-tprel-hi"},
+ {MO_TPREL_LO, "mips-tprel-lo"},
+ {MO_GPOFF_HI, "mips-gpoff-hi"},
+ {MO_GPOFF_LO, "mips-gpoff-lo"},
+ {MO_GOT_DISP, "mips-got-disp"},
+ {MO_GOT_PAGE, "mips-got-page"},
+ {MO_GOT_OFST, "mips-got-ofst"},
+ {MO_HIGHER, "mips-higher"},
+ {MO_HIGHEST, "mips-highest"},
+ {MO_GOT_HI16, "mips-got-hi16"},
+ {MO_GOT_LO16, "mips-got-lo16"},
+ {MO_CALL_HI16, "mips-call-hi16"},
+ {MO_CALL_LO16, "mips-call-lo16"}
+ };
+ return makeArrayRef(Flags);
+}
diff --git a/lib/Target/Mips/MipsInstrInfo.h b/lib/Target/Mips/MipsInstrInfo.h
index 45d700d8afd6..c18e395f9013 100644
--- a/lib/Target/Mips/MipsInstrInfo.h
+++ b/lib/Target/Mips/MipsInstrInfo.h
@@ -1,4 +1,4 @@
-//===-- MipsInstrInfo.h - Mips Instruction Information ----------*- C++ -*-===//
+//===- MipsInstrInfo.h - Mips Instruction Information -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,19 +18,30 @@
#ifndef LLVM_LIB_TARGET_MIPS_MIPSINSTRINFO_H
#define LLVM_LIB_TARGET_MIPS_MIPSINSTRINFO_H
+#include "MCTargetDesc/MipsMCTargetDesc.h"
#include "Mips.h"
#include "MipsRegisterInfo.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include <cstdint>
#define GET_INSTRINFO_HEADER
#include "MipsGenInstrInfo.inc"
namespace llvm {
+
+class MachineInstr;
+class MachineOperand;
class MipsSubtarget;
+class TargetRegisterClass;
+class TargetRegisterInfo;
+
class MipsInstrInfo : public MipsGenInstrInfo {
virtual void anchor();
+
protected:
const MipsSubtarget &Subtarget;
unsigned UncondBrOpc;
@@ -88,7 +99,6 @@ public:
/// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
/// such, whenever a client has an instance of instruction info, it should
/// always be able to get register info as well (through this method).
- ///
virtual const MipsRegisterInfo &getRegisterInfo() const = 0;
virtual unsigned getOppositeBranchOpc(unsigned Opc) const = 0;
@@ -138,6 +148,16 @@ public:
bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1,
unsigned &SrcOpIdx2) const override;
+ /// Perform target specific instruction verification.
+ bool verifyInstruction(const MachineInstr &MI,
+ StringRef &ErrInfo) const override;
+
+ std::pair<unsigned, unsigned>
+ decomposeMachineOperandsTargetFlags(unsigned TF) const override;
+
+ ArrayRef<std::pair<unsigned, const char *>>
+ getSerializableDirectMachineOperandTargetFlags() const override;
+
protected:
bool isZeroImm(const MachineOperand &op) const;
@@ -159,6 +179,6 @@ private:
const MipsInstrInfo *createMips16InstrInfo(const MipsSubtarget &STI);
const MipsInstrInfo *createMipsSEInstrInfo(const MipsSubtarget &STI);
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_LIB_TARGET_MIPS_MIPSINSTRINFO_H
diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td
index 89a5854bede0..e0d818b749df 100644
--- a/lib/Target/Mips/MipsInstrInfo.td
+++ b/lib/Target/Mips/MipsInstrInfo.td
@@ -208,10 +208,10 @@ def NotMips64r6 : Predicate<"!Subtarget->hasMips64r6()">,
AssemblerPredicate<"!FeatureMips64r6">;
def HasMicroMips32r6 : Predicate<"Subtarget->inMicroMips32r6Mode()">,
AssemblerPredicate<"FeatureMicroMips,FeatureMips32r6">;
-def HasMicroMips64r6 : Predicate<"Subtarget->inMicroMips64r6Mode()">,
- AssemblerPredicate<"FeatureMicroMips,FeatureMips64r6">;
def InMips16Mode : Predicate<"Subtarget->inMips16Mode()">,
AssemblerPredicate<"FeatureMips16">;
+def NotInMips16Mode : Predicate<"!Subtarget->inMips16Mode()">,
+ AssemblerPredicate<"!FeatureMips16">;
def HasCnMips : Predicate<"Subtarget->hasCnMips()">,
AssemblerPredicate<"FeatureCnMips">;
def NotCnMips : Predicate<"!Subtarget->hasCnMips()">,
@@ -220,6 +220,8 @@ def IsSym32 : Predicate<"Subtarget->HasSym32()">,
AssemblerPredicate<"FeatureSym32">;
def IsSym64 : Predicate<"!Subtarget->HasSym32()">,
AssemblerPredicate<"!FeatureSym32">;
+def IsN64 : Predicate<"Subtarget->isABI_N64()">;
+def IsNotN64 : Predicate<"!Subtarget->isABI_N64()">;
def RelocNotPIC : Predicate<"!TM.isPositionIndependent()">;
def RelocPIC : Predicate<"TM.isPositionIndependent()">;
def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">;
@@ -309,9 +311,6 @@ class ISA_MICROMIPS { list<Predicate> InsnPredicates = [InMicroMips]; }
class ISA_MICROMIPS32R6 {
list<Predicate> InsnPredicates = [HasMicroMips32r6];
}
-class ISA_MICROMIPS64R6 {
- list<Predicate> InsnPredicates = [HasMicroMips64r6];
-}
class ISA_MICROMIPS32_NOT_MIPS32R6 {
list<Predicate> InsnPredicates = [InMicroMips, NotMips32r6];
}
@@ -389,8 +388,8 @@ class ASE_MT {
// Class used for separating microMIPSr6 and microMIPS (r3) instruction.
// It can be used only on instructions that doesn't inherit PredicateControl.
-class ISA_MICROMIPS_NOT_32R6_64R6 : PredicateControl {
- let InsnPredicates = [InMicroMips, NotMips32r6, NotMips64r6];
+class ISA_MICROMIPS_NOT_32R6 : PredicateControl {
+ let InsnPredicates = [InMicroMips, NotMips32r6];
}
class ASE_NOT_DSP {
@@ -401,6 +400,16 @@ class MADD4 {
list<Predicate> AdditionalPredicates = [HasMadd4];
}
+// Classses used for separating expansions that differ based on the ABI in
+// use.
+class ABI_N64 {
+ list<Predicate> AdditionalPredicates = [IsN64];
+}
+
+class ABI_NOT_N64 {
+ list<Predicate> AdditionalPredicates = [IsNotN64];
+}
+
//===----------------------------------------------------------------------===//
class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl {
@@ -678,9 +687,14 @@ def ConstantUImm5Plus32NormalizeAsmOperandClass
// We must also subtract 32 when we render the operand.
let RenderMethod = "addConstantUImmOperands<5, 32, -32>";
}
+def ConstantUImm5Plus1ReportUImm6AsmOperandClass
+ : ConstantUImmAsmOperandClass<
+ 5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>{
+ let Name = "ConstantUImm5_Plus1_Report_UImm6";
+}
def ConstantUImm5Plus1AsmOperandClass
: ConstantUImmAsmOperandClass<
- 5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>;
+ 5, [ConstantUImm5Plus1ReportUImm6AsmOperandClass], 1>;
def ConstantUImm5AsmOperandClass
: ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus1AsmOperandClass]>;
def ConstantSImm5AsmOperandClass
@@ -787,6 +801,13 @@ def uimm5_plus1 : Operand<i32> {
let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
}
+def uimm5_plus1_report_uimm6 : Operand<i32> {
+ let PrintMethod = "printUImm<6, 1>";
+ let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
+ let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
+ let ParserMatchClass = ConstantUImm5Plus1ReportUImm6AsmOperandClass;
+}
+
def uimm5_plus32 : Operand<i32> {
let PrintMethod = "printUImm<5, 32>";
let ParserMatchClass = ConstantUImm5Plus32AsmOperandClass;
@@ -871,7 +892,7 @@ def uimm16_altrelaxed : Operand<i32> {
// Like uimm5 but reports a less confusing error for 32-63 when
// an instruction alias permits that.
def uimm5_report_uimm6 : Operand<i32> {
- let PrintMethod = "printUImm<5>";
+ let PrintMethod = "printUImm<6>";
let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
}
@@ -1193,6 +1214,25 @@ def immSExt16Plus1 : PatLeaf<(imm), [{
return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
}]>;
+def immZExtRange2To64 : PatLeaf<(imm), [{
+ return isUInt<7>(N->getZExtValue()) && (N->getZExtValue() >= 2) &&
+ (N->getZExtValue() <= 64);
+}]>;
+
+def ORiPred : PatLeaf<(imm), [{
+ return isUInt<16>(N->getZExtValue()) && !isInt<16>(N->getSExtValue());
+}], LO16>;
+
+def LUiPred : PatLeaf<(imm), [{
+ int64_t Val = N->getSExtValue();
+ return !isInt<16>(Val) && isInt<32>(Val) && !(Val & 0xffff);
+}]>;
+
+def LUiORiPred : PatLeaf<(imm), [{
+ int64_t SVal = N->getSExtValue();
+ return isInt<32>(SVal) && (SVal & 0xffff);
+}]>;
+
// Mips Address Mode! SDNode frameindex could possibily be a match
// since load and store instructions from stack used it.
def addr :
@@ -1370,27 +1410,47 @@ class SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
// Conditional Branch
class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
- RegisterOperand RO, bit DelaySlot = 1> :
+ RegisterOperand RO> :
InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
!strconcat(opstr, "\t$rs, $rt, $offset"),
[(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], II_BCC,
FrmI, opstr> {
let isBranch = 1;
let isTerminator = 1;
- let hasDelaySlot = DelaySlot;
+ let hasDelaySlot = 1;
+ let Defs = [AT];
+ bit isCTI = 1;
+}
+
+class CBranchLikely<string opstr, DAGOperand opnd, RegisterOperand RO> :
+ InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
+ !strconcat(opstr, "\t$rs, $rt, $offset"), [], II_BCC, FrmI, opstr> {
+ let isBranch = 1;
+ let isTerminator = 1;
+ let hasDelaySlot = 1;
let Defs = [AT];
bit isCTI = 1;
}
class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
- RegisterOperand RO, bit DelaySlot = 1> :
+ RegisterOperand RO> :
InstSE<(outs), (ins RO:$rs, opnd:$offset),
!strconcat(opstr, "\t$rs, $offset"),
[(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], II_BCCZ,
FrmI, opstr> {
let isBranch = 1;
let isTerminator = 1;
- let hasDelaySlot = DelaySlot;
+ let hasDelaySlot = 1;
+ let Defs = [AT];
+ bit isCTI = 1;
+}
+
+class CBranchZeroLikely<string opstr, DAGOperand opnd, RegisterOperand RO> :
+ InstSE<(outs), (ins RO:$rs, opnd:$offset),
+ !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZ, FrmI, opstr> {
+ let isBranch = 1;
+ let isTerminator = 1;
+ let hasDelaySlot = 1;
let Defs = [AT];
bit isCTI = 1;
}
@@ -1423,9 +1483,9 @@ class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
}
// Unconditional branch
-class UncondBranch<Instruction BEQInst> :
+class UncondBranch<Instruction BEQInst, DAGOperand opnd> :
PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], II_B>,
- PseudoInstExpansion<(BEQInst ZERO, ZERO, brtarget:$offset)> {
+ PseudoInstExpansion<(BEQInst ZERO, ZERO, opnd:$offset)> {
let isBranch = 1;
let isTerminator = 1;
let isBarrier = 1;
@@ -1466,10 +1526,10 @@ let isCall=1, hasDelaySlot=1, isCTI=1, Defs = [RA] in {
[], II_JALR, FrmR, opstr>;
class BGEZAL_FT<string opstr, DAGOperand opnd,
- RegisterOperand RO, bit DelaySlot = 1> :
+ RegisterOperand RO> :
InstSE<(outs), (ins RO:$rs, opnd:$offset),
!strconcat(opstr, "\t$rs, $offset"), [], II_BCCZAL, FrmI, opstr> {
- let hasDelaySlot = DelaySlot;
+ let hasDelaySlot = 1;
}
}
@@ -1481,7 +1541,7 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
PseudoInstExpansion<(JumpInst Opnd:$target)>;
class TailCallReg<RegisterOperand RO> :
- MipsPseudo<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>;
+ PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>;
}
class BAL_BR_Pseudo<Instruction RealInst> :
@@ -1659,15 +1719,17 @@ class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm,
SDPatternOperator Op = null_frag> :
InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size),
- !strconcat(opstr, " $rt, $rs, $pos, $size"),
+ !strconcat(opstr, "\t$rt, $rs, $pos, $size"),
[(set RO:$rt, (Op RO:$rs, PosImm:$pos, SizeImm:$size))], II_EXT,
FrmR, opstr>, ISA_MIPS32R2;
+// 'ins' and its' 64 bit variants are matched by C++ code.
class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
- Operand SizeOpnd, SDPatternOperator Op = null_frag>:
+ Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm>:
InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size, RO:$src),
- !strconcat(opstr, " $rt, $rs, $pos, $size"),
- [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size, RO:$src))],
+ !strconcat(opstr, "\t$rt, $rs, $pos, $size"),
+ [(set RO:$rt, (null_frag RO:$rs, PosImm:$pos, SizeImm:$size,
+ RO:$src))],
II_INS, FrmR, opstr>, ISA_MIPS32R2 {
let Constraints = "$src = $rt";
}
@@ -1978,31 +2040,32 @@ def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
/// Jump and Branch Instructions
def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
- AdditionalRequires<[RelocNotPIC]>, IsBranch;
+ AdditionalRequires<[RelocNotPIC, NotInMicroMips]>, IsBranch;
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>;
-def BEQL : MMRel, CBranch<"beql", brtarget, seteq, GPR32Opnd, 0>,
+def BEQL : MMRel, CBranchLikely<"beql", brtarget, GPR32Opnd>,
BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>;
-def BNEL : MMRel, CBranch<"bnel", brtarget, setne, GPR32Opnd, 0>,
+def BNEL : MMRel, CBranchLikely<"bnel", brtarget, GPR32Opnd>,
BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
BGEZ_FM<1, 1>;
-def BGEZL : MMRel, CBranchZero<"bgezl", brtarget, setge, GPR32Opnd, 0>,
+def BGEZL : MMRel, CBranchZeroLikely<"bgezl", brtarget, GPR32Opnd>,
BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
BGEZ_FM<7, 0>;
-def BGTZL : MMRel, CBranchZero<"bgtzl", brtarget, setgt, GPR32Opnd, 0>,
+def BGTZL : MMRel, CBranchZeroLikely<"bgtzl", brtarget, GPR32Opnd>,
BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
BGEZ_FM<6, 0>;
-def BLEZL : MMRel, CBranchZero<"blezl", brtarget, setle, GPR32Opnd, 0>,
+def BLEZL : MMRel, CBranchZeroLikely<"blezl", brtarget, GPR32Opnd>,
BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
BGEZ_FM<1, 0>;
-def BLTZL : MMRel, CBranchZero<"bltzl", brtarget, setlt, GPR32Opnd, 0>,
+def BLTZL : MMRel, CBranchZeroLikely<"bltzl", brtarget, GPR32Opnd>,
BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
-def B : UncondBranch<BEQ>;
+def B : UncondBranch<BEQ, brtarget>,
+ AdditionalRequires<[NotInMicroMips]>;
def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>;
let AdditionalPredicates = [NotInMicroMips] in {
@@ -2014,15 +2077,15 @@ def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
ISA_MIPS32_NOT_32R6_64R6;
def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
ISA_MIPS1_NOT_32R6_64R6;
-def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd, 0>,
+def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd>,
BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
ISA_MIPS1_NOT_32R6_64R6;
-def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd, 0>,
+def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd>,
BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
-let Predicates = [NotInMicroMips] in {
+let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips] in {
def TAILCALL : TailCall<J, jmptarget>;
}
@@ -2039,6 +2102,7 @@ class PseudoIndirectBranchBase<RegisterOperand RO> :
let isBranch = 1;
let isIndirectBranch = 1;
bit isCTI = 1;
+ let Predicates = [NotInMips16Mode];
}
def PseudoIndirectBranch : PseudoIndirectBranchBase<GPR32Opnd>;
@@ -2171,7 +2235,8 @@ let AdditionalPredicates = [NotInMicroMips] in {
immZExt5, immZExt5Plus1, MipsExt>,
EXT_FM<0>;
def INS : MMRel, StdMMR6Rel, InsBase<"ins", GPR32Opnd, uimm5,
- uimm5_inssize_plus1, MipsIns>,
+ uimm5_inssize_plus1, immZExt5,
+ immZExt5Plus1>,
EXT_FM<4>;
}
/// Move Control Registers From/To CPU Registers
@@ -2665,15 +2730,20 @@ multiclass MaterializeImms<ValueType VT, Register ZEROReg,
Instruction ADDiuOp, Instruction LUiOp,
Instruction ORiOp> {
-// Small immediates
-def : MipsPat<(VT immSExt16:$imm), (ADDiuOp ZEROReg, imm:$imm)>;
-def : MipsPat<(VT immZExt16:$imm), (ORiOp ZEROReg, imm:$imm)>;
+// Constant synthesis previously relied on the ordering of the patterns below.
+// By making the predicates they use non-overlapping, the patterns were
+// reordered so that the effect of the newly introduced predicates can be
+// observed.
+
+// Arbitrary immediates
+def : MipsPat<(VT LUiORiPred:$imm), (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>;
// Bits 32-16 set, sign/zero extended.
-def : MipsPat<(VT immSExt32Low16Zero:$imm), (LUiOp (HI16 imm:$imm))>;
+def : MipsPat<(VT LUiPred:$imm), (LUiOp (HI16 imm:$imm))>;
-// Arbitrary immediates
-def : MipsPat<(VT immSExt32:$imm), (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>;
+// Small immediates
+def : MipsPat<(VT ORiPred:$imm), (ORiOp ZEROReg, imm:$imm)>;
+def : MipsPat<(VT immSExt16:$imm), (ADDiuOp ZEROReg, imm:$imm)>;
}
let AdditionalPredicates = [NotInMicroMips] in
@@ -2706,10 +2776,12 @@ def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
// (JALR GPR32:$dst)>;
// Tail call
-def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
- (TAILCALL tglobaladdr:$dst)>;
-def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
- (TAILCALL texternalsym:$dst)>;
+let AdditionalPredicates = [NotInMicroMips] in {
+ def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
+ (TAILCALL tglobaladdr:$dst)>;
+ def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
+ (TAILCALL texternalsym:$dst)>;
+}
// hi/lo relocs
multiclass MipsHiLoRelocs<Instruction Lui, Instruction Addiu,
Register ZeroReg, RegisterOperand GPROpnd> {
@@ -2748,9 +2820,9 @@ def : MipsPat<(MipsGotHi texternalsym:$in), (LUi texternalsym:$in)>;
// gp_rel relocs
def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
- (ADDiu GPR32:$gp, tglobaladdr:$in)>;
+ (ADDiu GPR32:$gp, tglobaladdr:$in)>, ABI_NOT_N64;
def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
- (ADDiu GPR32:$gp, tconstpool:$in)>;
+ (ADDiu GPR32:$gp, tconstpool:$in)>, ABI_NOT_N64;
// wrapper_pic
class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
@@ -2937,10 +3009,6 @@ include "MicroMipsInstrFPU.td"
include "MicroMips32r6InstrFormats.td"
include "MicroMips32r6InstrInfo.td"
-// Micromips64 r6
-include "MicroMips64r6InstrFormats.td"
-include "MicroMips64r6InstrInfo.td"
-
// Micromips DSP
include "MicroMipsDSPInstrFormats.td"
include "MicroMipsDSPInstrInfo.td"
diff --git a/lib/Target/Mips/MipsLongBranch.cpp b/lib/Target/Mips/MipsLongBranch.cpp
index b95f1158fa56..bbf2050ce1eb 100644
--- a/lib/Target/Mips/MipsLongBranch.cpp
+++ b/lib/Target/Mips/MipsLongBranch.cpp
@@ -1,4 +1,4 @@
-//===-- MipsLongBranch.cpp - Emit long branches ---------------------------===//
+//===- MipsLongBranch.cpp - Emit long branches ----------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,6 +16,7 @@
#include "MCTargetDesc/MipsABIInfo.h"
#include "MCTargetDesc/MipsBaseInfo.h"
#include "MCTargetDesc/MipsMCNaCl.h"
+#include "MCTargetDesc/MipsMCTargetDesc.h"
#include "Mips.h"
#include "MipsInstrInfo.h"
#include "MipsMachineFunction.h"
@@ -30,6 +31,7 @@
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
@@ -59,8 +61,8 @@ static cl::opt<bool> ForceLongBranch(
namespace {
- typedef MachineBasicBlock::iterator Iter;
- typedef MachineBasicBlock::reverse_iterator ReverseIter;
+ using Iter = MachineBasicBlock::iterator;
+ using ReverseIter = MachineBasicBlock::reverse_iterator;
struct MBBInfo {
uint64_t Size = 0;
@@ -102,10 +104,10 @@ namespace {
unsigned LongBranchSeqSize;
};
- char MipsLongBranch::ID = 0;
-
} // end anonymous namespace
+char MipsLongBranch::ID = 0;
+
/// Iterate over list of Br's operands and search for a MachineBasicBlock
/// operand.
static MachineBasicBlock *getTargetMBB(const MachineInstr &Br) {
@@ -277,12 +279,16 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
LongBrMBB->addSuccessor(BalTgtMBB);
BalTgtMBB->addSuccessor(TgtMBB);
- // We must select between the MIPS32r6/MIPS64r6 BAL (which is a normal
+ // We must select between the MIPS32r6/MIPS64r6 BALC (which is a normal
// instruction) and the pre-MIPS32r6/MIPS64r6 definition (which is an
// pseudo-instruction wrapping BGEZAL).
- unsigned BalOp = Subtarget.hasMips32r6() ? Mips::BAL : Mips::BAL_BR;
+ const unsigned BalOp =
+ Subtarget.hasMips32r6()
+ ? Subtarget.inMicroMipsMode() ? Mips::BALC_MMR6 : Mips::BALC
+ : Mips::BAL_BR;
if (!ABI.IsN64()) {
+ // Pre R6:
// $longbr:
// addiu $sp, $sp, -8
// sw $ra, 0($sp)
@@ -297,6 +303,20 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
// $fallthrough:
//
+ // R6:
+ // $longbr:
+ // addiu $sp, $sp, -8
+ // sw $ra, 0($sp)
+ // lui $at, %hi($tgt - $baltgt)
+ // addiu $at, $at, %lo($tgt - $baltgt)
+ // balc $baltgt
+ // $baltgt:
+ // addu $at, $ra, $at
+ // lw $ra, 0($sp)
+ // addiu $sp, $sp, 8
+ // jic $at, 0
+ // $fallthrough:
+
Pos = LongBrMBB->begin();
BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
@@ -305,7 +325,7 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
.addReg(Mips::SP).addImm(0);
// LUi and ADDiu instructions create 32-bit offset of the target basic
- // block from the target of BAL instruction. We cannot use immediate
+ // block from the target of BAL(C) instruction. We cannot use immediate
// value for this offset because it cannot be determined accurately when
// the program has inline assembly statements. We therefore use the
// relocation expressions %hi($tgt-$baltgt) and %lo($tgt-$baltgt) which
@@ -322,12 +342,22 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi), Mips::AT)
.addMBB(TgtMBB).addMBB(BalTgtMBB);
- MIBundleBuilder(*LongBrMBB, Pos)
- .append(BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB))
- .append(BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_ADDiu), Mips::AT)
- .addReg(Mips::AT)
- .addMBB(TgtMBB)
- .addMBB(BalTgtMBB));
+
+ MachineInstrBuilder BalInstr =
+ BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB);
+ MachineInstrBuilder ADDiuInstr =
+ BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_ADDiu), Mips::AT)
+ .addReg(Mips::AT)
+ .addMBB(TgtMBB)
+ .addMBB(BalTgtMBB);
+ if (Subtarget.hasMips32r6()) {
+ LongBrMBB->insert(Pos, ADDiuInstr);
+ LongBrMBB->insert(Pos, BalInstr);
+ } else {
+ LongBrMBB->insert(Pos, BalInstr);
+ LongBrMBB->insert(Pos, ADDiuInstr);
+ LongBrMBB->rbegin()->bundleWithPred();
+ }
Pos = BalTgtMBB->begin();
@@ -335,28 +365,37 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
.addReg(Mips::RA).addReg(Mips::AT);
BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA)
.addReg(Mips::SP).addImm(0);
+ if (Subtarget.isTargetNaCl())
+ // Bundle-align the target of indirect branch JR.
+ TgtMBB->setAlignment(MIPS_NACL_BUNDLE_ALIGN);
// In NaCl, modifying the sp is not allowed in branch delay slot.
- if (Subtarget.isTargetNaCl())
+ // For MIPS32R6, we can skip using a delay slot branch.
+ if (Subtarget.isTargetNaCl() || Subtarget.hasMips32r6())
BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
.addReg(Mips::SP).addImm(8);
- if (Subtarget.hasMips32r6())
- BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JALR))
- .addReg(Mips::ZERO).addReg(Mips::AT);
- else
+ if (Subtarget.hasMips32r6()) {
+ const unsigned JICOp =
+ Subtarget.inMicroMipsMode() ? Mips::JIC_MMR6 : Mips::JIC;
+ BuildMI(*BalTgtMBB, Pos, DL, TII->get(JICOp))
+ .addReg(Mips::AT)
+ .addImm(0);
+
+ } else {
BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JR)).addReg(Mips::AT);
- if (Subtarget.isTargetNaCl()) {
- BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::NOP));
- // Bundle-align the target of indirect branch JR.
- TgtMBB->setAlignment(MIPS_NACL_BUNDLE_ALIGN);
- } else
- BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
- .addReg(Mips::SP).addImm(8);
+ if (Subtarget.isTargetNaCl()) {
+ BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::NOP));
+ } else
+ BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
+ .addReg(Mips::SP)
+ .addImm(8);
- BalTgtMBB->rbegin()->bundleWithPred();
+ BalTgtMBB->rbegin()->bundleWithPred();
+ }
} else {
+ // Pre R6:
// $longbr:
// daddiu $sp, $sp, -16
// sd $ra, 0($sp)
@@ -370,7 +409,21 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
// jr64 $at
// daddiu $sp, $sp, 16
// $fallthrough:
- //
+
+ // R6:
+ // $longbr:
+ // daddiu $sp, $sp, -16
+ // sd $ra, 0($sp)
+ // daddiu $at, $zero, %hi($tgt - $baltgt)
+ // dsll $at, $at, 16
+ // daddiu $at, $at, %lo($tgt - $baltgt)
+ // balc $baltgt
+ // $baltgt:
+ // daddu $at, $ra, $at
+ // ld $ra, 0($sp)
+ // daddiu $sp, $sp, 16
+ // jic $at, 0
+ // $fallthrough:
// We assume the branch is within-function, and that offset is within
// +/- 2GB. High 32 bits will therefore always be zero.
@@ -399,13 +452,21 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64)
.addReg(Mips::AT_64).addImm(16);
- MIBundleBuilder(*LongBrMBB, Pos)
- .append(BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB))
- .append(
- BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64)
- .addReg(Mips::AT_64)
- .addMBB(TgtMBB, MipsII::MO_ABS_LO)
- .addMBB(BalTgtMBB));
+ MachineInstrBuilder BalInstr =
+ BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB);
+ MachineInstrBuilder DADDiuInstr =
+ BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64)
+ .addReg(Mips::AT_64)
+ .addMBB(TgtMBB, MipsII::MO_ABS_LO)
+ .addMBB(BalTgtMBB);
+ if (Subtarget.hasMips32r6()) {
+ LongBrMBB->insert(Pos, DADDiuInstr);
+ LongBrMBB->insert(Pos, BalInstr);
+ } else {
+ LongBrMBB->insert(Pos, BalInstr);
+ LongBrMBB->insert(Pos, DADDiuInstr);
+ LongBrMBB->rbegin()->bundleWithPred();
+ }
Pos = BalTgtMBB->begin();
@@ -414,29 +475,40 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LD), Mips::RA_64)
.addReg(Mips::SP_64).addImm(0);
- if (Subtarget.hasMips64r6())
- BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JALR64))
- .addReg(Mips::ZERO_64).addReg(Mips::AT_64);
- else
+ if (Subtarget.hasMips64r6()) {
+ BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)
+ .addReg(Mips::SP_64)
+ .addImm(16);
+ BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JIC64))
+ .addReg(Mips::AT_64)
+ .addImm(0);
+ } else {
BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JR64)).addReg(Mips::AT_64);
-
- BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)
- .addReg(Mips::SP_64).addImm(16);
- BalTgtMBB->rbegin()->bundleWithPred();
+ BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)
+ .addReg(Mips::SP_64)
+ .addImm(16);
+ BalTgtMBB->rbegin()->bundleWithPred();
+ }
}
assert(LongBrMBB->size() + BalTgtMBB->size() == LongBranchSeqSize);
} else {
- // $longbr:
- // j $tgt
- // nop
+ // Pre R6: R6:
+ // $longbr: $longbr:
+ // j $tgt bc $tgt
+ // nop $fallthrough
// $fallthrough:
//
Pos = LongBrMBB->begin();
LongBrMBB->addSuccessor(TgtMBB);
- MIBundleBuilder(*LongBrMBB, Pos)
- .append(BuildMI(*MF, DL, TII->get(Mips::J)).addMBB(TgtMBB))
- .append(BuildMI(*MF, DL, TII->get(Mips::NOP)));
+ if (Subtarget.hasMips32r6())
+ BuildMI(*LongBrMBB, Pos, DL,
+ TII->get(Subtarget.inMicroMipsMode() ? Mips::BC_MMR6 : Mips::BC))
+ .addMBB(TgtMBB);
+ else
+ MIBundleBuilder(*LongBrMBB, Pos)
+ .append(BuildMI(*MF, DL, TII->get(Mips::J)).addMBB(TgtMBB))
+ .append(BuildMI(*MF, DL, TII->get(Mips::NOP)));
assert(LongBrMBB->size() == LongBranchSeqSize);
}
@@ -468,13 +540,12 @@ bool MipsLongBranch::runOnMachineFunction(MachineFunction &F) {
const MipsInstrInfo *TII =
static_cast<const MipsInstrInfo *>(STI.getInstrInfo());
-
const TargetMachine& TM = F.getTarget();
IsPIC = TM.isPositionIndependent();
ABI = static_cast<const MipsTargetMachine &>(TM).getABI();
- LongBranchSeqSize =
- !IsPIC ? 2 : (ABI.IsN64() ? 10 : (!STI.isTargetNaCl() ? 9 : 10));
+ LongBranchSeqSize = IsPIC ? ((ABI.IsN64() || STI.isTargetNaCl()) ? 10 : 9)
+ : (STI.hasMips32r6() ? 1 : 2);
if (STI.inMips16Mode() || !STI.enableLongBranchPass())
return false;
diff --git a/lib/Target/Mips/MipsMCInstLower.cpp b/lib/Target/Mips/MipsMCInstLower.cpp
index d5bc4e537c37..a4ab7d3a5780 100644
--- a/lib/Target/Mips/MipsMCInstLower.cpp
+++ b/lib/Target/Mips/MipsMCInstLower.cpp
@@ -1,4 +1,4 @@
-//===-- MipsMCInstLower.cpp - Convert Mips MachineInstr to MCInst ---------===//
+//===- MipsMCInstLower.cpp - Convert Mips MachineInstr to MCInst ----------===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,18 +11,18 @@
// MCInst records.
//
//===----------------------------------------------------------------------===//
+
#include "MipsMCInstLower.h"
#include "MCTargetDesc/MipsBaseInfo.h"
+#include "MCTargetDesc/MipsMCExpr.h"
#include "MipsAsmPrinter.h"
-#include "MipsInstrInfo.h"
-#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineOperand.h"
-#include "llvm/IR/Mangler.h"
-#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCStreamer.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
using namespace llvm;
@@ -278,4 +278,3 @@ void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
OutMI.addOperand(MCOp);
}
}
-
diff --git a/lib/Target/Mips/MipsMCInstLower.h b/lib/Target/Mips/MipsMCInstLower.h
index c25f90005480..fb5079643827 100644
--- a/lib/Target/Mips/MipsMCInstLower.h
+++ b/lib/Target/Mips/MipsMCInstLower.h
@@ -1,4 +1,4 @@
-//===-- MipsMCInstLower.h - Lower MachineInstr to MCInst -------*- C++ -*--===//
+//===- MipsMCInstLower.h - Lower MachineInstr to MCInst --------*- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,26 +9,31 @@
#ifndef LLVM_LIB_TARGET_MIPS_MIPSMCINSTLOWER_H
#define LLVM_LIB_TARGET_MIPS_MIPSMCINSTLOWER_H
+
#include "MCTargetDesc/MipsMCExpr.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/Support/Compiler.h"
namespace llvm {
- class MCContext;
- class MCInst;
- class MCOperand;
- class MachineInstr;
- class MachineFunction;
- class MipsAsmPrinter;
+
+class MachineBasicBlock;
+class MachineInstr;
+class MCContext;
+class MCInst;
+class MCOperand;
+class MipsAsmPrinter;
/// MipsMCInstLower - This class is used to lower an MachineInstr into an
-// MCInst.
+/// MCInst.
class LLVM_LIBRARY_VISIBILITY MipsMCInstLower {
- typedef MachineOperand::MachineOperandType MachineOperandType;
+ using MachineOperandType = MachineOperand::MachineOperandType;
+
MCContext *Ctx;
MipsAsmPrinter &AsmPrinter;
+
public:
MipsMCInstLower(MipsAsmPrinter &asmprinter);
+
void Initialize(MCContext *C);
void Lower(const MachineInstr *MI, MCInst &OutMI) const;
MCOperand LowerOperand(const MachineOperand& MO, unsigned offset = 0) const;
@@ -43,6 +48,7 @@ private:
MipsMCExpr::MipsExprKind Kind) const;
bool lowerLongBranch(const MachineInstr *MI, MCInst &OutMI) const;
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_LIB_TARGET_MIPS_MIPSMCINSTLOWER_H
diff --git a/lib/Target/Mips/MipsMachineFunction.cpp b/lib/Target/Mips/MipsMachineFunction.cpp
index e01c03db2227..1ee56d830090 100644
--- a/lib/Target/Mips/MipsMachineFunction.cpp
+++ b/lib/Target/Mips/MipsMachineFunction.cpp
@@ -14,8 +14,8 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
@@ -41,9 +41,7 @@ unsigned MipsFunctionInfo::getGlobalBaseReg() {
STI.inMips16Mode()
? &Mips::CPU16RegsRegClass
: STI.inMicroMipsMode()
- ? STI.hasMips64()
- ? &Mips::GPRMM16_64RegClass
- : &Mips::GPRMM16RegClass
+ ? &Mips::GPRMM16RegClass
: static_cast<const MipsTargetMachine &>(MF.getTarget())
.getABI()
.IsN64()
diff --git a/lib/Target/Mips/MipsOptimizePICCall.cpp b/lib/Target/Mips/MipsOptimizePICCall.cpp
index 79c8395d9dcc..a9ca31a6d09f 100644
--- a/lib/Target/Mips/MipsOptimizePICCall.cpp
+++ b/lib/Target/Mips/MipsOptimizePICCall.cpp
@@ -1,4 +1,4 @@
-//===--------- MipsOptimizePICCall.cpp - Optimize PIC Calls ---------------===//
+//===- MipsOptimizePICCall.cpp - Optimize PIC Calls -----------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,12 +14,31 @@
#include "MCTargetDesc/MipsBaseInfo.h"
#include "Mips.h"
-#include "MipsMachineFunction.h"
-#include "MipsTargetMachine.h"
+#include "MipsRegisterInfo.h"
+#include "MipsSubtarget.h"
+#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/ScopedHashTable.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/MachineValueType.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetOpcodes.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/RecyclingAllocator.h"
+#include <cassert>
+#include <utility>
+#include <vector>
using namespace llvm;
@@ -35,18 +54,18 @@ static cl::opt<bool> EraseGPOpnd("mips-erase-gp-opnd",
cl::Hidden);
namespace {
-typedef PointerUnion<const Value *, const PseudoSourceValue *> ValueType;
-typedef std::pair<unsigned, unsigned> CntRegP;
-typedef RecyclingAllocator<BumpPtrAllocator,
- ScopedHashTableVal<ValueType, CntRegP> >
-AllocatorTy;
-typedef ScopedHashTable<ValueType, CntRegP, DenseMapInfo<ValueType>,
- AllocatorTy> ScopedHTType;
+using ValueType = PointerUnion<const Value *, const PseudoSourceValue *>;
+using CntRegP = std::pair<unsigned, unsigned>;
+using AllocatorTy = RecyclingAllocator<BumpPtrAllocator,
+ ScopedHashTableVal<ValueType, CntRegP>>;
+using ScopedHTType = ScopedHashTable<ValueType, CntRegP,
+ DenseMapInfo<ValueType>, AllocatorTy>;
class MBBInfo {
public:
MBBInfo(MachineDomTreeNode *N);
+
const MachineDomTreeNode *getNode() const;
bool isVisited() const;
void preVisit(ScopedHTType &ScopedHT);
@@ -94,12 +113,14 @@ private:
void incCntAndSetReg(ValueType Entry, unsigned Reg);
ScopedHTType ScopedHT;
+
static char ID;
};
-char OptimizePICCall::ID = 0;
} // end of anonymous namespace
+char OptimizePICCall::ID = 0;
+
/// Return the first MachineOperand of MI if it is a used virtual register.
static MachineOperand *getCallTargetRegOpnd(MachineInstr &MI) {
if (MI.getNumOperands() == 0)
diff --git a/lib/Target/Mips/MipsRegisterInfo.cpp b/lib/Target/Mips/MipsRegisterInfo.cpp
index de3389b5a6bf..0e0d82270c89 100644
--- a/lib/Target/Mips/MipsRegisterInfo.cpp
+++ b/lib/Target/Mips/MipsRegisterInfo.cpp
@@ -1,4 +1,4 @@
-//===-- MipsRegisterInfo.cpp - MIPS Register Information -== --------------===//
+//===- MipsRegisterInfo.cpp - MIPS Register Information -------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,8 +12,8 @@
//===----------------------------------------------------------------------===//
#include "MipsRegisterInfo.h"
+#include "MCTargetDesc/MipsABIInfo.h"
#include "Mips.h"
-#include "MipsInstrInfo.h"
#include "MipsMachineFunction.h"
#include "MipsSubtarget.h"
#include "MipsTargetMachine.h"
@@ -21,19 +21,17 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/DebugInfo.h"
+#include "llvm/CodeGen/TargetFrameLowering.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/Function.h"
-#include "llvm/IR/Type.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetFrameLowering.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetOptions.h"
+#include <cstdint>
using namespace llvm;
@@ -56,11 +54,10 @@ MipsRegisterInfo::getPointerRegClass(const MachineFunction &MF,
case MipsPtrClass::Default:
return ABI.ArePtrs64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
case MipsPtrClass::GPR16MM:
- return ABI.ArePtrs64bit() ? &Mips::GPRMM16_64RegClass
- : &Mips::GPRMM16RegClass;
+ return &Mips::GPRMM16RegClass;
case MipsPtrClass::StackPointer:
return ABI.ArePtrs64bit() ? &Mips::SP64RegClass : &Mips::SP32RegClass;
- case MipsPtrClass::GlobalPointer:
+ case MipsPtrClass::GlobalPointer:
return ABI.ArePtrs64bit() ? &Mips::GP64RegClass : &Mips::GP32RegClass;
}
@@ -96,8 +93,8 @@ MipsRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
const MCPhysReg *
MipsRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
const MipsSubtarget &Subtarget = MF->getSubtarget<MipsSubtarget>();
- const Function *F = MF->getFunction();
- if (F->hasFnAttribute("interrupt")) {
+ const Function &F = MF->getFunction();
+ if (F.hasFnAttribute("interrupt")) {
if (Subtarget.hasMips64())
return Subtarget.hasMips64r6() ? CSR_Interrupt_64R6_SaveList
: CSR_Interrupt_64_SaveList;
@@ -162,7 +159,8 @@ getReservedRegs(const MachineFunction &MF) const {
BitVector Reserved(getNumRegs());
const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
- typedef TargetRegisterClass::const_iterator RegIter;
+
+ using RegIter = TargetRegisterClass::const_iterator;
for (unsigned I = 0; I < array_lengthof(ReservedGPR32); ++I)
Reserved.set(ReservedGPR32[I]);
@@ -240,7 +238,7 @@ getReservedRegs(const MachineFunction &MF) const {
Reserved.set(Mips::RA_64);
Reserved.set(Mips::T0);
Reserved.set(Mips::T1);
- if (MF.getFunction()->hasFnAttribute("saveS2") || MipsFI->hasSaveS2())
+ if (MF.getFunction().hasFnAttribute("saveS2") || MipsFI->hasSaveS2())
Reserved.set(Mips::S2);
}
diff --git a/lib/Target/Mips/MipsRegisterInfo.h b/lib/Target/Mips/MipsRegisterInfo.h
index 32f835e83108..fe8d7953ec8f 100644
--- a/lib/Target/Mips/MipsRegisterInfo.h
+++ b/lib/Target/Mips/MipsRegisterInfo.h
@@ -1,4 +1,4 @@
-//===-- MipsRegisterInfo.h - Mips Register Information Impl -----*- C++ -*-===//
+//===- MipsRegisterInfo.h - Mips Register Information Impl ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,12 +15,16 @@
#define LLVM_LIB_TARGET_MIPS_MIPSREGISTERINFO_H
#include "Mips.h"
-#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include <cstdint>
#define GET_REGINFO_HEADER
#include "MipsGenRegisterInfo.inc"
namespace llvm {
+
+class TargetRegisterClass;
+
class MipsRegisterInfo : public MipsGenRegisterInfo {
public:
enum class MipsPtrClass {
@@ -79,4 +83,4 @@ private:
} // end namespace llvm
-#endif
+#endif // LLVM_LIB_TARGET_MIPS_MIPSREGISTERINFO_H
diff --git a/lib/Target/Mips/MipsRegisterInfo.td b/lib/Target/Mips/MipsRegisterInfo.td
index 08fb3d7d4352..50537bed8ff0 100644
--- a/lib/Target/Mips/MipsRegisterInfo.td
+++ b/lib/Target/Mips/MipsRegisterInfo.td
@@ -349,12 +349,6 @@ def GPR64 : RegisterClass<"Mips", [i64], 64, (add
// Reserved
K0_64, K1_64, GP_64, SP_64, FP_64, RA_64)>;
-def GPRMM16_64 : RegisterClass<"Mips", [i64], 64, (add
- // Callee save
- S0_64, S1_64,
- // Return Values and Arguments
- V0_64, V1_64, A0_64, A1_64, A2_64, A3_64)>;
-
def CPU16Regs : RegisterClass<"Mips", [i32], 32, (add
// Return Values and Arguments
V0, V1, A0, A1, A2, A3,
@@ -616,6 +610,7 @@ def GPRMM16OpndZero : RegisterOperand<GPRMM16Zero> {
def GPRMM16OpndMoveP : RegisterOperand<GPRMM16MoveP> {
let ParserMatchClass = GPRMM16AsmOperandMoveP;
+ let EncoderMethod = "getMovePRegSingleOpValue";
}
def GPR64Opnd : RegisterOperand<GPR64> {
diff --git a/lib/Target/Mips/MipsSEFrameLowering.cpp b/lib/Target/Mips/MipsSEFrameLowering.cpp
index 735461c2a797..eb1eea7925c0 100644
--- a/lib/Target/Mips/MipsSEFrameLowering.cpp
+++ b/lib/Target/Mips/MipsSEFrameLowering.cpp
@@ -1,4 +1,4 @@
-//===-- MipsSEFrameLowering.cpp - Mips32/64 Frame Information -------------===//
+//===- MipsSEFrameLowering.cpp - Mips32/64 Frame Information --------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -29,6 +29,9 @@
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Function.h"
#include "llvm/MC/MCDwarf.h"
@@ -37,9 +40,6 @@
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
#include <cassert>
#include <cstdint>
#include <utility>
@@ -71,7 +71,7 @@ public:
bool expand();
private:
- typedef MachineBasicBlock::iterator Iter;
+ using Iter = MachineBasicBlock::iterator;
bool expandInstr(MachineBasicBlock &MBB, Iter I);
void expandLoadCCond(MachineBasicBlock &MBB, Iter I);
@@ -390,7 +390,7 @@ bool ExpandPseudo::expandExtractElementF64(MachineBasicBlock &MBB,
}
MipsSEFrameLowering::MipsSEFrameLowering(const MipsSubtarget &STI)
- : MipsFrameLowering(STI, STI.stackAlignment()) {}
+ : MipsFrameLowering(STI, STI.getStackAlignment()) {}
void MipsSEFrameLowering::emitPrologue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
@@ -424,7 +424,6 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF,
MachineModuleInfo &MMI = MF.getMMI();
const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
- MachineLocation DstML, SrcML;
// Adjust stack.
TII.adjustStackPtr(SP, -StackSize, MBB, MBBI);
@@ -435,7 +434,7 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF,
BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
.addCFIIndex(CFIIndex);
- if (MF.getFunction()->hasFnAttribute("interrupt"))
+ if (MF.getFunction().hasFnAttribute("interrupt"))
emitInterruptPrologueStub(MF, MBB);
const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
@@ -583,7 +582,7 @@ void MipsSEFrameLowering::emitInterruptPrologueStub(
// Perform ISR handling like GCC
StringRef IntKind =
- MF.getFunction()->getFnAttribute("interrupt").getValueAsString();
+ MF.getFunction().getFnAttribute("interrupt").getValueAsString();
const TargetRegisterClass *PtrRC = &Mips::GPR32RegClass;
// EIC interrupt handling needs to read the Cause register to disable
@@ -727,7 +726,7 @@ void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF,
}
}
- if (MF.getFunction()->hasFnAttribute("interrupt"))
+ if (MF.getFunction().hasFnAttribute("interrupt"))
emitInterruptEpilogueStub(MF, MBB);
// Get the number of bytes from FrameInfo
@@ -810,8 +809,8 @@ spillCalleeSavedRegisters(MachineBasicBlock &MBB,
// spilled to the stack frame.
bool IsLOHI = (Reg == Mips::LO0 || Reg == Mips::LO0_64 ||
Reg == Mips::HI0 || Reg == Mips::HI0_64);
- const Function *Func = MBB.getParent()->getFunction();
- if (IsLOHI && Func->hasFnAttribute("interrupt")) {
+ const Function &Func = MBB.getParent()->getFunction();
+ if (IsLOHI && Func.hasFnAttribute("interrupt")) {
DebugLoc DL = MI->getDebugLoc();
unsigned Op = 0;
diff --git a/lib/Target/Mips/MipsSEFrameLowering.h b/lib/Target/Mips/MipsSEFrameLowering.h
index bf30deb1905e..de8e6eed31d7 100644
--- a/lib/Target/Mips/MipsSEFrameLowering.h
+++ b/lib/Target/Mips/MipsSEFrameLowering.h
@@ -6,20 +6,19 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-//
-//
-//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_MIPS_MIPSSEFRAMELOWERING_H
#define LLVM_LIB_TARGET_MIPS_MIPSSEFRAMELOWERING_H
#include "MipsFrameLowering.h"
-#include "llvm/CodeGen/MachineBasicBlock.h"
#include <vector>
namespace llvm {
+class MachineBasicBlock;
+class MachineFunction;
+class MipsSubtarget;
+
class MipsSEFrameLowering : public MipsFrameLowering {
public:
explicit MipsSEFrameLowering(const MipsSubtarget &STI);
diff --git a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
index 4be26dd25dc0..893cae93e58f 100644
--- a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
+++ b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
@@ -161,7 +161,7 @@ void MipsSEDAGToDAGISel::initGlobalBaseReg(MachineFunction &MF) {
// lui $v0, %hi(%neg(%gp_rel(fname)))
// daddu $v1, $v0, $t9
// daddiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
- const GlobalValue *FName = MF.getFunction();
+ const GlobalValue *FName = &MF.getFunction();
BuildMI(MBB, I, DL, TII.get(Mips::LUi64), V0)
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
BuildMI(MBB, I, DL, TII.get(Mips::DADDu), V1).addReg(V0)
@@ -190,7 +190,7 @@ void MipsSEDAGToDAGISel::initGlobalBaseReg(MachineFunction &MF) {
// lui $v0, %hi(%neg(%gp_rel(fname)))
// addu $v1, $v0, $t9
// addiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
- const GlobalValue *FName = MF.getFunction();
+ const GlobalValue *FName = &MF.getFunction();
BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
BuildMI(MBB, I, DL, TII.get(Mips::ADDu), V1).addReg(V0).addReg(Mips::T9);
@@ -905,6 +905,64 @@ bool MipsSEDAGToDAGISel::trySelect(SDNode *Node) {
break;
}
+ // Manually match MipsISD::Ins nodes to get the correct instruction. It has
+ // to be done in this fashion so that we respect the differences between
+ // dins and dinsm, as the difference is that the size operand has the range
+ // 0 < size <= 32 for dins while dinsm has the range 2 <= size <= 64 which
+ // means SelectionDAGISel would have to test all the operands at once to
+ // match the instruction.
+ case MipsISD::Ins: {
+
+ // Sanity checking for the node operands.
+ if (Node->getValueType(0) != MVT::i32 && Node->getValueType(0) != MVT::i64)
+ return false;
+
+ if (Node->getNumOperands() != 4)
+ return false;
+
+ if (Node->getOperand(1)->getOpcode() != ISD::Constant ||
+ Node->getOperand(2)->getOpcode() != ISD::Constant)
+ return false;
+
+ MVT ResTy = Node->getSimpleValueType(0);
+ uint64_t Pos = Node->getConstantOperandVal(1);
+ uint64_t Size = Node->getConstantOperandVal(2);
+
+ // Size has to be >0 for 'ins', 'dins' and 'dinsu'.
+ if (!Size)
+ return false;
+
+ if (Pos + Size > 64)
+ return false;
+
+ if (ResTy != MVT::i32 && ResTy != MVT::i64)
+ return false;
+
+ unsigned Opcode = 0;
+ if (ResTy == MVT::i32) {
+ if (Pos + Size <= 32)
+ Opcode = Mips::INS;
+ } else {
+ if (Pos + Size <= 32)
+ Opcode = Mips::DINS;
+ else if (Pos < 32 && 1 < Size)
+ Opcode = Mips::DINSM;
+ else
+ Opcode = Mips::DINSU;
+ }
+
+ if (Opcode) {
+ SDValue Ops[4] = {
+ Node->getOperand(0), CurDAG->getTargetConstant(Pos, DL, MVT::i32),
+ CurDAG->getTargetConstant(Size, DL, MVT::i32), Node->getOperand(3)};
+
+ ReplaceNode(Node, CurDAG->getMachineNode(Opcode, DL, ResTy, Ops));
+ return true;
+ }
+
+ return false;
+ }
+
case MipsISD::ThreadPointer: {
EVT PtrVT = getTargetLowering()->getPointerTy(CurDAG->getDataLayout());
unsigned RdhwrOpc, DestReg;
@@ -1188,9 +1246,12 @@ bool MipsSEDAGToDAGISel::trySelect(SDNode *Node) {
// The obvious "missing" case is when both are zero, but that case is
// handled by the ldi case.
if (ResNonZero) {
+ IntegerType *Int32Ty =
+ IntegerType::get(MF->getFunction().getContext(), 32);
+ const ConstantInt *Const32 = ConstantInt::get(Int32Ty, 32);
SDValue Ops[4] = {HiResNonZero ? SDValue(HiRes, 0) : Zero64Val,
- CurDAG->getTargetConstant(64, DL, MVT::i32),
- CurDAG->getTargetConstant(32, DL, MVT::i32),
+ CurDAG->getConstant(*Const32, DL, MVT::i32),
+ CurDAG->getConstant(*Const32, DL, MVT::i32),
SDValue(Res, 0)};
Res = CurDAG->getMachineNode(Mips::DINSU, DL, MVT::i64, Ops);
diff --git a/lib/Target/Mips/MipsSEISelLowering.cpp b/lib/Target/Mips/MipsSEISelLowering.cpp
index 72b2738bfac4..f7d7e2af85e4 100644
--- a/lib/Target/Mips/MipsSEISelLowering.cpp
+++ b/lib/Target/Mips/MipsSEISelLowering.cpp
@@ -1,4 +1,4 @@
-//===-- MipsSEISelLowering.cpp - MipsSE DAG Lowering Interface --*- C++ -*-===//
+//===- MipsSEISelLowering.cpp - MipsSE DAG Lowering Interface -------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,19 +10,43 @@
// Subclass of MipsTargetLowering specialized for mips32/64.
//
//===----------------------------------------------------------------------===//
+
#include "MipsSEISelLowering.h"
#include "MipsMachineFunction.h"
#include "MipsRegisterInfo.h"
-#include "MipsTargetMachine.h"
+#include "MipsSubtarget.h"
#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/CodeGen/CallingConvLower.h"
+#include "llvm/CodeGen/ISDOpcodes.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/MachineValueType.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Intrinsics.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetInstrInfo.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <iterator>
+#include <utility>
using namespace llvm;
@@ -220,7 +244,7 @@ MipsSETargetLowering::MipsSETargetLowering(const MipsTargetMachine &TM,
assert(Subtarget.isFP64bit() && "FR=1 is required for MIPS32r6");
setOperationAction(ISD::SETCC, MVT::f64, Legal);
- setOperationAction(ISD::SELECT, MVT::f64, Legal);
+ setOperationAction(ISD::SELECT, MVT::f64, Custom);
setOperationAction(ISD::SELECT_CC, MVT::f64, Expand);
setOperationAction(ISD::BRCOND, MVT::Other, Legal);
@@ -367,6 +391,21 @@ addMSAFloatType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) {
}
}
+SDValue MipsSETargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
+ if(!Subtarget.hasMips32r6())
+ return MipsTargetLowering::LowerOperation(Op, DAG);
+
+ EVT ResTy = Op->getValueType(0);
+ SDLoc DL(Op);
+
+ // Although MTC1_D64 takes an i32 and writes an f64, the upper 32 bits of the
+ // floating point register are undefined. Not really an issue as sel.d, which
+ // is produced from an FSELECT node, only looks at bit 0.
+ SDValue Tmp = DAG.getNode(MipsISD::MTC1_D64, DL, MVT::f64, Op->getOperand(0));
+ return DAG.getNode(MipsISD::FSELECT, DL, ResTy, Tmp, Op->getOperand(1),
+ Op->getOperand(2));
+}
+
bool
MipsSETargetLowering::allowsMisalignedMemoryAccesses(EVT VT,
unsigned,
@@ -414,6 +453,7 @@ SDValue MipsSETargetLowering::LowerOperation(SDValue Op,
case ISD::EXTRACT_VECTOR_ELT: return lowerEXTRACT_VECTOR_ELT(Op, DAG);
case ISD::BUILD_VECTOR: return lowerBUILD_VECTOR(Op, DAG);
case ISD::VECTOR_SHUFFLE: return lowerVECTOR_SHUFFLE(Op, DAG);
+ case ISD::SELECT: return lowerSELECT(Op, DAG);
}
return MipsTargetLowering::LowerOperation(Op, DAG);
@@ -661,11 +701,8 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
return SDValue();
}
-static SDValue genConstMult(SDValue X, uint64_t C, const SDLoc &DL, EVT VT,
+static SDValue genConstMult(SDValue X, APInt C, const SDLoc &DL, EVT VT,
EVT ShiftTy, SelectionDAG &DAG) {
- // Clear the upper (64 - VT.sizeInBits) bits.
- C &= ((uint64_t)-1) >> (64 - VT.getSizeInBits());
-
// Return 0.
if (C == 0)
return DAG.getConstant(0, DL, VT);
@@ -675,18 +712,19 @@ static SDValue genConstMult(SDValue X, uint64_t C, const SDLoc &DL, EVT VT,
return X;
// If c is power of 2, return (shl x, log2(c)).
- if (isPowerOf2_64(C))
+ if (C.isPowerOf2())
return DAG.getNode(ISD::SHL, DL, VT, X,
- DAG.getConstant(Log2_64(C), DL, ShiftTy));
+ DAG.getConstant(C.logBase2(), DL, ShiftTy));
- unsigned Log2Ceil = Log2_64_Ceil(C);
- uint64_t Floor = 1LL << Log2_64(C);
- uint64_t Ceil = Log2Ceil == 64 ? 0LL : 1LL << Log2Ceil;
+ unsigned BitWidth = C.getBitWidth();
+ APInt Floor = APInt(BitWidth, 1) << C.logBase2();
+ APInt Ceil = C.isNegative() ? APInt(BitWidth, 0) :
+ APInt(BitWidth, 1) << C.ceilLogBase2();
// If |c - floor_c| <= |c - ceil_c|,
// where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))),
// return (add constMult(x, floor_c), constMult(x, c - floor_c)).
- if (C - Floor <= Ceil - C) {
+ if ((C - Floor).ule(Ceil - C)) {
SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG);
SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG);
return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1);
@@ -706,7 +744,7 @@ static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG,
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
if (!VT.isVector())
- return genConstMult(N->getOperand(0), C->getZExtValue(), SDLoc(N), VT,
+ return genConstMult(N->getOperand(0), C->getAPIntValue(), SDLoc(N), VT,
TL->getScalarShiftAmountTy(DAG.getDataLayout(), VT),
DAG);
@@ -1073,7 +1111,7 @@ bool MipsSETargetLowering::isEligibleForTailCallOptimization(
void MipsSETargetLowering::
getOpndList(SmallVectorImpl<SDValue> &Ops,
- std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
+ std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
SDValue Chain) const {
@@ -1689,11 +1727,10 @@ SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
return DAG.getNode(ISD::UDIV, DL, Op->getValueType(0), Op->getOperand(1),
Op->getOperand(2));
case Intrinsic::mips_fadd_w:
- case Intrinsic::mips_fadd_d: {
+ case Intrinsic::mips_fadd_d:
// TODO: If intrinsics have fast-math-flags, propagate them.
return DAG.getNode(ISD::FADD, DL, Op->getValueType(0), Op->getOperand(1),
Op->getOperand(2));
- }
// Don't lower mips_fcaf_[wd] since LLVM folds SETFALSE condcodes away
case Intrinsic::mips_fceq_w:
case Intrinsic::mips_fceq_d:
@@ -1736,11 +1773,10 @@ SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
Op->getOperand(2), ISD::SETUNE);
case Intrinsic::mips_fdiv_w:
- case Intrinsic::mips_fdiv_d: {
+ case Intrinsic::mips_fdiv_d:
// TODO: If intrinsics have fast-math-flags, propagate them.
return DAG.getNode(ISD::FDIV, DL, Op->getValueType(0), Op->getOperand(1),
Op->getOperand(2));
- }
case Intrinsic::mips_ffint_u_w:
case Intrinsic::mips_ffint_u_d:
return DAG.getNode(ISD::UINT_TO_FP, DL, Op->getValueType(0),
@@ -1777,11 +1813,10 @@ SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
return DAG.getNode(ISD::FMA, SDLoc(Op), Op->getValueType(0),
Op->getOperand(1), Op->getOperand(2), Op->getOperand(3));
case Intrinsic::mips_fmul_w:
- case Intrinsic::mips_fmul_d: {
+ case Intrinsic::mips_fmul_d:
// TODO: If intrinsics have fast-math-flags, propagate them.
return DAG.getNode(ISD::FMUL, DL, Op->getValueType(0), Op->getOperand(1),
Op->getOperand(2));
- }
case Intrinsic::mips_fmsub_w:
case Intrinsic::mips_fmsub_d: {
// TODO: If intrinsics have fast-math-flags, propagate them.
@@ -1797,11 +1832,10 @@ SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
case Intrinsic::mips_fsqrt_d:
return DAG.getNode(ISD::FSQRT, DL, Op->getValueType(0), Op->getOperand(1));
case Intrinsic::mips_fsub_w:
- case Intrinsic::mips_fsub_d: {
+ case Intrinsic::mips_fsub_d:
// TODO: If intrinsics have fast-math-flags, propagate them.
return DAG.getNode(ISD::FSUB, DL, Op->getValueType(0), Op->getOperand(1),
Op->getOperand(2));
- }
case Intrinsic::mips_ftrunc_u_w:
case Intrinsic::mips_ftrunc_u_d:
return DAG.getNode(ISD::FP_TO_UINT, DL, Op->getValueType(0),
@@ -3455,7 +3489,6 @@ MipsSETargetLowering::emitST_F16_PSEUDO(MachineInstr &MI,
// memory it's not supposed to.
// b) The load crosses an implementation specific boundary, requiring OS
// intervention.
-//
MachineBasicBlock *
MipsSETargetLowering::emitLD_F16_PSEUDO(MachineInstr &MI,
MachineBasicBlock *BB) const {
@@ -3542,7 +3575,6 @@ MipsSETargetLowering::emitLD_F16_PSEUDO(MachineInstr &MI,
// insert.w for one element, we avoid that potiential case. If
// fexdo.[hw] causes an exception in, the exception is valid and it
// occurs for all elements.
-//
MachineBasicBlock *
MipsSETargetLowering::emitFPROUND_PSEUDO(MachineInstr &MI,
MachineBasicBlock *BB,
@@ -3648,7 +3680,6 @@ MipsSETargetLowering::emitFPROUND_PSEUDO(MachineInstr &MI,
// mtc1 $rtemp, $ftemp
// copy_s.w $rtemp2, $wtemp2[1]
// $fd = mthc1 $rtemp2, $ftemp
-//
MachineBasicBlock *
MipsSETargetLowering::emitFPEXTEND_PSEUDO(MachineInstr &MI,
MachineBasicBlock *BB,
diff --git a/lib/Target/Mips/MipsSEISelLowering.h b/lib/Target/Mips/MipsSEISelLowering.h
index 0abb9b318bda..5976ecbcfc61 100644
--- a/lib/Target/Mips/MipsSEISelLowering.h
+++ b/lib/Target/Mips/MipsSEISelLowering.h
@@ -1,4 +1,4 @@
-//===-- MipsSEISelLowering.h - MipsSE DAG Lowering Interface ----*- C++ -*-===//
+//===- MipsSEISelLowering.h - MipsSE DAG Lowering Interface -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,9 +15,18 @@
#define LLVM_LIB_TARGET_MIPS_MIPSSEISELLOWERING_H
#include "MipsISelLowering.h"
-#include "MipsRegisterInfo.h"
+#include "llvm/CodeGen/MachineValueType.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
namespace llvm {
+
+class MachineBasicBlock;
+class MachineInstr;
+class MipsSubtarget;
+class MipsTargetMachine;
+class SelectionDAG;
+class TargetRegisterClass;
+
class MipsSETargetLowering : public MipsTargetLowering {
public:
explicit MipsSETargetLowering(const MipsTargetMachine &TM,
@@ -26,6 +35,7 @@ namespace llvm {
/// \brief Enable MSA support for the given integer type and Register
/// class.
void addMSAIntType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC);
+
/// \brief Enable MSA support for the given floating-point type and
/// Register class.
void addMSAFloatType(MVT::SimpleValueType Ty,
@@ -43,8 +53,7 @@ namespace llvm {
EmitInstrWithCustomInserter(MachineInstr &MI,
MachineBasicBlock *MBB) const override;
- bool isShuffleMaskLegal(const SmallVectorImpl<int> &Mask,
- EVT VT) const override {
+ bool isShuffleMaskLegal(ArrayRef<int> Mask, EVT VT) const override {
return false;
}
@@ -57,7 +66,7 @@ namespace llvm {
void
getOpndList(SmallVectorImpl<SDValue> &Ops,
- std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
+ std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
SDValue Chain) const override;
@@ -76,6 +85,7 @@ namespace llvm {
/// \brief Lower VECTOR_SHUFFLE into one of a number of instructions
/// depending on the indices in the shuffle.
SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
+ SDValue lowerSELECT(SDValue Op, SelectionDAG &DAG) const;
MachineBasicBlock *emitBPOSGE32(MachineInstr &MI,
MachineBasicBlock *BB) const;
@@ -126,6 +136,7 @@ namespace llvm {
MachineBasicBlock *BBi,
bool IsFGR64) const;
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_LIB_TARGET_MIPS_MIPSSEISELLOWERING_H
diff --git a/lib/Target/Mips/MipsSEInstrInfo.cpp b/lib/Target/Mips/MipsSEInstrInfo.cpp
index d2c21691abb0..59b7679971cd 100644
--- a/lib/Target/Mips/MipsSEInstrInfo.cpp
+++ b/lib/Target/Mips/MipsSEInstrInfo.cpp
@@ -231,8 +231,8 @@ storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
// Hi, Lo are normally caller save but they are callee save
// for interrupt handling.
- const Function *Func = MBB.getParent()->getFunction();
- if (Func->hasFnAttribute("interrupt")) {
+ const Function &Func = MBB.getParent()->getFunction();
+ if (Func.hasFnAttribute("interrupt")) {
if (Mips::HI32RegClass.hasSubClassEq(RC)) {
BuildMI(MBB, I, DL, get(Mips::MFHI), Mips::K0);
SrcReg = Mips::K0;
@@ -262,8 +262,8 @@ loadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad);
unsigned Opc = 0;
- const Function *Func = MBB.getParent()->getFunction();
- bool ReqIndirectLoad = Func->hasFnAttribute("interrupt") &&
+ const Function &Func = MBB.getParent()->getFunction();
+ bool ReqIndirectLoad = Func.hasFnAttribute("interrupt") &&
(DestReg == Mips::LO0 || DestReg == Mips::LO0_64 ||
DestReg == Mips::HI0 || DestReg == Mips::HI0_64);
@@ -455,6 +455,10 @@ unsigned MipsSEInstrInfo::getOppositeBranchOpc(unsigned Opc) const {
case Mips::BGEZC64: return Mips::BLTZC64;
case Mips::BLTZC64: return Mips::BGEZC64;
case Mips::BLEZC64: return Mips::BGTZC64;
+ case Mips::BBIT0: return Mips::BBIT1;
+ case Mips::BBIT1: return Mips::BBIT0;
+ case Mips::BBIT032: return Mips::BBIT132;
+ case Mips::BBIT132: return Mips::BBIT032;
}
}
@@ -536,16 +540,18 @@ unsigned MipsSEInstrInfo::getAnalyzableBrOpc(unsigned Opc) const {
Opc == Mips::BNE64 || Opc == Mips::BGTZ64 || Opc == Mips::BGEZ64 ||
Opc == Mips::BLTZ64 || Opc == Mips::BLEZ64 || Opc == Mips::BC1T ||
Opc == Mips::BC1F || Opc == Mips::B || Opc == Mips::J ||
- Opc == Mips::BEQZC_MM || Opc == Mips::BNEZC_MM || Opc == Mips::BEQC ||
- Opc == Mips::BNEC || Opc == Mips::BLTC || Opc == Mips::BGEC ||
- Opc == Mips::BLTUC || Opc == Mips::BGEUC || Opc == Mips::BGTZC ||
- Opc == Mips::BLEZC || Opc == Mips::BGEZC || Opc == Mips::BLTZC ||
- Opc == Mips::BEQZC || Opc == Mips::BNEZC || Opc == Mips::BEQZC64 ||
- Opc == Mips::BNEZC64 || Opc == Mips::BEQC64 || Opc == Mips::BNEC64 ||
- Opc == Mips::BGEC64 || Opc == Mips::BGEUC64 || Opc == Mips::BLTC64 ||
- Opc == Mips::BLTUC64 || Opc == Mips::BGTZC64 ||
- Opc == Mips::BGEZC64 || Opc == Mips::BLTZC64 ||
- Opc == Mips::BLEZC64 || Opc == Mips::BC) ? Opc : 0;
+ Opc == Mips::B_MM || Opc == Mips::BEQZC_MM ||
+ Opc == Mips::BNEZC_MM || Opc == Mips::BEQC || Opc == Mips::BNEC ||
+ Opc == Mips::BLTC || Opc == Mips::BGEC || Opc == Mips::BLTUC ||
+ Opc == Mips::BGEUC || Opc == Mips::BGTZC || Opc == Mips::BLEZC ||
+ Opc == Mips::BGEZC || Opc == Mips::BLTZC || Opc == Mips::BEQZC ||
+ Opc == Mips::BNEZC || Opc == Mips::BEQZC64 || Opc == Mips::BNEZC64 ||
+ Opc == Mips::BEQC64 || Opc == Mips::BNEC64 || Opc == Mips::BGEC64 ||
+ Opc == Mips::BGEUC64 || Opc == Mips::BLTC64 || Opc == Mips::BLTUC64 ||
+ Opc == Mips::BGTZC64 || Opc == Mips::BGEZC64 ||
+ Opc == Mips::BLTZC64 || Opc == Mips::BLEZC64 || Opc == Mips::BC ||
+ Opc == Mips::BBIT0 || Opc == Mips::BBIT1 || Opc == Mips::BBIT032 ||
+ Opc == Mips::BBIT132) ? Opc : 0;
}
void MipsSEInstrInfo::expandRetRA(MachineBasicBlock &MBB,
diff --git a/lib/Target/Mips/MipsSERegisterInfo.cpp b/lib/Target/Mips/MipsSERegisterInfo.cpp
index 86bd24166bb6..2ff6b99e78ff 100644
--- a/lib/Target/Mips/MipsSERegisterInfo.cpp
+++ b/lib/Target/Mips/MipsSERegisterInfo.cpp
@@ -23,6 +23,8 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/TargetFrameLowering.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/Function.h"
@@ -30,8 +32,6 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetFrameLowering.h"
-#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
diff --git a/lib/Target/Mips/MipsScheduleGeneric.td b/lib/Target/Mips/MipsScheduleGeneric.td
index e4c52a4e1825..744392c320ef 100644
--- a/lib/Target/Mips/MipsScheduleGeneric.td
+++ b/lib/Target/Mips/MipsScheduleGeneric.td
@@ -738,6 +738,7 @@ def : InstRW<[GenericDSPShort], (instregex "^MFHI_DSP_MM$")>;
def : InstRW<[GenericDSPShort], (instregex "^MFLO_DSP_MM$")>;
def : InstRW<[GenericDSPShort], (instregex "^MODSUB_MM$")>;
def : InstRW<[GenericDSPShort], (instregex "^MOVEP_MM$")>;
+def : InstRW<[GenericDSPShort], (instregex "^MOVEP_MMR6$")>;
def : InstRW<[GenericDSPShort], (instregex "^MOVN_I_MM$")>;
def : InstRW<[GenericDSPShort], (instregex "^MOVZ_I_MM$")>;
def : InstRW<[GenericDSPShort], (instregex "^MSUBU_DSP_MM$")>;
diff --git a/lib/Target/Mips/MipsScheduleP5600.td b/lib/Target/Mips/MipsScheduleP5600.td
index fedfac24e4e7..440f93d5b7eb 100644
--- a/lib/Target/Mips/MipsScheduleP5600.td
+++ b/lib/Target/Mips/MipsScheduleP5600.td
@@ -18,8 +18,8 @@ def MipsP5600Model : SchedMachineModel {
list<Predicate> UnsupportedFeatures = [HasMips32r6, HasMips64r6,
HasMips64, HasMips64r2, HasCnMips,
InMicroMips, InMips16Mode,
- HasMicroMips32r6, HasMicroMips64r6,
- HasDSP, HasDSPR2, HasMT];
+ HasMicroMips32r6, HasDSP,
+ HasDSPR2, HasMT];
}
diff --git a/lib/Target/Mips/MipsSubtarget.cpp b/lib/Target/Mips/MipsSubtarget.cpp
index eba21e0a1c67..f6af7e22e351 100644
--- a/lib/Target/Mips/MipsSubtarget.cpp
+++ b/lib/Target/Mips/MipsSubtarget.cpp
@@ -57,10 +57,11 @@ static cl::opt<bool>
GPOpt("mgpopt", cl::Hidden,
cl::desc("Enable gp-relative addressing of mips small data items"));
-void MipsSubtarget::anchor() { }
+void MipsSubtarget::anchor() {}
MipsSubtarget::MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
- bool little, const MipsTargetMachine &TM)
+ bool little, const MipsTargetMachine &TM,
+ unsigned StackAlignOverride)
: MipsGenSubtargetInfo(TT, CPU, FS), MipsArchVersion(MipsDefault),
IsLittle(little), IsSoftFloat(false), IsSingleFloat(false), IsFPXX(false),
NoABICalls(false), IsFP64bit(false), UseOddSPReg(true),
@@ -70,10 +71,10 @@ MipsSubtarget::MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
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), TM(TM),
- TargetTriple(TT), TSInfo(),
- InstrInfo(
- MipsInstrInfo::create(initializeSubtargetDependencies(CPU, FS, TM))),
+ HasEVA(false), DisableMadd4(false), HasMT(false),
+ StackAlignOverride(StackAlignOverride), TM(TM), TargetTriple(TT),
+ TSInfo(), InstrInfo(MipsInstrInfo::create(
+ initializeSubtargetDependencies(CPU, FS, TM))),
FrameLowering(MipsFrameLowering::create(*this)),
TLInfo(MipsTargetLowering::create(TM, *this)) {
@@ -103,6 +104,9 @@ MipsSubtarget::MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
if (IsFPXX && (isABI_N32() || isABI_N64()))
report_fatal_error("FPXX is not permitted for the N32/N64 ABI's.", false);
+ if (hasMips64r6() && InMicroMipsMode)
+ report_fatal_error("microMIPS64R6 is not supported", false);
+
if (hasMips32r6()) {
StringRef ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
@@ -136,8 +140,8 @@ bool MipsSubtarget::enablePostRAScheduler() const { return true; }
void MipsSubtarget::getCriticalPathRCs(RegClassVector &CriticalPathRCs) const {
CriticalPathRCs.clear();
- CriticalPathRCs.push_back(isGP64bit() ?
- &Mips::GPR64RegClass : &Mips::GPR32RegClass);
+ CriticalPathRCs.push_back(isGP64bit() ? &Mips::GPR64RegClass
+ : &Mips::GPR32RegClass);
}
CodeGenOpt::Level MipsSubtarget::getOptLevelToEnablePostRAScheduler() const {
@@ -157,6 +161,15 @@ MipsSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS,
if (InMips16Mode && !IsSoftFloat)
InMips16HardFloat = true;
+ if (StackAlignOverride)
+ stackAlignment = StackAlignOverride;
+ else if (isABI_N32() || isABI_N64())
+ stackAlignment = 16;
+ else {
+ assert(isABI_O32() && "Unknown ABI for stack alignment!");
+ stackAlignment = 8;
+ }
+
return *this;
}
diff --git a/lib/Target/Mips/MipsSubtarget.h b/lib/Target/Mips/MipsSubtarget.h
index cce3b8c4c8d1..8b10b0596e0e 100644
--- a/lib/Target/Mips/MipsSubtarget.h
+++ b/lib/Target/Mips/MipsSubtarget.h
@@ -19,10 +19,10 @@
#include "MipsISelLowering.h"
#include "MipsInstrInfo.h"
#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/MC/MCInstrItineraries.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
#include <string>
#define GET_SUBTARGETINFO_HEADER
@@ -155,6 +155,13 @@ class MipsSubtarget : public MipsGenSubtargetInfo {
// Disable use of the `jal` instruction.
bool UseLongCalls = false;
+ /// The minimum alignment known to hold of the stack frame on
+ /// entry to the function and which must be maintained by every function.
+ unsigned stackAlignment;
+
+ /// The overridden stack alignment.
+ unsigned StackAlignOverride;
+
InstrItineraryData InstrItins;
// We can override the determination of whether we are in mips16 mode
@@ -186,7 +193,7 @@ public:
/// This constructor initializes the data members to match that
/// of the specified triple.
MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS, bool little,
- const MipsTargetMachine &TM);
+ const MipsTargetMachine &TM, unsigned StackAlignOverride);
/// ParseSubtargetFeatures - Parses features string setting specified
/// subtarget options. Definition of function is auto generated by tblgen.
@@ -258,7 +265,6 @@ public:
}
bool inMicroMipsMode() const { return InMicroMipsMode; }
bool inMicroMips32r6Mode() const { return InMicroMipsMode && hasMips32r6(); }
- bool inMicroMips64r6Mode() const { return InMicroMipsMode && hasMips64r6(); }
bool hasDSP() const { return HasDSP; }
bool hasDSPR2() const { return HasDSPR2; }
bool hasDSPR3() const { return HasDSPR3; }
@@ -295,7 +301,7 @@ public:
// really use them if in addition we are in mips16 mode
static bool useConstantIslands();
- unsigned stackAlignment() const { return hasMips64() ? 16 : 8; }
+ unsigned getStackAlignment() const { return stackAlignment; }
// Grab relocation model
Reloc::Model getRelocationModel() const;
diff --git a/lib/Target/Mips/MipsTargetMachine.cpp b/lib/Target/Mips/MipsTargetMachine.cpp
index 330ae19ecd0f..85193bffef56 100644
--- a/lib/Target/Mips/MipsTargetMachine.cpp
+++ b/lib/Target/Mips/MipsTargetMachine.cpp
@@ -84,13 +84,19 @@ static std::string computeDataLayout(const Triple &TT, StringRef CPU,
return Ret;
}
-static Reloc::Model getEffectiveRelocModel(CodeModel::Model CM,
+static Reloc::Model getEffectiveRelocModel(bool JIT,
Optional<Reloc::Model> RM) {
- if (!RM.hasValue() || CM == CodeModel::JITDefault)
+ if (!RM.hasValue() || JIT)
return Reloc::Static;
return *RM;
}
+static CodeModel::Model getEffectiveCodeModel(Optional<CodeModel::Model> CM) {
+ if (CM)
+ return *CM;
+ return CodeModel::Small;
+}
+
// On function prologue, the stack is created by decrementing
// its pointer. Once decremented, all references are done with positive
// offset from the stack/frame pointer, using StackGrowsUp enables
@@ -100,18 +106,20 @@ MipsTargetMachine::MipsTargetMachine(const Target &T, const Triple &TT,
StringRef CPU, StringRef FS,
const TargetOptions &Options,
Optional<Reloc::Model> RM,
- CodeModel::Model CM, CodeGenOpt::Level OL,
+ Optional<CodeModel::Model> CM,
+ CodeGenOpt::Level OL, bool JIT,
bool isLittle)
: LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options, isLittle), TT,
- CPU, FS, Options, getEffectiveRelocModel(CM, RM), CM,
- OL),
+ CPU, FS, Options, getEffectiveRelocModel(JIT, RM),
+ getEffectiveCodeModel(CM), OL),
isLittle(isLittle), TLOF(llvm::make_unique<MipsTargetObjectFile>()),
ABI(MipsABIInfo::computeTargetABI(TT, CPU, Options.MCOptions)),
- Subtarget(nullptr), DefaultSubtarget(TT, CPU, FS, isLittle, *this),
+ Subtarget(nullptr), DefaultSubtarget(TT, CPU, FS, isLittle, *this,
+ Options.StackAlignmentOverride),
NoMips16Subtarget(TT, CPU, FS.empty() ? "-mips16" : FS.str() + ",-mips16",
- isLittle, *this),
+ isLittle, *this, Options.StackAlignmentOverride),
Mips16Subtarget(TT, CPU, FS.empty() ? "+mips16" : FS.str() + ",+mips16",
- isLittle, *this) {
+ isLittle, *this, Options.StackAlignmentOverride) {
Subtarget = &DefaultSubtarget;
initAsmInfo();
}
@@ -124,9 +132,9 @@ MipsebTargetMachine::MipsebTargetMachine(const Target &T, const Triple &TT,
StringRef CPU, StringRef FS,
const TargetOptions &Options,
Optional<Reloc::Model> RM,
- CodeModel::Model CM,
- CodeGenOpt::Level OL)
- : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
+ Optional<CodeModel::Model> CM,
+ CodeGenOpt::Level OL, bool JIT)
+ : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, false) {}
void MipselTargetMachine::anchor() {}
@@ -134,9 +142,9 @@ MipselTargetMachine::MipselTargetMachine(const Target &T, const Triple &TT,
StringRef CPU, StringRef FS,
const TargetOptions &Options,
Optional<Reloc::Model> RM,
- CodeModel::Model CM,
- CodeGenOpt::Level OL)
- : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
+ Optional<CodeModel::Model> CM,
+ CodeGenOpt::Level OL, bool JIT)
+ : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, true) {}
const MipsSubtarget *
MipsTargetMachine::getSubtargetImpl(const Function &F) const {
@@ -183,8 +191,8 @@ MipsTargetMachine::getSubtargetImpl(const Function &F) const {
// creation will depend on the TM and the code generation flags on the
// function that reside in TargetOptions.
resetTargetOptions(F);
- I = llvm::make_unique<MipsSubtarget>(TargetTriple, CPU, FS, isLittle,
- *this);
+ I = llvm::make_unique<MipsSubtarget>(TargetTriple, CPU, FS, isLittle, *this,
+ Options.StackAlignmentOverride);
}
return I.get();
}
@@ -192,7 +200,7 @@ MipsTargetMachine::getSubtargetImpl(const Function &F) const {
void MipsTargetMachine::resetSubtarget(MachineFunction *MF) {
DEBUG(dbgs() << "resetSubtarget\n");
- Subtarget = const_cast<MipsSubtarget *>(getSubtargetImpl(*MF->getFunction()));
+ Subtarget = const_cast<MipsSubtarget *>(getSubtargetImpl(MF->getFunction()));
MF->setSubtarget(Subtarget);
}
@@ -202,7 +210,7 @@ namespace {
class MipsPassConfig : public TargetPassConfig {
public:
MipsPassConfig(MipsTargetMachine &TM, PassManagerBase &PM)
- : TargetPassConfig(TM, PM) {
+ : TargetPassConfig(TM, PM) {
// The current implementation of long branch pass requires a scratch
// register ($at) to be available before branch instructions. Tail merging
// can break this requirement, so disable it when long branch pass is
@@ -270,12 +278,11 @@ TargetIRAnalysis MipsTargetMachine::getTargetIRAnalysis() {
void MipsPassConfig::addPreEmitPass() {
addPass(createMicroMipsSizeReductionPass());
- // The delay slot filler pass can potientially create forbidden slot (FS)
- // hazards for MIPSR6 which the hazard schedule pass (HSP) will fix. Any
- // (new) pass that creates compact branches after the HSP must handle FS
- // hazards itself or be pipelined before the HSP.
+ // The delay slot filler and the long branch passes can potientially create
+ // forbidden slot/ hazards for MIPSR6 which the hazard schedule pass will
+ // fix. Any new pass must come before the hazard schedule pass.
addPass(createMipsDelaySlotFillerPass());
- addPass(createMipsHazardSchedule());
addPass(createMipsLongBranchPass());
+ addPass(createMipsHazardSchedule());
addPass(createMipsConstantIslandPass());
}
diff --git a/lib/Target/Mips/MipsTargetMachine.h b/lib/Target/Mips/MipsTargetMachine.h
index a3462868cb11..ccfc9a938d9c 100644
--- a/lib/Target/Mips/MipsTargetMachine.h
+++ b/lib/Target/Mips/MipsTargetMachine.h
@@ -40,8 +40,8 @@ class MipsTargetMachine : public LLVMTargetMachine {
public:
MipsTargetMachine(const Target &T, const Triple &TT, StringRef CPU,
StringRef FS, const TargetOptions &Options,
- Optional<Reloc::Model> RM, CodeModel::Model CM,
- CodeGenOpt::Level OL, bool isLittle);
+ Optional<Reloc::Model> RM, Optional<CodeModel::Model> CM,
+ CodeGenOpt::Level OL, bool JIT, bool isLittle);
~MipsTargetMachine() override;
TargetIRAnalysis getTargetIRAnalysis() override;
@@ -80,8 +80,8 @@ class MipsebTargetMachine : public MipsTargetMachine {
public:
MipsebTargetMachine(const Target &T, const Triple &TT, StringRef CPU,
StringRef FS, const TargetOptions &Options,
- Optional<Reloc::Model> RM, CodeModel::Model CM,
- CodeGenOpt::Level OL);
+ Optional<Reloc::Model> RM, Optional<CodeModel::Model> CM,
+ CodeGenOpt::Level OL, bool JIT);
};
/// Mips32/64 little endian target machine.
@@ -92,8 +92,8 @@ class MipselTargetMachine : public MipsTargetMachine {
public:
MipselTargetMachine(const Target &T, const Triple &TT, StringRef CPU,
StringRef FS, const TargetOptions &Options,
- Optional<Reloc::Model> RM, CodeModel::Model CM,
- CodeGenOpt::Level OL);
+ Optional<Reloc::Model> RM, Optional<CodeModel::Model> CM,
+ CodeGenOpt::Level OL, bool JIT);
};
} // end namespace llvm
diff --git a/lib/Target/Mips/MipsTargetObjectFile.cpp b/lib/Target/Mips/MipsTargetObjectFile.cpp
index 4d73c3991035..9db6b7b1bcd6 100644
--- a/lib/Target/Mips/MipsTargetObjectFile.cpp
+++ b/lib/Target/Mips/MipsTargetObjectFile.cpp
@@ -36,6 +36,12 @@ ExternSData("mextern-sdata", cl::Hidden,
"current object."),
cl::init(true));
+static cl::opt<bool>
+EmbeddedData("membedded-data", cl::Hidden,
+ cl::desc("MIPS: Try to allocate variables in the following"
+ " sections if possible: .rodata, .sdata, .data ."),
+ cl::init(false));
+
void MipsTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){
TargetLoweringObjectFileELF::Initialize(Ctx, TM);
InitializeELF(TM.Options.UseInitArray);
@@ -77,8 +83,9 @@ bool MipsTargetObjectFile::IsGlobalInSmallSection(
bool MipsTargetObjectFile::
IsGlobalInSmallSection(const GlobalObject *GO, const TargetMachine &TM,
SectionKind Kind) const {
- return (IsGlobalInSmallSectionImpl(GO, TM) &&
- (Kind.isData() || Kind.isBSS() || Kind.isCommon()));
+ return IsGlobalInSmallSectionImpl(GO, TM) &&
+ (Kind.isData() || Kind.isBSS() || Kind.isCommon() ||
+ Kind.isReadOnly());
}
/// Return true if this global address should be placed into small data/bss
@@ -99,6 +106,22 @@ IsGlobalInSmallSectionImpl(const GlobalObject *GO,
if (!GVA)
return false;
+ // If the variable has an explicit section, it is placed in that section but
+ // it's addressing mode may change.
+ if (GVA->hasSection()) {
+ StringRef Section = GVA->getSection();
+
+ // Explicitly placing any variable in the small data section overrides
+ // the global -G value.
+ if (Section == ".sdata" || Section == ".sbss")
+ return true;
+
+ // Otherwise reject accessing it through the gp pointer. There are some
+ // historic cases which GCC doesn't appear to respect any more. These
+ // are .lit4, .lit8 and .srdata. For the moment reject these as well.
+ return false;
+ }
+
// Enforce -mlocal-sdata.
if (!LocalSData && GVA->hasLocalLinkage())
return false;
@@ -108,6 +131,10 @@ IsGlobalInSmallSectionImpl(const GlobalObject *GO,
GVA->hasCommonLinkage()))
return false;
+ // Enforce -membedded-data.
+ if (EmbeddedData && GVA->isConstant())
+ return false;
+
Type *Ty = GVA->getValueType();
return IsInSmallSection(
GVA->getParent()->getDataLayout().getTypeAllocSize(Ty));
@@ -123,6 +150,8 @@ MCSection *MipsTargetObjectFile::SelectSectionForGlobal(
return SmallBSSSection;
if (Kind.isData() && IsGlobalInSmallSection(GO, TM, Kind))
return SmallDataSection;
+ if (Kind.isReadOnly() && IsGlobalInSmallSection(GO, TM, Kind))
+ return SmallDataSection;
// Otherwise, we work the same as ELF.
return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, Kind, TM);
diff --git a/lib/Target/Mips/MipsTargetStreamer.h b/lib/Target/Mips/MipsTargetStreamer.h
index af24838665e1..42473aac7288 100644
--- a/lib/Target/Mips/MipsTargetStreamer.h
+++ b/lib/Target/Mips/MipsTargetStreamer.h
@@ -77,6 +77,7 @@ public:
virtual void emitDirectiveSetMips64R5();
virtual void emitDirectiveSetMips64R6();
virtual void emitDirectiveSetDsp();
+ virtual void emitDirectiveSetDspr2();
virtual void emitDirectiveSetNoDsp();
virtual void emitDirectiveSetPop();
virtual void emitDirectiveSetPush();
@@ -247,6 +248,7 @@ public:
void emitDirectiveSetMips64R5() override;
void emitDirectiveSetMips64R6() override;
void emitDirectiveSetDsp() override;
+ void emitDirectiveSetDspr2() override;
void emitDirectiveSetNoDsp() override;
void emitDirectiveSetPop() override;
void emitDirectiveSetPush() override;
diff --git a/lib/Target/Mips/Relocation.txt b/lib/Target/Mips/Relocation.txt
index f1a6fd8645f6..2f98e16886a1 100644
--- a/lib/Target/Mips/Relocation.txt
+++ b/lib/Target/Mips/Relocation.txt
@@ -69,40 +69,7 @@ to MIPS32 to compute addresses for the static relocation model.
The instantiation in Mips64InstrInfo.td is used for MIPS64 in ILP32
mode, as guarded by the predicate "SYM_32" and also for a submode of
-LP64 where symbols are assumed to be 32 bits wide. A similar
-multiclass for MIPS64 in LP64 mode is also defined:
-
- // lib/Target/Mips/Mips64InstrInfo.td
- multiclass MipsHighestHigherHiLoRelocs<Instruction Lui,
- Instruction Daddiu> {
- ...
- def : MipsPat<(MipsHighest (i64 tglobaladdr:$in)),
- (Lui tglobaladdr:$in)>;
- ...
- def : MipsPat<(MipsHigher (i64 tglobaladdr:$in)),
- (Daddiu ZERO_64, tglobaladdr:$in)>;
- ...
- def : MipsPat<(add GPR64:$hi, (MipsHigher (i64 tglobaladdr:$lo))),
- (Daddiu GPR64:$hi, tglobaladdr:$lo)>;
- ...
- def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tglobaladdr:$lo))),
- (Daddiu GPR64:$hi, tglobaladdr:$lo)>;
- ...
- def : MipsPat<(add GPR64:$hi, (MipsLo (i64 tglobaladdr:$lo))),
- (Daddiu GPR64:$hi, tglobaladdr:$lo)>;
- }
-
-and it is instantiated twice:
-
- // lib/Target/Mips/Mips64InstrInfo.td
- defm : MipsHighestHigherHiLoRelocs<LUi64, DADDiu>, SYM_64;
- // lib/Target/Mips/MicroMips64r6InstrInfo.td
- defm : MipsHighestHigherHiLoRelocs<LUi64, DADDIU_MM64R6>, SYM_64,
- ISA_MICROMIPS64R6;
-
-These patterns are used during instruction selection to match
-MipsISD::{Highest, Higher, Hi, Lo} to a specific machine instruction
-and operands.
+LP64 where symbols are assumed to be 32 bits wide.
More details on how multiclasses in TableGen work can be found in the
section "Multiclass definitions and instances" in the document
diff --git a/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp b/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp
index 4c1edfaaaeca..ab494d5bf41b 100644
--- a/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp
+++ b/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp
@@ -32,17 +32,17 @@ Target &llvm::getTheMips64elTarget() {
extern "C" void LLVMInitializeMipsTargetInfo() {
RegisterTarget<Triple::mips,
/*HasJIT=*/true>
- X(getTheMipsTarget(), "mips", "Mips");
+ X(getTheMipsTarget(), "mips", "Mips", "Mips");
RegisterTarget<Triple::mipsel,
/*HasJIT=*/true>
- Y(getTheMipselTarget(), "mipsel", "Mipsel");
+ Y(getTheMipselTarget(), "mipsel", "Mipsel", "Mips");
RegisterTarget<Triple::mips64,
/*HasJIT=*/true>
- A(getTheMips64Target(), "mips64", "Mips64 [experimental]");
+ A(getTheMips64Target(), "mips64", "Mips64 [experimental]", "Mips");
RegisterTarget<Triple::mips64el,
/*HasJIT=*/true>
- B(getTheMips64elTarget(), "mips64el", "Mips64el [experimental]");
+ B(getTheMips64elTarget(), "mips64el", "Mips64el [experimental]", "Mips");
}