summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Target/Mips
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Target/Mips')
-rw-r--r--contrib/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp98
-rw-r--r--contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp12
-rw-r--r--contrib/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp9
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp4
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h1
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp182
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp12
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp3
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h4
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp2
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp10
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h10
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp3
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp62
-rw-r--r--contrib/llvm/lib/Target/Mips/Mips64InstrInfo.td12
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsAsmPrinter.cpp19
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsFastISel.cpp301
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsFrameLowering.cpp17
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsFrameLowering.h2
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp3
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsISelLowering.h3
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsInstrFormats.td12
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsMCInstLower.cpp14
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsRegisterInfo.cpp71
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsRegisterInfo.h8
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp34
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp12
-rw-r--r--contrib/llvm/lib/Target/Mips/MipsTargetStreamer.h4
-rw-r--r--contrib/llvm/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp4
29 files changed, 687 insertions, 241 deletions
diff --git a/contrib/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/contrib/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index aade12b..9c054e5 100644
--- a/contrib/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/contrib/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -43,7 +43,7 @@ class MCInstrInfo;
namespace {
class MipsAssemblerOptions {
public:
- MipsAssemblerOptions(uint64_t Features_) :
+ MipsAssemblerOptions(const FeatureBitset &Features_) :
ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
@@ -70,8 +70,8 @@ public:
void setMacro() { Macro = true; }
void setNoMacro() { Macro = false; }
- uint64_t getFeatures() const { return Features; }
- void setFeatures(uint64_t Features_) { Features = Features_; }
+ const FeatureBitset &getFeatures() const { return Features; }
+ void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
// Set of features that are either architecture features or referenced
// by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
@@ -84,7 +84,7 @@ private:
unsigned ATReg;
bool Reorder;
bool Macro;
- uint64_t Features;
+ FeatureBitset Features;
};
}
@@ -247,6 +247,8 @@ class MipsAsmParser : public MCTargetAsmParser {
bool parseSetFpDirective();
bool parseSetPopDirective();
bool parseSetPushDirective();
+ bool parseSetSoftFloatDirective();
+ bool parseSetHardFloatDirective();
bool parseSetAssignment();
@@ -325,23 +327,23 @@ class MipsAsmParser : public MCTargetAsmParser {
STI.setFeatureBits(FeatureBits);
setAvailableFeatures(
ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
- AssemblerOptions.back()->setFeatures(getAvailableFeatures());
+ AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
}
void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
if (!(STI.getFeatureBits()[Feature])) {
setAvailableFeatures(
ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
+ AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
}
- AssemblerOptions.back()->setFeatures(getAvailableFeatures());
}
void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
if (STI.getFeatureBits()[Feature]) {
setAvailableFeatures(
ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
+ AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
}
- AssemblerOptions.back()->setFeatures(getAvailableFeatures());
}
public:
@@ -367,11 +369,11 @@ public:
// Remember the initial assembler options. The user can not modify these.
AssemblerOptions.push_back(
- make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
+ llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
// Create an assembler options environment for the user to modify.
AssemblerOptions.push_back(
- make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
+ llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
getTargetStreamer().updateABIInfo(*this);
@@ -1946,10 +1948,10 @@ void MipsAsmParser::expandLoadAddressSym(
unsigned RegNo = DstRegOp.getReg();
const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
const MCSymbolRefExpr *HiExpr =
- MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
+ MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
const MCSymbolRefExpr *LoExpr =
- MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
+ MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
if (!Is32BitSym) {
// If it's a 64-bit architecture, expand to:
@@ -1960,10 +1962,10 @@ void MipsAsmParser::expandLoadAddressSym(
// dsll d,d,16
// ori d,d,lo16(sym)
const MCSymbolRefExpr *HighestExpr =
- MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
+ MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
const MCSymbolRefExpr *HigherExpr =
- MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
+ MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
tmpInst.setOpcode(Mips::LUi);
@@ -2102,7 +2104,7 @@ void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
else {
if (ExprOffset->getKind() == MCExpr::SymbolRef) {
SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
- const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
+ const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
getContext());
TempInst.addOperand(MCOperand::createExpr(HiExpr));
@@ -2133,7 +2135,7 @@ void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
TempInst.addOperand(MCOperand::createImm(LoOffset));
else {
if (ExprOffset->getKind() == MCExpr::SymbolRef) {
- const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
+ const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
getContext());
TempInst.addOperand(MCOperand::createExpr(LoExpr));
@@ -2505,7 +2507,7 @@ bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
// Otherwise create a symbol reference.
const MCExpr *Res =
- MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
+ MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
return false;
@@ -2565,14 +2567,14 @@ const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
default:
report_fatal_error("unsupported reloc value");
}
- return MCConstantExpr::Create(Val, getContext());
+ return MCConstantExpr::create(Val, getContext());
}
if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
// It's a symbol, create a symbolic expression from the symbol.
StringRef Symbol = MSRE->getSymbol().getName();
MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
- Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
+ Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
return Res;
}
@@ -2581,17 +2583,17 @@ const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
// Try to create target expression.
if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
- return MipsMCExpr::Create(VK, Expr, getContext());
+ return MipsMCExpr::create(VK, Expr, getContext());
const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
- Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
+ Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
return Res;
}
if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
- Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
+ Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
return Res;
}
// Just return the original expression.
@@ -2779,7 +2781,7 @@ MipsAsmParser::parseMemOperand(OperandVector &Operands) {
Parser.Lex(); // Eat the ')' token.
if (!IdVal)
- IdVal = MCConstantExpr::Create(0, getContext());
+ IdVal = MCConstantExpr::create(0, getContext());
// Replace the register operand with the memory operand.
std::unique_ptr<MipsOperand> op(
@@ -2790,10 +2792,10 @@ MipsAsmParser::parseMemOperand(OperandVector &Operands) {
// Add the memory operand.
if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
int64_t Imm;
- if (IdVal->EvaluateAsAbsolute(Imm))
- IdVal = MCConstantExpr::Create(Imm, getContext());
+ if (IdVal->evaluateAsAbsolute(Imm))
+ IdVal = MCConstantExpr::create(Imm, getContext());
else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
- IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
+ IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
getContext());
}
@@ -3010,7 +3012,7 @@ MipsAsmParser::parseInvNum(OperandVector &Operands) {
int64_t Val = MCE->getValue();
SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Operands.push_back(MipsOperand::CreateImm(
- MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
+ MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
return MatchOperand_Success;
}
@@ -3034,7 +3036,7 @@ MipsAsmParser::parseLSAImm(OperandVector &Operands) {
return MatchOperand_ParseFail;
int64_t Val;
- if (!Expr->EvaluateAsAbsolute(Val)) {
+ if (!Expr->evaluateAsAbsolute(Val)) {
Error(S, "expected immediate value");
return MatchOperand_ParseFail;
}
@@ -3601,7 +3603,9 @@ bool MipsAsmParser::parseSetPopDirective() {
return reportParseError(Loc, ".set pop with no .set push");
AssemblerOptions.pop_back();
- setAvailableFeatures(AssemblerOptions.back()->getFeatures());
+ setAvailableFeatures(
+ ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
+ STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
getTargetStreamer().emitDirectiveSetPop();
return false;
@@ -3621,6 +3625,28 @@ bool MipsAsmParser::parseSetPushDirective() {
return false;
}
+bool MipsAsmParser::parseSetSoftFloatDirective() {
+ MCAsmParser &Parser = getParser();
+ Parser.Lex();
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return reportParseError("unexpected token, expected end of statement");
+
+ setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
+ getTargetStreamer().emitDirectiveSetSoftFloat();
+ return false;
+}
+
+bool MipsAsmParser::parseSetHardFloatDirective() {
+ MCAsmParser &Parser = getParser();
+ Parser.Lex();
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return reportParseError("unexpected token, expected end of statement");
+
+ clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
+ getTargetStreamer().emitDirectiveSetHardFloat();
+ return false;
+}
+
bool MipsAsmParser::parseSetAssignment() {
StringRef Name;
const MCExpr *Value;
@@ -3649,7 +3675,9 @@ bool MipsAsmParser::parseSetMips0Directive() {
return reportParseError("unexpected token, expected end of statement");
// Reset assembler options to their initial values.
- setAvailableFeatures(AssemblerOptions.front()->getFeatures());
+ setAvailableFeatures(
+ ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
+ STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
getTargetStreamer().emitDirectiveSetMips0();
@@ -3985,6 +4013,10 @@ bool MipsAsmParser::parseDirectiveSet() {
return parseSetMsaDirective();
} else if (Tok.getString() == "nomsa") {
return parseSetNoMsaDirective();
+ } else if (Tok.getString() == "softfloat") {
+ return parseSetSoftFloatDirective();
+ } else if (Tok.getString() == "hardfloat") {
+ return parseSetHardFloatDirective();
} else {
// It is just an identifier, look for an assignment.
parseSetAssignment();
@@ -4286,7 +4318,7 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
reportParseError("expected number after comma");
return false;
}
- if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
+ if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
reportParseError("expected an absolute expression after comma");
return false;
}
@@ -4366,7 +4398,7 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
return false;
}
- if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
+ if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
reportParseError("frame size not an absolute expression");
return false;
}
@@ -4427,7 +4459,7 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
return false;
}
- if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
+ if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
reportParseError("bitmask not an absolute expression");
return false;
}
@@ -4448,7 +4480,7 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
return false;
}
- if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
+ if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
reportParseError("frame offset not an absolute expression");
return false;
}
diff --git a/contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
index eb97c93..c8629b5 100644
--- a/contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
+++ b/contrib/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
@@ -47,6 +47,8 @@ public:
bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
+ bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; }
+
bool hasCOP3() const {
// Only present in MIPS-I and MIPS-II
return !hasMips32() && !hasMips3();
@@ -889,6 +891,16 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
}
}
+ if (hasCnMips()) {
+ DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
+ Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
+ Address, this, STI);
+ if (Result != MCDisassembler::Fail) {
+ Size = 4;
+ return Result;
+ }
+ }
+
if (isGP64()) {
DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
diff --git a/contrib/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp b/contrib/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
index e80a47b..a5637b1 100644
--- a/contrib/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
+++ b/contrib/llvm/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
@@ -122,7 +122,8 @@ void MipsInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
}
}
-static void printExpr(const MCExpr *Expr, raw_ostream &OS) {
+static void printExpr(const MCExpr *Expr, const MCAsmInfo *MAI,
+ raw_ostream &OS) {
int Offset = 0;
const MCSymbolRefExpr *SRE;
@@ -132,7 +133,7 @@ static void printExpr(const MCExpr *Expr, raw_ostream &OS) {
assert(SRE && CE && "Binary expression must be sym+const.");
Offset = CE->getValue();
} else if (const MipsMCExpr *ME = dyn_cast<MipsMCExpr>(Expr)) {
- ME->print(OS);
+ ME->print(OS, MAI);
return;
} else
SRE = cast<MCSymbolRefExpr>(Expr);
@@ -170,7 +171,7 @@ static void printExpr(const MCExpr *Expr, raw_ostream &OS) {
case MCSymbolRefExpr::VK_Mips_PCREL_LO16: OS << "%pcrel_lo("; break;
}
- OS << SRE->getSymbol();
+ SRE->getSymbol().print(OS, MAI);
if (Offset) {
if (Offset > 0)
@@ -199,7 +200,7 @@ void MipsInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
}
assert(Op.isExpr() && "unknown operand kind in printOperand");
- printExpr(Op.getExpr(), O);
+ printExpr(Op.getExpr(), &MAI, O);
}
void MipsInstPrinter::printUnsignedImm(const MCInst *MI, int opNum,
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
index b1f7c2f..bf8f7d1 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
@@ -99,6 +99,10 @@ unsigned MipsABIInfo::GetFramePtr() const {
return ArePtrs64bit() ? Mips::FP_64 : Mips::FP;
}
+unsigned MipsABIInfo::GetBasePtr() const {
+ return ArePtrs64bit() ? Mips::S7_64 : Mips::S7;
+}
+
unsigned MipsABIInfo::GetNullPtr() const {
return ArePtrs64bit() ? Mips::ZERO_64 : Mips::ZERO;
}
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h
index 9a6ba94..d20dc90 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h
@@ -65,6 +65,7 @@ public:
unsigned GetStackPtr() const;
unsigned GetFramePtr() const;
+ unsigned GetBasePtr() const;
unsigned GetNullPtr() const;
unsigned GetPtrAdduOp() const;
unsigned GetPtrAddiuOp() const;
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
index 8d9e3e3..982a7f5 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
@@ -12,10 +12,10 @@
#include "MCTargetDesc/MipsMCTargetDesc.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCAssembler.h"
-#include "llvm/MC/MCELF.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCSymbolELF.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/ErrorHandling.h"
#include <list>
@@ -46,7 +46,7 @@ struct MipsRelocationEntry {
unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
bool IsPCRel) const override;
- bool needsRelocateWithSymbol(const MCSymbolData &SD,
+ bool needsRelocateWithSymbol(const MCSymbol &Sym,
unsigned Type) const override;
virtual void sortRelocs(const MCAssembler &Asm,
std::vector<ELFRelocationEntry> &Relocs) override;
@@ -65,181 +65,134 @@ unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target,
const MCFixup &Fixup,
bool IsPCRel) const {
// determine the type of the relocation
- unsigned Type = (unsigned)ELF::R_MIPS_NONE;
unsigned Kind = (unsigned)Fixup.getKind();
switch (Kind) {
- default:
- llvm_unreachable("invalid fixup kind!");
case Mips::fixup_Mips_32:
case FK_Data_4:
- Type = ELF::R_MIPS_32;
- break;
+ return IsPCRel ? ELF::R_MIPS_PC32 : ELF::R_MIPS_32;
case Mips::fixup_Mips_64:
case FK_Data_8:
- Type = ELF::R_MIPS_64;
- break;
+ return ELF::R_MIPS_64;
case FK_GPRel_4:
if (isN64()) {
+ unsigned Type = (unsigned)ELF::R_MIPS_NONE;
Type = setRType((unsigned)ELF::R_MIPS_GPREL32, Type);
Type = setRType2((unsigned)ELF::R_MIPS_64, Type);
Type = setRType3((unsigned)ELF::R_MIPS_NONE, Type);
+ return Type;
}
- else
- Type = ELF::R_MIPS_GPREL32;
- break;
+ return ELF::R_MIPS_GPREL32;
case Mips::fixup_Mips_GPREL16:
- Type = ELF::R_MIPS_GPREL16;
- break;
+ return ELF::R_MIPS_GPREL16;
case Mips::fixup_Mips_26:
- Type = ELF::R_MIPS_26;
- break;
+ return ELF::R_MIPS_26;
case Mips::fixup_Mips_CALL16:
- Type = ELF::R_MIPS_CALL16;
- break;
+ return ELF::R_MIPS_CALL16;
case Mips::fixup_Mips_GOT_Global:
case Mips::fixup_Mips_GOT_Local:
- Type = ELF::R_MIPS_GOT16;
- break;
+ return ELF::R_MIPS_GOT16;
case Mips::fixup_Mips_HI16:
- Type = ELF::R_MIPS_HI16;
- break;
+ return ELF::R_MIPS_HI16;
case Mips::fixup_Mips_LO16:
- Type = ELF::R_MIPS_LO16;
- break;
+ return ELF::R_MIPS_LO16;
case Mips::fixup_Mips_TLSGD:
- Type = ELF::R_MIPS_TLS_GD;
- break;
+ return ELF::R_MIPS_TLS_GD;
case Mips::fixup_Mips_GOTTPREL:
- Type = ELF::R_MIPS_TLS_GOTTPREL;
- break;
+ return ELF::R_MIPS_TLS_GOTTPREL;
case Mips::fixup_Mips_TPREL_HI:
- Type = ELF::R_MIPS_TLS_TPREL_HI16;
- break;
+ return ELF::R_MIPS_TLS_TPREL_HI16;
case Mips::fixup_Mips_TPREL_LO:
- Type = ELF::R_MIPS_TLS_TPREL_LO16;
- break;
+ return ELF::R_MIPS_TLS_TPREL_LO16;
case Mips::fixup_Mips_TLSLDM:
- Type = ELF::R_MIPS_TLS_LDM;
- break;
+ return ELF::R_MIPS_TLS_LDM;
case Mips::fixup_Mips_DTPREL_HI:
- Type = ELF::R_MIPS_TLS_DTPREL_HI16;
- break;
+ return ELF::R_MIPS_TLS_DTPREL_HI16;
case Mips::fixup_Mips_DTPREL_LO:
- Type = ELF::R_MIPS_TLS_DTPREL_LO16;
- break;
+ return ELF::R_MIPS_TLS_DTPREL_LO16;
case Mips::fixup_Mips_Branch_PCRel:
case Mips::fixup_Mips_PC16:
- Type = ELF::R_MIPS_PC16;
- break;
+ return ELF::R_MIPS_PC16;
case Mips::fixup_Mips_GOT_PAGE:
- Type = ELF::R_MIPS_GOT_PAGE;
- break;
+ return ELF::R_MIPS_GOT_PAGE;
case Mips::fixup_Mips_GOT_OFST:
- Type = ELF::R_MIPS_GOT_OFST;
- break;
+ return ELF::R_MIPS_GOT_OFST;
case Mips::fixup_Mips_GOT_DISP:
- Type = ELF::R_MIPS_GOT_DISP;
- break;
- case Mips::fixup_Mips_GPOFF_HI:
+ return ELF::R_MIPS_GOT_DISP;
+ case Mips::fixup_Mips_GPOFF_HI: {
+ unsigned Type = (unsigned)ELF::R_MIPS_NONE;
Type = setRType((unsigned)ELF::R_MIPS_GPREL16, Type);
Type = setRType2((unsigned)ELF::R_MIPS_SUB, Type);
Type = setRType3((unsigned)ELF::R_MIPS_HI16, Type);
- break;
- case Mips::fixup_Mips_GPOFF_LO:
+ return Type;
+ }
+ case Mips::fixup_Mips_GPOFF_LO: {
+ unsigned Type = (unsigned)ELF::R_MIPS_NONE;
Type = setRType((unsigned)ELF::R_MIPS_GPREL16, Type);
Type = setRType2((unsigned)ELF::R_MIPS_SUB, Type);
Type = setRType3((unsigned)ELF::R_MIPS_LO16, Type);
- break;
+ return Type;
+ }
case Mips::fixup_Mips_HIGHER:
- Type = ELF::R_MIPS_HIGHER;
- break;
+ return ELF::R_MIPS_HIGHER;
case Mips::fixup_Mips_HIGHEST:
- Type = ELF::R_MIPS_HIGHEST;
- break;
+ return ELF::R_MIPS_HIGHEST;
case Mips::fixup_Mips_GOT_HI16:
- Type = ELF::R_MIPS_GOT_HI16;
- break;
+ return ELF::R_MIPS_GOT_HI16;
case Mips::fixup_Mips_GOT_LO16:
- Type = ELF::R_MIPS_GOT_LO16;
- break;
+ return ELF::R_MIPS_GOT_LO16;
case Mips::fixup_Mips_CALL_HI16:
- Type = ELF::R_MIPS_CALL_HI16;
- break;
+ return ELF::R_MIPS_CALL_HI16;
case Mips::fixup_Mips_CALL_LO16:
- Type = ELF::R_MIPS_CALL_LO16;
- break;
+ return ELF::R_MIPS_CALL_LO16;
case Mips::fixup_MICROMIPS_26_S1:
- Type = ELF::R_MICROMIPS_26_S1;
- break;
+ return ELF::R_MICROMIPS_26_S1;
case Mips::fixup_MICROMIPS_HI16:
- Type = ELF::R_MICROMIPS_HI16;
- break;
+ return ELF::R_MICROMIPS_HI16;
case Mips::fixup_MICROMIPS_LO16:
- Type = ELF::R_MICROMIPS_LO16;
- break;
+ return ELF::R_MICROMIPS_LO16;
case Mips::fixup_MICROMIPS_GOT16:
- Type = ELF::R_MICROMIPS_GOT16;
- break;
+ return ELF::R_MICROMIPS_GOT16;
case Mips::fixup_MICROMIPS_PC7_S1:
- Type = ELF::R_MICROMIPS_PC7_S1;
- break;
+ return ELF::R_MICROMIPS_PC7_S1;
case Mips::fixup_MICROMIPS_PC10_S1:
- Type = ELF::R_MICROMIPS_PC10_S1;
- break;
+ return ELF::R_MICROMIPS_PC10_S1;
case Mips::fixup_MICROMIPS_PC16_S1:
- Type = ELF::R_MICROMIPS_PC16_S1;
- break;
+ return ELF::R_MICROMIPS_PC16_S1;
case Mips::fixup_MICROMIPS_CALL16:
- Type = ELF::R_MICROMIPS_CALL16;
- break;
+ return ELF::R_MICROMIPS_CALL16;
case Mips::fixup_MICROMIPS_GOT_DISP:
- Type = ELF::R_MICROMIPS_GOT_DISP;
- break;
+ return ELF::R_MICROMIPS_GOT_DISP;
case Mips::fixup_MICROMIPS_GOT_PAGE:
- Type = ELF::R_MICROMIPS_GOT_PAGE;
- break;
+ return ELF::R_MICROMIPS_GOT_PAGE;
case Mips::fixup_MICROMIPS_GOT_OFST:
- Type = ELF::R_MICROMIPS_GOT_OFST;
- break;
+ return ELF::R_MICROMIPS_GOT_OFST;
case Mips::fixup_MICROMIPS_TLS_GD:
- Type = ELF::R_MICROMIPS_TLS_GD;
- break;
+ return ELF::R_MICROMIPS_TLS_GD;
case Mips::fixup_MICROMIPS_TLS_LDM:
- Type = ELF::R_MICROMIPS_TLS_LDM;
- break;
+ return ELF::R_MICROMIPS_TLS_LDM;
case Mips::fixup_MICROMIPS_TLS_DTPREL_HI16:
- Type = ELF::R_MICROMIPS_TLS_DTPREL_HI16;
- break;
+ return ELF::R_MICROMIPS_TLS_DTPREL_HI16;
case Mips::fixup_MICROMIPS_TLS_DTPREL_LO16:
- Type = ELF::R_MICROMIPS_TLS_DTPREL_LO16;
- break;
+ return ELF::R_MICROMIPS_TLS_DTPREL_LO16;
case Mips::fixup_MICROMIPS_TLS_TPREL_HI16:
- Type = ELF::R_MICROMIPS_TLS_TPREL_HI16;
- break;
+ return ELF::R_MICROMIPS_TLS_TPREL_HI16;
case Mips::fixup_MICROMIPS_TLS_TPREL_LO16:
- Type = ELF::R_MICROMIPS_TLS_TPREL_LO16;
- break;
+ return ELF::R_MICROMIPS_TLS_TPREL_LO16;
case Mips::fixup_MIPS_PC19_S2:
- Type = ELF::R_MIPS_PC19_S2;
- break;
+ return ELF::R_MIPS_PC19_S2;
case Mips::fixup_MIPS_PC18_S3:
- Type = ELF::R_MIPS_PC18_S3;
- break;
+ return ELF::R_MIPS_PC18_S3;
case Mips::fixup_MIPS_PC21_S2:
- Type = ELF::R_MIPS_PC21_S2;
- break;
+ return ELF::R_MIPS_PC21_S2;
case Mips::fixup_MIPS_PC26_S2:
- Type = ELF::R_MIPS_PC26_S2;
- break;
+ return ELF::R_MIPS_PC26_S2;
case Mips::fixup_MIPS_PCHI16:
- Type = ELF::R_MIPS_PCHI16;
- break;
+ return ELF::R_MIPS_PCHI16;
case Mips::fixup_MIPS_PCLO16:
- Type = ELF::R_MIPS_PCLO16;
- break;
+ return ELF::R_MIPS_PCLO16;
}
- return Type;
+ llvm_unreachable("invalid fixup kind!");
}
// Sort entries by SortOffset in descending order.
@@ -271,9 +224,7 @@ static unsigned getMatchingLoType(const MCAssembler &Asm,
if (Type == ELF::R_MIPS16_HI16)
return ELF::R_MIPS16_LO16;
- const MCSymbolData &SD = Asm.getSymbolData(*Reloc.Symbol);
-
- if (MCELF::GetBinding(SD) != ELF::STB_LOCAL)
+ if (Reloc.Symbol->getBinding() != ELF::STB_LOCAL)
return ELF::R_MIPS_NONE;
if (Type == ELF::R_MIPS_GOT16)
@@ -405,9 +356,8 @@ void MipsELFObjectWriter::sortRelocs(const MCAssembler &Asm,
Relocs[I] = MipsRelocs[I].R;
}
-bool
-MipsELFObjectWriter::needsRelocateWithSymbol(const MCSymbolData &SD,
- unsigned Type) const {
+bool MipsELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
+ unsigned Type) const {
// FIXME: This is extremely conservative. This really needs to use a
// whitelist with a clear explanation for why each realocation needs to
// point to the symbol, not to the section.
@@ -434,7 +384,7 @@ MipsELFObjectWriter::needsRelocateWithSymbol(const MCSymbolData &SD,
return true;
case ELF::R_MIPS_32:
- if (MCELF::getOther(SD) & (ELF::STO_MIPS_MICROMIPS >> 2))
+ if (cast<MCSymbolELF>(Sym).getOther() & ELF::STO_MIPS_MICROMIPS)
return true;
// falltrough
case ELF::R_MIPS_26:
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
index d2b5183..b45d9cf 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
@@ -9,8 +9,8 @@
#include "MipsELFStreamer.h"
#include "MipsTargetStreamer.h"
-#include "llvm/MC/MCELF.h"
#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCSymbolELF.h"
#include "llvm/Support/ELF.h"
using namespace llvm;
@@ -41,12 +41,10 @@ void MipsELFStreamer::createPendingLabelRelocs() {
// FIXME: Also mark labels when in MIPS16 mode.
if (ELFTargetStreamer->isMicroMipsEnabled()) {
- for (auto Label : Labels) {
- MCSymbolData &Data = getOrCreateSymbolData(Label);
- // The "other" values are stored in the last 6 bits of the second byte.
- // The traditional defines for STO values assume the full byte and thus
- // the shift to pack it.
- MCELF::setOther(Data, ELF::STO_MIPS_MICROMIPS >> 2);
+ for (auto *L : Labels) {
+ auto *Label = cast<MCSymbolELF>(L);
+ getAssembler().registerSymbol(*Label);
+ Label->setOther(ELF::STO_MIPS_MICROMIPS);
}
}
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
index e2bd5a8..4d55458 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
@@ -18,8 +18,7 @@ using namespace llvm;
void MipsMCAsmInfo::anchor() { }
-MipsMCAsmInfo::MipsMCAsmInfo(StringRef TT) {
- Triple TheTriple(TT);
+MipsMCAsmInfo::MipsMCAsmInfo(const Triple &TheTriple) {
if ((TheTriple.getArch() == Triple::mips) ||
(TheTriple.getArch() == Triple::mips64))
IsLittleEndian = false;
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h
index 59ff1c4..5d23fcb 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h
@@ -17,12 +17,12 @@
#include "llvm/MC/MCAsmInfoELF.h"
namespace llvm {
- class StringRef;
+ class Triple;
class MipsMCAsmInfo : public MCAsmInfoELF {
void anchor() override;
public:
- explicit MipsMCAsmInfo(StringRef TT);
+ explicit MipsMCAsmInfo(const Triple &TheTriple);
};
} // namespace llvm
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
index a0d9e15..93925bf 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
@@ -467,7 +467,7 @@ getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
int64_t Res;
- if (Expr->EvaluateAsAbsolute(Res))
+ if (Expr->evaluateAsAbsolute(Res))
return Res;
MCExpr::ExprKind Kind = Expr->getKind();
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp
index 74490f3..c85fc48 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp
@@ -41,7 +41,7 @@ bool MipsMCExpr::isSupportedBinaryExpr(MCSymbolRefExpr::VariantKind VK,
}
const MipsMCExpr*
-MipsMCExpr::Create(MCSymbolRefExpr::VariantKind VK, const MCExpr *Expr,
+MipsMCExpr::create(MCSymbolRefExpr::VariantKind VK, const MCExpr *Expr,
MCContext &Ctx) {
VariantKind Kind;
switch (VK) {
@@ -64,7 +64,7 @@ MipsMCExpr::Create(MCSymbolRefExpr::VariantKind VK, const MCExpr *Expr,
return new (Ctx) MipsMCExpr(Kind, Expr);
}
-void MipsMCExpr::PrintImpl(raw_ostream &OS) const {
+void MipsMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
switch (Kind) {
default: llvm_unreachable("Invalid kind!");
case VK_Mips_LO: OS << "%lo"; break;
@@ -74,15 +74,15 @@ void MipsMCExpr::PrintImpl(raw_ostream &OS) const {
}
OS << '(';
- Expr->print(OS);
+ Expr->print(OS, MAI);
OS << ')';
}
bool
-MipsMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
+MipsMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout,
const MCFixup *Fixup) const {
- return getSubExpr()->EvaluateAsRelocatable(Res, Layout, Fixup);
+ return getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup);
}
void MipsMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h
index ee11461..fd2ed17 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h
@@ -37,7 +37,7 @@ public:
static bool isSupportedBinaryExpr(MCSymbolRefExpr::VariantKind VK,
const MCBinaryExpr *BE);
- static const MipsMCExpr *Create(MCSymbolRefExpr::VariantKind VK,
+ static const MipsMCExpr *create(MCSymbolRefExpr::VariantKind VK,
const MCExpr *Expr, MCContext &Ctx);
/// getOpcode - Get the kind of this expression.
@@ -46,13 +46,13 @@ public:
/// getSubExpr - Get the child of this expression.
const MCExpr *getSubExpr() const { return Expr; }
- void PrintImpl(raw_ostream &OS) const override;
- bool EvaluateAsRelocatableImpl(MCValue &Res,
+ void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
+ bool evaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout,
const MCFixup *Fixup) const override;
void visitUsedExpr(MCStreamer &Streamer) const override;
- MCSection *FindAssociatedSection() const override {
- return getSubExpr()->FindAssociatedSection();
+ MCSection *findAssociatedSection() const override {
+ return getSubExpr()->findAssociatedSection();
}
// There are no TLS MipsMCExprs at the moment.
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
index 2e3179a..54d8863 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
@@ -75,7 +75,8 @@ static MCSubtargetInfo *createMipsMCSubtargetInfo(StringRef TT, StringRef CPU,
return X;
}
-static MCAsmInfo *createMipsMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) {
+static MCAsmInfo *createMipsMCAsmInfo(const MCRegisterInfo &MRI,
+ const Triple &TT) {
MCAsmInfo *MAI = new MipsMCAsmInfo(TT);
unsigned SP = MRI.getDwarfRegNum(Mips::SP, true);
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
index 8e6f047..a051f4c 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
@@ -17,10 +17,9 @@
#include "MipsTargetObjectFile.h"
#include "MipsTargetStreamer.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCELF.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCSymbolELF.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h"
@@ -81,6 +80,12 @@ void MipsTargetStreamer::emitDirectiveSetMips64R5() { forbidModuleDirective(); }
void MipsTargetStreamer::emitDirectiveSetMips64R6() { forbidModuleDirective(); }
void MipsTargetStreamer::emitDirectiveSetPop() { forbidModuleDirective(); }
void MipsTargetStreamer::emitDirectiveSetPush() { forbidModuleDirective(); }
+void MipsTargetStreamer::emitDirectiveSetSoftFloat() {
+ forbidModuleDirective();
+}
+void MipsTargetStreamer::emitDirectiveSetHardFloat() {
+ forbidModuleDirective();
+}
void MipsTargetStreamer::emitDirectiveSetDsp() { forbidModuleDirective(); }
void MipsTargetStreamer::emitDirectiveSetNoDsp() { forbidModuleDirective(); }
void MipsTargetStreamer::emitDirectiveCpLoad(unsigned RegNo) {}
@@ -308,6 +313,16 @@ void MipsTargetAsmStreamer::emitDirectiveSetPush() {
MipsTargetStreamer::emitDirectiveSetPush();
}
+void MipsTargetAsmStreamer::emitDirectiveSetSoftFloat() {
+ OS << "\t.set\tsoftfloat\n";
+ MipsTargetStreamer::emitDirectiveSetSoftFloat();
+}
+
+void MipsTargetAsmStreamer::emitDirectiveSetHardFloat() {
+ OS << "\t.set\thardfloat\n";
+ MipsTargetStreamer::emitDirectiveSetHardFloat();
+}
+
// Print a 32 bit hex number with all numbers.
static void printHex32(unsigned Value, raw_ostream &OS) {
OS << "0x";
@@ -358,7 +373,6 @@ void MipsTargetAsmStreamer::emitDirectiveModuleFP(
MipsABIFlagsSection::FpABIKind Value, bool Is32BitABI) {
MipsTargetStreamer::emitDirectiveModuleFP(Value, Is32BitABI);
- StringRef ModuleValue;
OS << "\t.module\tfp=";
OS << ABIFlagsSection.getFpABIString(Value) << "\n";
}
@@ -367,7 +381,6 @@ void MipsTargetAsmStreamer::emitDirectiveSetFp(
MipsABIFlagsSection::FpABIKind Value) {
MipsTargetStreamer::emitDirectiveSetFp(Value);
- StringRef ModuleValue;
OS << "\t.set\tfp=";
OS << ABIFlagsSection.getFpABIString(Value) << "\n";
}
@@ -440,18 +453,16 @@ MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S,
MCA.setELFHeaderEFlags(EFlags);
}
-void MipsTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
+void MipsTargetELFStreamer::emitLabel(MCSymbol *S) {
+ auto *Symbol = cast<MCSymbolELF>(S);
if (!isMicroMipsEnabled())
return;
- MCSymbolData &Data = getStreamer().getOrCreateSymbolData(Symbol);
- uint8_t Type = MCELF::GetType(Data);
+ getStreamer().getAssembler().registerSymbol(*Symbol);
+ uint8_t Type = Symbol->getType();
if (Type != ELF::STT_FUNC)
return;
- // The "other" values are stored in the last 6 bits of the second byte
- // The traditional defines for STO values assume the full byte and thus
- // the shift to pack it.
- MCELF::setOther(Data, ELF::STO_MIPS_MICROMIPS >> 2);
+ Symbol->setOther(ELF::STO_MIPS_MICROMIPS);
}
void MipsTargetELFStreamer::finish() {
@@ -505,23 +516,18 @@ void MipsTargetELFStreamer::finish() {
emitMipsAbiFlags();
}
-void MipsTargetELFStreamer::emitAssignment(MCSymbol *Symbol,
- const MCExpr *Value) {
+void MipsTargetELFStreamer::emitAssignment(MCSymbol *S, const MCExpr *Value) {
+ auto *Symbol = cast<MCSymbolELF>(S);
// If on rhs is micromips symbol then mark Symbol as microMips.
if (Value->getKind() != MCExpr::SymbolRef)
return;
- const MCSymbol &RhsSym =
- static_cast<const MCSymbolRefExpr *>(Value)->getSymbol();
- MCSymbolData &Data = getStreamer().getOrCreateSymbolData(&RhsSym);
+ const auto &RhsSym = cast<MCSymbolELF>(
+ static_cast<const MCSymbolRefExpr *>(Value)->getSymbol());
- if (!(MCELF::getOther(Data) & (ELF::STO_MIPS_MICROMIPS >> 2)))
+ if (!(RhsSym.getOther() & ELF::STO_MIPS_MICROMIPS))
return;
- MCSymbolData &SymbolData = getStreamer().getOrCreateSymbolData(Symbol);
- // The "other" values are stored in the last 6 bits of the second byte.
- // The traditional defines for STO values assume the full byte and thus
- // the shift to pack it.
- MCELF::setOther(SymbolData, ELF::STO_MIPS_MICROMIPS >> 2);
+ Symbol->setOther(ELF::STO_MIPS_MICROMIPS);
}
MCELFStreamer &MipsTargetELFStreamer::getStreamer() {
@@ -568,7 +574,7 @@ void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) {
ELF::SHF_ALLOC | ELF::SHT_REL);
const MCSymbolRefExpr *ExprRef =
- MCSymbolRefExpr::Create(Name, MCSymbolRefExpr::VK_None, Context);
+ MCSymbolRefExpr::create(Name, MCSymbolRefExpr::VK_None, Context);
MCA.registerSection(*Sec);
Sec->setAlignment(4);
@@ -693,12 +699,12 @@ void MipsTargetELFStreamer::emitDirectiveCpLoad(unsigned RegNo) {
StringRef SymName("_gp_disp");
MCAssembler &MCA = getStreamer().getAssembler();
MCSymbol *GP_Disp = MCA.getContext().getOrCreateSymbol(SymName);
- MCA.getOrCreateSymbolData(*GP_Disp);
+ MCA.registerSymbol(*GP_Disp);
MCInst TmpInst;
TmpInst.setOpcode(Mips::LUi);
TmpInst.addOperand(MCOperand::createReg(Mips::GP));
- const MCSymbolRefExpr *HiSym = MCSymbolRefExpr::Create(
+ const MCSymbolRefExpr *HiSym = MCSymbolRefExpr::create(
"_gp_disp", MCSymbolRefExpr::VK_Mips_ABS_HI, MCA.getContext());
TmpInst.addOperand(MCOperand::createExpr(HiSym));
getStreamer().EmitInstruction(TmpInst, STI);
@@ -708,7 +714,7 @@ void MipsTargetELFStreamer::emitDirectiveCpLoad(unsigned RegNo) {
TmpInst.setOpcode(Mips::ADDiu);
TmpInst.addOperand(MCOperand::createReg(Mips::GP));
TmpInst.addOperand(MCOperand::createReg(Mips::GP));
- const MCSymbolRefExpr *LoSym = MCSymbolRefExpr::Create(
+ const MCSymbolRefExpr *LoSym = MCSymbolRefExpr::create(
"_gp_disp", MCSymbolRefExpr::VK_Mips_ABS_LO, MCA.getContext());
TmpInst.addOperand(MCOperand::createExpr(LoSym));
getStreamer().EmitInstruction(TmpInst, STI);
@@ -752,9 +758,9 @@ void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo,
getStreamer().EmitInstruction(Inst, STI);
Inst.clear();
- const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
+ const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
&Sym, MCSymbolRefExpr::VK_Mips_GPOFF_HI, MCA.getContext());
- const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
+ const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
&Sym, MCSymbolRefExpr::VK_Mips_GPOFF_LO, MCA.getContext());
// lui $gp, %hi(%neg(%gp_rel(funcSym)))
diff --git a/contrib/llvm/lib/Target/Mips/Mips64InstrInfo.td b/contrib/llvm/lib/Target/Mips/Mips64InstrInfo.td
index 272933f..8a27874 100644
--- a/contrib/llvm/lib/Target/Mips/Mips64InstrInfo.td
+++ b/contrib/llvm/lib/Target/Mips/Mips64InstrInfo.td
@@ -305,8 +305,9 @@ let isCodeGenOnly = 1, rs = 0, shamt = 0 in {
def LONG_BRANCH_DADDiu : PseudoSE<(outs GPR64Opnd:$dst),
(ins GPR64Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>;
-// Cavium Octeon cmMIPS instructions
-let EncodingPredicates = []<Predicate>, // FIXME: The lack of HasStdEnc is probably a bug
+// Cavium Octeon cnMIPS instructions
+let DecoderNamespace = "CnMips",
+ EncodingPredicates = []<Predicate>, // FIXME: The lack of HasStdEnc is probably a bug
AdditionalPredicates = [HasCnMips] in {
class Count1s<string opstr, RegisterOperand RO>:
@@ -353,6 +354,10 @@ class CBranchBitNum<string opstr, DAGOperand opnd, PatFrag cond_op,
let Defs = [AT];
}
+class MFC2OP<string asmstr, RegisterOperand RO> :
+ InstSE<(outs RO:$rt, uimm16:$imm16), (ins),
+ !strconcat(asmstr, "\t$rt, $imm16"), [], NoItinerary, FrmFR>;
+
// Unsigned Byte Add
let Pattern = [(set GPR64Opnd:$rd,
(and (add GPR64Opnd:$rs, GPR64Opnd:$rt), 255))] in
@@ -415,6 +420,9 @@ let Defs = [MPL1, MPL2, P0, P1, P2] in
def VMULU : ArithLogicR<"vmulu", GPR64Opnd, 0, II_DMUL>,
ADD_FM<0x1c, 0x0f>;
+// Move between CPU and coprocessor registers
+def DMFC2_OCTEON : MFC2OP<"dmfc2", GPR64Opnd>, MFC2OP_FM<0x12, 1>;
+def DMTC2_OCTEON : MFC2OP<"dmtc2", GPR64Opnd>, MFC2OP_FM<0x12, 5>;
}
}
diff --git a/contrib/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/contrib/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
index a3995b8c..f84666b 100644
--- a/contrib/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/contrib/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -41,7 +41,7 @@
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionELF.h"
-#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCSymbolELF.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
@@ -594,11 +594,11 @@ void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
break;
case MachineOperand::MO_MachineBasicBlock:
- O << *MO.getMBB()->getSymbol();
+ MO.getMBB()->getSymbol()->print(O, MAI);
return;
case MachineOperand::MO_GlobalAddress:
- O << *getSymbol(MO.getGlobal());
+ getSymbol(MO.getGlobal())->print(O, MAI);
break;
case MachineOperand::MO_BlockAddress: {
@@ -778,7 +778,7 @@ void MipsAsmPrinter::EmitJal(const MCSubtargetInfo &STI, MCSymbol *Symbol) {
MCInst I;
I.setOpcode(Mips::JAL);
I.addOperand(
- MCOperand::createExpr(MCSymbolRefExpr::Create(Symbol, OutContext)));
+ MCOperand::createExpr(MCSymbolRefExpr::create(Symbol, OutContext)));
OutStreamer->EmitInstruction(I, STI);
}
@@ -983,7 +983,8 @@ void MipsAsmPrinter::EmitFPCallStub(
// __call_stub_fp_xxxx:
//
std::string x = "__call_stub_fp_" + std::string(Symbol);
- MCSymbol *Stub = OutContext.getOrCreateSymbol(StringRef(x));
+ MCSymbolELF *Stub =
+ cast<MCSymbolELF>(OutContext.getOrCreateSymbol(StringRef(x)));
TS.emitDirectiveEnt(*Stub);
MCSymbol *MType =
OutContext.getOrCreateSymbol("__call_stub_fp_" + Twine(Symbol));
@@ -1028,10 +1029,10 @@ void MipsAsmPrinter::EmitFPCallStub(
MCSymbol *Tmp = OutContext.createTempSymbol();
OutStreamer->EmitLabel(Tmp);
- const MCSymbolRefExpr *E = MCSymbolRefExpr::Create(Stub, OutContext);
- const MCSymbolRefExpr *T = MCSymbolRefExpr::Create(Tmp, OutContext);
- const MCExpr *T_min_E = MCBinaryExpr::CreateSub(T, E, OutContext);
- OutStreamer->EmitELFSize(Stub, T_min_E);
+ const MCSymbolRefExpr *E = MCSymbolRefExpr::create(Stub, OutContext);
+ const MCSymbolRefExpr *T = MCSymbolRefExpr::create(Tmp, OutContext);
+ const MCExpr *T_min_E = MCBinaryExpr::createSub(T, E, OutContext);
+ OutStreamer->emitELFSize(Stub, T_min_E);
TS.emitDirectiveEnd(x);
OutStreamer->PopSection();
}
diff --git a/contrib/llvm/lib/Target/Mips/MipsFastISel.cpp b/contrib/llvm/lib/Target/Mips/MipsFastISel.cpp
index 4faee10..3d020ab 100644
--- a/contrib/llvm/lib/Target/Mips/MipsFastISel.cpp
+++ b/contrib/llvm/lib/Target/Mips/MipsFastISel.cpp
@@ -82,6 +82,7 @@ class MipsFastISel final : public FastISel {
LLVMContext *Context;
bool fastLowerCall(CallLoweringInfo &CLI) override;
+ bool fastLowerIntrinsicCall(const IntrinsicInst *II) override;
bool TargetSupported;
bool UnsupportedFPMode; // To allow fast-isel to proceed and just not handle
@@ -94,6 +95,7 @@ private:
bool selectLoad(const Instruction *I);
bool selectStore(const Instruction *I);
bool selectBranch(const Instruction *I);
+ bool selectSelect(const Instruction *I);
bool selectCmp(const Instruction *I);
bool selectFPExt(const Instruction *I);
bool selectFPTrunc(const Instruction *I);
@@ -102,6 +104,7 @@ private:
bool selectTrunc(const Instruction *I);
bool selectIntExt(const Instruction *I);
bool selectShift(const Instruction *I);
+ bool selectDivRem(const Instruction *I, unsigned ISDOpcode);
// Utility helper routines.
bool isTypeLegal(Type *Ty, MVT &VT);
@@ -140,6 +143,7 @@ private:
unsigned materializeGV(const GlobalValue *GV, MVT VT);
unsigned materializeInt(const Constant *C, MVT VT);
unsigned materialize32BitInt(int64_t Imm, const TargetRegisterClass *RC);
+ unsigned materializeExternalCallSym(const char *SynName);
MachineInstrBuilder emitInst(unsigned Opc) {
return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc));
@@ -156,6 +160,12 @@ private:
unsigned MemReg, int64_t MemOffset) {
return emitInst(Opc, DstReg).addReg(MemReg).addImm(MemOffset);
}
+
+ unsigned fastEmitInst_rr(unsigned MachineInstOpcode,
+ const TargetRegisterClass *RC,
+ unsigned Op0, bool Op0IsKill,
+ unsigned Op1, bool Op1IsKill);
+
// for some reason, this default is not generated by tablegen
// so we explicitly generate it here.
//
@@ -359,6 +369,15 @@ unsigned MipsFastISel::materializeGV(const GlobalValue *GV, MVT VT) {
return DestReg;
}
+unsigned MipsFastISel::materializeExternalCallSym(const char *SymName) {
+ const TargetRegisterClass *RC = &Mips::GPR32RegClass;
+ unsigned DestReg = createResultReg(RC);
+ emitInst(Mips::LW, DestReg)
+ .addReg(MFI->getGlobalBaseReg())
+ .addExternalSymbol(SymName, MipsII::MO_GOT);
+ return DestReg;
+}
+
// Materialize a constant into a register, and return the register
// number (or zero if we failed to handle it).
unsigned MipsFastISel::fastMaterializeConstant(const Constant *C) {
@@ -463,15 +482,51 @@ bool MipsFastISel::computeAddress(const Value *Obj, Address &Addr) {
}
bool MipsFastISel::computeCallAddress(const Value *V, Address &Addr) {
- const GlobalValue *GV = dyn_cast<GlobalValue>(V);
- if (GV && isa<Function>(GV) && cast<Function>(GV)->isIntrinsic())
- return false;
- if (!GV)
- return false;
+ const User *U = nullptr;
+ unsigned Opcode = Instruction::UserOp1;
+
+ if (const auto *I = dyn_cast<Instruction>(V)) {
+ // Check if the value is defined in the same basic block. This information
+ // is crucial to know whether or not folding an operand is valid.
+ if (I->getParent() == FuncInfo.MBB->getBasicBlock()) {
+ Opcode = I->getOpcode();
+ U = I;
+ }
+ } else if (const auto *C = dyn_cast<ConstantExpr>(V)) {
+ Opcode = C->getOpcode();
+ U = C;
+ }
+
+ switch (Opcode) {
+ default:
+ break;
+ case Instruction::BitCast:
+ // Look past bitcasts if its operand is in the same BB.
+ return computeCallAddress(U->getOperand(0), Addr);
+ break;
+ case Instruction::IntToPtr:
+ // Look past no-op inttoptrs if its operand is in the same BB.
+ if (TLI.getValueType(U->getOperand(0)->getType()) == TLI.getPointerTy())
+ return computeCallAddress(U->getOperand(0), Addr);
+ break;
+ case Instruction::PtrToInt:
+ // Look past no-op ptrtoints if its operand is in the same BB.
+ if (TLI.getValueType(U->getType()) == TLI.getPointerTy())
+ return computeCallAddress(U->getOperand(0), Addr);
+ break;
+ }
+
if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
Addr.setGlobalValue(GV);
return true;
}
+
+ // If all else fails, try to materialize the value in a register.
+ if (!Addr.getGlobalValue()) {
+ Addr.setReg(getRegForValue(V));
+ return Addr.getReg() != 0;
+ }
+
return false;
}
@@ -893,6 +948,50 @@ bool MipsFastISel::selectFPExt(const Instruction *I) {
return true;
}
+bool MipsFastISel::selectSelect(const Instruction *I) {
+ assert(isa<SelectInst>(I) && "Expected a select instruction.");
+
+ MVT VT;
+ if (!isTypeSupported(I->getType(), VT))
+ return false;
+
+ unsigned CondMovOpc;
+ const TargetRegisterClass *RC;
+
+ if (VT.isInteger() && !VT.isVector() && VT.getSizeInBits() <= 32) {
+ CondMovOpc = Mips::MOVN_I_I;
+ RC = &Mips::GPR32RegClass;
+ } else if (VT == MVT::f32) {
+ CondMovOpc = Mips::MOVN_I_S;
+ RC = &Mips::FGR32RegClass;
+ } else if (VT == MVT::f64) {
+ CondMovOpc = Mips::MOVN_I_D32;
+ RC = &Mips::AFGR64RegClass;
+ } else
+ return false;
+
+ const SelectInst *SI = cast<SelectInst>(I);
+ const Value *Cond = SI->getCondition();
+ unsigned Src1Reg = getRegForValue(SI->getTrueValue());
+ unsigned Src2Reg = getRegForValue(SI->getFalseValue());
+ unsigned CondReg = getRegForValue(Cond);
+
+ if (!Src1Reg || !Src2Reg || !CondReg)
+ return false;
+
+ unsigned ResultReg = createResultReg(RC);
+ unsigned TempReg = createResultReg(RC);
+
+ if (!ResultReg || !TempReg)
+ return false;
+
+ emitInst(TargetOpcode::COPY, TempReg).addReg(Src2Reg);
+ emitInst(CondMovOpc, ResultReg)
+ .addReg(Src1Reg).addReg(CondReg).addReg(TempReg);
+ updateValueMap(I, ResultReg);
+ return true;
+}
+
// Attempt to fast-select a floating-point truncate instruction.
bool MipsFastISel::selectFPTrunc(const Instruction *I) {
if (UnsupportedFPMode)
@@ -1135,7 +1234,7 @@ bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) {
bool IsTailCall = CLI.IsTailCall;
bool IsVarArg = CLI.IsVarArg;
const Value *Callee = CLI.Callee;
- // const char *SymName = CLI.SymName;
+ const char *SymName = CLI.SymName;
// Allow SelectionDAG isel to handle tail calls.
if (IsTailCall)
@@ -1182,8 +1281,15 @@ bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) {
if (!processCallArgs(CLI, OutVTs, NumBytes))
return false;
+ if (!Addr.getGlobalValue())
+ return false;
+
// Issue the call.
- unsigned DestAddress = materializeGV(Addr.getGlobalValue(), MVT::i32);
+ unsigned DestAddress;
+ if (SymName)
+ DestAddress = materializeExternalCallSym(SymName);
+ else
+ DestAddress = materializeGV(Addr.getGlobalValue(), MVT::i32);
emitInst(TargetOpcode::COPY, Mips::T9).addReg(DestAddress);
MachineInstrBuilder MIB =
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::JALR),
@@ -1203,6 +1309,98 @@ bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) {
return finishCall(CLI, RetVT, NumBytes);
}
+bool MipsFastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) {
+ switch (II->getIntrinsicID()) {
+ default:
+ return false;
+ case Intrinsic::bswap: {
+ Type *RetTy = II->getCalledFunction()->getReturnType();
+
+ MVT VT;
+ if (!isTypeSupported(RetTy, VT))
+ return false;
+
+ unsigned SrcReg = getRegForValue(II->getOperand(0));
+ if (SrcReg == 0)
+ return false;
+ unsigned DestReg = createResultReg(&Mips::GPR32RegClass);
+ if (DestReg == 0)
+ return false;
+ if (VT == MVT::i16) {
+ if (Subtarget->hasMips32r2()) {
+ emitInst(Mips::WSBH, DestReg).addReg(SrcReg);
+ updateValueMap(II, DestReg);
+ return true;
+ } else {
+ unsigned TempReg[3];
+ for (int i = 0; i < 3; i++) {
+ TempReg[i] = createResultReg(&Mips::GPR32RegClass);
+ if (TempReg[i] == 0)
+ return false;
+ }
+ emitInst(Mips::SLL, TempReg[0]).addReg(SrcReg).addImm(8);
+ emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(8);
+ emitInst(Mips::OR, TempReg[2]).addReg(TempReg[0]).addReg(TempReg[1]);
+ emitInst(Mips::ANDi, DestReg).addReg(TempReg[2]).addImm(0xFFFF);
+ updateValueMap(II, DestReg);
+ return true;
+ }
+ } else if (VT == MVT::i32) {
+ if (Subtarget->hasMips32r2()) {
+ unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
+ emitInst(Mips::WSBH, TempReg).addReg(SrcReg);
+ emitInst(Mips::ROTR, DestReg).addReg(TempReg).addImm(16);
+ updateValueMap(II, DestReg);
+ return true;
+ } else {
+ unsigned TempReg[8];
+ for (int i = 0; i < 8; i++) {
+ TempReg[i] = createResultReg(&Mips::GPR32RegClass);
+ if (TempReg[i] == 0)
+ return false;
+ }
+
+ emitInst(Mips::SRL, TempReg[0]).addReg(SrcReg).addImm(8);
+ emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(24);
+ emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[0]).addImm(0xFF00);
+ emitInst(Mips::OR, TempReg[3]).addReg(TempReg[1]).addReg(TempReg[2]);
+
+ emitInst(Mips::ANDi, TempReg[4]).addReg(SrcReg).addImm(0xFF00);
+ emitInst(Mips::SLL, TempReg[5]).addReg(TempReg[4]).addImm(8);
+
+ emitInst(Mips::SLL, TempReg[6]).addReg(SrcReg).addImm(24);
+ emitInst(Mips::OR, TempReg[7]).addReg(TempReg[3]).addReg(TempReg[5]);
+ emitInst(Mips::OR, DestReg).addReg(TempReg[6]).addReg(TempReg[7]);
+ updateValueMap(II, DestReg);
+ return true;
+ }
+ }
+ return false;
+ }
+ case Intrinsic::memcpy:
+ case Intrinsic::memmove: {
+ const auto *MTI = cast<MemTransferInst>(II);
+ // Don't handle volatile.
+ if (MTI->isVolatile())
+ return false;
+ if (!MTI->getLength()->getType()->isIntegerTy(32))
+ return false;
+ const char *IntrMemName = isa<MemCpyInst>(II) ? "memcpy" : "memmove";
+ return lowerCallTo(II, IntrMemName, II->getNumArgOperands() - 2);
+ }
+ case Intrinsic::memset: {
+ const MemSetInst *MSI = cast<MemSetInst>(II);
+ // Don't handle volatile.
+ if (MSI->isVolatile())
+ return false;
+ if (!MSI->getLength()->getType()->isIntegerTy(32))
+ return false;
+ return lowerCallTo(II, "memset", II->getNumArgOperands() - 2);
+ }
+ }
+ return false;
+}
+
bool MipsFastISel::selectRet(const Instruction *I) {
const Function &F = *I->getParent()->getParent();
const ReturnInst *Ret = cast<ReturnInst>(I);
@@ -1420,6 +1618,50 @@ unsigned MipsFastISel::emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
return Success ? DestReg : 0;
}
+bool MipsFastISel::selectDivRem(const Instruction *I, unsigned ISDOpcode) {
+ EVT DestEVT = TLI.getValueType(I->getType(), true);
+ if (!DestEVT.isSimple())
+ return false;
+
+ MVT DestVT = DestEVT.getSimpleVT();
+ if (DestVT != MVT::i32)
+ return false;
+
+ unsigned DivOpc;
+ switch (ISDOpcode) {
+ default:
+ return false;
+ case ISD::SDIV:
+ case ISD::SREM:
+ DivOpc = Mips::SDIV;
+ break;
+ case ISD::UDIV:
+ case ISD::UREM:
+ DivOpc = Mips::UDIV;
+ break;
+ }
+
+ unsigned Src0Reg = getRegForValue(I->getOperand(0));
+ unsigned Src1Reg = getRegForValue(I->getOperand(1));
+ if (!Src0Reg || !Src1Reg)
+ return false;
+
+ emitInst(DivOpc).addReg(Src0Reg).addReg(Src1Reg);
+ emitInst(Mips::TEQ).addReg(Src1Reg).addReg(Mips::ZERO).addImm(7);
+
+ unsigned ResultReg = createResultReg(&Mips::GPR32RegClass);
+ if (!ResultReg)
+ return false;
+
+ unsigned MFOpc = (ISDOpcode == ISD::SREM || ISDOpcode == ISD::UREM)
+ ? Mips::MFHI
+ : Mips::MFLO;
+ emitInst(MFOpc, ResultReg);
+
+ updateValueMap(I, ResultReg);
+ return true;
+}
+
bool MipsFastISel::selectShift(const Instruction *I) {
MVT RetVT;
@@ -1505,6 +1747,22 @@ bool MipsFastISel::fastSelectInstruction(const Instruction *I) {
return selectLoad(I);
case Instruction::Store:
return selectStore(I);
+ case Instruction::SDiv:
+ if (!selectBinaryOp(I, ISD::SDIV))
+ return selectDivRem(I, ISD::SDIV);
+ return true;
+ case Instruction::UDiv:
+ if (!selectBinaryOp(I, ISD::UDIV))
+ return selectDivRem(I, ISD::UDIV);
+ return true;
+ case Instruction::SRem:
+ if (!selectBinaryOp(I, ISD::SREM))
+ return selectDivRem(I, ISD::SREM);
+ return true;
+ case Instruction::URem:
+ if (!selectBinaryOp(I, ISD::UREM))
+ return selectDivRem(I, ISD::UREM);
+ return true;
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
@@ -1533,6 +1791,8 @@ bool MipsFastISel::fastSelectInstruction(const Instruction *I) {
case Instruction::ICmp:
case Instruction::FCmp:
return selectCmp(I);
+ case Instruction::Select:
+ return selectSelect(I);
}
return false;
}
@@ -1563,6 +1823,33 @@ void MipsFastISel::simplifyAddress(Address &Addr) {
}
}
+unsigned MipsFastISel::fastEmitInst_rr(unsigned MachineInstOpcode,
+ const TargetRegisterClass *RC,
+ unsigned Op0, bool Op0IsKill,
+ unsigned Op1, bool Op1IsKill) {
+ // We treat the MUL instruction in a special way because it clobbers
+ // the HI0 & LO0 registers. The TableGen definition of this instruction can
+ // mark these registers only as implicitly defined. As a result, the
+ // register allocator runs out of registers when this instruction is
+ // followed by another instruction that defines the same registers too.
+ // We can fix this by explicitly marking those registers as dead.
+ if (MachineInstOpcode == Mips::MUL) {
+ unsigned ResultReg = createResultReg(RC);
+ const MCInstrDesc &II = TII.get(MachineInstOpcode);
+ Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs());
+ Op1 = constrainOperandRegClass(II, Op1, II.getNumDefs() + 1);
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, ResultReg)
+ .addReg(Op0, getKillRegState(Op0IsKill))
+ .addReg(Op1, getKillRegState(Op1IsKill))
+ .addReg(Mips::HI0, RegState::ImplicitDefine | RegState::Dead)
+ .addReg(Mips::LO0, RegState::ImplicitDefine | RegState::Dead);
+ return ResultReg;
+ }
+
+ return FastISel::fastEmitInst_rr(MachineInstOpcode, RC, Op0, Op0IsKill, Op1,
+ Op1IsKill);
+}
+
namespace llvm {
FastISel *Mips::createFastISel(FunctionLoweringInfo &funcInfo,
const TargetLibraryInfo *libInfo) {
diff --git a/contrib/llvm/lib/Target/Mips/MipsFrameLowering.cpp b/contrib/llvm/lib/Target/Mips/MipsFrameLowering.cpp
index 826fbaf..a74c8ab 100644
--- a/contrib/llvm/lib/Target/Mips/MipsFrameLowering.cpp
+++ b/contrib/llvm/lib/Target/Mips/MipsFrameLowering.cpp
@@ -90,12 +90,23 @@ const MipsFrameLowering *MipsFrameLowering::create(const MipsSubtarget &ST) {
}
// hasFP - Return true if the specified function should have a dedicated frame
-// pointer register. This is true if the function has variable sized allocas or
-// if frame pointer elimination is disabled.
+// pointer register. This is true if the function has variable sized allocas,
+// if it needs dynamic stack realignment, if frame pointer elimination is
+// disabled, or if the frame address is taken.
bool MipsFrameLowering::hasFP(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
+ const TargetRegisterInfo *TRI = STI.getRegisterInfo();
+
return MF.getTarget().Options.DisableFramePointerElim(MF) ||
- MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken();
+ MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken() ||
+ TRI->needsStackRealignment(MF);
+}
+
+bool MipsFrameLowering::hasBP(const MachineFunction &MF) const {
+ const MachineFrameInfo *MFI = MF.getFrameInfo();
+ const TargetRegisterInfo *TRI = STI.getRegisterInfo();
+
+ return MFI->hasVarSizedObjects() && TRI->needsStackRealignment(MF);
}
uint64_t MipsFrameLowering::estimateStackSize(const MachineFunction &MF) const {
diff --git a/contrib/llvm/lib/Target/Mips/MipsFrameLowering.h b/contrib/llvm/lib/Target/Mips/MipsFrameLowering.h
index 0b51830..5eabd58 100644
--- a/contrib/llvm/lib/Target/Mips/MipsFrameLowering.h
+++ b/contrib/llvm/lib/Target/Mips/MipsFrameLowering.h
@@ -32,6 +32,8 @@ public:
bool hasFP(const MachineFunction &MF) const override;
+ bool hasBP(const MachineFunction &MF) const;
+
bool isFPCloseToIncomingSP() const override { return false; }
void
diff --git a/contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp b/contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp
index 6c7f089..67ddcc4 100644
--- a/contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -3547,7 +3547,8 @@ void MipsTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
}
bool MipsTargetLowering::isLegalAddressingMode(const AddrMode &AM,
- Type *Ty) const {
+ Type *Ty,
+ unsigned AS) const {
// No global is ever allowed as a base.
if (AM.BaseGV)
return false;
diff --git a/contrib/llvm/lib/Target/Mips/MipsISelLowering.h b/contrib/llvm/lib/Target/Mips/MipsISelLowering.h
index 6ea14b5..bc9a1ce 100644
--- a/contrib/llvm/lib/Target/Mips/MipsISelLowering.h
+++ b/contrib/llvm/lib/Target/Mips/MipsISelLowering.h
@@ -514,7 +514,8 @@ namespace llvm {
return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
}
- bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const override;
+ bool isLegalAddressingMode(const AddrMode &AM, Type *Ty,
+ unsigned AS) const override;
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
diff --git a/contrib/llvm/lib/Target/Mips/MipsInstrFormats.td b/contrib/llvm/lib/Target/Mips/MipsInstrFormats.td
index 02ecf32..5f4fcc3 100644
--- a/contrib/llvm/lib/Target/Mips/MipsInstrFormats.td
+++ b/contrib/llvm/lib/Target/Mips/MipsInstrFormats.td
@@ -226,6 +226,18 @@ class MFC3OP_FM<bits<6> op, bits<5> mfmt>
let Inst{2-0} = sel;
}
+class MFC2OP_FM<bits<6> op, bits<5> mfmt> : StdArch {
+ bits<5> rt;
+ bits<16> imm16;
+
+ bits<32> Inst;
+
+ let Inst{31-26} = op;
+ let Inst{25-21} = mfmt;
+ let Inst{20-16} = rt;
+ let Inst{15-0} = imm16;
+}
+
class ADD_FM<bits<6> op, bits<6> funct> : StdArch {
bits<5> rd;
bits<5> rs;
diff --git a/contrib/llvm/lib/Target/Mips/MipsMCInstLower.cpp b/contrib/llvm/lib/Target/Mips/MipsMCInstLower.cpp
index 9e61180..6b2a44d 100644
--- a/contrib/llvm/lib/Target/Mips/MipsMCInstLower.cpp
+++ b/contrib/llvm/lib/Target/Mips/MipsMCInstLower.cpp
@@ -101,7 +101,7 @@ MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
llvm_unreachable("<unknown operand type>");
}
- const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol, Kind, *Ctx);
+ const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, Kind, *Ctx);
if (!Offset)
return MCOperand::createExpr(MCSym);
@@ -109,8 +109,8 @@ MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
// Assume offset is never negative.
assert(Offset > 0);
- const MCConstantExpr *OffsetExpr = MCConstantExpr::Create(Offset, *Ctx);
- const MCBinaryExpr *Add = MCBinaryExpr::CreateAdd(MCSym, OffsetExpr, *Ctx);
+ const MCConstantExpr *OffsetExpr = MCConstantExpr::create(Offset, *Ctx);
+ const MCBinaryExpr *Add = MCBinaryExpr::createAdd(MCSym, OffsetExpr, *Ctx);
return MCOperand::createExpr(Add);
}
@@ -155,11 +155,11 @@ MCOperand MipsMCInstLower::LowerOperand(const MachineOperand &MO,
MCOperand MipsMCInstLower::createSub(MachineBasicBlock *BB1,
MachineBasicBlock *BB2,
MCSymbolRefExpr::VariantKind Kind) const {
- const MCSymbolRefExpr *Sym1 = MCSymbolRefExpr::Create(BB1->getSymbol(), *Ctx);
- const MCSymbolRefExpr *Sym2 = MCSymbolRefExpr::Create(BB2->getSymbol(), *Ctx);
- const MCBinaryExpr *Sub = MCBinaryExpr::CreateSub(Sym1, Sym2, *Ctx);
+ const MCSymbolRefExpr *Sym1 = MCSymbolRefExpr::create(BB1->getSymbol(), *Ctx);
+ const MCSymbolRefExpr *Sym2 = MCSymbolRefExpr::create(BB2->getSymbol(), *Ctx);
+ const MCBinaryExpr *Sub = MCBinaryExpr::createSub(Sym1, Sym2, *Ctx);
- return MCOperand::createExpr(MipsMCExpr::Create(Kind, Sub, *Ctx));
+ return MCOperand::createExpr(MipsMCExpr::create(Kind, Sub, *Ctx));
}
void MipsMCInstLower::
diff --git a/contrib/llvm/lib/Target/Mips/MipsRegisterInfo.cpp b/contrib/llvm/lib/Target/Mips/MipsRegisterInfo.cpp
index f72fb4d..f6647e6 100644
--- a/contrib/llvm/lib/Target/Mips/MipsRegisterInfo.cpp
+++ b/contrib/llvm/lib/Target/Mips/MipsRegisterInfo.cpp
@@ -21,6 +21,7 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/IR/Constants.h"
@@ -178,6 +179,15 @@ getReservedRegs(const MachineFunction &MF) const {
else {
Reserved.set(Mips::FP);
Reserved.set(Mips::FP_64);
+
+ // Reserve the base register if we need to both realign the stack and
+ // allocate variable-sized objects at runtime. This should test the
+ // same conditions as MipsFrameLowering::hasBP().
+ if (needsStackRealignment(MF) &&
+ MF.getFrameInfo()->hasVarSizedObjects()) {
+ Reserved.set(Mips::S7);
+ Reserved.set(Mips::S7_64);
+ }
}
}
@@ -271,6 +281,67 @@ getFrameRegister(const MachineFunction &MF) const {
else
return TFI->hasFP(MF) ? (IsN64 ? Mips::FP_64 : Mips::FP) :
(IsN64 ? Mips::SP_64 : Mips::SP);
+}
+bool MipsRegisterInfo::canRealignStack(const MachineFunction &MF) const {
+ const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
+ unsigned FP = Subtarget.isGP32bit() ? Mips::FP : Mips::FP_64;
+ unsigned BP = Subtarget.isGP32bit() ? Mips::S7 : Mips::S7_64;
+
+ // Support dynamic stack realignment only for targets with standard encoding.
+ if (!Subtarget.hasStandardEncoding())
+ return false;
+
+ // We can't perform dynamic stack realignment if we can't reserve the
+ // frame pointer register.
+ if (!MF.getRegInfo().canReserveReg(FP))
+ return false;
+
+ // We can realign the stack if we know the maximum call frame size and we
+ // don't have variable sized objects.
+ if (Subtarget.getFrameLowering()->hasReservedCallFrame(MF))
+ return true;
+
+ // We have to reserve the base pointer register in the presence of variable
+ // sized objects.
+ return MF.getRegInfo().canReserveReg(BP);
}
+bool MipsRegisterInfo::needsStackRealignment(const MachineFunction &MF) const {
+ const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
+ const MachineFrameInfo *MFI = MF.getFrameInfo();
+
+ bool CanRealign = canRealignStack(MF);
+
+ // Avoid realigning functions that explicitly do not want to be realigned.
+ // Normally, we should report an error when a function should be dynamically
+ // realigned but also has the attribute no-realign-stack. Unfortunately,
+ // with this attribute, MachineFrameInfo clamps each new object's alignment
+ // to that of the stack's alignment as specified by the ABI. As a result,
+ // the information of whether we have objects with larger alignment
+ // requirement than the stack's alignment is already lost at this point.
+ if (MF.getFunction()->hasFnAttribute("no-realign-stack"))
+ return false;
+
+ const Function *F = MF.getFunction();
+ if (F->hasFnAttribute(Attribute::StackAlignment)) {
+#ifdef DEBUG
+ if (!CanRealign)
+ DEBUG(dbgs() << "It's not possible to realign the stack of the function: "
+ << F->getName() << "\n");
+#endif
+ return CanRealign;
+ }
+
+ unsigned StackAlignment = Subtarget.getFrameLowering()->getStackAlignment();
+ if (MFI->getMaxAlignment() > StackAlignment) {
+#ifdef DEBUG
+ if (!CanRealign)
+ DEBUG(dbgs() << "It's not possible to realign the stack of the function: "
+ << F->getName() << "\n");
+#endif
+ return CanRealign;
+ }
+
+ return false;
+}
diff --git a/contrib/llvm/lib/Target/Mips/MipsRegisterInfo.h b/contrib/llvm/lib/Target/Mips/MipsRegisterInfo.h
index 76e84bd..ee1f6bc 100644
--- a/contrib/llvm/lib/Target/Mips/MipsRegisterInfo.h
+++ b/contrib/llvm/lib/Target/Mips/MipsRegisterInfo.h
@@ -57,6 +57,14 @@ public:
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS = nullptr) const override;
+ void processFunctionBeforeFrameFinalized(MachineFunction &MF,
+ RegScavenger *RS = nullptr) const;
+
+ // Stack realignment queries.
+ bool canRealignStack(const MachineFunction &MF) const;
+
+ bool needsStackRealignment(const MachineFunction &MF) const override;
+
/// Debug information queries.
unsigned getFrameRegister(const MachineFunction &MF) const override;
diff --git a/contrib/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp b/contrib/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp
index 19efa59..ec7bf31 100644
--- a/contrib/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp
+++ b/contrib/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp
@@ -382,6 +382,11 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF,
unsigned FP = ABI.GetFramePtr();
unsigned ZERO = ABI.GetNullPtr();
unsigned ADDu = ABI.GetPtrAdduOp();
+ unsigned ADDiu = ABI.GetPtrAddiuOp();
+ unsigned AND = ABI.IsN64() ? Mips::AND64 : Mips::AND;
+
+ const TargetRegisterClass *RC = ABI.ArePtrs64bit() ?
+ &Mips::GPR64RegClass : &Mips::GPR32RegClass;
// First, compute final stack size.
uint64_t StackSize = MFI->getStackSize();
@@ -464,15 +469,12 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF,
}
if (MipsFI->callsEhReturn()) {
- const TargetRegisterClass *PtrRC =
- ABI.ArePtrs64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
-
// Insert instructions that spill eh data registers.
for (int I = 0; I < 4; ++I) {
if (!MBB.isLiveIn(ABI.GetEhDataReg(I)))
MBB.addLiveIn(ABI.GetEhDataReg(I));
TII.storeRegToStackSlot(MBB, MBBI, ABI.GetEhDataReg(I), false,
- MipsFI->getEhDataRegFI(I), PtrRC, &RegInfo);
+ MipsFI->getEhDataRegFI(I), RC, &RegInfo);
}
// Emit .cfi_offset directives for eh data registers.
@@ -497,6 +499,26 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF,
nullptr, MRI->getDwarfRegNum(FP, true)));
BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
.addCFIIndex(CFIIndex);
+
+ if (RegInfo.needsStackRealignment(MF)) {
+ // addiu $Reg, $zero, -MaxAlignment
+ // andi $sp, $sp, $Reg
+ unsigned VR = MF.getRegInfo().createVirtualRegister(RC);
+ assert(isInt<16>(MFI->getMaxAlignment()) &&
+ "Function's alignment size requirement is not supported.");
+ int MaxAlign = - (signed) MFI->getMaxAlignment();
+
+ BuildMI(MBB, MBBI, dl, TII.get(ADDiu), VR).addReg(ZERO) .addImm(MaxAlign);
+ BuildMI(MBB, MBBI, dl, TII.get(AND), SP).addReg(SP).addReg(VR);
+
+ if (hasBP(MF)) {
+ // move $s7, $sp
+ unsigned BP = STI.isABI_N64() ? Mips::S7_64 : Mips::S7;
+ BuildMI(MBB, MBBI, dl, TII.get(ADDu), BP)
+ .addReg(SP)
+ .addReg(ZERO);
+ }
+ }
}
}
@@ -606,10 +628,14 @@ processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
MipsABIInfo ABI = STI.getABI();
unsigned FP = ABI.GetFramePtr();
+ unsigned BP = ABI.IsN64() ? Mips::S7_64 : Mips::S7;
// Mark $fp as used if function has dedicated frame pointer.
if (hasFP(MF))
MRI.setPhysRegUsed(FP);
+ // Mark $s7 as used if function has dedicated base pointer.
+ if (hasBP(MF))
+ MRI.setPhysRegUsed(BP);
// Create spill slots for eh data registers if function calls eh_return.
if (MipsFI->callsEhReturn())
diff --git a/contrib/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp b/contrib/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp
index 8c74a98..132c3a1 100644
--- a/contrib/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp
+++ b/contrib/llvm/lib/Target/Mips/MipsSERegisterInfo.cpp
@@ -110,8 +110,11 @@ void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
MachineFunction &MF = *MI.getParent()->getParent();
MachineFrameInfo *MFI = MF.getFrameInfo();
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
+
MipsABIInfo ABI =
static_cast<const MipsTargetMachine &>(MF.getTarget()).getABI();
+ const MipsRegisterInfo *RegInfo =
+ static_cast<const MipsRegisterInfo *>(MF.getSubtarget().getRegisterInfo());
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
int MinCSFI = 0;
@@ -135,7 +138,14 @@ void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
if ((FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI) || EhDataRegFI)
FrameReg = ABI.GetStackPtr();
- else
+ else if (RegInfo->needsStackRealignment(MF)) {
+ if (MFI->hasVarSizedObjects() && !MFI->isFixedObjectIndex(FrameIndex))
+ FrameReg = ABI.GetBasePtr();
+ else if (MFI->isFixedObjectIndex(FrameIndex))
+ FrameReg = getFrameRegister(MF);
+ else
+ FrameReg = ABI.GetStackPtr();
+ } else
FrameReg = getFrameRegister(MF);
// Calculate final offset.
diff --git a/contrib/llvm/lib/Target/Mips/MipsTargetStreamer.h b/contrib/llvm/lib/Target/Mips/MipsTargetStreamer.h
index 22b0c6c..fed0600 100644
--- a/contrib/llvm/lib/Target/Mips/MipsTargetStreamer.h
+++ b/contrib/llvm/lib/Target/Mips/MipsTargetStreamer.h
@@ -72,6 +72,8 @@ public:
virtual void emitDirectiveSetNoDsp();
virtual void emitDirectiveSetPop();
virtual void emitDirectiveSetPush();
+ virtual void emitDirectiveSetSoftFloat();
+ virtual void emitDirectiveSetHardFloat();
// PIC support
virtual void emitDirectiveCpLoad(unsigned RegNo);
@@ -188,6 +190,8 @@ public:
void emitDirectiveSetNoDsp() override;
void emitDirectiveSetPop() override;
void emitDirectiveSetPush() override;
+ void emitDirectiveSetSoftFloat() override;
+ void emitDirectiveSetHardFloat() override;
// PIC support
void emitDirectiveCpLoad(unsigned RegNo) override;
diff --git a/contrib/llvm/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp b/contrib/llvm/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp
index 3615c14..6a65943 100644
--- a/contrib/llvm/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp
+++ b/contrib/llvm/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp
@@ -23,9 +23,9 @@ extern "C" void LLVMInitializeMipsTargetInfo() {
/*HasJIT=*/true> Y(TheMipselTarget, "mipsel", "Mipsel");
RegisterTarget<Triple::mips64,
- /*HasJIT=*/false> A(TheMips64Target, "mips64", "Mips64 [experimental]");
+ /*HasJIT=*/true> A(TheMips64Target, "mips64", "Mips64 [experimental]");
RegisterTarget<Triple::mips64el,
- /*HasJIT=*/false> B(TheMips64elTarget,
+ /*HasJIT=*/true> B(TheMips64elTarget,
"mips64el", "Mips64el [experimental]");
}
OpenPOWER on IntegriCloud