diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index d054578deb67..f40d33c8eaa7 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -7,47 +7,67 @@ // //===----------------------------------------------------------------------===// +#include "MCTargetDesc/MipsABIFlagsSection.h" #include "MCTargetDesc/MipsABIInfo.h" #include "MCTargetDesc/MipsMCExpr.h" #include "MCTargetDesc/MipsMCTargetDesc.h" -#include "MipsRegisterInfo.h" -#include "MipsTargetObjectFile.h" #include "MipsTargetStreamer.h" #include "MCTargetDesc/MipsBaseInfo.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/STLExtras.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/MCExpr.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/MCAsmParser.h" +#include "llvm/MC/MCParser/MCAsmParserExtension.h" #include "llvm/MC/MCParser/MCParsedAsmOperand.h" #include "llvm/MC/MCParser/MCTargetAsmParser.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.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/ELF.h" +#include "llvm/Support/ErrorHandling.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/TargetRegistry.h" -#include "llvm/Support/raw_ostream.h" +#include +#include +#include #include +#include +#include using namespace llvm; #define DEBUG_TYPE "mips-asm-parser" namespace llvm { + class MCInstrInfo; -} + +} // end namespace llvm namespace { + class MipsAssemblerOptions { public: - MipsAssemblerOptions(const FeatureBitset &Features_) : - ATReg(1), Reorder(true), Macro(true), Features(Features_) {} + MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {} MipsAssemblerOptions(const MipsAssemblerOptions *Opts) { ATReg = Opts->getATRegIndex(); @@ -84,12 +104,13 @@ public: static const FeatureBitset AllArchRelatedMask; private: - unsigned ATReg; - bool Reorder; - bool Macro; + unsigned ATReg = 1; + bool Reorder = true; + bool Macro = true; FeatureBitset Features; }; -} + +} // end anonymous namespace const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = { Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3, @@ -103,6 +124,7 @@ const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = { }; namespace { + class MipsAsmParser : public MCTargetAsmParser { MipsTargetStreamer &getTargetStreamer() { MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); @@ -466,9 +488,11 @@ public: bool isGP64bit() const { return getSTI().getFeatureBits()[Mips::FeatureGP64Bit]; } + bool isFP64bit() const { return getSTI().getFeatureBits()[Mips::FeatureFP64Bit]; } + const MipsABIInfo &getABI() const { return ABI; } bool isABI_N32() const { return ABI.IsN32(); } bool isABI_N64() const { return ABI.IsN64(); } @@ -484,48 +508,63 @@ public: bool inMicroMipsMode() const { return getSTI().getFeatureBits()[Mips::FeatureMicroMips]; } + bool hasMips1() const { return getSTI().getFeatureBits()[Mips::FeatureMips1]; } + bool hasMips2() const { return getSTI().getFeatureBits()[Mips::FeatureMips2]; } + bool hasMips3() const { return getSTI().getFeatureBits()[Mips::FeatureMips3]; } + bool hasMips4() const { return getSTI().getFeatureBits()[Mips::FeatureMips4]; } + bool hasMips5() const { return getSTI().getFeatureBits()[Mips::FeatureMips5]; } + bool hasMips32() const { return getSTI().getFeatureBits()[Mips::FeatureMips32]; } + bool hasMips64() const { return getSTI().getFeatureBits()[Mips::FeatureMips64]; } + bool hasMips32r2() const { return getSTI().getFeatureBits()[Mips::FeatureMips32r2]; } + bool hasMips64r2() const { return getSTI().getFeatureBits()[Mips::FeatureMips64r2]; } + bool hasMips32r3() const { return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]); } + bool hasMips64r3() const { return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]); } + bool hasMips32r5() const { return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]); } + bool hasMips64r5() const { return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]); } + bool hasMips32r6() const { return getSTI().getFeatureBits()[Mips::FeatureMips32r6]; } + bool hasMips64r6() const { return getSTI().getFeatureBits()[Mips::FeatureMips64r6]; } @@ -533,15 +572,19 @@ public: bool hasDSP() const { return getSTI().getFeatureBits()[Mips::FeatureDSP]; } + bool hasDSPR2() const { return getSTI().getFeatureBits()[Mips::FeatureDSPR2]; } + bool hasDSPR3() const { return getSTI().getFeatureBits()[Mips::FeatureDSPR3]; } + bool hasMSA() const { return getSTI().getFeatureBits()[Mips::FeatureMSA]; } + bool hasCnMips() const { return (getSTI().getFeatureBits()[Mips::FeatureCnMips]); } @@ -627,9 +670,6 @@ public: } } }; -} - -namespace { /// MipsOperand - Instances of this class represent a parsed Mips machine /// instruction. @@ -671,6 +711,22 @@ public: MipsOperand(KindTy K, MipsAsmParser &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: /// For diagnostics, and checking the assembler temporary MipsAsmParser &AsmParser; @@ -716,7 +772,7 @@ private: const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, MipsAsmParser &Parser) { - auto Op = make_unique(k_RegisterIndex, Parser); + auto Op = llvm::make_unique(k_RegisterIndex, Parser); Op->RegIdx.Index = Index; Op->RegIdx.RegInfo = RegInfo; Op->RegIdx.Kind = RegKind; @@ -1104,45 +1160,58 @@ public: // $0/$zero here so that MCK_ZERO works correctly. return isGPRAsmReg() && RegIdx.Index == 0; } + bool isRegIdx() const { return Kind == k_RegisterIndex; } bool isImm() const override { return Kind == k_Immediate; } + bool isConstantImm() const { int64_t Res; return isImm() && getImm()->evaluateAsAbsolute(Res); } + bool isConstantImmz() const { return isConstantImm() && getConstantImm() == 0; } + template bool isConstantUImm() const { return isConstantImm() && isUInt(getConstantImm() - Offset); } + template bool isSImm() const { return isConstantImm() ? isInt(getConstantImm()) : isImm(); } + template bool isUImm() const { return isConstantImm() ? isUInt(getConstantImm()) : isImm(); } + template bool isAnyImm() const { return isConstantImm() ? (isInt(getConstantImm()) || isUInt(getConstantImm())) : isImm(); } + template bool isConstantSImm() const { return isConstantImm() && isInt(getConstantImm() - Offset); } + template bool isConstantUImmRange() const { return isConstantImm() && getConstantImm() >= Bottom && getConstantImm() <= Top; } + bool isToken() const override { // Note: It's not possible to pretend that other operand kinds are tokens. // The matcher emitter checks tokens first. return Kind == k_Token; } + bool isMem() const override { return Kind == k_Memory; } + bool isConstantMemOff() const { return isMem() && isa(getMemOff()); } + // Allow relocation operators. // FIXME: This predicate and others need to look through binary expressions // and determine whether a Value is a constant or not. @@ -1160,28 +1229,34 @@ public: bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr); return IsReloc && isShiftedInt(Res.getConstant()); } + bool isMemWithGRPMM16Base() const { return isMem() && getMemBase()->isMM16AsmReg(); } + template bool isMemWithUimmOffsetSP() const { return isMem() && isConstantMemOff() && isUInt(getConstantMemOff()) && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP); } + template bool isMemWithUimmWordAlignedOffsetSP() const { return isMem() && isConstantMemOff() && isUInt(getConstantMemOff()) && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP); } + template bool isMemWithSimmWordAlignedOffsetGP() const { return isMem() && isConstantMemOff() && isInt(getConstantMemOff()) && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::GP); } + template bool isScaledUImm() const { return isConstantImm() && isShiftedUInt(getConstantImm()); } + template bool isScaledSImm() const { if (isConstantImm() && isShiftedInt(getConstantImm())) @@ -1193,6 +1268,7 @@ public: bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr); return Success && isShiftedInt(Res.getConstant()); } + bool isRegList16() const { if (!isRegList()) return false; @@ -1217,14 +1293,18 @@ public: return true; } + bool isInvNum() const { return Kind == k_Immediate; } + bool isLSAImm() const { if (!isConstantImm()) return false; int64_t Val = getConstantImm(); return 1 <= Val && Val <= 4; } + bool isRegList() const { return Kind == k_RegList; } + bool isMovePRegPair() const { if (Kind != k_RegList || RegList.List->size() != 2) return false; @@ -1257,6 +1337,7 @@ public: assert(Kind == k_Token && "Invalid access!"); return StringRef(Tok.Data, Tok.Length); } + bool isRegPair() const { return Kind == k_RegPair && RegIdx.Index <= 30; } @@ -1310,7 +1391,7 @@ public: static std::unique_ptr CreateToken(StringRef Str, SMLoc S, MipsAsmParser &Parser) { - auto Op = make_unique(k_Token, Parser); + auto Op = llvm::make_unique(k_Token, Parser); Op->Tok.Data = Str.data(); Op->Tok.Length = Str.size(); Op->StartLoc = S; @@ -1385,7 +1466,7 @@ public: static std::unique_ptr CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) { - auto Op = make_unique(k_Immediate, Parser); + auto Op = llvm::make_unique(k_Immediate, Parser); Op->Imm.Val = Val; Op->StartLoc = S; Op->EndLoc = E; @@ -1395,7 +1476,7 @@ public: static std::unique_ptr CreateMem(std::unique_ptr Base, const MCExpr *Off, SMLoc S, SMLoc E, MipsAsmParser &Parser) { - auto Op = make_unique(k_Memory, Parser); + auto Op = llvm::make_unique(k_Memory, Parser); Op->Mem.Base = Base.release(); Op->Mem.Off = Off; Op->StartLoc = S; @@ -1406,9 +1487,9 @@ public: static std::unique_ptr CreateRegList(SmallVectorImpl &Regs, SMLoc StartLoc, SMLoc EndLoc, MipsAsmParser &Parser) { - assert (Regs.size() > 0 && "Empty list not allowed"); + assert(Regs.size() > 0 && "Empty list not allowed"); - auto Op = make_unique(k_RegList, Parser); + auto Op = llvm::make_unique(k_RegList, Parser); Op->RegList.List = new SmallVector(Regs.begin(), Regs.end()); Op->StartLoc = StartLoc; Op->EndLoc = EndLoc; @@ -1418,7 +1499,7 @@ public: static std::unique_ptr CreateRegPair(const MipsOperand &MOP, SMLoc S, SMLoc E, MipsAsmParser &Parser) { - auto Op = make_unique(k_RegPair, Parser); + auto Op = llvm::make_unique(k_RegPair, Parser); Op->RegIdx.Index = MOP.RegIdx.Index; Op->RegIdx.RegInfo = MOP.RegIdx.RegInfo; Op->RegIdx.Kind = MOP.RegIdx.Kind; @@ -1430,11 +1511,13 @@ public: bool isGPRAsmReg() const { return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31; } + bool isMM16AsmReg() const { if (!(isRegIdx() && RegIdx.Kind)) return false; return ((RegIdx.Index >= 2 && RegIdx.Index <= 7) || RegIdx.Index == 16 || RegIdx.Index == 17); + } bool isMM16AsmRegZero() const { if (!(isRegIdx() && RegIdx.Kind)) @@ -1443,42 +1526,53 @@ public: (RegIdx.Index >= 2 && RegIdx.Index <= 7) || RegIdx.Index == 17); } + bool isMM16AsmRegMoveP() const { if (!(isRegIdx() && RegIdx.Kind)) return false; return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) || (RegIdx.Index >= 16 && RegIdx.Index <= 20)); } + bool isFGRAsmReg() const { // AFGR64 is $0-$15 but we handle this in getAFGR64() return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31; } + bool isHWRegsAsmReg() const { return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31; } + bool isCCRAsmReg() const { return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31; } + bool isFCCAsmReg() const { if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC)) return false; return RegIdx.Index <= 7; } + bool isACCAsmReg() const { return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3; } + bool isCOP0AsmReg() const { return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31; } + bool isCOP2AsmReg() const { return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31; } + bool isCOP3AsmReg() const { return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31; } + bool isMSA128AsmReg() const { return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31; } + bool isMSACtrlAsmReg() const { 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. 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 { switch (Kind) { case k_Immediate: @@ -1553,11 +1631,15 @@ public: } } }; // class MipsOperand -} // namespace + +} // end anonymous namespace namespace llvm { + extern const MCInstrDesc MipsInsts[]; -} + +} // end namespace llvm + static const MCInstrDesc &getInstDesc(unsigned Opcode) { return MipsInsts[Opcode]; } @@ -2904,9 +2986,9 @@ bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, unsigned Opcode = Inst.getOpcode(); unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM; - assert (Inst.getOperand(OpNum - 1).isImm() && - Inst.getOperand(OpNum - 2).isReg() && - Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand."); + assert(Inst.getOperand(OpNum - 1).isImm() && + Inst.getOperand(OpNum - 2).isReg() && + Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand."); if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 && Inst.getOperand(OpNum - 1).getImm() >= 0 && @@ -3503,10 +3585,10 @@ bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, const MCSubtargetInfo *STI) { MipsTargetStreamer &TOut = getTargetStreamer(); - assert (Inst.getNumOperands() == 3 && "Invalid operand count"); - assert (Inst.getOperand(0).isReg() && - Inst.getOperand(1).isReg() && - Inst.getOperand(2).isImm() && "Invalid instruction operand."); + assert(Inst.getNumOperands() == 3 && "Invalid operand count"); + assert(Inst.getOperand(0).isReg() && + Inst.getOperand(1).isReg() && + Inst.getOperand(2).isImm() && "Invalid instruction operand."); unsigned ATReg = Mips::NoRegister; unsigned FinalDstReg = Mips::NoRegister; @@ -3578,7 +3660,6 @@ bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, unsigned SecondShift = Mips::NOP; if (hasMips32r2()) { - if (DReg == SReg) { TmpReg = getATReg(Inst.getLoc()); if (!TmpReg) @@ -3600,7 +3681,6 @@ bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, } if (hasMips32()) { - switch (Inst.getOpcode()) { default: llvm_unreachable("unexpected instruction opcode"); @@ -3642,7 +3722,6 @@ bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc, unsigned SecondShift = Mips::NOP; if (hasMips32r2()) { - if (Inst.getOpcode() == Mips::ROLImm) { uint64_t MaxShift = 32; uint64_t ShiftValue = ImmValue; @@ -3661,7 +3740,6 @@ bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc, } if (hasMips32()) { - if (ImmValue == 0) { TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI); return false; @@ -3707,7 +3785,6 @@ bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, unsigned SecondShift = Mips::NOP; if (hasMips64r2()) { - if (TmpReg == SReg) { TmpReg = getATReg(Inst.getLoc()); if (!TmpReg) @@ -3729,7 +3806,6 @@ bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, } if (hasMips64()) { - switch (Inst.getOpcode()) { default: llvm_unreachable("unexpected instruction opcode"); @@ -3773,7 +3849,6 @@ bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCInst TmpInst; if (hasMips64r2()) { - unsigned FinalOpcode = Mips::NOP; if (ImmValue == 0) FinalOpcode = Mips::DROTR; @@ -3801,7 +3876,6 @@ bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc, } if (hasMips64()) { - if (ImmValue == 0) { TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI); return false; @@ -3985,7 +4059,6 @@ bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, const MCSubtargetInfo *STI) { - warnIfNoMacro(IDLoc); MipsTargetStreamer &TOut = getTargetStreamer(); @@ -4158,17 +4231,15 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm) { - MCInst Inst; unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); switch (MatchResult) { - case Match_Success: { + case Match_Success: if (processInstruction(Inst, IDLoc, Out, STI)) return true; return false; - } case Match_MissingFeature: Error(IDLoc, "instruction requires a CPU feature not currently enabled"); return true; @@ -4441,7 +4512,6 @@ int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) { } int MipsAsmParser::matchFPURegisterName(StringRef Name) { - if (Name[0] == 'f') { StringRef NumString = Name.substr(1); unsigned IntVal; @@ -4455,7 +4525,6 @@ int MipsAsmParser::matchFPURegisterName(StringRef Name) { } int MipsAsmParser::matchFCCRegisterName(StringRef Name) { - if (Name.startswith("fcc")) { StringRef NumString = Name.substr(3); unsigned IntVal; @@ -4469,7 +4538,6 @@ int MipsAsmParser::matchFCCRegisterName(StringRef Name) { } int MipsAsmParser::matchACRegisterName(StringRef Name) { - if (Name.startswith("ac")) { StringRef NumString = Name.substr(2); unsigned IntVal; @@ -4589,7 +4657,6 @@ bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { } bool MipsAsmParser::isEvaluated(const MCExpr *Expr) { - switch (Expr->getKind()) { case MCExpr::Constant: return true; @@ -5522,7 +5589,7 @@ bool MipsAsmParser::parseSetPushDirective() { // Create a copy of the current assembler options environment and push it. AssemblerOptions.push_back( - make_unique(AssemblerOptions.back().get())); + llvm::make_unique(AssemblerOptions.back().get())); getTargetStreamer().emitDirectiveSetPush(); return false; @@ -6001,7 +6068,7 @@ bool MipsAsmParser::parseDirectiveSet() { bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) { MCAsmParser &Parser = getParser(); if (getLexer().isNot(AsmToken::EndOfStatement)) { - for (;;) { + while (true) { const MCExpr *Value; if (getParser().parseExpression(Value)) return true; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp index 44494b12fe2d..324fd3c6fe14 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -7,33 +7,38 @@ // //===----------------------------------------------------------------------===// -#include -#include -#include "MCTargetDesc/MipsBaseInfo.h" #include "MCTargetDesc/MipsFixupKinds.h" -#include "MCTargetDesc/MipsMCExpr.h" #include "MCTargetDesc/MipsMCTargetDesc.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCELFObjectWriter.h" -#include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCSection.h" +#include "llvm/MC/MCFixup.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/ELF.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/raw_ostream.h" +#include +#include +#include +#include +#include +#include #define DEBUG_TYPE "mips-elf-object-writer" using namespace llvm; namespace { + /// Holds additional information needed by the relocation ordering algorithm. struct MipsRelocationEntry { 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 { R.print(Out); @@ -53,23 +58,33 @@ public: MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI, bool _isN64, bool IsLittleEndian); - ~MipsELFObjectWriter() override; + ~MipsELFObjectWriter() override = default; unsigned getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const override; bool needsRelocateWithSymbol(const MCSymbol &Sym, unsigned Type) const override; - virtual void sortRelocs(const MCAssembler &Asm, - std::vector &Relocs) override; + void sortRelocs(const MCAssembler &Asm, + std::vector &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 /// d2 when the predicate is false. This is essentially both std::copy_if and /// std::remove_copy_if combined into a single pass. template -std::pair copy_if_else(InputIt First, InputIt Last, - OutputIt1 d1, OutputIt2 d2, - UnaryPredicate Predicate) { +static std::pair copy_if_else(InputIt First, InputIt Last, + OutputIt1 d1, OutputIt2 d2, + UnaryPredicate Predicate) { for (InputIt I = First; I != Last; ++I) { if (Predicate(*I)) { *d1 = *I; @@ -83,14 +98,6 @@ std::pair copy_if_else(InputIt First, InputIt Last, 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). /// /// An element matches when Predicate(X) returns FindBest_Match or @@ -101,8 +108,8 @@ enum FindBestPredicateResult { /// This is similar to std::find_if but finds the best of multiple possible /// matches. template -InputIt find_best(InputIt First, InputIt Last, UnaryPredicate Predicate, - Comparator BetterThan) { +static InputIt find_best(InputIt First, InputIt Last, UnaryPredicate Predicate, + Comparator BetterThan) { InputIt Best = Last; for (InputIt I = First; I != Last; ++I) { @@ -202,16 +209,12 @@ static void dumpRelocs(const char *Prefix, const Container &Relocs) { } #endif -} // end anonymous namespace - MipsELFObjectWriter::MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI, bool _isN64, bool IsLittleEndian) : MCELFObjectTargetWriter(_is64Bit, OSABI, ELF::EM_MIPS, /*HasRelocationAddend*/ _isN64, /*IsN64*/ _isN64) {} -MipsELFObjectWriter::~MipsELFObjectWriter() {} - unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, @@ -419,7 +422,6 @@ unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx, /// always match using the expressions from the source. void MipsELFObjectWriter::sortRelocs(const MCAssembler &Asm, std::vector &Relocs) { - // 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, // rather than it being split across a pair of relocations. diff --git a/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp b/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp index 5fca5ff28316..026f66a1c0e1 100644 --- a/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp +++ b/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// // -// // This pass is used to make Pc relative loads of constants. // For now, only Mips16 will use this. // @@ -19,30 +18,43 @@ // This can be particularly helpful in static relocation mode for embedded // non-linux targets. // -// +//===----------------------------------------------------------------------===// #include "Mips.h" -#include "MCTargetDesc/MipsBaseInfo.h" #include "Mips16InstrInfo.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/STLExtras.h" +#include "llvm/ADT/StringRef.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DebugLoc.h" #include "llvm/IR/Function.h" -#include "llvm/IR/InstIterator.h" +#include "llvm/IR/Type.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegisterInfo.h" #include +#include +#include +#include +#include +#include using namespace llvm; @@ -58,7 +70,6 @@ static cl::opt AlignConstantIslands("mips-align-constant-islands", cl::Hidden, cl::init(true), cl::desc("Align constant islands in code")); - // Rather than do make check tests with huge amounts of code, we force // the test to use this amount. // @@ -178,7 +189,6 @@ static unsigned int branchMaxOffsets(unsigned int Opcode) { namespace { - typedef MachineBasicBlock::iterator Iter; typedef MachineBasicBlock::reverse_iterator ReverseIter; @@ -195,7 +205,6 @@ namespace { /// tracks a list of users. class MipsConstantIslands : public MachineFunctionPass { - /// BasicBlockInfo - Information about the offset and size of a single /// basic block. struct BasicBlockInfo { @@ -208,14 +217,16 @@ namespace { /// /// Because worst case padding is used, the computed offset of an aligned /// block may not actually be aligned. - unsigned Offset; + unsigned Offset = 0; /// Size - Size of the basic block in bytes. If the block contains /// inline assembly, this is a worst case estimate. /// /// The size does not include any alignment padding whether from the /// 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 // @@ -223,9 +234,6 @@ namespace { unsigned PO = Offset + Size; return PO; } - - BasicBlockInfo() : Offset(0), Size(0) {} - }; std::vector BBInfo; @@ -257,13 +265,16 @@ namespace { MachineInstr *MI; MachineInstr *CPEMI; MachineBasicBlock *HighWaterMark; + private: unsigned MaxDisp; unsigned LongFormMaxDisp; // mips16 has 16/32 bit instructions // with different displacements unsigned LongFormOpcode; + public: bool NegOk; + CPUser(MachineInstr *mi, MachineInstr *cpemi, unsigned maxdisp, bool neg, unsigned longformmaxdisp, unsigned longformopcode) @@ -272,18 +283,22 @@ namespace { NegOk(neg){ HighWaterMark = CPEMI->getParent(); } + /// getMaxDisp - Returns the maximum displacement supported by MI. unsigned getMaxDisp() const { unsigned xMaxDisp = ConstantIslandsSmallOffset? ConstantIslandsSmallOffset: MaxDisp; return xMaxDisp; } + void setMaxDisp(unsigned val) { MaxDisp = val; } + unsigned getLongFormMaxDisp() const { return LongFormMaxDisp; } + unsigned getLongFormOpcode() const { return LongFormOpcode; } @@ -300,6 +315,7 @@ namespace { MachineInstr *CPEMI; unsigned CPI; unsigned RefCount; + CPEntry(MachineInstr *cpemi, unsigned cpi, unsigned rc = 0) : CPEMI(cpemi), CPI(cpi), RefCount(rc) {} }; @@ -309,7 +325,7 @@ namespace { /// existed upon entry to this pass), it keeps a vector of entries. /// Original elements are cloned as we go along; the clones are /// put in the vector of the original element, but have distinct CPIs. - std::vector > CPEntries; + std::vector> CPEntries; /// ImmBranch - One per immediate branch, keeping the machine instruction /// pointer, conditional or unconditional, the max displacement, @@ -320,6 +336,7 @@ namespace { unsigned MaxDisp : 31; bool isCond : 1; int UncondBr; + ImmBranch(MachineInstr *mi, unsigned maxdisp, bool cond, int ubr) : MI(mi), MaxDisp(maxdisp), isCond(cond), UncondBr(ubr) {} }; @@ -332,29 +349,27 @@ namespace { /// the branch fix up pass. bool HasFarJump; - const MipsSubtarget *STI; + const MipsSubtarget *STI = nullptr; const Mips16InstrInfo *TII; MipsFunctionInfo *MFI; - MachineFunction *MF; - MachineConstantPool *MCP; + MachineFunction *MF = nullptr; + MachineConstantPool *MCP = nullptr; unsigned PICLabelUId; - bool PrescannedForConstants; + bool PrescannedForConstants = false; void initPICLabelUId(unsigned UId) { PICLabelUId = UId; } - unsigned createPICLabelUId() { return PICLabelUId++; } public: static char ID; - MipsConstantIslands() - : MachineFunctionPass(ID), STI(nullptr), MF(nullptr), MCP(nullptr), - PrescannedForConstants(false) {} + + MipsConstantIslands() : MachineFunctionPass(ID) {} StringRef getPassName() const override { return "Mips Constant Islands"; } @@ -403,13 +418,11 @@ namespace { bool fixupUnconditionalBr(ImmBranch &Br); void prescanForConstants(); - - private: - }; char MipsConstantIslands::ID = 0; -} // end of anonymous namespace + +} // end anonymous namespace bool MipsConstantIslands::isOffsetInRange (unsigned UserOffset, unsigned TrialOffset, @@ -417,6 +430,7 @@ bool MipsConstantIslands::isOffsetInRange return isOffsetInRange(UserOffset, TrialOffset, U.getMaxDisp(), U.NegOk); } + #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) /// print block size and offset information - debugging LLVM_DUMP_METHOD void MipsConstantIslands::dumpBBs() { @@ -427,10 +441,6 @@ LLVM_DUMP_METHOD void MipsConstantIslands::dumpBBs() { } } #endif -/// Returns a pass that converts branches to long branches. -FunctionPass *llvm::createMipsConstantIslandPass() { - return new MipsConstantIslands(); -} bool MipsConstantIslands::runOnMachineFunction(MachineFunction &mf) { // The intention is for this to be a mips16 only pass for now @@ -527,7 +537,6 @@ MipsConstantIslands::doInitialPlacement(std::vector &CPEMIs) { MachineBasicBlock *BB = MF->CreateMachineBasicBlock(); MF->push_back(BB); - // MachineConstantPool measures alignment in bytes. We measure in log2(bytes). unsigned MaxAlign = Log2_32(MCP->getConstantPoolAlignment()); @@ -647,7 +656,6 @@ initializeFunctionInfo(const std::vector &CPEMIs) { for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E; ++I) computeBlockSize(&*I); - // Compute block offsets. adjustBBOffsetsAfter(&MF->front()); @@ -737,7 +745,6 @@ initializeFunctionInfo(const std::vector &CPEMIs) { if (Opc == Mips::CONSTPOOL_ENTRY) continue; - // Scan the instructions for constant pool operands. for (unsigned op = 0, e = MI.getNumOperands(); op != e; ++op) if (MI.getOperand(op).isCPI()) { @@ -784,12 +791,9 @@ initializeFunctionInfo(const std::vector &CPEMIs) { // Instructions can only use one CP entry, don't bother scanning the // rest of the operands. break; - } - } } - } /// computeBlockSize - Compute the size and some alignment information for MBB. @@ -921,8 +925,6 @@ MipsConstantIslands::splitBlockBeforeInstr(MachineInstr &MI) { return NewBB; } - - /// isOffsetInRange - Checks whether UserOffset (the location of a constant pool /// reference) is within MaxDisp of TrialOffset (a proposed location of a /// constant pool entry). @@ -1337,7 +1339,6 @@ bool MipsConstantIslands::handleConstantPoolUser(unsigned CPUserIndex) { if (result==1) return false; else if (result==2) return true; - // Look for water where we can place this CPE. MachineBasicBlock *NewIsland = MF->CreateMachineBasicBlock(); MachineBasicBlock *NewMBB; @@ -1371,7 +1372,7 @@ bool MipsConstantIslands::handleConstantPoolUser(unsigned CPUserIndex) { // it. Check for this so it will be removed from the WaterList. // Also remove any entry from NewWaterList. MachineBasicBlock *WaterBB = &*--NewMBB->getIterator(); - IP = find(WaterList, WaterBB); + IP = llvm::find(WaterList, WaterBB); if (IP != WaterList.end()) NewWaterList.erase(WaterBB); @@ -1473,9 +1474,7 @@ bool MipsConstantIslands::removeUnusedCPEntries() { /// specific BB can fit in MI's displacement field. bool MipsConstantIslands::isBBInRange (MachineInstr *MI,MachineBasicBlock *DestBB, unsigned MaxDisp) { - -unsigned PCAdj = 4; - + unsigned PCAdj = 4; unsigned BrOffset = getOffsetOf(MI) + PCAdj; unsigned DestOffset = BBInfo[DestBB->getNumber()].Offset; @@ -1553,7 +1552,6 @@ MipsConstantIslands::fixupUnconditionalBr(ImmBranch &Br) { return true; } - /// fixupConditionalBr - Fix up a conditional branch whose destination is too /// far away to fit in its displacement field. It is converted to an inverse /// conditional branch + an unconditional branch to the destination. @@ -1614,7 +1612,6 @@ MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) { } } - if (NeedSplit) { splitBlockBeforeInstr(*MI); // No need for the branch to the next block. We're adding an unconditional @@ -1654,7 +1651,6 @@ MipsConstantIslands::fixupConditionalBr(ImmBranch &Br) { return true; } - void MipsConstantIslands::prescanForConstants() { unsigned J = 0; (void)J; @@ -1667,11 +1663,11 @@ void MipsConstantIslands::prescanForConstants() { PrescannedForConstants = true; DEBUG(dbgs() << "constant island constant " << *I << "\n"); J = I->getNumOperands(); - DEBUG(dbgs() << "num operands " << J << "\n"); + DEBUG(dbgs() << "num operands " << J << "\n"); MachineOperand& Literal = I->getOperand(1); if (Literal.isImm()) { int64_t V = Literal.getImm(); - DEBUG(dbgs() << "literal " << V << "\n"); + DEBUG(dbgs() << "literal " << V << "\n"); Type *Int32Ty = Type::getInt32Ty(MF->getFunction()->getContext()); const Constant *C = ConstantInt::get(Int32Ty, V); @@ -1692,3 +1688,8 @@ void MipsConstantIslands::prescanForConstants() { } } } + +/// Returns a pass that converts branches to long branches. +FunctionPass *llvm::createMipsConstantIslandPass() { + return new MipsConstantIslands(); +} diff --git a/llvm/lib/Target/Mips/MipsFastISel.cpp b/llvm/lib/Target/Mips/MipsFastISel.cpp index a44192f57aa0..c060cf06099d 100644 --- a/llvm/lib/Target/Mips/MipsFastISel.cpp +++ b/llvm/lib/Target/Mips/MipsFastISel.cpp @@ -1,4 +1,4 @@ -//===-- MipsFastISel.cpp - Mips FastISel implementation --------------------===// +//===-- MipsFastISel.cpp - Mips FastISel implementation -------------------===// // // The LLVM Compiler Infrastructure // @@ -14,24 +14,62 @@ /// //===----------------------------------------------------------------------===// +#include "MCTargetDesc/MipsABIInfo.h" +#include "MCTargetDesc/MipsBaseInfo.h" #include "MipsCCState.h" #include "MipsInstrInfo.h" #include "MipsISelLowering.h" #include "MipsMachineFunction.h" -#include "MipsRegisterInfo.h" #include "MipsSubtarget.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/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/FastISel.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/MachineMemOperand.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/GlobalAlias.h" +#include "llvm/IR/GlobalValue.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/Target/TargetInstrInfo.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Compiler.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 +#include +#include +#include #define DEBUG_TYPE "mips-fastisel" @@ -47,35 +85,40 @@ class MipsFastISel final : public FastISel { typedef enum { RegBase, FrameIndexBase } BaseKind; private: - BaseKind Kind; + BaseKind Kind = RegBase; union { unsigned Reg; int FI; } Base; - int64_t Offset; + int64_t Offset = 0; - const GlobalValue *GV; + const GlobalValue *GV = nullptr; public: // 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; } BaseKind getKind() const { return Kind; } bool isRegBase() const { return Kind == RegBase; } bool isFIBase() const { return Kind == FrameIndexBase; } + void setReg(unsigned Reg) { assert(isRegBase() && "Invalid base register access!"); Base.Reg = Reg; } + unsigned getReg() const { assert(isRegBase() && "Invalid base register access!"); return Base.Reg; } + void setFI(unsigned FI) { assert(isFIBase() && "Invalid base frame index access!"); Base.FI = FI; } + unsigned getFI() const { assert(isFIBase() && "Invalid base frame index access!"); return Base.FI; @@ -165,14 +208,17 @@ private: MachineInstrBuilder emitInst(unsigned Opc) { return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc)); } + MachineInstrBuilder emitInst(unsigned Opc, unsigned DstReg) { return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), DstReg); } + MachineInstrBuilder emitInstStore(unsigned Opc, unsigned SrcReg, unsigned MemReg, int64_t MemOffset) { return emitInst(Opc).addReg(SrcReg).addReg(MemReg).addImm(MemOffset); } + MachineInstrBuilder emitInstLoad(unsigned Opc, unsigned DstReg, unsigned MemReg, int64_t MemOffset) { return emitInst(Opc, DstReg).addReg(MemReg).addImm(MemOffset); @@ -198,6 +244,7 @@ private: bool processCallArgs(CallLoweringInfo &CLI, SmallVectorImpl &ArgVTs, unsigned &NumBytes); bool finishCall(CallLoweringInfo &CLI, MVT RetVT, unsigned NumBytes); + const MipsABIInfo &getABI() const { return static_cast(TM).getABI(); } @@ -220,7 +267,8 @@ public: #include "MipsGenFastISel.inc" }; -} // end anonymous namespace. + +} // end anonymous namespace static bool CC_Mips(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, @@ -414,7 +462,6 @@ unsigned MipsFastISel::fastMaterializeConstant(const Constant *C) { } bool MipsFastISel::computeAddress(const Value *Obj, Address &Addr) { - const User *U = nullptr; unsigned Opcode = Instruction::UserOp1; if (const Instruction *I = dyn_cast(Obj)) { @@ -432,10 +479,9 @@ bool MipsFastISel::computeAddress(const Value *Obj, Address &Addr) { switch (Opcode) { default: break; - case Instruction::BitCast: { + case Instruction::BitCast: // Look through bitcasts. return computeAddress(U->getOperand(0), Addr); - } case Instruction::GetElementPtr: { Address SavedAddr = Addr; int64_t TmpOffset = Addr.getOffset(); @@ -451,7 +497,7 @@ bool MipsFastISel::computeAddress(const Value *Obj, Address &Addr) { TmpOffset += SL->getElementOffset(Idx); } else { uint64_t S = DL.getTypeAllocSize(GTI.getIndexedType()); - for (;;) { + while (true) { if (const ConstantInt *CI = dyn_cast(Op)) { // Constant-offset addressing. 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); break; } - case CmpInst::ICMP_UGT: { + case CmpInst::ICMP_UGT: emitInst(Mips::SLTu, ResultReg).addReg(RightReg).addReg(LeftReg); break; - } - case CmpInst::ICMP_ULT: { + case CmpInst::ICMP_ULT: emitInst(Mips::SLTu, ResultReg).addReg(LeftReg).addReg(RightReg); break; - } case CmpInst::ICMP_UGE: { unsigned TempReg = createResultReg(&Mips::GPR32RegClass); 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); break; } - case CmpInst::ICMP_SGT: { + case CmpInst::ICMP_SGT: emitInst(Mips::SLT, ResultReg).addReg(RightReg).addReg(LeftReg); break; - } - case CmpInst::ICMP_SLT: { + case CmpInst::ICMP_SLT: emitInst(Mips::SLT, ResultReg).addReg(LeftReg).addReg(RightReg); break; - } case CmpInst::ICMP_SGE: { unsigned TempReg = createResultReg(&Mips::GPR32RegClass); emitInst(Mips::SLT, TempReg).addReg(LeftReg).addReg(RightReg); @@ -709,6 +751,7 @@ bool MipsFastISel::emitCmp(unsigned ResultReg, const CmpInst *CI) { } return true; } + bool MipsFastISel::emitLoad(MVT VT, unsigned &ResultReg, Address &Addr, unsigned Alignment) { // @@ -716,35 +759,30 @@ bool MipsFastISel::emitLoad(MVT VT, unsigned &ResultReg, Address &Addr, // unsigned Opc; switch (VT.SimpleTy) { - case MVT::i32: { + case MVT::i32: ResultReg = createResultReg(&Mips::GPR32RegClass); Opc = Mips::LW; break; - } - case MVT::i16: { + case MVT::i16: ResultReg = createResultReg(&Mips::GPR32RegClass); Opc = Mips::LHu; break; - } - case MVT::i8: { + case MVT::i8: ResultReg = createResultReg(&Mips::GPR32RegClass); Opc = Mips::LBu; break; - } - case MVT::f32: { + case MVT::f32: if (UnsupportedFPMode) return false; ResultReg = createResultReg(&Mips::FGR32RegClass); Opc = Mips::LWC1; break; - } - case MVT::f64: { + case MVT::f64: if (UnsupportedFPMode) return false; ResultReg = createResultReg(&Mips::AFGR64RegClass); Opc = Mips::LDC1; break; - } default: return false; } @@ -1730,6 +1768,7 @@ bool MipsFastISel::selectTrunc(const Instruction *I) { updateValueMap(I, SrcReg); return true; } + bool MipsFastISel::selectIntExt(const Instruction *I) { Type *DestTy = I->getType(); Value *Src = I->getOperand(0); @@ -1757,6 +1796,7 @@ bool MipsFastISel::selectIntExt(const Instruction *I) { updateValueMap(I, ResultReg); return true; } + bool MipsFastISel::emitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg) { unsigned ShiftAmt; @@ -2074,8 +2114,10 @@ unsigned MipsFastISel::fastEmitInst_rr(unsigned MachineInstOpcode, } namespace llvm { + FastISel *Mips::createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo) { return new MipsFastISel(funcInfo, libInfo); } -} + +} // end namespace llvm diff --git a/llvm/lib/Target/Mips/MipsMachineFunction.cpp b/llvm/lib/Target/Mips/MipsMachineFunction.cpp index d0609b15341d..5bf4c958c7b9 100644 --- a/llvm/lib/Target/Mips/MipsMachineFunction.cpp +++ b/llvm/lib/Target/Mips/MipsMachineFunction.cpp @@ -7,16 +7,15 @@ // //===----------------------------------------------------------------------===// -#include "MCTargetDesc/MipsBaseInfo.h" -#include "MipsInstrInfo.h" +#include "MCTargetDesc/MipsABIInfo.h" #include "MipsMachineFunction.h" #include "MipsSubtarget.h" #include "MipsTargetMachine.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/IR/Function.h" +#include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetRegisterInfo.h" using namespace llvm; @@ -24,7 +23,7 @@ static cl::opt FixGlobalBaseReg("mips-fix-global-base-reg", cl::Hidden, cl::init(true), cl::desc("Always use $gp as the global base register.")); -MipsFunctionInfo::~MipsFunctionInfo() {} +MipsFunctionInfo::~MipsFunctionInfo() = default; bool MipsFunctionInfo::globalBaseRegSet() const { return GlobalBaseReg; @@ -101,4 +100,4 @@ int MipsFunctionInfo::getMoveF64ViaSpillFI(const TargetRegisterClass *RC) { return MoveF64ViaSpillFI; } -void MipsFunctionInfo::anchor() { } +void MipsFunctionInfo::anchor() {} diff --git a/llvm/lib/Target/Mips/MipsMachineFunction.h b/llvm/lib/Target/Mips/MipsMachineFunction.h index c9e5fddc1932..553a66703b26 100644 --- a/llvm/lib/Target/Mips/MipsMachineFunction.h +++ b/llvm/lib/Target/Mips/MipsMachineFunction.h @@ -1,4 +1,4 @@ -//===-- MipsMachineFunctionInfo.h - Private data used for Mips ----*- C++ -*-=// +//===- MipsMachineFunctionInfo.h - Private data used for Mips ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -15,12 +15,8 @@ #define LLVM_LIB_TARGET_MIPS_MIPSMACHINEFUNCTION_H #include "Mips16HardFloatInfo.h" -#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineMemOperand.h" -#include "llvm/CodeGen/PseudoSourceValue.h" -#include "llvm/Target/TargetFrameLowering.h" -#include "llvm/Target/TargetMachine.h" #include namespace llvm { @@ -29,12 +25,9 @@ namespace llvm { /// Mips target-specific information for each MachineFunction. class MipsFunctionInfo : public MachineFunctionInfo { public: - MipsFunctionInfo(MachineFunction &MF) - : MF(MF), SRetReturnReg(0), GlobalBaseReg(0), VarArgsFrameIndex(0), - CallsEhReturn(false), IsISR(false), SaveS2(false), - MoveF64ViaSpillFI(-1) {} + MipsFunctionInfo(MachineFunction &MF) : MF(MF) {} - ~MipsFunctionInfo(); + ~MipsFunctionInfo() override; unsigned getSRetReturnReg() const { return SRetReturnReg; } void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; } @@ -81,25 +74,26 @@ public: int getMoveF64ViaSpillFI(const TargetRegisterClass *RC); - std::map + std::map StubsNeeded; private: virtual void anchor(); MachineFunction& MF; + /// SRetReturnReg - Some subtargets require that sret lowering includes /// returning the value of the returned struct in a register. This field /// 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 /// use as the global base register. This is used for PIC in some PIC /// relocation models. - unsigned GlobalBaseReg; + unsigned GlobalBaseReg = 0; /// VarArgsFrameIndex - FrameIndex for start of varargs area. - int VarArgsFrameIndex; + int VarArgsFrameIndex = 0; /// True if function has a byval argument. bool HasByvalArg; @@ -108,25 +102,25 @@ private: unsigned IncomingArgSize; /// CallsEhReturn - Whether the function calls llvm.eh.return. - bool CallsEhReturn; + bool CallsEhReturn = false; /// Frame objects for spilling eh data registers. int EhDataRegFI[4]; /// ISR - Whether the function is an Interrupt Service Routine. - bool IsISR; + bool IsISR = false; /// Frame objects for spilling C0_STATUS, C0_EPC int ISRDataRegFI[2]; // saveS2 - bool SaveS2; + bool SaveS2 = false; /// FrameIndex for expanding BuildPairF64 nodes to spill and reload when the /// 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