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) { @@ -95,6 +95,7 @@ } MCSubtargetInfo &STI; + 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 @@ -307,7 +308,8 @@ MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, const MCInstrInfo &MII, const MCTargetOptions &Options) - : MCTargetAsmParser(), STI(sti) { + : MCTargetAsmParser(), STI(sti), + ABI(getTargetStreamer().getABI()) { MCAsmParserExtension::Initialize(parser); // Initialize the set of available features. @@ -321,13 +323,11 @@ 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"); @@ -340,9 +340,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 { @@ -1717,7 +1718,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\""); @@ -3317,7 +3318,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; @@ -3335,7 +3336,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; @@ -3377,7 +3378,7 @@ } // Unknown option. - Warning(Parser.getTok().getLoc(), + Warning(Parser.getTok().getLoc(), "unknown option, expected 'pic0' or 'pic2'"); Parser.eatToEndOfStatement(); return false; @@ -3758,7 +3759,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/CMakeLists.txt =================================================================== --- lib/Target/Mips/CMakeLists.txt +++ lib/Target/Mips/CMakeLists.txt @@ -21,7 +21,6 @@ Mips16ISelDAGToDAG.cpp Mips16ISelLowering.cpp Mips16RegisterInfo.cpp - MipsABIInfo.cpp MipsAnalyzeImmediate.cpp MipsAsmPrinter.cpp MipsCCState.cpp 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" @@ -34,17 +34,18 @@ class MipsDisassemblerBase : public MCDisassembler { public: MipsDisassemblerBase(const MCSubtargetInfo &STI, MCContext &Ctx, - bool IsBigEndian) - : MCDisassembler(STI, Ctx), - IsN64(STI.getFeatureBits() & Mips::FeatureN64), - IsBigEndian(IsBigEndian) {} + bool IsBigEndian) : + MCDisassembler(STI, Ctx), IsBigEndian(IsBigEndian) { + 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,66 @@ +//===---- 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/ArrayRef.h" +#include "llvm/ADT/Triple.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/IR/CallingConv.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; } + + /// The registers to use for byval arguments. + const ArrayRef GetByValArgRegs() const; + + /// The registers to use for the variable argument list. + const ArrayRef GetVarArgRegs() const; + + /// Obtain the size of the area allocated by the callee for arguments. + /// CallingConv::FastCall affects the value for O32. + unsigned GetCalleeAllocdArgSizeInBytes(CallingConv::ID CC) const; + + /// 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 Index: lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp =================================================================== --- /dev/null +++ lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp @@ -0,0 +1,79 @@ +//===---- 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 "MipsABIInfo.h" +#include "MipsRegisterInfo.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/CommandLine.h" + + +using namespace llvm; + +namespace { +static const MCPhysReg O32IntRegs[4] = {Mips::A0, Mips::A1, Mips::A2, Mips::A3}; + +static const MCPhysReg Mips64IntRegs[8] = { + Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64, + Mips::T0_64, Mips::T1_64, Mips::T2_64, Mips::T3_64}; +} + +const ArrayRef MipsABIInfo::GetByValArgRegs() const { + if (IsO32()) + return makeArrayRef(O32IntRegs); + if (IsN32() || IsN64()) + return makeArrayRef(Mips64IntRegs); + llvm_unreachable("Unhandled ABI"); +} + +const ArrayRef MipsABIInfo::GetVarArgRegs() const { + if (IsO32()) + return makeArrayRef(O32IntRegs); + if (IsN32() || IsN64()) + return makeArrayRef(Mips64IntRegs); + llvm_unreachable("Unhandled ABI"); +} + +unsigned MipsABIInfo::GetCalleeAllocdArgSizeInBytes(CallingConv::ID CC) const { + if (IsO32()) + return CC != CallingConv::Fast ? 16 : 0; + if (IsN32() || IsN64() || IsEABI()) + return 0; + llvm_unreachable("Unhandled ABI"); +} + +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 "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: @@ -396,35 +409,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/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 @@ -341,6 +341,9 @@ ? true : false; + //Update ABI info + if (!ABIInfo.IsKnown()) + ABIInfo = MipsABIInfo(Features & Mips::FeatureGP64Bit); // Update e_header flags unsigned EFlags = 0; @@ -370,13 +373,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 +391,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/MipsABIInfo.h =================================================================== --- lib/Target/Mips/MipsABIInfo.h +++ /dev/null @@ -1,61 +0,0 @@ -//===---- 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/ArrayRef.h" -#include "llvm/MC/MCRegisterInfo.h" -#include "llvm/IR/CallingConv.h" - -namespace llvm { - -class MipsABIInfo { -public: - enum class ABI { Unknown, O32, N32, N64, EABI }; - -protected: - ABI ThisABI; - -public: - MipsABIInfo(ABI ThisABI) : ThisABI(ThisABI) {} - - 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; } - - /// The registers to use for byval arguments. - const ArrayRef GetByValArgRegs() const; - - /// The registers to use for the variable argument list. - const ArrayRef GetVarArgRegs() const; - - /// Obtain the size of the area allocated by the callee for arguments. - /// CallingConv::FastCall affects the value for O32. - unsigned GetCalleeAllocdArgSizeInBytes(CallingConv::ID CC) const; - - /// 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(); - } -}; -} - -#endif Index: lib/Target/Mips/MipsABIInfo.cpp =================================================================== --- lib/Target/Mips/MipsABIInfo.cpp +++ /dev/null @@ -1,45 +0,0 @@ -//===---- 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 "MipsABIInfo.h" -#include "MipsRegisterInfo.h" - -using namespace llvm; - -namespace { -static const MCPhysReg O32IntRegs[4] = {Mips::A0, Mips::A1, Mips::A2, Mips::A3}; - -static const MCPhysReg Mips64IntRegs[8] = { - Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64, - Mips::T0_64, Mips::T1_64, Mips::T2_64, Mips::T3_64}; -} - -const ArrayRef MipsABIInfo::GetByValArgRegs() const { - if (IsO32()) - return makeArrayRef(O32IntRegs); - if (IsN32() || IsN64()) - return makeArrayRef(Mips64IntRegs); - llvm_unreachable("Unhandled ABI"); -} - -const ArrayRef MipsABIInfo::GetVarArgRegs() const { - if (IsO32()) - return makeArrayRef(O32IntRegs); - if (IsN32() || IsN64()) - return makeArrayRef(Mips64IntRegs); - llvm_unreachable("Unhandled ABI"); -} - -unsigned MipsABIInfo::GetCalleeAllocdArgSizeInBytes(CallingConv::ID CC) const { - if (IsO32()) - return CC != CallingConv::Fast ? 16 : 0; - if (IsN32() || IsN64() || IsEABI()) - return 0; - llvm_unreachable("Unhandled ABI"); -} Index: lib/Target/Mips/MipsAsmPrinter.cpp =================================================================== --- lib/Target/Mips/MipsAsmPrinter.cpp +++ lib/Target/Mips/MipsAsmPrinter.cpp @@ -705,7 +705,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 @@ -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/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,7 +22,7 @@ #include "llvm/MC/MCInstrItineraries.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Target/TargetSubtargetInfo.h" -#include "MipsABIInfo.h" +#include "MCTargetDesc/MipsABIInfo.h" #include #define GET_SUBTARGETINFO_HEADER @@ -45,8 +45,8 @@ // Mips architecture version MipsArchEnum MipsArchVersion; - // Selected ABI - MipsABIInfo ABI; + // Mips supported ABIs + MipsABIInfo MipsABI; // IsLittle - The target is Little Endian bool IsLittle; @@ -153,12 +153,12 @@ CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const override; /// Only O32 and EABI supported right now. - 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_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; } - const MipsABIInfo &getABI() const { return ABI; } + const MipsABIInfo &getABI() 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 @@ -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), @@ -139,13 +127,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(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())) || @@ -204,8 +188,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. @@ -229,3 +213,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 { @@ -94,14 +95,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 getABI() { 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; @@ -225,10 +233,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