[Mips] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC).

llvm-svn: 293565
This commit is contained in:
Eugene Zelenko 2017-01-30 23:21:32 +00:00
parent 365c9bd941
commit dde94e4c4f
6 changed files with 310 additions and 205 deletions

View File

@ -7,47 +7,67 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "MCTargetDesc/MipsABIFlagsSection.h"
#include "MCTargetDesc/MipsABIInfo.h" #include "MCTargetDesc/MipsABIInfo.h"
#include "MCTargetDesc/MipsMCExpr.h" #include "MCTargetDesc/MipsMCExpr.h"
#include "MCTargetDesc/MipsMCTargetDesc.h" #include "MCTargetDesc/MipsMCTargetDesc.h"
#include "MipsRegisterInfo.h"
#include "MipsTargetObjectFile.h"
#include "MipsTargetStreamer.h" #include "MipsTargetStreamer.h"
#include "MCTargetDesc/MipsBaseInfo.h" #include "MCTargetDesc/MipsBaseInfo.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCContext.h" #include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h" #include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstBuilder.h" #include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h" #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h" #include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCSymbolELF.h"
#include "llvm/MC/MCValue.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/ELF.h" #include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h" #include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/SourceMgr.h" #include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h" #include <algorithm>
#include <cassert>
#include <cstdint>
#include <memory> #include <memory>
#include <string>
#include <utility>
using namespace llvm; using namespace llvm;
#define DEBUG_TYPE "mips-asm-parser" #define DEBUG_TYPE "mips-asm-parser"
namespace llvm { namespace llvm {
class MCInstrInfo; class MCInstrInfo;
}
} // end namespace llvm
namespace { namespace {
class MipsAssemblerOptions { class MipsAssemblerOptions {
public: public:
MipsAssemblerOptions(const FeatureBitset &Features_) : MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
MipsAssemblerOptions(const MipsAssemblerOptions *Opts) { MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
ATReg = Opts->getATRegIndex(); ATReg = Opts->getATRegIndex();
@ -84,12 +104,13 @@ public:
static const FeatureBitset AllArchRelatedMask; static const FeatureBitset AllArchRelatedMask;
private: private:
unsigned ATReg; unsigned ATReg = 1;
bool Reorder; bool Reorder = true;
bool Macro; bool Macro = true;
FeatureBitset Features; FeatureBitset Features;
}; };
}
} // end anonymous namespace
const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = { const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3, Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
@ -103,6 +124,7 @@ const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
}; };
namespace { namespace {
class MipsAsmParser : public MCTargetAsmParser { class MipsAsmParser : public MCTargetAsmParser {
MipsTargetStreamer &getTargetStreamer() { MipsTargetStreamer &getTargetStreamer() {
MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
@ -466,9 +488,11 @@ public:
bool isGP64bit() const { bool isGP64bit() const {
return getSTI().getFeatureBits()[Mips::FeatureGP64Bit]; return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
} }
bool isFP64bit() const { bool isFP64bit() const {
return getSTI().getFeatureBits()[Mips::FeatureFP64Bit]; return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
} }
const MipsABIInfo &getABI() const { return ABI; } const MipsABIInfo &getABI() const { return ABI; }
bool isABI_N32() const { return ABI.IsN32(); } bool isABI_N32() const { return ABI.IsN32(); }
bool isABI_N64() const { return ABI.IsN64(); } bool isABI_N64() const { return ABI.IsN64(); }
@ -484,48 +508,63 @@ public:
bool inMicroMipsMode() const { bool inMicroMipsMode() const {
return getSTI().getFeatureBits()[Mips::FeatureMicroMips]; return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
} }
bool hasMips1() const { bool hasMips1() const {
return getSTI().getFeatureBits()[Mips::FeatureMips1]; return getSTI().getFeatureBits()[Mips::FeatureMips1];
} }
bool hasMips2() const { bool hasMips2() const {
return getSTI().getFeatureBits()[Mips::FeatureMips2]; return getSTI().getFeatureBits()[Mips::FeatureMips2];
} }
bool hasMips3() const { bool hasMips3() const {
return getSTI().getFeatureBits()[Mips::FeatureMips3]; return getSTI().getFeatureBits()[Mips::FeatureMips3];
} }
bool hasMips4() const { bool hasMips4() const {
return getSTI().getFeatureBits()[Mips::FeatureMips4]; return getSTI().getFeatureBits()[Mips::FeatureMips4];
} }
bool hasMips5() const { bool hasMips5() const {
return getSTI().getFeatureBits()[Mips::FeatureMips5]; return getSTI().getFeatureBits()[Mips::FeatureMips5];
} }
bool hasMips32() const { bool hasMips32() const {
return getSTI().getFeatureBits()[Mips::FeatureMips32]; return getSTI().getFeatureBits()[Mips::FeatureMips32];
} }
bool hasMips64() const { bool hasMips64() const {
return getSTI().getFeatureBits()[Mips::FeatureMips64]; return getSTI().getFeatureBits()[Mips::FeatureMips64];
} }
bool hasMips32r2() const { bool hasMips32r2() const {
return getSTI().getFeatureBits()[Mips::FeatureMips32r2]; return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
} }
bool hasMips64r2() const { bool hasMips64r2() const {
return getSTI().getFeatureBits()[Mips::FeatureMips64r2]; return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
} }
bool hasMips32r3() const { bool hasMips32r3() const {
return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]); return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
} }
bool hasMips64r3() const { bool hasMips64r3() const {
return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]); return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
} }
bool hasMips32r5() const { bool hasMips32r5() const {
return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]); return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
} }
bool hasMips64r5() const { bool hasMips64r5() const {
return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]); return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
} }
bool hasMips32r6() const { bool hasMips32r6() const {
return getSTI().getFeatureBits()[Mips::FeatureMips32r6]; return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
} }
bool hasMips64r6() const { bool hasMips64r6() const {
return getSTI().getFeatureBits()[Mips::FeatureMips64r6]; return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
} }
@ -533,15 +572,19 @@ public:
bool hasDSP() const { bool hasDSP() const {
return getSTI().getFeatureBits()[Mips::FeatureDSP]; return getSTI().getFeatureBits()[Mips::FeatureDSP];
} }
bool hasDSPR2() const { bool hasDSPR2() const {
return getSTI().getFeatureBits()[Mips::FeatureDSPR2]; return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
} }
bool hasDSPR3() const { bool hasDSPR3() const {
return getSTI().getFeatureBits()[Mips::FeatureDSPR3]; return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
} }
bool hasMSA() const { bool hasMSA() const {
return getSTI().getFeatureBits()[Mips::FeatureMSA]; return getSTI().getFeatureBits()[Mips::FeatureMSA];
} }
bool hasCnMips() const { bool hasCnMips() const {
return (getSTI().getFeatureBits()[Mips::FeatureCnMips]); return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
} }
@ -627,9 +670,6 @@ public:
} }
} }
}; };
}
namespace {
/// MipsOperand - Instances of this class represent a parsed Mips machine /// MipsOperand - Instances of this class represent a parsed Mips machine
/// instruction. /// instruction.
@ -671,6 +711,22 @@ public:
MipsOperand(KindTy K, MipsAsmParser &Parser) MipsOperand(KindTy K, MipsAsmParser &Parser)
: MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {} : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
~MipsOperand() override {
switch (Kind) {
case k_Immediate:
break;
case k_Memory:
delete Mem.Base;
break;
case k_RegList:
delete RegList.List;
case k_RegisterIndex:
case k_Token:
case k_RegPair:
break;
}
}
private: private:
/// For diagnostics, and checking the assembler temporary /// For diagnostics, and checking the assembler temporary
MipsAsmParser &AsmParser; MipsAsmParser &AsmParser;
@ -716,7 +772,7 @@ private:
const MCRegisterInfo *RegInfo, const MCRegisterInfo *RegInfo,
SMLoc S, SMLoc E, SMLoc S, SMLoc E,
MipsAsmParser &Parser) { MipsAsmParser &Parser) {
auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser); auto Op = llvm::make_unique<MipsOperand>(k_RegisterIndex, Parser);
Op->RegIdx.Index = Index; Op->RegIdx.Index = Index;
Op->RegIdx.RegInfo = RegInfo; Op->RegIdx.RegInfo = RegInfo;
Op->RegIdx.Kind = RegKind; Op->RegIdx.Kind = RegKind;
@ -1104,45 +1160,58 @@ public:
// $0/$zero here so that MCK_ZERO works correctly. // $0/$zero here so that MCK_ZERO works correctly.
return isGPRAsmReg() && RegIdx.Index == 0; return isGPRAsmReg() && RegIdx.Index == 0;
} }
bool isRegIdx() const { return Kind == k_RegisterIndex; } bool isRegIdx() const { return Kind == k_RegisterIndex; }
bool isImm() const override { return Kind == k_Immediate; } bool isImm() const override { return Kind == k_Immediate; }
bool isConstantImm() const { bool isConstantImm() const {
int64_t Res; int64_t Res;
return isImm() && getImm()->evaluateAsAbsolute(Res); return isImm() && getImm()->evaluateAsAbsolute(Res);
} }
bool isConstantImmz() const { bool isConstantImmz() const {
return isConstantImm() && getConstantImm() == 0; return isConstantImm() && getConstantImm() == 0;
} }
template <unsigned Bits, int Offset = 0> bool isConstantUImm() const { template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset); return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
} }
template <unsigned Bits> bool isSImm() const { template <unsigned Bits> bool isSImm() const {
return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm(); return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
} }
template <unsigned Bits> bool isUImm() const { template <unsigned Bits> bool isUImm() const {
return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm(); return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
} }
template <unsigned Bits> bool isAnyImm() const { template <unsigned Bits> bool isAnyImm() const {
return isConstantImm() ? (isInt<Bits>(getConstantImm()) || return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
isUInt<Bits>(getConstantImm())) isUInt<Bits>(getConstantImm()))
: isImm(); : isImm();
} }
template <unsigned Bits, int Offset = 0> bool isConstantSImm() const { template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
return isConstantImm() && isInt<Bits>(getConstantImm() - Offset); return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
} }
template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const { template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
return isConstantImm() && getConstantImm() >= Bottom && return isConstantImm() && getConstantImm() >= Bottom &&
getConstantImm() <= Top; getConstantImm() <= Top;
} }
bool isToken() const override { bool isToken() const override {
// Note: It's not possible to pretend that other operand kinds are tokens. // Note: It's not possible to pretend that other operand kinds are tokens.
// The matcher emitter checks tokens first. // The matcher emitter checks tokens first.
return Kind == k_Token; return Kind == k_Token;
} }
bool isMem() const override { return Kind == k_Memory; } bool isMem() const override { return Kind == k_Memory; }
bool isConstantMemOff() const { bool isConstantMemOff() const {
return isMem() && isa<MCConstantExpr>(getMemOff()); return isMem() && isa<MCConstantExpr>(getMemOff());
} }
// Allow relocation operators. // Allow relocation operators.
// FIXME: This predicate and others need to look through binary expressions // FIXME: This predicate and others need to look through binary expressions
// and determine whether a Value is a constant or not. // and determine whether a Value is a constant or not.
@ -1160,28 +1229,34 @@ public:
bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr); bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant()); return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
} }
bool isMemWithGRPMM16Base() const { bool isMemWithGRPMM16Base() const {
return isMem() && getMemBase()->isMM16AsmReg(); return isMem() && getMemBase()->isMM16AsmReg();
} }
template <unsigned Bits> bool isMemWithUimmOffsetSP() const { template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff()) return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
&& getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP); && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
} }
template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const { template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff()) return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
&& (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx() && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
&& (getMemBase()->getGPR32Reg() == Mips::SP); && (getMemBase()->getGPR32Reg() == Mips::SP);
} }
template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const { template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()) return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
&& (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx() && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
&& (getMemBase()->getGPR32Reg() == Mips::GP); && (getMemBase()->getGPR32Reg() == Mips::GP);
} }
template <unsigned Bits, unsigned ShiftLeftAmount> template <unsigned Bits, unsigned ShiftLeftAmount>
bool isScaledUImm() const { bool isScaledUImm() const {
return isConstantImm() && return isConstantImm() &&
isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm()); isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
} }
template <unsigned Bits, unsigned ShiftLeftAmount> template <unsigned Bits, unsigned ShiftLeftAmount>
bool isScaledSImm() const { bool isScaledSImm() const {
if (isConstantImm() && isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm())) if (isConstantImm() && isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
@ -1193,6 +1268,7 @@ public:
bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr); bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant()); return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
} }
bool isRegList16() const { bool isRegList16() const {
if (!isRegList()) if (!isRegList())
return false; return false;
@ -1217,14 +1293,18 @@ public:
return true; return true;
} }
bool isInvNum() const { return Kind == k_Immediate; } bool isInvNum() const { return Kind == k_Immediate; }
bool isLSAImm() const { bool isLSAImm() const {
if (!isConstantImm()) if (!isConstantImm())
return false; return false;
int64_t Val = getConstantImm(); int64_t Val = getConstantImm();
return 1 <= Val && Val <= 4; return 1 <= Val && Val <= 4;
} }
bool isRegList() const { return Kind == k_RegList; } bool isRegList() const { return Kind == k_RegList; }
bool isMovePRegPair() const { bool isMovePRegPair() const {
if (Kind != k_RegList || RegList.List->size() != 2) if (Kind != k_RegList || RegList.List->size() != 2)
return false; return false;
@ -1257,6 +1337,7 @@ public:
assert(Kind == k_Token && "Invalid access!"); assert(Kind == k_Token && "Invalid access!");
return StringRef(Tok.Data, Tok.Length); return StringRef(Tok.Data, Tok.Length);
} }
bool isRegPair() const { bool isRegPair() const {
return Kind == k_RegPair && RegIdx.Index <= 30; return Kind == k_RegPair && RegIdx.Index <= 30;
} }
@ -1310,7 +1391,7 @@ public:
static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S, static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
MipsAsmParser &Parser) { MipsAsmParser &Parser) {
auto Op = make_unique<MipsOperand>(k_Token, Parser); auto Op = llvm::make_unique<MipsOperand>(k_Token, Parser);
Op->Tok.Data = Str.data(); Op->Tok.Data = Str.data();
Op->Tok.Length = Str.size(); Op->Tok.Length = Str.size();
Op->StartLoc = S; Op->StartLoc = S;
@ -1385,7 +1466,7 @@ public:
static std::unique_ptr<MipsOperand> static std::unique_ptr<MipsOperand>
CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) { CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
auto Op = make_unique<MipsOperand>(k_Immediate, Parser); auto Op = llvm::make_unique<MipsOperand>(k_Immediate, Parser);
Op->Imm.Val = Val; Op->Imm.Val = Val;
Op->StartLoc = S; Op->StartLoc = S;
Op->EndLoc = E; Op->EndLoc = E;
@ -1395,7 +1476,7 @@ public:
static std::unique_ptr<MipsOperand> static std::unique_ptr<MipsOperand>
CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S, CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
SMLoc E, MipsAsmParser &Parser) { SMLoc E, MipsAsmParser &Parser) {
auto Op = make_unique<MipsOperand>(k_Memory, Parser); auto Op = llvm::make_unique<MipsOperand>(k_Memory, Parser);
Op->Mem.Base = Base.release(); Op->Mem.Base = Base.release();
Op->Mem.Off = Off; Op->Mem.Off = Off;
Op->StartLoc = S; Op->StartLoc = S;
@ -1406,9 +1487,9 @@ public:
static std::unique_ptr<MipsOperand> static std::unique_ptr<MipsOperand>
CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc, CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
MipsAsmParser &Parser) { MipsAsmParser &Parser) {
assert (Regs.size() > 0 && "Empty list not allowed"); assert(Regs.size() > 0 && "Empty list not allowed");
auto Op = make_unique<MipsOperand>(k_RegList, Parser); auto Op = llvm::make_unique<MipsOperand>(k_RegList, Parser);
Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end()); Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
Op->StartLoc = StartLoc; Op->StartLoc = StartLoc;
Op->EndLoc = EndLoc; Op->EndLoc = EndLoc;
@ -1418,7 +1499,7 @@ public:
static std::unique_ptr<MipsOperand> CreateRegPair(const MipsOperand &MOP, static std::unique_ptr<MipsOperand> CreateRegPair(const MipsOperand &MOP,
SMLoc S, SMLoc E, SMLoc S, SMLoc E,
MipsAsmParser &Parser) { MipsAsmParser &Parser) {
auto Op = make_unique<MipsOperand>(k_RegPair, Parser); auto Op = llvm::make_unique<MipsOperand>(k_RegPair, Parser);
Op->RegIdx.Index = MOP.RegIdx.Index; Op->RegIdx.Index = MOP.RegIdx.Index;
Op->RegIdx.RegInfo = MOP.RegIdx.RegInfo; Op->RegIdx.RegInfo = MOP.RegIdx.RegInfo;
Op->RegIdx.Kind = MOP.RegIdx.Kind; Op->RegIdx.Kind = MOP.RegIdx.Kind;
@ -1430,11 +1511,13 @@ public:
bool isGPRAsmReg() const { bool isGPRAsmReg() const {
return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31; return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
} }
bool isMM16AsmReg() const { bool isMM16AsmReg() const {
if (!(isRegIdx() && RegIdx.Kind)) if (!(isRegIdx() && RegIdx.Kind))
return false; return false;
return ((RegIdx.Index >= 2 && RegIdx.Index <= 7) return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
|| RegIdx.Index == 16 || RegIdx.Index == 17); || RegIdx.Index == 16 || RegIdx.Index == 17);
} }
bool isMM16AsmRegZero() const { bool isMM16AsmRegZero() const {
if (!(isRegIdx() && RegIdx.Kind)) if (!(isRegIdx() && RegIdx.Kind))
@ -1443,42 +1526,53 @@ public:
(RegIdx.Index >= 2 && RegIdx.Index <= 7) || (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
RegIdx.Index == 17); RegIdx.Index == 17);
} }
bool isMM16AsmRegMoveP() const { bool isMM16AsmRegMoveP() const {
if (!(isRegIdx() && RegIdx.Kind)) if (!(isRegIdx() && RegIdx.Kind))
return false; return false;
return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) || return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
(RegIdx.Index >= 16 && RegIdx.Index <= 20)); (RegIdx.Index >= 16 && RegIdx.Index <= 20));
} }
bool isFGRAsmReg() const { bool isFGRAsmReg() const {
// AFGR64 is $0-$15 but we handle this in getAFGR64() // AFGR64 is $0-$15 but we handle this in getAFGR64()
return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31; return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
} }
bool isHWRegsAsmReg() const { bool isHWRegsAsmReg() const {
return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31; return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
} }
bool isCCRAsmReg() const { bool isCCRAsmReg() const {
return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31; return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
} }
bool isFCCAsmReg() const { bool isFCCAsmReg() const {
if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC)) if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
return false; return false;
return RegIdx.Index <= 7; return RegIdx.Index <= 7;
} }
bool isACCAsmReg() const { bool isACCAsmReg() const {
return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3; return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
} }
bool isCOP0AsmReg() const { bool isCOP0AsmReg() const {
return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31; return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
} }
bool isCOP2AsmReg() const { bool isCOP2AsmReg() const {
return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31; return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
} }
bool isCOP3AsmReg() const { bool isCOP3AsmReg() const {
return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31; return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
} }
bool isMSA128AsmReg() const { bool isMSA128AsmReg() const {
return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31; return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
} }
bool isMSACtrlAsmReg() const { bool isMSACtrlAsmReg() const {
return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7; return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
} }
@ -1488,22 +1582,6 @@ public:
/// getEndLoc - Get the location of the last token of this operand. /// getEndLoc - Get the location of the last token of this operand.
SMLoc getEndLoc() const override { return EndLoc; } SMLoc getEndLoc() const override { return EndLoc; }
virtual ~MipsOperand() {
switch (Kind) {
case k_Immediate:
break;
case k_Memory:
delete Mem.Base;
break;
case k_RegList:
delete RegList.List;
case k_RegisterIndex:
case k_Token:
case k_RegPair:
break;
}
}
void print(raw_ostream &OS) const override { void print(raw_ostream &OS) const override {
switch (Kind) { switch (Kind) {
case k_Immediate: case k_Immediate:
@ -1553,11 +1631,15 @@ public:
} }
} }
}; // class MipsOperand }; // class MipsOperand
} // namespace
} // end anonymous namespace
namespace llvm { namespace llvm {
extern const MCInstrDesc MipsInsts[]; extern const MCInstrDesc MipsInsts[];
}
} // end namespace llvm
static const MCInstrDesc &getInstDesc(unsigned Opcode) { static const MCInstrDesc &getInstDesc(unsigned Opcode) {
return MipsInsts[Opcode]; return MipsInsts[Opcode];
} }
@ -2904,7 +2986,7 @@ bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
unsigned Opcode = Inst.getOpcode(); unsigned Opcode = Inst.getOpcode();
unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM; unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
assert (Inst.getOperand(OpNum - 1).isImm() && assert(Inst.getOperand(OpNum - 1).isImm() &&
Inst.getOperand(OpNum - 2).isReg() && Inst.getOperand(OpNum - 2).isReg() &&
Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand."); Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
@ -3503,8 +3585,8 @@ bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
const MCSubtargetInfo *STI) { const MCSubtargetInfo *STI) {
MipsTargetStreamer &TOut = getTargetStreamer(); MipsTargetStreamer &TOut = getTargetStreamer();
assert (Inst.getNumOperands() == 3 && "Invalid operand count"); assert(Inst.getNumOperands() == 3 && "Invalid operand count");
assert (Inst.getOperand(0).isReg() && assert(Inst.getOperand(0).isReg() &&
Inst.getOperand(1).isReg() && Inst.getOperand(1).isReg() &&
Inst.getOperand(2).isImm() && "Invalid instruction operand."); Inst.getOperand(2).isImm() && "Invalid instruction operand.");
@ -3578,7 +3660,6 @@ bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
unsigned SecondShift = Mips::NOP; unsigned SecondShift = Mips::NOP;
if (hasMips32r2()) { if (hasMips32r2()) {
if (DReg == SReg) { if (DReg == SReg) {
TmpReg = getATReg(Inst.getLoc()); TmpReg = getATReg(Inst.getLoc());
if (!TmpReg) if (!TmpReg)
@ -3600,7 +3681,6 @@ bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
} }
if (hasMips32()) { if (hasMips32()) {
switch (Inst.getOpcode()) { switch (Inst.getOpcode()) {
default: default:
llvm_unreachable("unexpected instruction opcode"); llvm_unreachable("unexpected instruction opcode");
@ -3642,7 +3722,6 @@ bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
unsigned SecondShift = Mips::NOP; unsigned SecondShift = Mips::NOP;
if (hasMips32r2()) { if (hasMips32r2()) {
if (Inst.getOpcode() == Mips::ROLImm) { if (Inst.getOpcode() == Mips::ROLImm) {
uint64_t MaxShift = 32; uint64_t MaxShift = 32;
uint64_t ShiftValue = ImmValue; uint64_t ShiftValue = ImmValue;
@ -3661,7 +3740,6 @@ bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
} }
if (hasMips32()) { if (hasMips32()) {
if (ImmValue == 0) { if (ImmValue == 0) {
TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI); TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
return false; return false;
@ -3707,7 +3785,6 @@ bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
unsigned SecondShift = Mips::NOP; unsigned SecondShift = Mips::NOP;
if (hasMips64r2()) { if (hasMips64r2()) {
if (TmpReg == SReg) { if (TmpReg == SReg) {
TmpReg = getATReg(Inst.getLoc()); TmpReg = getATReg(Inst.getLoc());
if (!TmpReg) if (!TmpReg)
@ -3729,7 +3806,6 @@ bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
} }
if (hasMips64()) { if (hasMips64()) {
switch (Inst.getOpcode()) { switch (Inst.getOpcode()) {
default: default:
llvm_unreachable("unexpected instruction opcode"); llvm_unreachable("unexpected instruction opcode");
@ -3773,7 +3849,6 @@ bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
MCInst TmpInst; MCInst TmpInst;
if (hasMips64r2()) { if (hasMips64r2()) {
unsigned FinalOpcode = Mips::NOP; unsigned FinalOpcode = Mips::NOP;
if (ImmValue == 0) if (ImmValue == 0)
FinalOpcode = Mips::DROTR; FinalOpcode = Mips::DROTR;
@ -3801,7 +3876,6 @@ bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
} }
if (hasMips64()) { if (hasMips64()) {
if (ImmValue == 0) { if (ImmValue == 0) {
TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI); TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
return false; return false;
@ -3985,7 +4059,6 @@ bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI) { const MCSubtargetInfo *STI) {
warnIfNoMacro(IDLoc); warnIfNoMacro(IDLoc);
MipsTargetStreamer &TOut = getTargetStreamer(); MipsTargetStreamer &TOut = getTargetStreamer();
@ -4158,17 +4231,15 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
MCStreamer &Out, MCStreamer &Out,
uint64_t &ErrorInfo, uint64_t &ErrorInfo,
bool MatchingInlineAsm) { bool MatchingInlineAsm) {
MCInst Inst; MCInst Inst;
unsigned MatchResult = unsigned MatchResult =
MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
switch (MatchResult) { switch (MatchResult) {
case Match_Success: { case Match_Success:
if (processInstruction(Inst, IDLoc, Out, STI)) if (processInstruction(Inst, IDLoc, Out, STI))
return true; return true;
return false; return false;
}
case Match_MissingFeature: case Match_MissingFeature:
Error(IDLoc, "instruction requires a CPU feature not currently enabled"); Error(IDLoc, "instruction requires a CPU feature not currently enabled");
return true; return true;
@ -4441,7 +4512,6 @@ int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
} }
int MipsAsmParser::matchFPURegisterName(StringRef Name) { int MipsAsmParser::matchFPURegisterName(StringRef Name) {
if (Name[0] == 'f') { if (Name[0] == 'f') {
StringRef NumString = Name.substr(1); StringRef NumString = Name.substr(1);
unsigned IntVal; unsigned IntVal;
@ -4455,7 +4525,6 @@ int MipsAsmParser::matchFPURegisterName(StringRef Name) {
} }
int MipsAsmParser::matchFCCRegisterName(StringRef Name) { int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
if (Name.startswith("fcc")) { if (Name.startswith("fcc")) {
StringRef NumString = Name.substr(3); StringRef NumString = Name.substr(3);
unsigned IntVal; unsigned IntVal;
@ -4469,7 +4538,6 @@ int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
} }
int MipsAsmParser::matchACRegisterName(StringRef Name) { int MipsAsmParser::matchACRegisterName(StringRef Name) {
if (Name.startswith("ac")) { if (Name.startswith("ac")) {
StringRef NumString = Name.substr(2); StringRef NumString = Name.substr(2);
unsigned IntVal; unsigned IntVal;
@ -4589,7 +4657,6 @@ bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
} }
bool MipsAsmParser::isEvaluated(const MCExpr *Expr) { bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
switch (Expr->getKind()) { switch (Expr->getKind()) {
case MCExpr::Constant: case MCExpr::Constant:
return true; return true;
@ -5522,7 +5589,7 @@ bool MipsAsmParser::parseSetPushDirective() {
// Create a copy of the current assembler options environment and push it. // Create a copy of the current assembler options environment and push it.
AssemblerOptions.push_back( AssemblerOptions.push_back(
make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get())); llvm::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
getTargetStreamer().emitDirectiveSetPush(); getTargetStreamer().emitDirectiveSetPush();
return false; return false;
@ -6001,7 +6068,7 @@ bool MipsAsmParser::parseDirectiveSet() {
bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) { bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
MCAsmParser &Parser = getParser(); MCAsmParser &Parser = getParser();
if (getLexer().isNot(AsmToken::EndOfStatement)) { if (getLexer().isNot(AsmToken::EndOfStatement)) {
for (;;) { while (true) {
const MCExpr *Value; const MCExpr *Value;
if (getParser().parseExpression(Value)) if (getParser().parseExpression(Value))
return true; return true;

View File

@ -7,33 +7,38 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include <algorithm>
#include <list>
#include "MCTargetDesc/MipsBaseInfo.h"
#include "MCTargetDesc/MipsFixupKinds.h" #include "MCTargetDesc/MipsFixupKinds.h"
#include "MCTargetDesc/MipsMCExpr.h"
#include "MCTargetDesc/MipsMCTargetDesc.h" #include "MCTargetDesc/MipsMCTargetDesc.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSymbolELF.h" #include "llvm/MC/MCSymbolELF.h"
#include "llvm/MC/MCValue.h" #include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <iterator>
#include <list>
#include <utility>
#define DEBUG_TYPE "mips-elf-object-writer" #define DEBUG_TYPE "mips-elf-object-writer"
using namespace llvm; using namespace llvm;
namespace { namespace {
/// Holds additional information needed by the relocation ordering algorithm. /// Holds additional information needed by the relocation ordering algorithm.
struct MipsRelocationEntry { struct MipsRelocationEntry {
const ELFRelocationEntry R; ///< The relocation. const ELFRelocationEntry R; ///< The relocation.
bool Matched; ///< Is this relocation part of a match. bool Matched = false; ///< Is this relocation part of a match.
MipsRelocationEntry(const ELFRelocationEntry &R) : R(R), Matched(false) {} MipsRelocationEntry(const ELFRelocationEntry &R) : R(R) {}
void print(raw_ostream &Out) const { void print(raw_ostream &Out) const {
R.print(Out); R.print(Out);
@ -53,21 +58,31 @@ public:
MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI, bool _isN64, MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI, bool _isN64,
bool IsLittleEndian); bool IsLittleEndian);
~MipsELFObjectWriter() override; ~MipsELFObjectWriter() override = default;
unsigned getRelocType(MCContext &Ctx, const MCValue &Target, unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
const MCFixup &Fixup, bool IsPCRel) const override; const MCFixup &Fixup, bool IsPCRel) const override;
bool needsRelocateWithSymbol(const MCSymbol &Sym, bool needsRelocateWithSymbol(const MCSymbol &Sym,
unsigned Type) const override; unsigned Type) const override;
virtual void sortRelocs(const MCAssembler &Asm, void sortRelocs(const MCAssembler &Asm,
std::vector<ELFRelocationEntry> &Relocs) override; std::vector<ELFRelocationEntry> &Relocs) override;
}; };
/// The possible results of the Predicate function used by find_best.
enum FindBestPredicateResult {
FindBest_NoMatch = 0, ///< The current element is not a match.
FindBest_Match, ///< The current element is a match but better ones are
/// possible.
FindBest_PerfectMatch, ///< The current element is an unbeatable match.
};
} // end anonymous namespace
/// Copy elements in the range [First, Last) to d1 when the predicate is true or /// Copy elements in the range [First, Last) to d1 when the predicate is true or
/// d2 when the predicate is false. This is essentially both std::copy_if and /// d2 when the predicate is false. This is essentially both std::copy_if and
/// std::remove_copy_if combined into a single pass. /// std::remove_copy_if combined into a single pass.
template <class InputIt, class OutputIt1, class OutputIt2, class UnaryPredicate> template <class InputIt, class OutputIt1, class OutputIt2, class UnaryPredicate>
std::pair<OutputIt1, OutputIt2> copy_if_else(InputIt First, InputIt Last, static std::pair<OutputIt1, OutputIt2> copy_if_else(InputIt First, InputIt Last,
OutputIt1 d1, OutputIt2 d2, OutputIt1 d1, OutputIt2 d2,
UnaryPredicate Predicate) { UnaryPredicate Predicate) {
for (InputIt I = First; I != Last; ++I) { for (InputIt I = First; I != Last; ++I) {
@ -83,14 +98,6 @@ std::pair<OutputIt1, OutputIt2> copy_if_else(InputIt First, InputIt Last,
return std::make_pair(d1, d2); return std::make_pair(d1, d2);
} }
/// The possible results of the Predicate function used by find_best.
enum FindBestPredicateResult {
FindBest_NoMatch = 0, ///< The current element is not a match.
FindBest_Match, ///< The current element is a match but better ones are
/// possible.
FindBest_PerfectMatch, ///< The current element is an unbeatable match.
};
/// Find the best match in the range [First, Last). /// Find the best match in the range [First, Last).
/// ///
/// An element matches when Predicate(X) returns FindBest_Match or /// An element matches when Predicate(X) returns FindBest_Match or
@ -101,7 +108,7 @@ enum FindBestPredicateResult {
/// This is similar to std::find_if but finds the best of multiple possible /// This is similar to std::find_if but finds the best of multiple possible
/// matches. /// matches.
template <class InputIt, class UnaryPredicate, class Comparator> template <class InputIt, class UnaryPredicate, class Comparator>
InputIt find_best(InputIt First, InputIt Last, UnaryPredicate Predicate, static InputIt find_best(InputIt First, InputIt Last, UnaryPredicate Predicate,
Comparator BetterThan) { Comparator BetterThan) {
InputIt Best = Last; InputIt Best = Last;
@ -202,16 +209,12 @@ static void dumpRelocs(const char *Prefix, const Container &Relocs) {
} }
#endif #endif
} // end anonymous namespace
MipsELFObjectWriter::MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI, MipsELFObjectWriter::MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI,
bool _isN64, bool IsLittleEndian) bool _isN64, bool IsLittleEndian)
: MCELFObjectTargetWriter(_is64Bit, OSABI, ELF::EM_MIPS, : MCELFObjectTargetWriter(_is64Bit, OSABI, ELF::EM_MIPS,
/*HasRelocationAddend*/ _isN64, /*HasRelocationAddend*/ _isN64,
/*IsN64*/ _isN64) {} /*IsN64*/ _isN64) {}
MipsELFObjectWriter::~MipsELFObjectWriter() {}
unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx, unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx,
const MCValue &Target, const MCValue &Target,
const MCFixup &Fixup, const MCFixup &Fixup,
@ -419,7 +422,6 @@ unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx,
/// always match using the expressions from the source. /// always match using the expressions from the source.
void MipsELFObjectWriter::sortRelocs(const MCAssembler &Asm, void MipsELFObjectWriter::sortRelocs(const MCAssembler &Asm,
std::vector<ELFRelocationEntry> &Relocs) { std::vector<ELFRelocationEntry> &Relocs) {
// We do not need to sort the relocation table for RELA relocations which // We do not need to sort the relocation table for RELA relocations which
// N32/N64 uses as the relocation addend contains the value we require, // N32/N64 uses as the relocation addend contains the value we require,
// rather than it being split across a pair of relocations. // rather than it being split across a pair of relocations.

View File

@ -7,7 +7,6 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
//
// This pass is used to make Pc relative loads of constants. // This pass is used to make Pc relative loads of constants.
// For now, only Mips16 will use this. // For now, only Mips16 will use this.
// //
@ -19,30 +18,43 @@
// This can be particularly helpful in static relocation mode for embedded // This can be particularly helpful in static relocation mode for embedded
// non-linux targets. // non-linux targets.
// //
// //===----------------------------------------------------------------------===//
#include "Mips.h" #include "Mips.h"
#include "MCTargetDesc/MipsBaseInfo.h"
#include "Mips16InstrInfo.h" #include "Mips16InstrInfo.h"
#include "MipsMachineFunction.h" #include "MipsMachineFunction.h"
#include "MipsTargetMachine.h" #include "MipsSubtarget.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Function.h" #include "llvm/IR/Function.h"
#include "llvm/IR/InstIterator.h" #include "llvm/IR/Type.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h" #include "llvm/Support/Format.h"
#include "llvm/Support/MathExtras.h" #include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include <algorithm> #include <algorithm>
#include <cassert>
#include <cstdint>
#include <iterator>
#include <new>
#include <vector>
using namespace llvm; using namespace llvm;
@ -58,7 +70,6 @@ static cl::opt<bool>
AlignConstantIslands("mips-align-constant-islands", cl::Hidden, cl::init(true), AlignConstantIslands("mips-align-constant-islands", cl::Hidden, cl::init(true),
cl::desc("Align constant islands in code")); cl::desc("Align constant islands in code"));
// Rather than do make check tests with huge amounts of code, we force // Rather than do make check tests with huge amounts of code, we force
// the test to use this amount. // the test to use this amount.
// //
@ -178,7 +189,6 @@ static unsigned int branchMaxOffsets(unsigned int Opcode) {
namespace { namespace {
typedef MachineBasicBlock::iterator Iter; typedef MachineBasicBlock::iterator Iter;
typedef MachineBasicBlock::reverse_iterator ReverseIter; typedef MachineBasicBlock::reverse_iterator ReverseIter;
@ -195,7 +205,6 @@ namespace {
/// tracks a list of users. /// tracks a list of users.
class MipsConstantIslands : public MachineFunctionPass { class MipsConstantIslands : public MachineFunctionPass {
/// BasicBlockInfo - Information about the offset and size of a single /// BasicBlockInfo - Information about the offset and size of a single
/// basic block. /// basic block.
struct BasicBlockInfo { struct BasicBlockInfo {
@ -208,14 +217,16 @@ namespace {
/// ///
/// Because worst case padding is used, the computed offset of an aligned /// Because worst case padding is used, the computed offset of an aligned
/// block may not actually be aligned. /// block may not actually be aligned.
unsigned Offset; unsigned Offset = 0;
/// Size - Size of the basic block in bytes. If the block contains /// Size - Size of the basic block in bytes. If the block contains
/// inline assembly, this is a worst case estimate. /// inline assembly, this is a worst case estimate.
/// ///
/// The size does not include any alignment padding whether from the /// The size does not include any alignment padding whether from the
/// beginning of the block, or from an aligned jump table at the end. /// beginning of the block, or from an aligned jump table at the end.
unsigned Size; unsigned Size = 0;
BasicBlockInfo() = default;
// FIXME: ignore LogAlign for this patch // FIXME: ignore LogAlign for this patch
// //
@ -223,9 +234,6 @@ namespace {
unsigned PO = Offset + Size; unsigned PO = Offset + Size;
return PO; return PO;
} }
BasicBlockInfo() : Offset(0), Size(0) {}
}; };
std::vector<BasicBlockInfo> BBInfo; std::vector<BasicBlockInfo> BBInfo;
@ -257,13 +265,16 @@ namespace {
MachineInstr *MI; MachineInstr *MI;
MachineInstr *CPEMI; MachineInstr *CPEMI;
MachineBasicBlock *HighWaterMark; MachineBasicBlock *HighWaterMark;
private: private:
unsigned MaxDisp; unsigned MaxDisp;
unsigned LongFormMaxDisp; // mips16 has 16/32 bit instructions unsigned LongFormMaxDisp; // mips16 has 16/32 bit instructions
// with different displacements // with different displacements
unsigned LongFormOpcode; unsigned LongFormOpcode;
public: public:
bool NegOk; bool NegOk;
CPUser(MachineInstr *mi, MachineInstr *cpemi, unsigned maxdisp, CPUser(MachineInstr *mi, MachineInstr *cpemi, unsigned maxdisp,
bool neg, bool neg,
unsigned longformmaxdisp, unsigned longformopcode) unsigned longformmaxdisp, unsigned longformopcode)
@ -272,18 +283,22 @@ namespace {
NegOk(neg){ NegOk(neg){
HighWaterMark = CPEMI->getParent(); HighWaterMark = CPEMI->getParent();
} }
/// getMaxDisp - Returns the maximum displacement supported by MI. /// getMaxDisp - Returns the maximum displacement supported by MI.
unsigned getMaxDisp() const { unsigned getMaxDisp() const {
unsigned xMaxDisp = ConstantIslandsSmallOffset? unsigned xMaxDisp = ConstantIslandsSmallOffset?
ConstantIslandsSmallOffset: MaxDisp; ConstantIslandsSmallOffset: MaxDisp;
return xMaxDisp; return xMaxDisp;
} }
void setMaxDisp(unsigned val) { void setMaxDisp(unsigned val) {
MaxDisp = val; MaxDisp = val;
} }
unsigned getLongFormMaxDisp() const { unsigned getLongFormMaxDisp() const {
return LongFormMaxDisp; return LongFormMaxDisp;
} }
unsigned getLongFormOpcode() const { unsigned getLongFormOpcode() const {
return LongFormOpcode; return LongFormOpcode;
} }
@ -300,6 +315,7 @@ namespace {
MachineInstr *CPEMI; MachineInstr *CPEMI;
unsigned CPI; unsigned CPI;
unsigned RefCount; unsigned RefCount;
CPEntry(MachineInstr *cpemi, unsigned cpi, unsigned rc = 0) CPEntry(MachineInstr *cpemi, unsigned cpi, unsigned rc = 0)
: CPEMI(cpemi), CPI(cpi), RefCount(rc) {} : CPEMI(cpemi), CPI(cpi), RefCount(rc) {}
}; };
@ -309,7 +325,7 @@ namespace {
/// existed upon entry to this pass), it keeps a vector of entries. /// existed upon entry to this pass), it keeps a vector of entries.
/// Original elements are cloned as we go along; the clones are /// Original elements are cloned as we go along; the clones are
/// put in the vector of the original element, but have distinct CPIs. /// put in the vector of the original element, but have distinct CPIs.
std::vector<std::vector<CPEntry> > CPEntries; std::vector<std::vector<CPEntry>> CPEntries;
/// ImmBranch - One per immediate branch, keeping the machine instruction /// ImmBranch - One per immediate branch, keeping the machine instruction
/// pointer, conditional or unconditional, the max displacement, /// pointer, conditional or unconditional, the max displacement,
@ -320,6 +336,7 @@ namespace {
unsigned MaxDisp : 31; unsigned MaxDisp : 31;
bool isCond : 1; bool isCond : 1;
int UncondBr; int UncondBr;
ImmBranch(MachineInstr *mi, unsigned maxdisp, bool cond, int ubr) ImmBranch(MachineInstr *mi, unsigned maxdisp, bool cond, int ubr)
: MI(mi), MaxDisp(maxdisp), isCond(cond), UncondBr(ubr) {} : MI(mi), MaxDisp(maxdisp), isCond(cond), UncondBr(ubr) {}
}; };
@ -332,29 +349,27 @@ namespace {
/// the branch fix up pass. /// the branch fix up pass.
bool HasFarJump; bool HasFarJump;
const MipsSubtarget *STI; const MipsSubtarget *STI = nullptr;
const Mips16InstrInfo *TII; const Mips16InstrInfo *TII;
MipsFunctionInfo *MFI; MipsFunctionInfo *MFI;
MachineFunction *MF; MachineFunction *MF = nullptr;
MachineConstantPool *MCP; MachineConstantPool *MCP = nullptr;
unsigned PICLabelUId; unsigned PICLabelUId;
bool PrescannedForConstants; bool PrescannedForConstants = false;
void initPICLabelUId(unsigned UId) { void initPICLabelUId(unsigned UId) {
PICLabelUId = UId; PICLabelUId = UId;
} }
unsigned createPICLabelUId() { unsigned createPICLabelUId() {
return PICLabelUId++; return PICLabelUId++;
} }
public: public:
static char ID; static char ID;
MipsConstantIslands()
: MachineFunctionPass(ID), STI(nullptr), MF(nullptr), MCP(nullptr), MipsConstantIslands() : MachineFunctionPass(ID) {}
PrescannedForConstants(false) {}
StringRef getPassName() const override { return "Mips Constant Islands"; } StringRef getPassName() const override { return "Mips Constant Islands"; }
@ -403,13 +418,11 @@ namespace {
bool fixupUnconditionalBr(ImmBranch &Br); bool fixupUnconditionalBr(ImmBranch &Br);
void prescanForConstants(); void prescanForConstants();
private:
}; };
char MipsConstantIslands::ID = 0; char MipsConstantIslands::ID = 0;
} // end of anonymous namespace
} // end anonymous namespace
bool MipsConstantIslands::isOffsetInRange bool MipsConstantIslands::isOffsetInRange
(unsigned UserOffset, unsigned TrialOffset, (unsigned UserOffset, unsigned TrialOffset,
@ -417,6 +430,7 @@ bool MipsConstantIslands::isOffsetInRange
return isOffsetInRange(UserOffset, TrialOffset, return isOffsetInRange(UserOffset, TrialOffset,
U.getMaxDisp(), U.NegOk); U.getMaxDisp(), U.NegOk);
} }
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
/// print block size and offset information - debugging /// print block size and offset information - debugging
LLVM_DUMP_METHOD void MipsConstantIslands::dumpBBs() { LLVM_DUMP_METHOD void MipsConstantIslands::dumpBBs() {
@ -427,10 +441,6 @@ LLVM_DUMP_METHOD void MipsConstantIslands::dumpBBs() {
} }
} }
#endif #endif
/// Returns a pass that converts branches to long branches.
FunctionPass *llvm::createMipsConstantIslandPass() {
return new MipsConstantIslands();
}
bool MipsConstantIslands::runOnMachineFunction(MachineFunction &mf) { bool MipsConstantIslands::runOnMachineFunction(MachineFunction &mf) {
// The intention is for this to be a mips16 only pass for now // The intention is for this to be a mips16 only pass for now
@ -527,7 +537,6 @@ MipsConstantIslands::doInitialPlacement(std::vector<MachineInstr*> &CPEMIs) {
MachineBasicBlock *BB = MF->CreateMachineBasicBlock(); MachineBasicBlock *BB = MF->CreateMachineBasicBlock();
MF->push_back(BB); MF->push_back(BB);
// MachineConstantPool measures alignment in bytes. We measure in log2(bytes). // MachineConstantPool measures alignment in bytes. We measure in log2(bytes).
unsigned MaxAlign = Log2_32(MCP->getConstantPoolAlignment()); unsigned MaxAlign = Log2_32(MCP->getConstantPoolAlignment());
@ -647,7 +656,6 @@ initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {
for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E; ++I) for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E; ++I)
computeBlockSize(&*I); computeBlockSize(&*I);
// Compute block offsets. // Compute block offsets.
adjustBBOffsetsAfter(&MF->front()); adjustBBOffsetsAfter(&MF->front());
@ -737,7 +745,6 @@ initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {
if (Opc == Mips::CONSTPOOL_ENTRY) if (Opc == Mips::CONSTPOOL_ENTRY)
continue; continue;
// Scan the instructions for constant pool operands. // Scan the instructions for constant pool operands.
for (unsigned op = 0, e = MI.getNumOperands(); op != e; ++op) for (unsigned op = 0, e = MI.getNumOperands(); op != e; ++op)
if (MI.getOperand(op).isCPI()) { if (MI.getOperand(op).isCPI()) {
@ -784,12 +791,9 @@ initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {
// Instructions can only use one CP entry, don't bother scanning the // Instructions can only use one CP entry, don't bother scanning the
// rest of the operands. // rest of the operands.
break; break;
}
} }
} }
}
} }
/// computeBlockSize - Compute the size and some alignment information for MBB. /// computeBlockSize - Compute the size and some alignment information for MBB.
@ -921,8 +925,6 @@ MipsConstantIslands::splitBlockBeforeInstr(MachineInstr &MI) {
return NewBB; return NewBB;
} }
/// isOffsetInRange - Checks whether UserOffset (the location of a constant pool /// isOffsetInRange - Checks whether UserOffset (the location of a constant pool
/// reference) is within MaxDisp of TrialOffset (a proposed location of a /// reference) is within MaxDisp of TrialOffset (a proposed location of a
/// constant pool entry). /// constant pool entry).
@ -1337,7 +1339,6 @@ bool MipsConstantIslands::handleConstantPoolUser(unsigned CPUserIndex) {
if (result==1) return false; if (result==1) return false;
else if (result==2) return true; else if (result==2) return true;
// Look for water where we can place this CPE. // Look for water where we can place this CPE.
MachineBasicBlock *NewIsland = MF->CreateMachineBasicBlock(); MachineBasicBlock *NewIsland = MF->CreateMachineBasicBlock();
MachineBasicBlock *NewMBB; MachineBasicBlock *NewMBB;
@ -1371,7 +1372,7 @@ bool MipsConstantIslands::handleConstantPoolUser(unsigned CPUserIndex) {
// it. Check for this so it will be removed from the WaterList. // it. Check for this so it will be removed from the WaterList.
// Also remove any entry from NewWaterList. // Also remove any entry from NewWaterList.
MachineBasicBlock *WaterBB = &*--NewMBB->getIterator(); MachineBasicBlock *WaterBB = &*--NewMBB->getIterator();
IP = find(WaterList, WaterBB); IP = llvm::find(WaterList, WaterBB);
if (IP != WaterList.end()) if (IP != WaterList.end())
NewWaterList.erase(WaterBB); NewWaterList.erase(WaterBB);
@ -1473,9 +1474,7 @@ bool MipsConstantIslands::removeUnusedCPEntries() {
/// specific BB can fit in MI's displacement field. /// specific BB can fit in MI's displacement field.
bool MipsConstantIslands::isBBInRange bool MipsConstantIslands::isBBInRange
(MachineInstr *MI,MachineBasicBlock *DestBB, unsigned MaxDisp) { (MachineInstr *MI,MachineBasicBlock *DestBB, unsigned MaxDisp) {
unsigned PCAdj = 4;
unsigned PCAdj = 4;
unsigned BrOffset = getOffsetOf(MI) + PCAdj; unsigned BrOffset = getOffsetOf(MI) + PCAdj;
unsigned DestOffset = BBInfo[DestBB->getNumber()].Offset; unsigned DestOffset = BBInfo[DestBB->getNumber()].Offset;
@ -1553,7 +1552,6 @@ MipsConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {
return true; return true;
} }
/// fixupConditionalBr - Fix up a conditional branch whose destination is too /// fixupConditionalBr - Fix up a conditional branch whose destination is too
/// far away to fit in its displacement field. It is converted to an inverse /// far away to fit in its displacement field. It is converted to an inverse
/// conditional branch + an unconditional branch to the destination. /// conditional branch + an unconditional branch to the destination.
@ -1614,7 +1612,6 @@ MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {
} }
} }
if (NeedSplit) { if (NeedSplit) {
splitBlockBeforeInstr(*MI); splitBlockBeforeInstr(*MI);
// No need for the branch to the next block. We're adding an unconditional // No need for the branch to the next block. We're adding an unconditional
@ -1654,7 +1651,6 @@ MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) {
return true; return true;
} }
void MipsConstantIslands::prescanForConstants() { void MipsConstantIslands::prescanForConstants() {
unsigned J = 0; unsigned J = 0;
(void)J; (void)J;
@ -1692,3 +1688,8 @@ void MipsConstantIslands::prescanForConstants() {
} }
} }
} }
/// Returns a pass that converts branches to long branches.
FunctionPass *llvm::createMipsConstantIslandPass() {
return new MipsConstantIslands();
}

View File

@ -1,4 +1,4 @@
//===-- MipsFastISel.cpp - Mips FastISel implementation --------------------===// //===-- MipsFastISel.cpp - Mips FastISel implementation -------------------===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -14,24 +14,62 @@
/// ///
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "MCTargetDesc/MipsABIInfo.h"
#include "MCTargetDesc/MipsBaseInfo.h"
#include "MipsCCState.h" #include "MipsCCState.h"
#include "MipsInstrInfo.h" #include "MipsInstrInfo.h"
#include "MipsISelLowering.h" #include "MipsISelLowering.h"
#include "MipsMachineFunction.h" #include "MipsMachineFunction.h"
#include "MipsRegisterInfo.h"
#include "MipsSubtarget.h" #include "MipsSubtarget.h"
#include "MipsTargetMachine.h" #include "MipsTargetMachine.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/FastISel.h" #include "llvm/CodeGen/FastISel.h"
#include "llvm/CodeGen/FunctionLoweringInfo.h" #include "llvm/CodeGen/FunctionLoweringInfo.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MachineValueType.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h" #include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSymbol.h"
#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.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 "llvm/Target/TargetLowering.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <new>
#define DEBUG_TYPE "mips-fastisel" #define DEBUG_TYPE "mips-fastisel"
@ -47,35 +85,40 @@ class MipsFastISel final : public FastISel {
typedef enum { RegBase, FrameIndexBase } BaseKind; typedef enum { RegBase, FrameIndexBase } BaseKind;
private: private:
BaseKind Kind; BaseKind Kind = RegBase;
union { union {
unsigned Reg; unsigned Reg;
int FI; int FI;
} Base; } Base;
int64_t Offset; int64_t Offset = 0;
const GlobalValue *GV; const GlobalValue *GV = nullptr;
public: public:
// Innocuous defaults for our address. // Innocuous defaults for our address.
Address() : Kind(RegBase), Offset(0), GV(0) { Base.Reg = 0; } Address() { Base.Reg = 0; }
void setKind(BaseKind K) { Kind = K; } void setKind(BaseKind K) { Kind = K; }
BaseKind getKind() const { return Kind; } BaseKind getKind() const { return Kind; }
bool isRegBase() const { return Kind == RegBase; } bool isRegBase() const { return Kind == RegBase; }
bool isFIBase() const { return Kind == FrameIndexBase; } bool isFIBase() const { return Kind == FrameIndexBase; }
void setReg(unsigned Reg) { void setReg(unsigned Reg) {
assert(isRegBase() && "Invalid base register access!"); assert(isRegBase() && "Invalid base register access!");
Base.Reg = Reg; Base.Reg = Reg;
} }
unsigned getReg() const { unsigned getReg() const {
assert(isRegBase() && "Invalid base register access!"); assert(isRegBase() && "Invalid base register access!");
return Base.Reg; return Base.Reg;
} }
void setFI(unsigned FI) { void setFI(unsigned FI) {
assert(isFIBase() && "Invalid base frame index access!"); assert(isFIBase() && "Invalid base frame index access!");
Base.FI = FI; Base.FI = FI;
} }
unsigned getFI() const { unsigned getFI() const {
assert(isFIBase() && "Invalid base frame index access!"); assert(isFIBase() && "Invalid base frame index access!");
return Base.FI; return Base.FI;
@ -165,14 +208,17 @@ private:
MachineInstrBuilder emitInst(unsigned Opc) { MachineInstrBuilder emitInst(unsigned Opc) {
return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc)); return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc));
} }
MachineInstrBuilder emitInst(unsigned Opc, unsigned DstReg) { MachineInstrBuilder emitInst(unsigned Opc, unsigned DstReg) {
return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc),
DstReg); DstReg);
} }
MachineInstrBuilder emitInstStore(unsigned Opc, unsigned SrcReg, MachineInstrBuilder emitInstStore(unsigned Opc, unsigned SrcReg,
unsigned MemReg, int64_t MemOffset) { unsigned MemReg, int64_t MemOffset) {
return emitInst(Opc).addReg(SrcReg).addReg(MemReg).addImm(MemOffset); return emitInst(Opc).addReg(SrcReg).addReg(MemReg).addImm(MemOffset);
} }
MachineInstrBuilder emitInstLoad(unsigned Opc, unsigned DstReg, MachineInstrBuilder emitInstLoad(unsigned Opc, unsigned DstReg,
unsigned MemReg, int64_t MemOffset) { unsigned MemReg, int64_t MemOffset) {
return emitInst(Opc, DstReg).addReg(MemReg).addImm(MemOffset); return emitInst(Opc, DstReg).addReg(MemReg).addImm(MemOffset);
@ -198,6 +244,7 @@ private:
bool processCallArgs(CallLoweringInfo &CLI, SmallVectorImpl<MVT> &ArgVTs, bool processCallArgs(CallLoweringInfo &CLI, SmallVectorImpl<MVT> &ArgVTs,
unsigned &NumBytes); unsigned &NumBytes);
bool finishCall(CallLoweringInfo &CLI, MVT RetVT, unsigned NumBytes); bool finishCall(CallLoweringInfo &CLI, MVT RetVT, unsigned NumBytes);
const MipsABIInfo &getABI() const { const MipsABIInfo &getABI() const {
return static_cast<const MipsTargetMachine &>(TM).getABI(); return static_cast<const MipsTargetMachine &>(TM).getABI();
} }
@ -220,7 +267,8 @@ public:
#include "MipsGenFastISel.inc" #include "MipsGenFastISel.inc"
}; };
} // end anonymous namespace.
} // end anonymous namespace
static bool CC_Mips(unsigned ValNo, MVT ValVT, MVT LocVT, static bool CC_Mips(unsigned ValNo, MVT ValVT, MVT LocVT,
CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
@ -414,7 +462,6 @@ unsigned MipsFastISel::fastMaterializeConstant(const Constant *C) {
} }
bool MipsFastISel::computeAddress(const Value *Obj, Address &Addr) { bool MipsFastISel::computeAddress(const Value *Obj, Address &Addr) {
const User *U = nullptr; const User *U = nullptr;
unsigned Opcode = Instruction::UserOp1; unsigned Opcode = Instruction::UserOp1;
if (const Instruction *I = dyn_cast<Instruction>(Obj)) { if (const Instruction *I = dyn_cast<Instruction>(Obj)) {
@ -432,10 +479,9 @@ bool MipsFastISel::computeAddress(const Value *Obj, Address &Addr) {
switch (Opcode) { switch (Opcode) {
default: default:
break; break;
case Instruction::BitCast: { case Instruction::BitCast:
// Look through bitcasts. // Look through bitcasts.
return computeAddress(U->getOperand(0), Addr); return computeAddress(U->getOperand(0), Addr);
}
case Instruction::GetElementPtr: { case Instruction::GetElementPtr: {
Address SavedAddr = Addr; Address SavedAddr = Addr;
int64_t TmpOffset = Addr.getOffset(); int64_t TmpOffset = Addr.getOffset();
@ -451,7 +497,7 @@ bool MipsFastISel::computeAddress(const Value *Obj, Address &Addr) {
TmpOffset += SL->getElementOffset(Idx); TmpOffset += SL->getElementOffset(Idx);
} else { } else {
uint64_t S = DL.getTypeAllocSize(GTI.getIndexedType()); uint64_t S = DL.getTypeAllocSize(GTI.getIndexedType());
for (;;) { while (true) {
if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) { if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
// Constant-offset addressing. // Constant-offset addressing.
TmpOffset += CI->getSExtValue() * S; TmpOffset += CI->getSExtValue() * S;
@ -613,14 +659,12 @@ bool MipsFastISel::emitCmp(unsigned ResultReg, const CmpInst *CI) {
emitInst(Mips::SLTu, ResultReg).addReg(Mips::ZERO).addReg(TempReg); emitInst(Mips::SLTu, ResultReg).addReg(Mips::ZERO).addReg(TempReg);
break; break;
} }
case CmpInst::ICMP_UGT: { case CmpInst::ICMP_UGT:
emitInst(Mips::SLTu, ResultReg).addReg(RightReg).addReg(LeftReg); emitInst(Mips::SLTu, ResultReg).addReg(RightReg).addReg(LeftReg);
break; break;
} case CmpInst::ICMP_ULT:
case CmpInst::ICMP_ULT: {
emitInst(Mips::SLTu, ResultReg).addReg(LeftReg).addReg(RightReg); emitInst(Mips::SLTu, ResultReg).addReg(LeftReg).addReg(RightReg);
break; break;
}
case CmpInst::ICMP_UGE: { case CmpInst::ICMP_UGE: {
unsigned TempReg = createResultReg(&Mips::GPR32RegClass); unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
emitInst(Mips::SLTu, TempReg).addReg(LeftReg).addReg(RightReg); emitInst(Mips::SLTu, TempReg).addReg(LeftReg).addReg(RightReg);
@ -633,14 +677,12 @@ bool MipsFastISel::emitCmp(unsigned ResultReg, const CmpInst *CI) {
emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1); emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);
break; break;
} }
case CmpInst::ICMP_SGT: { case CmpInst::ICMP_SGT:
emitInst(Mips::SLT, ResultReg).addReg(RightReg).addReg(LeftReg); emitInst(Mips::SLT, ResultReg).addReg(RightReg).addReg(LeftReg);
break; break;
} case CmpInst::ICMP_SLT:
case CmpInst::ICMP_SLT: {
emitInst(Mips::SLT, ResultReg).addReg(LeftReg).addReg(RightReg); emitInst(Mips::SLT, ResultReg).addReg(LeftReg).addReg(RightReg);
break; break;
}
case CmpInst::ICMP_SGE: { case CmpInst::ICMP_SGE: {
unsigned TempReg = createResultReg(&Mips::GPR32RegClass); unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
emitInst(Mips::SLT, TempReg).addReg(LeftReg).addReg(RightReg); emitInst(Mips::SLT, TempReg).addReg(LeftReg).addReg(RightReg);
@ -709,6 +751,7 @@ bool MipsFastISel::emitCmp(unsigned ResultReg, const CmpInst *CI) {
} }
return true; return true;
} }
bool MipsFastISel::emitLoad(MVT VT, unsigned &ResultReg, Address &Addr, bool MipsFastISel::emitLoad(MVT VT, unsigned &ResultReg, Address &Addr,
unsigned Alignment) { unsigned Alignment) {
// //
@ -716,35 +759,30 @@ bool MipsFastISel::emitLoad(MVT VT, unsigned &ResultReg, Address &Addr,
// //
unsigned Opc; unsigned Opc;
switch (VT.SimpleTy) { switch (VT.SimpleTy) {
case MVT::i32: { case MVT::i32:
ResultReg = createResultReg(&Mips::GPR32RegClass); ResultReg = createResultReg(&Mips::GPR32RegClass);
Opc = Mips::LW; Opc = Mips::LW;
break; break;
} case MVT::i16:
case MVT::i16: {
ResultReg = createResultReg(&Mips::GPR32RegClass); ResultReg = createResultReg(&Mips::GPR32RegClass);
Opc = Mips::LHu; Opc = Mips::LHu;
break; break;
} case MVT::i8:
case MVT::i8: {
ResultReg = createResultReg(&Mips::GPR32RegClass); ResultReg = createResultReg(&Mips::GPR32RegClass);
Opc = Mips::LBu; Opc = Mips::LBu;
break; break;
} case MVT::f32:
case MVT::f32: {
if (UnsupportedFPMode) if (UnsupportedFPMode)
return false; return false;
ResultReg = createResultReg(&Mips::FGR32RegClass); ResultReg = createResultReg(&Mips::FGR32RegClass);
Opc = Mips::LWC1; Opc = Mips::LWC1;
break; break;
} case MVT::f64:
case MVT::f64: {
if (UnsupportedFPMode) if (UnsupportedFPMode)
return false; return false;
ResultReg = createResultReg(&Mips::AFGR64RegClass); ResultReg = createResultReg(&Mips::AFGR64RegClass);
Opc = Mips::LDC1; Opc = Mips::LDC1;
break; break;
}
default: default:
return false; return false;
} }
@ -1730,6 +1768,7 @@ bool MipsFastISel::selectTrunc(const Instruction *I) {
updateValueMap(I, SrcReg); updateValueMap(I, SrcReg);
return true; return true;
} }
bool MipsFastISel::selectIntExt(const Instruction *I) { bool MipsFastISel::selectIntExt(const Instruction *I) {
Type *DestTy = I->getType(); Type *DestTy = I->getType();
Value *Src = I->getOperand(0); Value *Src = I->getOperand(0);
@ -1757,6 +1796,7 @@ bool MipsFastISel::selectIntExt(const Instruction *I) {
updateValueMap(I, ResultReg); updateValueMap(I, ResultReg);
return true; return true;
} }
bool MipsFastISel::emitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT, bool MipsFastISel::emitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT,
unsigned DestReg) { unsigned DestReg) {
unsigned ShiftAmt; unsigned ShiftAmt;
@ -2074,8 +2114,10 @@ unsigned MipsFastISel::fastEmitInst_rr(unsigned MachineInstOpcode,
} }
namespace llvm { namespace llvm {
FastISel *Mips::createFastISel(FunctionLoweringInfo &funcInfo, FastISel *Mips::createFastISel(FunctionLoweringInfo &funcInfo,
const TargetLibraryInfo *libInfo) { const TargetLibraryInfo *libInfo) {
return new MipsFastISel(funcInfo, libInfo); return new MipsFastISel(funcInfo, libInfo);
} }
}
} // end namespace llvm

View File

@ -7,16 +7,15 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "MCTargetDesc/MipsBaseInfo.h" #include "MCTargetDesc/MipsABIInfo.h"
#include "MipsInstrInfo.h"
#include "MipsMachineFunction.h" #include "MipsMachineFunction.h"
#include "MipsSubtarget.h" #include "MipsSubtarget.h"
#include "MipsTargetMachine.h" #include "MipsTargetMachine.h"
#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/IR/Function.h" #include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm; using namespace llvm;
@ -24,7 +23,7 @@ static cl::opt<bool>
FixGlobalBaseReg("mips-fix-global-base-reg", cl::Hidden, cl::init(true), FixGlobalBaseReg("mips-fix-global-base-reg", cl::Hidden, cl::init(true),
cl::desc("Always use $gp as the global base register.")); cl::desc("Always use $gp as the global base register."));
MipsFunctionInfo::~MipsFunctionInfo() {} MipsFunctionInfo::~MipsFunctionInfo() = default;
bool MipsFunctionInfo::globalBaseRegSet() const { bool MipsFunctionInfo::globalBaseRegSet() const {
return GlobalBaseReg; return GlobalBaseReg;
@ -101,4 +100,4 @@ int MipsFunctionInfo::getMoveF64ViaSpillFI(const TargetRegisterClass *RC) {
return MoveF64ViaSpillFI; return MoveF64ViaSpillFI;
} }
void MipsFunctionInfo::anchor() { } void MipsFunctionInfo::anchor() {}

View File

@ -1,4 +1,4 @@
//===-- MipsMachineFunctionInfo.h - Private data used for Mips ----*- C++ -*-=// //===- MipsMachineFunctionInfo.h - Private data used for Mips ---*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -15,12 +15,8 @@
#define LLVM_LIB_TARGET_MIPS_MIPSMACHINEFUNCTION_H #define LLVM_LIB_TARGET_MIPS_MIPSMACHINEFUNCTION_H
#include "Mips16HardFloatInfo.h" #include "Mips16HardFloatInfo.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetMachine.h"
#include <map> #include <map>
namespace llvm { namespace llvm {
@ -29,12 +25,9 @@ namespace llvm {
/// Mips target-specific information for each MachineFunction. /// Mips target-specific information for each MachineFunction.
class MipsFunctionInfo : public MachineFunctionInfo { class MipsFunctionInfo : public MachineFunctionInfo {
public: public:
MipsFunctionInfo(MachineFunction &MF) MipsFunctionInfo(MachineFunction &MF) : MF(MF) {}
: MF(MF), SRetReturnReg(0), GlobalBaseReg(0), VarArgsFrameIndex(0),
CallsEhReturn(false), IsISR(false), SaveS2(false),
MoveF64ViaSpillFI(-1) {}
~MipsFunctionInfo(); ~MipsFunctionInfo() override;
unsigned getSRetReturnReg() const { return SRetReturnReg; } unsigned getSRetReturnReg() const { return SRetReturnReg; }
void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; } void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
@ -81,25 +74,26 @@ public:
int getMoveF64ViaSpillFI(const TargetRegisterClass *RC); int getMoveF64ViaSpillFI(const TargetRegisterClass *RC);
std::map<const char *, const llvm::Mips16HardFloatInfo::FuncSignature *> std::map<const char *, const Mips16HardFloatInfo::FuncSignature *>
StubsNeeded; StubsNeeded;
private: private:
virtual void anchor(); virtual void anchor();
MachineFunction& MF; MachineFunction& MF;
/// SRetReturnReg - Some subtargets require that sret lowering includes /// SRetReturnReg - Some subtargets require that sret lowering includes
/// returning the value of the returned struct in a register. This field /// returning the value of the returned struct in a register. This field
/// holds the virtual register into which the sret argument is passed. /// holds the virtual register into which the sret argument is passed.
unsigned SRetReturnReg; unsigned SRetReturnReg = 0;
/// GlobalBaseReg - keeps track of the virtual register initialized for /// GlobalBaseReg - keeps track of the virtual register initialized for
/// use as the global base register. This is used for PIC in some PIC /// use as the global base register. This is used for PIC in some PIC
/// relocation models. /// relocation models.
unsigned GlobalBaseReg; unsigned GlobalBaseReg = 0;
/// VarArgsFrameIndex - FrameIndex for start of varargs area. /// VarArgsFrameIndex - FrameIndex for start of varargs area.
int VarArgsFrameIndex; int VarArgsFrameIndex = 0;
/// True if function has a byval argument. /// True if function has a byval argument.
bool HasByvalArg; bool HasByvalArg;
@ -108,25 +102,25 @@ private:
unsigned IncomingArgSize; unsigned IncomingArgSize;
/// CallsEhReturn - Whether the function calls llvm.eh.return. /// CallsEhReturn - Whether the function calls llvm.eh.return.
bool CallsEhReturn; bool CallsEhReturn = false;
/// Frame objects for spilling eh data registers. /// Frame objects for spilling eh data registers.
int EhDataRegFI[4]; int EhDataRegFI[4];
/// ISR - Whether the function is an Interrupt Service Routine. /// ISR - Whether the function is an Interrupt Service Routine.
bool IsISR; bool IsISR = false;
/// Frame objects for spilling C0_STATUS, C0_EPC /// Frame objects for spilling C0_STATUS, C0_EPC
int ISRDataRegFI[2]; int ISRDataRegFI[2];
// saveS2 // saveS2
bool SaveS2; bool SaveS2 = false;
/// FrameIndex for expanding BuildPairF64 nodes to spill and reload when the /// FrameIndex for expanding BuildPairF64 nodes to spill and reload when the
/// O32 FPXX ABI is enabled. -1 is used to denote invalid index. /// O32 FPXX ABI is enabled. -1 is used to denote invalid index.
int MoveF64ViaSpillFI; int MoveF64ViaSpillFI = -1;
}; };
} // end of namespace llvm } // end namespace llvm
#endif #endif // LLVM_LIB_TARGET_MIPS_MIPSMACHINEFUNCTION_H