diff options
Diffstat (limited to 'llvm/lib/Target/Mips/MCTargetDesc')
15 files changed, 312 insertions, 142 deletions
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp index 3aa78224432d..08cbba952ccc 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp @@ -9,7 +9,6 @@ #include "MipsABIInfo.h" #include "Mips.h" #include "llvm/ADT/StringRef.h" -#include "llvm/CodeGenTypes/LowLevelType.h" #include "llvm/MC/MCTargetOptions.h" #include "llvm/Support/CommandLine.h" @@ -62,7 +61,7 @@ MipsABIInfo MipsABIInfo::computeTargetABI(const Triple &TT, StringRef CPU, return MipsABIInfo::N32(); if (Options.getABIName().starts_with("n64")) return MipsABIInfo::N64(); - if (TT.getEnvironment() == llvm::Triple::GNUABIN32) + if (TT.isABIN32()) return MipsABIInfo::N32(); assert(Options.getABIName().empty() && "Unknown ABI option for MIPS"); @@ -125,4 +124,3 @@ unsigned MipsABIInfo::GetEhDataReg(unsigned I) const { return IsN64() ? EhDataReg64[I] : EhDataReg[I]; } - diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp index f8172e576ce4..4af6768b13cc 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -14,14 +14,11 @@ #include "MCTargetDesc/MipsAsmBackend.h" #include "MCTargetDesc/MipsABIInfo.h" #include "MCTargetDesc/MipsFixupKinds.h" -#include "MCTargetDesc/MipsMCExpr.h" #include "MCTargetDesc/MipsMCTargetDesc.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" -#include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCObjectWriter.h" @@ -29,7 +26,6 @@ #include "llvm/MC/MCTargetOptions.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/Format.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" @@ -546,6 +542,7 @@ bool MipsAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count, bool MipsAsmBackend::shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, + const uint64_t, const MCSubtargetInfo *STI) { if (Fixup.getKind() >= FirstLiteralRelocationKind) return true; @@ -597,10 +594,30 @@ bool MipsAsmBackend::isMicroMips(const MCSymbol *Sym) const { return false; } +namespace { + +class WindowsMipsAsmBackend : public MipsAsmBackend { +public: + WindowsMipsAsmBackend(const Target &T, const MCRegisterInfo &MRI, + const MCSubtargetInfo &STI) + : MipsAsmBackend(T, MRI, STI.getTargetTriple(), STI.getCPU(), false) {} + + std::unique_ptr<MCObjectTargetWriter> + createObjectTargetWriter() const override { + return createMipsWinCOFFObjectWriter(); + } +}; + +} // end anonymous namespace + MCAsmBackend *llvm::createMipsAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options) { + const Triple &TheTriple = STI.getTargetTriple(); + if (TheTriple.isOSWindows() && TheTriple.isOSBinFormatCOFF()) + return new WindowsMipsAsmBackend(T, MRI, STI); + MipsABIInfo ABI = MipsABIInfo::computeTargetABI(STI.getTargetTriple(), STI.getCPU(), Options); return new MipsAsmBackend(T, MRI, STI.getTargetTriple(), STI.getCPU(), diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h index 799dd569f1ad..3a2c5e824a53 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h @@ -55,7 +55,7 @@ public: const MCSubtargetInfo *STI) const override; bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, + const MCValue &Target, const uint64_t Value, const MCSubtargetInfo *STI) override; bool isMicroMips(const MCSymbol *Sym) const override; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h index aa35e7db6bda..b9a2af334123 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h @@ -92,7 +92,12 @@ namespace MipsII { MO_CALL_LO16, /// Helper operand used to generate R_MIPS_JALR - MO_JALR + MO_JALR, + + /// MO_DLLIMPORT - On a symbol operand "FOO", this indicates that the + /// reference is actually to the "__imp_FOO" symbol. This is used for + /// dllimport linkage on windows. + MO_DLLIMPORT = 0x20, }; enum { diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp index 4d6a00c14a35..f2d4a6a5bf26 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -21,7 +21,6 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" -#include <algorithm> #include <cassert> #include <cstdint> #include <iterator> @@ -40,20 +39,8 @@ struct MipsRelocationEntry { bool Matched = false; ///< Is this relocation part of a match. MipsRelocationEntry(const ELFRelocationEntry &R) : R(R) {} - - void print(raw_ostream &Out) const { - R.print(Out); - Out << ", Matched=" << Matched; - } }; -#ifndef NDEBUG -raw_ostream &operator<<(raw_ostream &OS, const MipsRelocationEntry &RHS) { - RHS.print(OS); - return OS; -} -#endif - class MipsELFObjectWriter : public MCELFObjectTargetWriter { public: MipsELFObjectWriter(uint8_t OSABI, bool HasRelocationAddend, bool Is64); @@ -115,17 +102,11 @@ static InputIt find_best(InputIt First, InputIt Last, UnaryPredicate Predicate, for (InputIt I = First; I != Last; ++I) { unsigned Matched = Predicate(*I); if (Matched != FindBest_NoMatch) { - LLVM_DEBUG(dbgs() << std::distance(First, I) << " is a match ("; - I->print(dbgs()); dbgs() << ")\n"); - if (Best == Last || BetterThan(*I, *Best)) { - LLVM_DEBUG(dbgs() << ".. and it beats the last one\n"); + if (Best == Last || BetterThan(*I, *Best)) Best = I; - } } - if (Matched == FindBest_PerfectMatch) { - LLVM_DEBUG(dbgs() << ".. and it is unbeatable\n"); + if (Matched == FindBest_PerfectMatch) break; - } } return Best; @@ -147,8 +128,7 @@ static unsigned getMatchingLoType(const ELFRelocationEntry &Reloc) { if (Type == ELF::R_MIPS16_HI16) return ELF::R_MIPS16_LO16; - if (Reloc.OriginalSymbol && - Reloc.OriginalSymbol->getBinding() != ELF::STB_LOCAL) + if (Reloc.Symbol && Reloc.Symbol->getBinding() != ELF::STB_LOCAL) return ELF::R_MIPS_NONE; if (Type == ELF::R_MIPS_GOT16) @@ -161,54 +141,12 @@ static unsigned getMatchingLoType(const ELFRelocationEntry &Reloc) { return ELF::R_MIPS_NONE; } -/// Determine whether a relocation (X) matches the one given in R. -/// -/// A relocation matches if: -/// - It's type matches that of a corresponding low part. This is provided in -/// MatchingType for efficiency. -/// - It's based on the same symbol. -/// - It's offset of greater or equal to that of the one given in R. -/// It should be noted that this rule assumes the programmer does not use -/// offsets that exceed the alignment of the symbol. The carry-bit will be -/// incorrect if this is not true. -/// -/// A matching relocation is unbeatable if: -/// - It is not already involved in a match. -/// - It's offset is exactly that of the one given in R. -static FindBestPredicateResult isMatchingReloc(const MipsRelocationEntry &X, - const ELFRelocationEntry &R, - unsigned MatchingType) { - if (X.R.Type == MatchingType && X.R.OriginalSymbol == R.OriginalSymbol) { - if (!X.Matched && - X.R.OriginalAddend == R.OriginalAddend) - return FindBest_PerfectMatch; - else if (X.R.OriginalAddend >= R.OriginalAddend) - return FindBest_Match; - } - return FindBest_NoMatch; -} - -/// Determine whether Candidate or PreviousBest is the better match. -/// The return value is true if Candidate is the better match. -/// -/// A matching relocation is a better match if: -/// - It has a smaller addend. -/// - It is not already involved in a match. -static bool compareMatchingRelocs(const MipsRelocationEntry &Candidate, - const MipsRelocationEntry &PreviousBest) { - if (Candidate.R.OriginalAddend != PreviousBest.R.OriginalAddend) - return Candidate.R.OriginalAddend < PreviousBest.R.OriginalAddend; - return PreviousBest.Matched && !Candidate.Matched; -} - -#ifndef NDEBUG -/// Print all the relocations. -template <class Container> -static void dumpRelocs(const char *Prefix, const Container &Relocs) { - for (const auto &R : Relocs) - dbgs() << Prefix << R << "\n"; +// Determine whether a relocation X is a low-part and matches the high-part R +// perfectly by symbol and addend. +static bool isMatchingReloc(unsigned MatchingType, const ELFRelocationEntry &R, + const ELFRelocationEntry &X) { + return X.Type == MatchingType && X.Symbol == R.Symbol && X.Addend == R.Addend; } -#endif MipsELFObjectWriter::MipsELFObjectWriter(uint8_t OSABI, bool HasRelocationAddend, bool Is64) @@ -436,65 +374,52 @@ void MipsELFObjectWriter::sortRelocs(const MCAssembler &Asm, if (hasRelocationAddend()) return; - if (Relocs.size() < 2) - return; - // Sort relocations by the address they are applied to. llvm::sort(Relocs, [](const ELFRelocationEntry &A, const ELFRelocationEntry &B) { return A.Offset < B.Offset; }); + // Place relocations in a list for reorder convenience. Hi16 contains the + // iterators of high-part relocations. std::list<MipsRelocationEntry> Sorted; - std::list<ELFRelocationEntry> Remainder; - - LLVM_DEBUG(dumpRelocs("R: ", Relocs)); - - // Separate the movable relocations (AHL relocations using the high bits) from - // the immobile relocations (everything else). This does not preserve high/low - // matches that already existed in the input. - copy_if_else(Relocs.begin(), Relocs.end(), std::back_inserter(Remainder), - std::back_inserter(Sorted), [](const ELFRelocationEntry &Reloc) { - return getMatchingLoType(Reloc) != ELF::R_MIPS_NONE; - }); - - for (auto &R : Remainder) { - LLVM_DEBUG(dbgs() << "Matching: " << R << "\n"); + SmallVector<std::list<MipsRelocationEntry>::iterator, 0> Hi16; + for (auto &R : Relocs) { + Sorted.push_back(R); + if (getMatchingLoType(R) != ELF::R_MIPS_NONE) + Hi16.push_back(std::prev(Sorted.end())); + } + for (auto I : Hi16) { + auto &R = I->R; unsigned MatchingType = getMatchingLoType(R); - assert(MatchingType != ELF::R_MIPS_NONE && - "Wrong list for reloc that doesn't need a match"); - - // Find the best matching relocation for the current high part. - // See isMatchingReloc for a description of a matching relocation and - // compareMatchingRelocs for a description of what 'best' means. - auto InsertionPoint = - find_best(Sorted.begin(), Sorted.end(), - [&R, &MatchingType](const MipsRelocationEntry &X) { - return isMatchingReloc(X, R, MatchingType); - }, - compareMatchingRelocs); - - // If we matched then insert the high part in front of the match and mark - // both relocations as being involved in a match. We only mark the high - // part for cosmetic reasons in the debug output. + // If the next relocation is a perfect match, continue; + if (std::next(I) != Sorted.end() && + isMatchingReloc(MatchingType, R, std::next(I)->R)) + continue; + // Otherwise, find the best matching low-part relocation with the following + // criteria. It must have the same symbol and its addend is no lower than + // that of the current high-part. // - // If we failed to find a match then the high part is orphaned. This is not - // permitted since the relocation cannot be evaluated without knowing the - // carry-in. We can sometimes handle this using a matching low part that is - // already used in a match but we already cover that case in - // isMatchingReloc and compareMatchingRelocs. For the remaining cases we - // should insert the high part at the end of the list. This will cause the - // linker to fail but the alternative is to cause the linker to bind the - // high part to a semi-matching low part and silently calculate the wrong - // value. Unfortunately we have no means to warn the user that we did this - // so leave it up to the linker to complain about it. - if (InsertionPoint != Sorted.end()) - InsertionPoint->Matched = true; - Sorted.insert(InsertionPoint, R)->Matched = true; - } + // (1) %lo with a smaller offset is preferred. + // (2) %lo with the same offset that is unmatched is preferred. + // (3) later %lo is preferred. + auto Best = Sorted.end(); + for (auto J = Sorted.begin(); J != Sorted.end(); ++J) { + auto &R1 = J->R; + if (R1.Type == MatchingType && R.Symbol == R1.Symbol && + R.Addend <= R1.Addend && + (Best == Sorted.end() || R1.Addend < Best->R.Addend || + (!Best->Matched && R1.Addend == Best->R.Addend))) + Best = J; + } + if (Best != Sorted.end() && R.Addend == Best->R.Addend) + Best->Matched = true; - LLVM_DEBUG(dumpRelocs("S: ", Sorted)); + // Move the high-part before the low-part, or if not found, the end of the + // list. The unmatched high-part will lead to a linker warning/error. + Sorted.splice(Best, Sorted, I); + } assert(Relocs.size() == Sorted.size() && "Some relocs were not consumed"); diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp index 1518a539782e..dc7e887167d3 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp @@ -12,7 +12,6 @@ #include "MipsInstPrinter.h" #include "Mips.h" -#include "MipsMCExpr.h" #include "llvm/ADT/StringExtras.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" @@ -72,7 +71,7 @@ const char* Mips::MipsFCCToString(Mips::CondCode CC) { llvm_unreachable("Impossible condition code!"); } -void MipsInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) const { +void MipsInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) { markup(OS, Markup::Register) << '$' << StringRef(getRegisterName(Reg)).lower(); } diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.h index 0652b237509f..3924cf02e2d6 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.h @@ -79,12 +79,13 @@ public: : MCInstPrinter(MAI, MII, MRI) {} // Autogenerated by tblgen. - std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override; + std::pair<const char *, uint64_t> + getMnemonic(const MCInst &MI) const override; void printInstruction(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O); static const char *getRegisterName(MCRegister Reg); - void printRegName(raw_ostream &OS, MCRegister Reg) const override; + void printRegName(raw_ostream &OS, MCRegister Reg) override; void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &O) override; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp index f89c78e75d3e..fa09a14b3e23 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp @@ -16,10 +16,10 @@ using namespace llvm; -void MipsMCAsmInfo::anchor() { } +void MipsELFMCAsmInfo::anchor() {} -MipsMCAsmInfo::MipsMCAsmInfo(const Triple &TheTriple, - const MCTargetOptions &Options) { +MipsELFMCAsmInfo::MipsELFMCAsmInfo(const Triple &TheTriple, + const MCTargetOptions &Options) { IsLittleEndian = TheTriple.isLittleEndian(); MipsABIInfo ABI = MipsABIInfo::computeTargetABI(TheTriple, "", Options); @@ -51,3 +51,14 @@ MipsMCAsmInfo::MipsMCAsmInfo(const Triple &TheTriple, DwarfRegNumForCFI = true; HasMipsExpressions = true; } + +void MipsCOFFMCAsmInfo::anchor() {} + +MipsCOFFMCAsmInfo::MipsCOFFMCAsmInfo() { + HasSingleParameterDotFile = true; + WinEHEncodingType = WinEH::EncodingType::Itanium; + + ExceptionsType = ExceptionHandling::WinEH; + + AllowAtInName = true; +} diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h index d8bfe58d24a8..3a2895a79f9c 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h @@ -13,17 +13,25 @@ #ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSMCASMINFO_H #define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSMCASMINFO_H +#include "llvm/MC/MCAsmInfoCOFF.h" #include "llvm/MC/MCAsmInfoELF.h" namespace llvm { class Triple; -class MipsMCAsmInfo : public MCAsmInfoELF { +class MipsELFMCAsmInfo : public MCAsmInfoELF { void anchor() override; public: - explicit MipsMCAsmInfo(const Triple &TheTriple, - const MCTargetOptions &Options); + explicit MipsELFMCAsmInfo(const Triple &TheTriple, + const MCTargetOptions &Options); +}; + +class MipsCOFFMCAsmInfo : public MCAsmInfoGNUCOFF { + void anchor() override; + +public: + explicit MipsCOFFMCAsmInfo(); }; } // namespace llvm diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp index ca95f67174da..add36d87b9ef 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp @@ -19,6 +19,7 @@ #include "MipsMCNaCl.h" #include "MipsTargetStreamer.h" #include "TargetInfo/MipsTargetInfo.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCELFStreamer.h" #include "llvm/MC/MCInstrAnalysis.h" @@ -27,7 +28,6 @@ #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/MC/MachineLocation.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" @@ -45,6 +45,93 @@ using namespace llvm; #define GET_REGINFO_MC_DESC #include "MipsGenRegisterInfo.inc" +void MIPS_MC::initLLVMToCVRegMapping(MCRegisterInfo *MRI) { + // Mapping from CodeView to MC register id. + static const struct { + codeview::RegisterId CVReg; + MCPhysReg Reg; + } RegMap[] = { + {codeview::RegisterId::MIPS_ZERO, Mips::ZERO}, + {codeview::RegisterId::MIPS_AT, Mips::AT}, + {codeview::RegisterId::MIPS_V0, Mips::V0}, + {codeview::RegisterId::MIPS_V1, Mips::V1}, + {codeview::RegisterId::MIPS_A0, Mips::A0}, + {codeview::RegisterId::MIPS_A1, Mips::A1}, + {codeview::RegisterId::MIPS_A2, Mips::A2}, + {codeview::RegisterId::MIPS_A3, Mips::A3}, + {codeview::RegisterId::MIPS_T0, Mips::T0}, + {codeview::RegisterId::MIPS_T1, Mips::T1}, + {codeview::RegisterId::MIPS_T2, Mips::T2}, + {codeview::RegisterId::MIPS_T3, Mips::T3}, + {codeview::RegisterId::MIPS_T4, Mips::T4}, + {codeview::RegisterId::MIPS_T5, Mips::T5}, + {codeview::RegisterId::MIPS_T6, Mips::T6}, + {codeview::RegisterId::MIPS_T7, Mips::T7}, + {codeview::RegisterId::MIPS_S0, Mips::S0}, + {codeview::RegisterId::MIPS_S1, Mips::S1}, + {codeview::RegisterId::MIPS_S2, Mips::S2}, + {codeview::RegisterId::MIPS_S3, Mips::S3}, + {codeview::RegisterId::MIPS_S4, Mips::S4}, + {codeview::RegisterId::MIPS_S5, Mips::S5}, + {codeview::RegisterId::MIPS_S6, Mips::S6}, + {codeview::RegisterId::MIPS_S7, Mips::S7}, + {codeview::RegisterId::MIPS_T8, Mips::T8}, + {codeview::RegisterId::MIPS_T9, Mips::T9}, + {codeview::RegisterId::MIPS_K0, Mips::K0}, + {codeview::RegisterId::MIPS_K1, Mips::K1}, + {codeview::RegisterId::MIPS_GP, Mips::GP}, + {codeview::RegisterId::MIPS_SP, Mips::SP}, + {codeview::RegisterId::MIPS_S8, Mips::FP}, + {codeview::RegisterId::MIPS_RA, Mips::RA}, + {codeview::RegisterId::MIPS_LO, Mips::HI0}, + {codeview::RegisterId::MIPS_HI, Mips::LO0}, + {codeview::RegisterId::MIPS_Fir, Mips::FCR0}, + {codeview::RegisterId::MIPS_Psr, Mips::COP012}, // CP0.Status + {codeview::RegisterId::MIPS_F0, Mips::F0}, + {codeview::RegisterId::MIPS_F1, Mips::F1}, + {codeview::RegisterId::MIPS_F2, Mips::F2}, + {codeview::RegisterId::MIPS_F3, Mips::F3}, + {codeview::RegisterId::MIPS_F4, Mips::F4}, + {codeview::RegisterId::MIPS_F5, Mips::F5}, + {codeview::RegisterId::MIPS_F6, Mips::F6}, + {codeview::RegisterId::MIPS_F7, Mips::F7}, + {codeview::RegisterId::MIPS_F8, Mips::F8}, + {codeview::RegisterId::MIPS_F9, Mips::F9}, + {codeview::RegisterId::MIPS_F10, Mips::F10}, + {codeview::RegisterId::MIPS_F11, Mips::F11}, + {codeview::RegisterId::MIPS_F12, Mips::F12}, + {codeview::RegisterId::MIPS_F13, Mips::F13}, + {codeview::RegisterId::MIPS_F14, Mips::F14}, + {codeview::RegisterId::MIPS_F15, Mips::F15}, + {codeview::RegisterId::MIPS_F16, Mips::F16}, + {codeview::RegisterId::MIPS_F17, Mips::F17}, + {codeview::RegisterId::MIPS_F18, Mips::F18}, + {codeview::RegisterId::MIPS_F19, Mips::F19}, + {codeview::RegisterId::MIPS_F20, Mips::F20}, + {codeview::RegisterId::MIPS_F21, Mips::F21}, + {codeview::RegisterId::MIPS_F22, Mips::F22}, + {codeview::RegisterId::MIPS_F23, Mips::F23}, + {codeview::RegisterId::MIPS_F24, Mips::F24}, + {codeview::RegisterId::MIPS_F25, Mips::F25}, + {codeview::RegisterId::MIPS_F26, Mips::F26}, + {codeview::RegisterId::MIPS_F27, Mips::F27}, + {codeview::RegisterId::MIPS_F28, Mips::F28}, + {codeview::RegisterId::MIPS_F29, Mips::F29}, + {codeview::RegisterId::MIPS_F30, Mips::F30}, + {codeview::RegisterId::MIPS_F31, Mips::F31}, + {codeview::RegisterId::MIPS_Fsr, Mips::FCR31}, + }; + for (const auto &I : RegMap) + MRI->mapLLVMRegToCVReg(I.Reg, static_cast<int>(I.CVReg)); +} + +namespace { +class MipsWinCOFFTargetStreamer : public MipsTargetStreamer { +public: + MipsWinCOFFTargetStreamer(MCStreamer &S) : MipsTargetStreamer(S) {} +}; +} // end namespace + /// Select the Mips CPU for the given triple and cpu name. StringRef MIPS_MC::selectMipsCPU(const Triple &TT, StringRef CPU) { if (CPU.empty() || CPU == "generic") { @@ -84,7 +171,12 @@ static MCSubtargetInfo *createMipsMCSubtargetInfo(const Triple &TT, static MCAsmInfo *createMipsMCAsmInfo(const MCRegisterInfo &MRI, const Triple &TT, const MCTargetOptions &Options) { - MCAsmInfo *MAI = new MipsMCAsmInfo(TT, Options); + MCAsmInfo *MAI; + + if (TT.isOSWindows()) + MAI = new MipsCOFFMCAsmInfo(); + else + MAI = new MipsELFMCAsmInfo(TT, Options); unsigned SP = MRI.getDwarfRegNum(Mips::SP, true); MCCFIInstruction Inst = MCCFIInstruction::createDefCfaRegister(nullptr, SP); @@ -127,6 +219,8 @@ static MCTargetStreamer *createMipsNullTargetStreamer(MCStreamer &S) { static MCTargetStreamer * createMipsObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { + if (STI.getTargetTriple().isOSBinFormatCOFF()) + return new MipsWinCOFFTargetStreamer(S); return new MipsTargetELFStreamer(S, STI); } @@ -186,6 +280,8 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsTargetMC() { TargetRegistry::RegisterNullTargetStreamer(*T, createMipsNullTargetStreamer); + TargetRegistry::RegisterCOFFStreamer(*T, createMipsWinCOFFStreamer); + // Register the MC subtarget info. TargetRegistry::RegisterMCSubtargetInfo(*T, createMipsMCSubtargetInfo); diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h index d51f3b9abcfd..f3e3e6e8d107 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h @@ -23,7 +23,9 @@ class MCCodeEmitter; class MCContext; class MCInstrInfo; class MCObjectTargetWriter; +class MCObjectWriter; class MCRegisterInfo; +class MCStreamer; class MCSubtargetInfo; class MCTargetOptions; class StringRef; @@ -39,10 +41,24 @@ MCAsmBackend *createMipsAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options); +/// Construct an MIPS Windows COFF machine code streamer which will generate +/// PE/COFF format object files. +/// +/// Takes ownership of \p AB and \p CE. +MCStreamer *createMipsWinCOFFStreamer(MCContext &C, + std::unique_ptr<MCAsmBackend> &&AB, + std::unique_ptr<MCObjectWriter> &&OW, + std::unique_ptr<MCCodeEmitter> &&CE); + +/// Construct a Mips ELF object writer. std::unique_ptr<MCObjectTargetWriter> createMipsELFObjectWriter(const Triple &TT, bool IsN32); +/// Construct a Mips Win COFF object writer. +std::unique_ptr<MCObjectTargetWriter> createMipsWinCOFFObjectWriter(); namespace MIPS_MC { +void initLLVMToCVRegMapping(MCRegisterInfo *MRI); + StringRef selectMipsCPU(const Triple &TT, StringRef CPU); } diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp index 86194a9ebb61..8bd2b2ac231b 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp @@ -16,7 +16,6 @@ // //===----------------------------------------------------------------------===// -#include "Mips.h" #include "MipsELFStreamer.h" #include "MipsMCNaCl.h" #include "llvm/MC/MCAsmBackend.h" diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index 1650ffc85619..e547e6209440 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -19,6 +19,7 @@ #include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSubtargetInfo.h" @@ -804,8 +805,8 @@ MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S, ELFObjectWriter &W = getStreamer().getWriter(); // It's possible that MCObjectFileInfo isn't fully initialized at this point - // due to an initialization order problem where LLVMTargetMachine creates the - // target streamer before TargetLoweringObjectFile calls + // due to an initialization order problem where CodeGenTargetMachineImpl + // creates the target streamer before TargetLoweringObjectFile calls // InitializeMCObjectFileInfo. There doesn't seem to be a single place that // covers all cases so this statement covers most cases and direct object // emission must call setPic() once MCObjectFileInfo has been initialized. The diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsWinCOFFObjectWriter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsWinCOFFObjectWriter.cpp new file mode 100644 index 000000000000..cbe74f87a221 --- /dev/null +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsWinCOFFObjectWriter.cpp @@ -0,0 +1,61 @@ +//===- MipsWinCOFFObjectWriter.cpp------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#include "MCTargetDesc/MipsFixupKinds.h" +#include "MCTargetDesc/MipsMCTargetDesc.h" +#include "llvm/BinaryFormat/COFF.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCWinCOFFObjectWriter.h" + +using namespace llvm; + +namespace { + +class MipsWinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter { +public: + MipsWinCOFFObjectWriter(); + + unsigned getRelocType(MCContext &Ctx, const MCValue &Target, + const MCFixup &Fixup, bool IsCrossSection, + const MCAsmBackend &MAB) const override; +}; + +} // end anonymous namespace + +MipsWinCOFFObjectWriter::MipsWinCOFFObjectWriter() + : MCWinCOFFObjectTargetWriter(COFF::IMAGE_FILE_MACHINE_R4000) {} + +unsigned MipsWinCOFFObjectWriter::getRelocType(MCContext &Ctx, + const MCValue &Target, + const MCFixup &Fixup, + bool IsCrossSection, + const MCAsmBackend &MAB) const { + unsigned FixupKind = Fixup.getKind(); + + switch (FixupKind) { + case FK_Data_4: + return COFF::IMAGE_REL_MIPS_REFWORD; + case FK_SecRel_2: + return COFF::IMAGE_REL_MIPS_SECTION; + case FK_SecRel_4: + return COFF::IMAGE_REL_MIPS_SECREL; + case Mips::fixup_Mips_26: + return COFF::IMAGE_REL_MIPS_JMPADDR; + case Mips::fixup_Mips_HI16: + return COFF::IMAGE_REL_MIPS_REFHI; + case Mips::fixup_Mips_LO16: + return COFF::IMAGE_REL_MIPS_REFLO; + default: + Ctx.reportError(Fixup.getLoc(), "unsupported relocation type"); + return COFF::IMAGE_REL_MIPS_REFWORD; + } +} + +std::unique_ptr<MCObjectTargetWriter> llvm::createMipsWinCOFFObjectWriter() { + return std::make_unique<MipsWinCOFFObjectWriter>(); +} diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsWinCOFFStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsWinCOFFStreamer.cpp new file mode 100644 index 000000000000..22bf2e1be203 --- /dev/null +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsWinCOFFStreamer.cpp @@ -0,0 +1,33 @@ +//===- MipsWinCOFFStreamer.cpp-----------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#include "MipsMCTargetDesc.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCWinCOFFStreamer.h" + +using namespace llvm; + +namespace { +class MipsWinCOFFStreamer : public MCWinCOFFStreamer { +public: + MipsWinCOFFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> AB, + std::unique_ptr<MCCodeEmitter> CE, + std::unique_ptr<MCObjectWriter> OW) + : MCWinCOFFStreamer(C, std::move(AB), std::move(CE), std::move(OW)) {} +}; +} // namespace + +MCStreamer *llvm::createMipsWinCOFFStreamer( + MCContext &C, std::unique_ptr<MCAsmBackend> &&AB, + std::unique_ptr<MCObjectWriter> &&OW, std::unique_ptr<MCCodeEmitter> &&CE) { + return new MipsWinCOFFStreamer(C, std::move(AB), std::move(CE), + std::move(OW)); +} |
