Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -40,7 +40,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) { @@ -95,6 +95,7 @@ MCSubtargetInfo &STI; MCAsmParser &Parser; + MipsABIInfo ABI; SmallVector, 2> AssemblerOptions; MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a // nullptr, which indicates that no function is currently @@ -299,25 +300,24 @@ MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, const MCInstrInfo &MII, const MCTargetOptions &Options) - : MCTargetAsmParser(), STI(sti), Parser(parser) { + : MCTargetAsmParser(), STI(sti), Parser(parser), + ABI(getTargetStreamer().getABIInfo()) { // Initialize the set of available features. setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); - + // Remember the initial assembler options. The user can not modify these. AssemblerOptions.push_back( make_unique(getAvailableFeatures())); - + // Create an assembler options environment for the user to modify. AssemblerOptions.push_back( make_unique(getAvailableFeatures())); - getTargetStreamer().updateABIInfo(*this); + if (!ABI.IsKnown()) + ABI = MipsABIInfo(isGP64bit()); - // 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"); @@ -333,9 +333,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 ABI.IsEABI(); } + bool isABI_N64() const { return ABI.IsN64(); } + bool isABI_N32() const { return ABI.IsN32(); } + bool isABI_O32() const { return ABI.IsO32(); } bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; } bool useOddSPReg() const { @@ -1608,7 +1609,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\""); @@ -3085,7 +3086,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; @@ -3102,7 +3103,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; @@ -3143,7 +3144,7 @@ } // Unknown option. - Warning(Parser.getTok().getLoc(), + Warning(Parser.getTok().getLoc(), "unknown option, expected 'pic0' or 'pic2'"); Parser.eatToEndOfStatement(); return false; @@ -3520,7 +3521,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/Disassembler/MipsDisassembler.cpp =================================================================== --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -13,7 +13,7 @@ #include "Mips.h" #include "MipsRegisterInfo.h" -#include "MipsSubtarget.h" +#include "MCTargetDesc/MipsABIInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDisassembler.h" #include "llvm/MC/MCFixedLenDisassembler.h" @@ -38,15 +38,17 @@ /// MipsDisassemblerBase(const MCSubtargetInfo &STI, MCContext &Ctx, bool bigEndian) : - MCDisassembler(STI, Ctx), - IsN64(STI.getFeatureBits() & Mips::FeatureN64), isBigEndian(bigEndian) {} + MCDisassembler(STI, Ctx), isBigEndian(bigEndian) { + if (!ABI.IsKnown()) + ABI = MipsABIInfo(STI.getFeatureBits() & Mips::FeatureGP64Bit); + } virtual ~MipsDisassemblerBase() {} - bool isN64() const { return IsN64; } + bool isN64() const { return ABI.IsN64(); } private: - bool IsN64; + MipsABIInfo ABI; protected: bool isBigEndian; }; Index: lib/Target/Mips/MCTargetDesc/CMakeLists.txt =================================================================== --- lib/Target/Mips/MCTargetDesc/CMakeLists.txt +++ lib/Target/Mips/MCTargetDesc/CMakeLists.txt @@ -1,4 +1,5 @@ add_llvm_library(LLVMMipsDesc + MipsABIInfo.cpp MipsABIFlagsSection.cpp MipsAsmBackend.cpp MipsELFObjectWriter.cpp Index: lib/Target/Mips/MCTargetDesc/MipsABIInfo.h =================================================================== --- /dev/null +++ lib/Target/Mips/MCTargetDesc/MipsABIInfo.h @@ -0,0 +1,52 @@ +//===---- MipsABIInfo.h - Information about MIPS ABI's --------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef MIPSABIINFO_H +#define MIPSABIINFO_H + +#include "llvm/ADT/Triple.h" +#include "llvm/ADT/StringRef.h" + +namespace llvm { +class MipsABIInfo { +public: + enum class ABI { Unknown, O32, N32, N64, EABI }; + +protected: + ABI ThisABI; + +public: + MipsABIInfo(ABI ThisABI) : ThisABI(ThisABI) {} + MipsABIInfo(bool is64bit); + MipsABIInfo(); + + static MipsABIInfo Unknown() { return MipsABIInfo(ABI::Unknown); } + static MipsABIInfo O32() { return MipsABIInfo(ABI::O32); } + static MipsABIInfo N32() { return MipsABIInfo(ABI::N32); } + static MipsABIInfo N64() { return MipsABIInfo(ABI::N64); } + static MipsABIInfo EABI() { return MipsABIInfo(ABI::EABI); } + + bool IsKnown() const { return ThisABI != ABI::Unknown; } + bool IsO32() const { return ThisABI == ABI::O32; } + bool IsN32() const { return ThisABI == ABI::N32; } + bool IsN64() const { return ThisABI == ABI::N64; } + bool IsEABI() const { return ThisABI == ABI::EABI; } + ABI GetEnumValue() const { return ThisABI; } + + /// Ordering of ABI's + /// MipsGenSubtargetInfo.inc will use this to resolve conflicts when given + /// multiple ABI options. + bool operator<(const MipsABIInfo Other) const { + return ThisABI < Other.GetEnumValue(); + } + static StringRef selectMipsCPU(Triple TT, StringRef CPU); +}; +} + +#endif \ No newline at end of file Index: lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp =================================================================== --- /dev/null +++ lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp @@ -0,0 +1,45 @@ +//===---- MipsABIInfo.cpp - Information about MIPS ABI's ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "MCTargetDesc/MipsABIInfo.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/CommandLine.h" + +using namespace llvm; + +cl::opt TargetABI( + "target-abi", + cl::init(""), + cl::desc("ABI used"), + cl::Hidden); + +MipsABIInfo::MipsABIInfo(bool is64Bit) { + ThisABI = is64Bit ? ABI::N64 : ABI::O32; +} +MipsABIInfo::MipsABIInfo() { + + ThisABI = StringSwitch(TargetABI.getValue()) + .Cases("32", "o32", ABI::O32) + .Case("n32", ABI::N32) + .Cases("64", "n64", ABI::N64) + .Default(ABI::Unknown); +} + +/// 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; +} \ No newline at end of file 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 "MCTargetDesc/MipsABIInfo.h" using namespace llvm; @@ -140,8 +141,20 @@ } MCObjectWriter *MipsAsmBackend::createObjectWriter(raw_ostream &OS) const { + + MipsABIInfo ABIInfo; + if (!ABIInfo.IsKnown()) { + bool isCPU64Bit = false; + if (CPU.startswith("mips64")) + isCPU64Bit = true; + else isCPU64Bit = StringSwitch(CPU) + .Cases("mips3", "mips4", "mips5", true) + .Default(false); + ABIInfo = MipsABIInfo(isCPU64Bit); + } + return createMipsELFObjectWriter(OS, - MCELFObjectTargetWriter::getOSABI(OSType), IsLittle, Is64Bit); + MCELFObjectTargetWriter::getOSABI(OSType), IsLittle, Is64Bit, ABIInfo.IsN64()); } // Little-endian fixup data byte ordering: @@ -391,35 +404,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 "MCTargetDesc/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/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; Index: lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp +++ lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp @@ -19,12 +19,14 @@ uint64_t Features = STI.getFeatureBits(); Streamer->PushSection(); + if (!ABI.IsKnown()) + ABI = MipsABIInfo(Features & Mips::FeatureGP64Bit); // 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 (ABI.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 +52,7 @@ Context.getELFSection(".reginfo", ELF::SHT_MIPS_REGINFO, ELF::SHF_ALLOC, SectionKind::getMetadata(), 24, ""); MCA.getOrCreateSectionData(*Sec) - .setAlignment(Features & Mips::FeatureN32 ? 8 : 4); + .setAlignment(ABI.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 @@ -335,6 +335,9 @@ ? true : false; + //Update ABI info + if (!ABIInfo.IsKnown()) + ABIInfo = MipsABIInfo(Features & Mips::FeatureGP64Bit); // Update e_header flags unsigned EFlags = 0; @@ -364,13 +367,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; @@ -382,7 +385,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", "MipsABI", "O32", - "Enable o32 ABI">; -def FeatureN32 : SubtargetFeature<"n32", "MipsABI", "N32", - "Enable n32 ABI">; -def FeatureN64 : SubtargetFeature<"n64", "MipsABI", "N64", - "Enable n64 ABI">; -def FeatureEABI : SubtargetFeature<"eabi", "MipsABI", "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 @@ -319,11 +319,11 @@ /// Emit Set directives. const char *MipsAsmPrinter::getCurrentABIString() const { - switch (Subtarget->getTargetABI()) { - case MipsSubtarget::O32: return "abi32"; - case MipsSubtarget::N32: return "abiN32"; - case MipsSubtarget::N64: return "abi64"; - case MipsSubtarget::EABI: return "eabi32"; // TODO: handle eabi64 + switch (Subtarget->getABIInfo().GetEnumValue()) { + case MipsABIInfo::ABI::O32: return "abi32"; + case MipsABIInfo::ABI::N32: return "abiN32"; + case MipsABIInfo::ABI::N64: return "abi64"; + case MipsABIInfo::ABI::EABI: return "eabi32"; // TODO: handle eabi64 default: llvm_unreachable("Unknown Mips ABI"); } } @@ -707,7 +707,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/MipsConstantIslandPass.cpp =================================================================== --- lib/Target/Mips/MipsConstantIslandPass.cpp +++ lib/Target/Mips/MipsConstantIslandPass.cpp @@ -367,8 +367,7 @@ static char ID; MipsConstantIslands(TargetMachine &tm) : MachineFunctionPass(ID), TM(tm), - IsPIC(TM.getRelocationModel() == Reloc::PIC_), - ABI(TM.getSubtarget().getTargetABI()), STI(nullptr), + IsPIC(TM.getRelocationModel() == Reloc::PIC_), STI(nullptr), MF(nullptr), MCP(nullptr), PrescannedForConstants(false) {} const char *getPassName() const override { Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -180,8 +180,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/MipsLongBranch.cpp =================================================================== --- lib/Target/Mips/MipsLongBranch.cpp +++ lib/Target/Mips/MipsLongBranch.cpp @@ -65,8 +65,8 @@ MipsLongBranch(TargetMachine &tm) : MachineFunctionPass(ID), TM(tm), IsPIC(TM.getRelocationModel() == Reloc::PIC_), - ABI(TM.getSubtarget().getTargetABI()), - LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 10 : + ABI(TM.getSubtarget().getABIInfo()), + LongBranchSeqSize(!IsPIC ? 2 : (ABI.IsN64() ? 10 : (!TM.getSubtarget().isTargetNaCl() ? 9 : 10))) {} const char *getPassName() const override { @@ -87,7 +87,7 @@ MachineFunction *MF; SmallVector MBBInfos; bool IsPIC; - unsigned ABI; + MipsABIInfo ABI; unsigned LongBranchSeqSize; }; @@ -274,7 +274,7 @@ const MipsSubtarget &Subtarget = TM.getSubtarget(); unsigned BalOp = Subtarget.hasMips32r6() ? Mips::BAL : Mips::BAL_BR; - if (ABI != MipsSubtarget::N64) { + if (ABI.IsN64()) { // $longbr: // addiu $sp, $sp, -8 // sw $ra, 0($sp) Index: lib/Target/Mips/MipsOptionRecord.h =================================================================== --- lib/Target/Mips/MipsOptionRecord.h +++ lib/Target/Mips/MipsOptionRecord.h @@ -21,6 +21,7 @@ #define LLVM_LIB_TARGET_MIPS_MIPSOPTIONRECORD_H #include "MCTargetDesc/MipsMCTargetDesc.h" +#include "MCTargetDesc/MipsABIInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCRegisterInfo.h" @@ -73,6 +74,7 @@ uint32_t ri_gprmask; uint32_t ri_cprmask[4]; int64_t ri_gp_value; + MipsABIInfo ABI; }; } // namespace llvm #endif Index: lib/Target/Mips/MipsSubtarget.h =================================================================== --- lib/Target/Mips/MipsSubtarget.h +++ lib/Target/Mips/MipsSubtarget.h @@ -22,6 +22,7 @@ #include "llvm/MC/MCInstrItineraries.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Target/TargetSubtargetInfo.h" +#include "MCTargetDesc/MipsABIInfo.h" #include #define GET_SUBTARGETINFO_HEADER @@ -36,10 +37,6 @@ virtual void anchor(); public: - // NOTE: O64 will not be supported. - enum MipsABIEnum { - UnknownABI, O32, N32, N64, EABI - }; protected: enum MipsArchEnum { @@ -51,7 +48,7 @@ MipsArchEnum MipsArchVersion; // Mips supported ABIs - MipsABIEnum MipsABI; + MipsABIInfo MipsABI; // IsLittle - The target is Little Endian bool IsLittle; @@ -158,12 +155,12 @@ CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const override; /// Only O32 and EABI supported right now. - bool isABI_EABI() const { return MipsABI == EABI; } - bool isABI_N64() const { return MipsABI == N64; } - bool isABI_N32() const { return MipsABI == N32; } - bool isABI_O32() const { return MipsABI == O32; } + bool isABI_EABI() const { return MipsABI.IsEABI(); } + bool isABI_N64() const { return MipsABI.IsN64(); } + bool isABI_N32() const { return MipsABI.IsN32(); } + bool isABI_O32() const { return MipsABI.IsO32(); } bool isABI_FPXX() const { return isABI_O32() && IsFPXX; } - unsigned getTargetABI() const { return MipsABI; } + const MipsABIInfo &getABIInfo() const { return MipsABI; } /// This constructor initializes the data members to match that /// of the specified triple. Index: lib/Target/Mips/MipsSubtarget.cpp =================================================================== --- lib/Target/Mips/MipsSubtarget.cpp +++ lib/Target/Mips/MipsSubtarget.cpp @@ -58,18 +58,6 @@ cl::desc("MIPS: mips16 constant islands enable."), cl::init(true)); -/// 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) { @@ -106,15 +94,14 @@ const std::string &FS, bool little, MipsTargetMachine *_TM) : MipsGenSubtargetInfo(TT, CPU, FS), MipsArchVersion(Mips32), - MipsABI(UnknownABI), 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), + IsLittle(little), IsSingleFloat(false), IsFPXX(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), InMips16Mode(false), InMips16HardFloat(Mips16HardFloat), InMicroMipsMode(false), HasDSP(false), HasDSPR2(false), - AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16), - HasMSA(false), TM(_TM), TargetTriple(TT), + AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16), HasMSA(false), + TM(_TM), TargetTriple(TT), DL(computeDataLayout(initializeSubtargetDependencies(CPU, FS, TM))), TSInfo(DL), InstrInfo(MipsInstrInfo::create(*this)), FrameLowering(MipsFrameLowering::create(*this)), @@ -134,13 +121,9 @@ false); if (MipsArchVersion == Mips5) report_fatal_error("Code generation for MIPS-V is not implemented", false); + if (!MipsABI.IsKnown()) + MipsABI = MipsABIInfo(isGP64bit()); - // Assert exactly one ABI was chosen. - assert(MipsABI != UnknownABI); - 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())) || @@ -193,8 +176,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. @@ -218,3 +201,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 { @@ -93,14 +94,21 @@ // 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 getABIInfo() { return ABIInfo; } + protected: MipsABIFlagsSection ABIFlagsSection; + MipsABIInfo ABIInfo; + + bool isO32() const { return ABIInfo.IsO32(); } + bool isN32() const { return ABIInfo.IsN32(); } + bool isN64() const { return ABIInfo.IsN64(); } bool GPRInfoSet; unsigned GPRBitMask; @@ -223,10 +231,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