[Mips] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC).
llvm-svn: 293565
This commit is contained in:
parent
365c9bd941
commit
dde94e4c4f
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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() {}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue