Index: include/llvm/MC/MCParser/MCAsmParserExtension.h =================================================================== --- include/llvm/MC/MCParser/MCAsmParserExtension.h +++ include/llvm/MC/MCParser/MCAsmParserExtension.h @@ -65,6 +65,10 @@ SourceMgr &getSourceManager() { return getParser().getSourceManager(); } MCStreamer &getStreamer() { return getParser().getStreamer(); } + const MCStreamer &getStreamer() const { + return const_cast(this)->getStreamer(); + } + bool Warning(SMLoc L, const Twine &Msg) { return getParser().Warning(L, Msg); } Index: include/llvm/MC/MCStreamer.h =================================================================== --- include/llvm/MC/MCStreamer.h +++ include/llvm/MC/MCStreamer.h @@ -230,6 +230,10 @@ return TargetStreamer.get(); } + const MCTargetStreamer *getTargetStreamer() const { + return const_cast(this)->getTargetStreamer(); + } + unsigned getNumFrameInfos() { return DwarfFrameInfos.size(); } ArrayRef getDwarfFrameInfos() const { return DwarfFrameInfos; Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -41,7 +41,7 @@ namespace { class MipsAssemblerOptions { public: - MipsAssemblerOptions(uint64_t Features_) : + MipsAssemblerOptions(uint64_t Features_) : ATReg(1), Reorder(true), Macro(true), Features(Features_) {} MipsAssemblerOptions(const MipsAssemblerOptions *Opts) { @@ -94,6 +94,10 @@ return static_cast(TS); } + const MipsTargetStreamer &getTargetStreamer() const { + return const_cast(this)->getTargetStreamer(); + } + MCSubtargetInfo &STI; SmallVector, 2> AssemblerOptions; MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a @@ -327,13 +331,8 @@ AssemblerOptions.push_back( make_unique(getAvailableFeatures())); - getTargetStreamer().updateABIInfo(*this); - - // Assert exactly one ABI was chosen. - assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) + - ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) + - ((STI.getFeatureBits() & Mips::FeatureN32) != 0) + - ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1); + getTargetStreamer().updateABIFlagsSection( + static_cast(*this)); if (!isABI_O32() && !useOddSPReg() != 0) report_fatal_error("-mno-odd-spreg requires the O32 ABI"); @@ -346,9 +345,10 @@ bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; } bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; } - bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; } - bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; } - bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; } + bool isABI_EABI() const { return getTargetStreamer().getABI().IsEABI(); } + bool isABI_N64() const { return getTargetStreamer().getABI().IsN64(); } + bool isABI_N32() const { return getTargetStreamer().getABI().IsN32(); } + bool isABI_O32() const { return getTargetStreamer().getABI().IsO32(); } bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; } bool useOddSPReg() const { @@ -1872,7 +1872,7 @@ } void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) { - if ((RegIndex != 0) && + if ((RegIndex != 0) && ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) { if (RegIndex == 1) Warning(Loc, "used $at without \".set noat\""); @@ -3564,7 +3564,7 @@ getParser().getStreamer().EmitGPRel32Value(Value); if (getLexer().isNot(AsmToken::EndOfStatement)) - return Error(getLexer().getLoc(), + return Error(getLexer().getLoc(), "unexpected token, expected end of statement"); Parser.Lex(); // Eat EndOfStatement token. return false; @@ -3582,7 +3582,7 @@ getParser().getStreamer().EmitGPRel64Value(Value); if (getLexer().isNot(AsmToken::EndOfStatement)) - return Error(getLexer().getLoc(), + return Error(getLexer().getLoc(), "unexpected token, expected end of statement"); Parser.Lex(); // Eat EndOfStatement token. return false; @@ -3624,7 +3624,7 @@ } // Unknown option. - Warning(Parser.getTok().getLoc(), + Warning(Parser.getTok().getLoc(), "unknown option, expected 'pic0' or 'pic2'"); Parser.eatToEndOfStatement(); return false; @@ -4005,7 +4005,7 @@ if (IDVal == ".abicalls") { getTargetStreamer().emitDirectiveAbiCalls(); if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { - Error(Parser.getTok().getLoc(), + Error(Parser.getTok().getLoc(), "unexpected token, expected end of statement"); // Clear line Parser.eatToEndOfStatement(); Index: lib/Target/Mips/MCTargetDesc/MipsABIInfo.h =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsABIInfo.h +++ lib/Target/Mips/MCTargetDesc/MipsABIInfo.h @@ -11,6 +11,8 @@ #define MIPSABIINFO_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Triple.h" +#include "llvm/ADT/StringRef.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/IR/CallingConv.h" @@ -25,6 +27,7 @@ public: MipsABIInfo(ABI ThisABI) : ThisABI(ThisABI) {} + MipsABIInfo(bool is64bit); static MipsABIInfo Unknown() { return MipsABIInfo(ABI::Unknown); } static MipsABIInfo O32() { return MipsABIInfo(ABI::O32); } @@ -55,6 +58,7 @@ bool operator<(const MipsABIInfo Other) const { return ThisABI < Other.GetEnumValue(); } + static StringRef selectMipsCPU(Triple TT, StringRef CPU); }; } Index: lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp +++ lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp @@ -9,6 +9,9 @@ #include "MipsABIInfo.h" #include "MipsRegisterInfo.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/CommandLine.h" + using namespace llvm; @@ -43,3 +46,32 @@ return 0; llvm_unreachable("Unhandled ABI"); } + +cl::opt TargetABI( + "target-abi", + cl::init(""), + cl::desc("ABI used"), + cl::Hidden); + +MipsABIInfo::MipsABIInfo(bool is64Bit) { + ThisABI = StringSwitch(TargetABI.getValue()) + .Cases("32", "o32", ABI::O32) + .Case("n32", ABI::N32) + .Cases("64", "n64", ABI::N64) + .Default(ABI::Unknown); + if(!IsKnown()) + ThisABI = is64Bit ? ABI::N64 : ABI::O32; +} + +/// Select the Mips CPU for the given triple and cpu name. +StringRef MipsABIInfo::selectMipsCPU(Triple TT, StringRef CPU) { + StringRef MipsCPU; + if (CPU.empty() || CPU == "generic") { + if (TT.getArch() == Triple::mips || TT.getArch() == Triple::mipsel) + MipsCPU = "mips32"; + else + MipsCPU = "mips64"; + } else + MipsCPU = CPU; + return MipsCPU; +} Index: lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h +++ lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h @@ -30,12 +30,13 @@ Triple::OSType OSType; bool IsLittle; // Big or little endian bool Is64Bit; // 32 or 64 bit words + StringRef CPU; public: MipsAsmBackend(const Target &T, Triple::OSType _OSType, bool _isLittle, - bool _is64Bit) + bool _is64Bit, StringRef CPU_) : MCAsmBackend(), OSType(_OSType), IsLittle(_isLittle), - Is64Bit(_is64Bit) {} + Is64Bit(_is64Bit), CPU(CPU_) {} MCObjectWriter *createObjectWriter(raw_ostream &OS) const override; Index: lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -26,6 +26,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" +#include "MipsABIInfo.h" using namespace llvm; @@ -140,8 +141,17 @@ } MCObjectWriter *MipsAsmBackend::createObjectWriter(raw_ostream &OS) const { + + bool isCPU64Bit = false; + if (CPU.startswith("mips64")) + isCPU64Bit = true; + else isCPU64Bit = StringSwitch(CPU) + .Cases("mips3", "mips4", "mips5", true) + .Default(false); + MipsABIInfo ABIInfo = MipsABIInfo(isCPU64Bit); + return createMipsELFObjectWriter(OS, - MCELFObjectTargetWriter::getOSABI(OSType), IsLittle, Is64Bit); + MCELFObjectTargetWriter::getOSABI(OSType), IsLittle, Is64Bit, ABIInfo.IsN64()); } // Little-endian fixup data byte ordering: @@ -396,35 +406,40 @@ (void)adjustFixupValue(Fixup, Value, &Asm.getContext()); } + // MCAsmBackend MCAsmBackend *llvm::createMipsAsmBackendEL32(const Target &T, const MCRegisterInfo &MRI, StringRef TT, StringRef CPU) { + StringRef MipsCPU = MipsABIInfo::selectMipsCPU(Triple(TT), CPU); return new MipsAsmBackend(T, Triple(TT).getOS(), - /*IsLittle*/true, /*Is64Bit*/false); + /*IsLittle*/true, /*Is64Bit*/false, MipsCPU); } MCAsmBackend *llvm::createMipsAsmBackendEB32(const Target &T, const MCRegisterInfo &MRI, StringRef TT, StringRef CPU) { + StringRef MipsCPU = MipsABIInfo::selectMipsCPU(Triple(TT), CPU); return new MipsAsmBackend(T, Triple(TT).getOS(), - /*IsLittle*/false, /*Is64Bit*/false); + /*IsLittle*/false, /*Is64Bit*/false, MipsCPU); } MCAsmBackend *llvm::createMipsAsmBackendEL64(const Target &T, const MCRegisterInfo &MRI, StringRef TT, StringRef CPU) { + StringRef MipsCPU = MipsABIInfo::selectMipsCPU(Triple(TT), CPU); return new MipsAsmBackend(T, Triple(TT).getOS(), - /*IsLittle*/true, /*Is64Bit*/true); + /*IsLittle*/true, /*Is64Bit*/true, MipsCPU); } MCAsmBackend *llvm::createMipsAsmBackendEB64(const Target &T, const MCRegisterInfo &MRI, StringRef TT, StringRef CPU) { + StringRef MipsCPU = MipsABIInfo::selectMipsCPU(Triple(TT), CPU); return new MipsAsmBackend(T, Triple(TT).getOS(), - /*IsLittle*/false, /*Is64Bit*/true); + /*IsLittle*/false, /*Is64Bit*/true, MipsCPU); } Index: lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -10,6 +10,7 @@ #include "MCTargetDesc/MipsBaseInfo.h" #include "MCTargetDesc/MipsFixupKinds.h" #include "MCTargetDesc/MipsMCTargetDesc.h" +#include "MipsABIInfo.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCExpr.h" @@ -255,9 +256,12 @@ MCObjectWriter *llvm::createMipsELFObjectWriter(raw_ostream &OS, uint8_t OSABI, bool IsLittleEndian, - bool Is64Bit) { - MCELFObjectTargetWriter *MOTW = new MipsELFObjectWriter(Is64Bit, OSABI, + bool Is64Bit, + bool IsN64) { + + MCELFObjectTargetWriter *MOTW = new MipsELFObjectWriter(IsN64, OSABI, (Is64Bit) ? true : false, IsLittleEndian); + return createELFObjectWriter(MOTW, OS, IsLittleEndian); } Index: lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h +++ lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h @@ -36,7 +36,6 @@ MipsELFStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS, MCCodeEmitter *Emitter, const MCSubtargetInfo &STI) : MCELFStreamer(Context, MAB, OS, Emitter) { - RegInfoRecord = new MipsRegInfoRecord(this, Context, STI); MipsOptionRecords.push_back( std::unique_ptr(RegInfoRecord)); Index: lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h +++ lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h @@ -58,7 +58,8 @@ MCObjectWriter *createMipsELFObjectWriter(raw_ostream &OS, uint8_t OSABI, bool IsLittleEndian, - bool Is64Bit); + bool Is64Bit, + bool IsN64); } // End llvm namespace // Defines symbolic names for Mips registers. This defines a mapping from Index: lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp +++ lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp @@ -17,6 +17,7 @@ #include "MipsMCNaCl.h" #include "MipsMCTargetDesc.h" #include "MipsTargetStreamer.h" +#include "MipsABIInfo.h" #include "llvm/ADT/Triple.h" #include "llvm/MC/MCCodeGenInfo.h" #include "llvm/MC/MCELFStreamer.h" @@ -41,20 +42,6 @@ #define GET_REGINFO_MC_DESC #include "MipsGenRegisterInfo.inc" -/// Select the Mips CPU for the given triple and cpu name. -/// FIXME: Merge with the copy in MipsSubtarget.cpp -static inline StringRef selectMipsCPU(StringRef TT, StringRef CPU) { - if (CPU.empty() || CPU == "generic") { - Triple TheTriple(TT); - if (TheTriple.getArch() == Triple::mips || - TheTriple.getArch() == Triple::mipsel) - CPU = "mips32"; - else - CPU = "mips64"; - } - return CPU; -} - static MCInstrInfo *createMipsMCInstrInfo() { MCInstrInfo *X = new MCInstrInfo(); InitMipsMCInstrInfo(X); @@ -69,7 +56,7 @@ static MCSubtargetInfo *createMipsMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS) { - CPU = selectMipsCPU(TT, CPU); + CPU = MipsABIInfo::selectMipsCPU(Triple(TT), CPU); MCSubtargetInfo *X = new MCSubtargetInfo(); InitMipsMCSubtargetInfo(X, TT, CPU, FS); return X; @@ -115,7 +102,8 @@ S = createMipsELFStreamer(Context, MAB, OS, Emitter, STI, RelaxAll); else S = createMipsNaClELFStreamer(Context, MAB, OS, Emitter, STI, RelaxAll); - new MipsTargetELFStreamer(*S, STI); + MipsABIInfo ABI(STI.getFeatureBits() & Mips::FeatureGP64Bit); + new MipsTargetELFStreamer(*S, ABI, STI); return S; } @@ -126,13 +114,15 @@ MCAsmBackend *TAB, bool ShowInst) { MCStreamer *S = llvm::createAsmStreamer( Ctx, OS, isVerboseAsm, useDwarfDirectory, InstPrint, CE, TAB, ShowInst); - new MipsTargetAsmStreamer(*S, OS); + MipsABIInfo ABI(false); + new MipsTargetAsmStreamer(*S, ABI, OS); return S; } static MCStreamer *createMipsNullStreamer(MCContext &Ctx) { MCStreamer *S = llvm::createNullStreamer(Ctx); - new MipsTargetStreamer(*S); + MipsABIInfo ABI(false); + new MipsTargetStreamer(*S,ABI); return S; } Index: lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp +++ lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp @@ -9,6 +9,7 @@ #include "MipsOptionRecord.h" #include "MipsELFStreamer.h" +#include "MipsTargetStreamer.h" #include "llvm/MC/MCSectionELF.h" using namespace llvm; @@ -16,15 +17,17 @@ void MipsRegInfoRecord::EmitMipsOptionRecord() { MCAssembler &MCA = Streamer->getAssembler(); Triple T(STI.getTargetTriple()); - uint64_t Features = STI.getFeatureBits(); + MipsTargetStreamer *TargetStreamer = + static_cast(Streamer->getTargetStreamer()); + Streamer->PushSection(); // We need to distinguish between N64 and the rest because at the moment // we don't emit .Mips.options for other ELFs other than N64. // Since .reginfo has the same information as .Mips.options (ODK_REGINFO), // we can use the same abstraction (MipsRegInfoRecord class) to handle both. - if (Features & Mips::FeatureN64) { + if (TargetStreamer->getABI().IsN64()) { // The EntrySize value of 1 seems strange since the records are neither // 1-byte long nor fixed length but it matches the value GAS emits. const MCSectionELF *Sec = @@ -50,7 +53,7 @@ Context.getELFSection(".reginfo", ELF::SHT_MIPS_REGINFO, ELF::SHF_ALLOC, SectionKind::getMetadata(), 24, ""); MCA.getOrCreateSectionData(*Sec) - .setAlignment(Features & Mips::FeatureN32 ? 8 : 4); + .setAlignment(TargetStreamer->getABI().IsN32() ? 8 : 4); Streamer->SwitchSection(Sec); Streamer->EmitIntValue(ri_gprmask, 4); Index: lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -28,8 +28,8 @@ using namespace llvm; -MipsTargetStreamer::MipsTargetStreamer(MCStreamer &S) - : MCTargetStreamer(S), ModuleDirectiveAllowed(true) { +MipsTargetStreamer::MipsTargetStreamer(MCStreamer &S, MipsABIInfo ABI) + : MCTargetStreamer(S), ABIInfo(ABI), ModuleDirectiveAllowed(true) { GPRInfoSet = FPRInfoSet = FrameInfoSet = false; } void MipsTargetStreamer::emitDirectiveSetMicroMips() {} @@ -85,9 +85,9 @@ report_fatal_error("+nooddspreg is only valid for O32"); } -MipsTargetAsmStreamer::MipsTargetAsmStreamer(MCStreamer &S, +MipsTargetAsmStreamer::MipsTargetAsmStreamer(MCStreamer &S, MipsABIInfo ABI, formatted_raw_ostream &OS) - : MipsTargetStreamer(S), OS(OS) {} + : MipsTargetStreamer(S, ABI), OS(OS) {} void MipsTargetAsmStreamer::emitDirectiveSetMicroMips() { OS << "\t.set\tmicromips\n"; @@ -331,9 +331,9 @@ } // This part is for ELF object output. -MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S, +MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S, MipsABIInfo ABI, const MCSubtargetInfo &STI) - : MipsTargetStreamer(S), MicroMipsEnabled(false), STI(STI) { + : MipsTargetStreamer(S, ABI), MicroMipsEnabled(false), STI(STI) { MCAssembler &MCA = getStreamer().getAssembler(); uint64_t Features = STI.getFeatureBits(); Triple T(STI.getTargetTriple()); @@ -370,13 +370,13 @@ // ABI // N64 does not require any ABI bits. - if (Features & Mips::FeatureO32) + if (isO32()) EFlags |= ELF::EF_MIPS_ABI_O32; - else if (Features & Mips::FeatureN32) + else if (isN32()) EFlags |= ELF::EF_MIPS_ABI2; if (Features & Mips::FeatureGP64Bit) { - if (Features & Mips::FeatureO32) + if (isO32()) EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */ } else if (Features & Mips::FeatureMips64r2 || Features & Mips::FeatureMips64) EFlags |= ELF::EF_MIPS_32BITMODE; @@ -388,7 +388,7 @@ // -mabicalls and -mplt are not implemented but we should act as if they were // given. EFlags |= ELF::EF_MIPS_CPIC; - if (Features & Mips::FeatureN64) + if (isN64()) EFlags |= ELF::EF_MIPS_PIC; MCA.setELFHeaderEFlags(EFlags); Index: lib/Target/Mips/Mips.td =================================================================== --- lib/Target/Mips/Mips.td +++ lib/Target/Mips/Mips.td @@ -69,14 +69,6 @@ "IEEE 754-2008 NaN encoding.">; def FeatureSingleFloat : SubtargetFeature<"single-float", "IsSingleFloat", "true", "Only supports single precision float">; -def FeatureO32 : SubtargetFeature<"o32", "ABI", "MipsABIInfo::O32()", - "Enable o32 ABI">; -def FeatureN32 : SubtargetFeature<"n32", "ABI", "MipsABIInfo::N32()", - "Enable n32 ABI">; -def FeatureN64 : SubtargetFeature<"n64", "ABI", "MipsABIInfo::N64()", - "Enable n64 ABI">; -def FeatureEABI : SubtargetFeature<"eabi", "ABI", "MipsABIInfo::EABI()", - "Enable eabi ABI">; def FeatureNoOddSPReg : SubtargetFeature<"nooddspreg", "UseOddSPReg", "false", "Disable odd numbered single-precision " "registers">; @@ -162,20 +154,20 @@ class Proc Features> : Processor; -def : Proc<"mips1", [FeatureMips1, FeatureO32]>; -def : Proc<"mips2", [FeatureMips2, FeatureO32]>; -def : Proc<"mips32", [FeatureMips32, FeatureO32]>; -def : Proc<"mips32r2", [FeatureMips32r2, FeatureO32]>; -def : Proc<"mips32r6", [FeatureMips32r6, FeatureO32]>; - -def : Proc<"mips3", [FeatureMips3, FeatureN64]>; -def : Proc<"mips4", [FeatureMips4, FeatureN64]>; -def : Proc<"mips5", [FeatureMips5, FeatureN64]>; -def : Proc<"mips64", [FeatureMips64, FeatureN64]>; -def : Proc<"mips64r2", [FeatureMips64r2, FeatureN64]>; -def : Proc<"mips64r6", [FeatureMips64r6, FeatureN64]>; -def : Proc<"mips16", [FeatureMips16, FeatureO32]>; -def : Proc<"octeon", [FeatureMips64r2, FeatureN64, FeatureCnMips]>; +def : Proc<"mips1", [FeatureMips1]>; +def : Proc<"mips2", [FeatureMips2]>; +def : Proc<"mips32", [FeatureMips32]>; +def : Proc<"mips32r2", [FeatureMips32r2]>; +def : Proc<"mips32r6", [FeatureMips32r6]>; + +def : Proc<"mips3", [FeatureMips3]>; +def : Proc<"mips4", [FeatureMips4]>; +def : Proc<"mips5", [FeatureMips5]>; +def : Proc<"mips64", [FeatureMips64]>; +def : Proc<"mips64r2", [FeatureMips64r2]>; +def : Proc<"mips64r6", [FeatureMips64r6]>; +def : Proc<"mips16", [FeatureMips16]>; +def : Proc<"octeon", [FeatureMips64r2, FeatureCnMips]>; def MipsAsmParser : AsmParser { let ShouldEmitMatchRegisterName = 0; Index: lib/Target/Mips/MipsAsmPrinter.cpp =================================================================== --- lib/Target/Mips/MipsAsmPrinter.cpp +++ lib/Target/Mips/MipsAsmPrinter.cpp @@ -725,7 +725,7 @@ SectionKind::getDataRel())); } - getTargetStreamer().updateABIInfo(*Subtarget); + getTargetStreamer().updateABIFlagsSection(*Subtarget); // We should always emit a '.module fp=...' but binutils 2.24 does not accept // it. We therefore emit it when it contradicts the ABI defaults (-mfpxx or Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -182,8 +182,6 @@ AssemblerPredicate<"FeatureMips64r6">; def NotMips64r6 : Predicate<"!Subtarget->hasMips64r6()">, AssemblerPredicate<"!FeatureMips64r6">; -def IsN64 : Predicate<"Subtarget->isABI_N64()">, - AssemblerPredicate<"FeatureN64">; def InMips16Mode : Predicate<"Subtarget->inMips16Mode()">, AssemblerPredicate<"FeatureMips16">; def HasCnMips : Predicate<"Subtarget->hasCnMips()">, Index: lib/Target/Mips/MipsSubtarget.h =================================================================== --- lib/Target/Mips/MipsSubtarget.h +++ lib/Target/Mips/MipsSubtarget.h @@ -45,9 +45,6 @@ // Mips architecture version MipsArchEnum MipsArchVersion; - // Selected ABI - MipsABIInfo ABI; - // IsLittle - The target is Little Endian bool IsLittle; @@ -146,6 +143,8 @@ std::unique_ptr FrameLowering; std::unique_ptr TLInfo; + // Selected ABI + MipsABIInfo ABI; public: /// This overrides the PostRAScheduler bit in the SchedModel for each CPU. bool enablePostMachineScheduler() const override; Index: lib/Target/Mips/MipsSubtarget.cpp =================================================================== --- lib/Target/Mips/MipsSubtarget.cpp +++ lib/Target/Mips/MipsSubtarget.cpp @@ -62,18 +62,6 @@ GPOpt("mgpopt", cl::Hidden, cl::desc("MIPS: Enable gp-relative addressing of small data items")); -/// Select the Mips CPU for the given triple and cpu name. -/// FIXME: Merge with the copy in MipsMCTargetDesc.cpp -static StringRef selectMipsCPU(Triple TT, StringRef CPU) { - if (CPU.empty() || CPU == "generic") { - if (TT.getArch() == Triple::mips || TT.getArch() == Triple::mipsel) - CPU = "mips32"; - else - CPU = "mips64"; - } - return CPU; -} - void MipsSubtarget::anchor() { } static std::string computeDataLayout(const MipsSubtarget &ST) { @@ -110,8 +98,8 @@ const std::string &FS, bool little, const MipsTargetMachine *_TM) : MipsGenSubtargetInfo(TT, CPU, FS), MipsArchVersion(MipsDefault), - ABI(MipsABIInfo::Unknown()), IsLittle(little), IsSingleFloat(false), - IsFPXX(false), NoABICalls(false), IsFP64bit(false), UseOddSPReg(true), + IsLittle(little), IsSingleFloat(false), IsFPXX(false), + NoABICalls(false), IsFP64bit(false), UseOddSPReg(true), IsNaN2008bit(false), IsGP64bit(false), HasVFPU(false), HasCnMips(false), IsLinux(true), HasMips3_32(false), HasMips3_32r2(false), HasMips4_32(false), HasMips4_32r2(false), HasMips5_32r2(false), @@ -122,7 +110,7 @@ DL(computeDataLayout(initializeSubtargetDependencies(CPU, FS, TM))), TSInfo(DL), InstrInfo(MipsInstrInfo::create(*this)), FrameLowering(MipsFrameLowering::create(*this)), - TLInfo(MipsTargetLowering::create(*TM, *this)) { + TLInfo(MipsTargetLowering::create(*TM, *this)), ABI(IsGP64bit) { PreviousInMips16Mode = InMips16Mode; @@ -136,13 +124,6 @@ if (MipsArchVersion == Mips5) report_fatal_error("Code generation for MIPS-V is not implemented", false); - // Assert exactly one ABI was chosen. - assert(ABI.IsKnown()); - assert((((getFeatureBits() & Mips::FeatureO32) != 0) + - ((getFeatureBits() & Mips::FeatureEABI) != 0) + - ((getFeatureBits() & Mips::FeatureN32) != 0) + - ((getFeatureBits() & Mips::FeatureN64) != 0)) == 1); - // Check if Architecture and ABI are compatible. assert(((!isGP64bit() && (isABI_O32() || isABI_EABI())) || (isGP64bit() && (isABI_N32() || isABI_N64()))) && @@ -200,8 +181,8 @@ MipsSubtarget & MipsSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS, const TargetMachine *TM) { - std::string CPUName = selectMipsCPU(TargetTriple, CPU); - + std::string CPUName = MipsABIInfo::selectMipsCPU(TargetTriple, CPU); + // Parse features string. ParseSubtargetFeatures(CPUName, FS); // Initialize scheduling itinerary for the specified CPU. @@ -225,3 +206,4 @@ Reloc::Model MipsSubtarget::getRelocationModel() const { return TM->getRelocationModel(); } + Index: lib/Target/Mips/MipsTargetStreamer.h =================================================================== --- lib/Target/Mips/MipsTargetStreamer.h +++ lib/Target/Mips/MipsTargetStreamer.h @@ -14,6 +14,7 @@ #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" #include "MCTargetDesc/MipsABIFlagsSection.h" +#include "MCTargetDesc/MipsABIInfo.h" namespace llvm { @@ -21,7 +22,7 @@ class MipsTargetStreamer : public MCTargetStreamer { public: - MipsTargetStreamer(MCStreamer &S); + MipsTargetStreamer(MCStreamer &S, MipsABIInfo ABI); virtual void emitDirectiveSetMicroMips(); virtual void emitDirectiveSetNoMicroMips(); virtual void emitDirectiveSetMips16(); @@ -94,15 +95,23 @@ // This method enables template classes to set internal abi flags // structure values. template - void updateABIInfo(const PredicateLibrary &P) { + void updateABIFlagsSection(const PredicateLibrary &P) { ABIFlagsSection.setAllFromPredicates(P); } MipsABIFlagsSection &getABIFlagsSection() { return ABIFlagsSection; } + MipsABIInfo getABI() { return ABIInfo; } + const MipsABIInfo getABI() const { return ABIInfo; } + protected: + MipsABIInfo ABIInfo; MipsABIFlagsSection ABIFlagsSection; + bool isO32() const { return ABIInfo.IsO32(); } + bool isN32() const { return ABIInfo.IsN32(); } + bool isN64() const { return ABIInfo.IsN64(); } + bool GPRInfoSet; unsigned GPRBitMask; int GPROffset; @@ -125,7 +134,8 @@ formatted_raw_ostream &OS; public: - MipsTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS); + MipsTargetAsmStreamer(MCStreamer &S, MipsABIInfo ABI, + formatted_raw_ostream &OS); void emitDirectiveSetMicroMips() override; void emitDirectiveSetNoMicroMips() override; void emitDirectiveSetMips16() override; @@ -192,7 +202,8 @@ public: bool isMicroMipsEnabled() const { return MicroMipsEnabled; } MCELFStreamer &getStreamer(); - MipsTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI); + MipsTargetELFStreamer(MCStreamer &S, MipsABIInfo ABI, + const MCSubtargetInfo &STI); void emitLabel(MCSymbol *Symbol) override; void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; @@ -225,10 +236,6 @@ void emitDirectiveModuleOddSPReg(bool Enabled, bool IsO32ABI) override; void emitMipsAbiFlags() override; -protected: - bool isO32() const { return STI.getFeatureBits() & Mips::FeatureO32; } - bool isN32() const { return STI.getFeatureBits() & Mips::FeatureN32; } - bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; } }; } #endif