diff options
Diffstat (limited to 'lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp')
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp | 128 |
1 files changed, 111 insertions, 17 deletions
diff --git a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp index 1ad524c06969..4397c971d080 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -16,6 +16,7 @@ #include "MCTargetDesc/MipsFixupKinds.h" #include "MCTargetDesc/MipsMCExpr.h" #include "MCTargetDesc/MipsMCTargetDesc.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" @@ -53,6 +54,8 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, case Mips::fixup_Mips_GOT_DISP: case Mips::fixup_Mips_GOT_LO16: case Mips::fixup_Mips_CALL_LO16: + case Mips::fixup_MICROMIPS_GPOFF_HI: + case Mips::fixup_MICROMIPS_GPOFF_LO: case Mips::fixup_MICROMIPS_LO16: case Mips::fixup_MICROMIPS_GOT_PAGE: case Mips::fixup_MICROMIPS_GOT_OFST: @@ -107,10 +110,12 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, Value = ((Value + 0x8000) >> 16) & 0xffff; break; case Mips::fixup_Mips_HIGHER: + case Mips::fixup_MICROMIPS_HIGHER: // Get the 3rd 16-bits. Value = ((Value + 0x80008000LL) >> 32) & 0xffff; break; case Mips::fixup_Mips_HIGHEST: + case Mips::fixup_MICROMIPS_HIGHEST: // Get the 4th 16-bits. Value = ((Value + 0x800080008000LL) >> 48) & 0xffff; break; @@ -210,9 +215,9 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, return Value; } -std::unique_ptr<MCObjectWriter> -MipsAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const { - return createMipsELFObjectWriter(OS, TheTriple, IsN32); +std::unique_ptr<MCObjectTargetWriter> +MipsAsmBackend::createObjectTargetWriter() const { + return createMipsELFObjectWriter(TheTriple, IsN32); } // Little-endian fixup data byte ordering: @@ -238,7 +243,8 @@ static unsigned calculateMMLEIndex(unsigned i) { void MipsAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, MutableArrayRef<char> Data, uint64_t Value, - bool IsResolved) const { + bool IsResolved, + const MCSubtargetInfo *STI) const { MCFixupKind Kind = Fixup.getKind(); MCContext &Ctx = Asm.getContext(); Value = adjustFixupValue(Fixup, Value, Ctx); @@ -275,9 +281,9 @@ void MipsAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, bool microMipsLEByteOrder = needsMMLEByteOrder((unsigned) Kind); for (unsigned i = 0; i != NumBytes; ++i) { - unsigned Idx = IsLittle ? (microMipsLEByteOrder ? calculateMMLEIndex(i) - : i) - : (FullSize - 1 - i); + unsigned Idx = Endian == support::little + ? (microMipsLEByteOrder ? calculateMMLEIndex(i) : i) + : (FullSize - 1 - i); CurVal |= (uint64_t)((uint8_t)Data[Offset + Idx]) << (i*8); } @@ -287,9 +293,9 @@ void MipsAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, // Write out the fixed up bytes back to the code/data bits. for (unsigned i = 0; i != NumBytes; ++i) { - unsigned Idx = IsLittle ? (microMipsLEByteOrder ? calculateMMLEIndex(i) - : i) - : (FullSize - 1 - i); + unsigned Idx = Endian == support::little + ? (microMipsLEByteOrder ? calculateMMLEIndex(i) : i) + : (FullSize - 1 - i); Data[Offset + Idx] = (uint8_t)((CurVal >> (i*8)) & 0xff); } } @@ -298,12 +304,46 @@ Optional<MCFixupKind> MipsAsmBackend::getFixupKind(StringRef Name) const { return StringSwitch<Optional<MCFixupKind>>(Name) .Case("R_MIPS_NONE", (MCFixupKind)Mips::fixup_Mips_NONE) .Case("R_MIPS_32", FK_Data_4) + .Case("R_MIPS_GOT_PAGE", (MCFixupKind)Mips::fixup_Mips_GOT_PAGE) + .Case("R_MIPS_CALL_HI16", (MCFixupKind)Mips::fixup_Mips_CALL_HI16) + .Case("R_MIPS_CALL_LO16", (MCFixupKind)Mips::fixup_Mips_CALL_LO16) + .Case("R_MIPS_CALL16", (MCFixupKind)Mips::fixup_Mips_CALL16) + .Case("R_MIPS_GOT16", (MCFixupKind)Mips::fixup_Mips_GOT) + .Case("R_MIPS_GOT_PAGE", (MCFixupKind)Mips::fixup_Mips_GOT_PAGE) + .Case("R_MIPS_GOT_OFST", (MCFixupKind)Mips::fixup_Mips_GOT_OFST) + .Case("R_MIPS_GOT_DISP", (MCFixupKind)Mips::fixup_Mips_GOT_DISP) + .Case("R_MIPS_GOT_HI16", (MCFixupKind)Mips::fixup_Mips_GOT_HI16) + .Case("R_MIPS_GOT_LO16", (MCFixupKind)Mips::fixup_Mips_GOT_LO16) + .Case("R_MIPS_TLS_GOTTPREL", (MCFixupKind)Mips::fixup_Mips_GOTTPREL) + .Case("R_MIPS_TLS_DTPREL_HI16", (MCFixupKind)Mips::fixup_Mips_DTPREL_HI) + .Case("R_MIPS_TLS_DTPREL_LO16", (MCFixupKind)Mips::fixup_Mips_DTPREL_LO) + .Case("R_MIPS_TLS_GD", (MCFixupKind)Mips::fixup_Mips_TLSGD) + .Case("R_MIPS_TLS_LDM", (MCFixupKind)Mips::fixup_Mips_TLSLDM) + .Case("R_MIPS_TLS_TPREL_HI16", (MCFixupKind)Mips::fixup_Mips_TPREL_HI) + .Case("R_MIPS_TLS_TPREL_LO16", (MCFixupKind)Mips::fixup_Mips_TPREL_LO) + .Case("R_MICROMIPS_CALL16", (MCFixupKind)Mips::fixup_MICROMIPS_CALL16) + .Case("R_MICROMIPS_GOT_DISP", (MCFixupKind)Mips::fixup_MICROMIPS_GOT_DISP) + .Case("R_MICROMIPS_GOT_PAGE", (MCFixupKind)Mips::fixup_MICROMIPS_GOT_PAGE) + .Case("R_MICROMIPS_GOT_OFST", (MCFixupKind)Mips::fixup_MICROMIPS_GOT_OFST) + .Case("R_MICROMIPS_GOT16", (MCFixupKind)Mips::fixup_MICROMIPS_GOT16) + .Case("R_MICROMIPS_TLS_GOTTPREL", + (MCFixupKind)Mips::fixup_MICROMIPS_GOTTPREL) + .Case("R_MICROMIPS_TLS_DTPREL_HI16", + (MCFixupKind)Mips::fixup_MICROMIPS_TLS_DTPREL_HI16) + .Case("R_MICROMIPS_TLS_DTPREL_LO16", + (MCFixupKind)Mips::fixup_MICROMIPS_TLS_DTPREL_LO16) + .Case("R_MICROMIPS_TLS_GD", (MCFixupKind)Mips::fixup_MICROMIPS_TLS_GD) + .Case("R_MICROMIPS_TLS_LDM", (MCFixupKind)Mips::fixup_MICROMIPS_TLS_LDM) + .Case("R_MICROMIPS_TLS_TPREL_HI16", + (MCFixupKind)Mips::fixup_MICROMIPS_TLS_TPREL_HI16) + .Case("R_MICROMIPS_TLS_TPREL_LO16", + (MCFixupKind)Mips::fixup_MICROMIPS_TLS_TPREL_LO16) .Default(MCAsmBackend::getFixupKind(Name)); } const MCFixupKindInfo &MipsAsmBackend:: getFixupKindInfo(MCFixupKind Kind) const { - const static MCFixupKindInfo LittleEndianInfos[Mips::NumTargetFixupKinds] = { + const static MCFixupKindInfo LittleEndianInfos[] = { // This table *must* be in same the order of fixup_* kinds in // MipsFixupKinds.h. // @@ -333,12 +373,16 @@ getFixupKindInfo(MCFixupKind Kind) const { { "fixup_Mips_DTPREL_LO", 0, 16, 0 }, { "fixup_Mips_Branch_PCRel", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_Mips_GPOFF_HI", 0, 16, 0 }, + { "fixup_MICROMIPS_GPOFF_HI",0, 16, 0 }, { "fixup_Mips_GPOFF_LO", 0, 16, 0 }, + { "fixup_MICROMIPS_GPOFF_LO",0, 16, 0 }, { "fixup_Mips_GOT_PAGE", 0, 16, 0 }, { "fixup_Mips_GOT_OFST", 0, 16, 0 }, { "fixup_Mips_GOT_DISP", 0, 16, 0 }, { "fixup_Mips_HIGHER", 0, 16, 0 }, + { "fixup_MICROMIPS_HIGHER", 0, 16, 0 }, { "fixup_Mips_HIGHEST", 0, 16, 0 }, + { "fixup_MICROMIPS_HIGHEST", 0, 16, 0 }, { "fixup_Mips_GOT_HI16", 0, 16, 0 }, { "fixup_Mips_GOT_LO16", 0, 16, 0 }, { "fixup_Mips_CALL_HI16", 0, 16, 0 }, @@ -374,8 +418,10 @@ getFixupKindInfo(MCFixupKind Kind) const { { "fixup_Mips_SUB", 0, 64, 0 }, { "fixup_MICROMIPS_SUB", 0, 64, 0 } }; + static_assert(array_lengthof(LittleEndianInfos) == Mips::NumTargetFixupKinds, + "Not all MIPS little endian fixup kinds added!"); - const static MCFixupKindInfo BigEndianInfos[Mips::NumTargetFixupKinds] = { + const static MCFixupKindInfo BigEndianInfos[] = { // This table *must* be in same the order of fixup_* kinds in // MipsFixupKinds.h. // @@ -405,12 +451,16 @@ getFixupKindInfo(MCFixupKind Kind) const { { "fixup_Mips_DTPREL_LO", 16, 16, 0 }, { "fixup_Mips_Branch_PCRel",16, 16, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_Mips_GPOFF_HI", 16, 16, 0 }, + { "fixup_MICROMIPS_GPOFF_HI", 16, 16, 0 }, { "fixup_Mips_GPOFF_LO", 16, 16, 0 }, + { "fixup_MICROMIPS_GPOFF_LO", 16, 16, 0 }, { "fixup_Mips_GOT_PAGE", 16, 16, 0 }, { "fixup_Mips_GOT_OFST", 16, 16, 0 }, { "fixup_Mips_GOT_DISP", 16, 16, 0 }, { "fixup_Mips_HIGHER", 16, 16, 0 }, + { "fixup_MICROMIPS_HIGHER", 16, 16, 0 }, { "fixup_Mips_HIGHEST", 16, 16, 0 }, + { "fixup_MICROMIPS_HIGHEST",16, 16, 0 }, { "fixup_Mips_GOT_HI16", 16, 16, 0 }, { "fixup_Mips_GOT_LO16", 16, 16, 0 }, { "fixup_Mips_CALL_HI16", 16, 16, 0 }, @@ -446,6 +496,8 @@ getFixupKindInfo(MCFixupKind Kind) const { { "fixup_Mips_SUB", 0, 64, 0 }, { "fixup_MICROMIPS_SUB", 0, 64, 0 } }; + static_assert(array_lengthof(BigEndianInfos) == Mips::NumTargetFixupKinds, + "Not all MIPS big endian fixup kinds added!"); if (Kind < FirstTargetFixupKind) return MCAsmBackend::getFixupKindInfo(Kind); @@ -453,7 +505,7 @@ getFixupKindInfo(MCFixupKind Kind) const { assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && "Invalid kind!"); - if (IsLittle) + if (Endian == support::little) return LittleEndianInfos[Kind - FirstTargetFixupKind]; return BigEndianInfos[Kind - FirstTargetFixupKind]; } @@ -463,7 +515,7 @@ getFixupKindInfo(MCFixupKind Kind) const { /// it should return an error. /// /// \return - True on success. -bool MipsAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const { +bool MipsAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const { // Check for a less than instruction size number of bytes // FIXME: 16 bit instructions are not handled yet here. // We shouldn't be using a hard coded number for instruction size. @@ -471,13 +523,55 @@ bool MipsAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const { // If the count is not 4-byte aligned, we must be writing data into the text // section (otherwise we have unaligned instructions, and thus have far // bigger problems), so just write zeros instead. - OW->WriteZeros(Count); + OS.write_zeros(Count); return true; } +bool MipsAsmBackend::shouldForceRelocation(const MCAssembler &Asm, + const MCFixup &Fixup, + const MCValue &Target) { + const unsigned FixupKind = Fixup.getKind(); + switch (FixupKind) { + default: + return false; + // All these relocations require special processing + // at linking time. Delegate this work to a linker. + case Mips::fixup_Mips_CALL_HI16: + case Mips::fixup_Mips_CALL_LO16: + case Mips::fixup_Mips_CALL16: + case Mips::fixup_Mips_GOT: + case Mips::fixup_Mips_GOT_PAGE: + case Mips::fixup_Mips_GOT_OFST: + case Mips::fixup_Mips_GOT_DISP: + case Mips::fixup_Mips_GOT_HI16: + case Mips::fixup_Mips_GOT_LO16: + case Mips::fixup_Mips_GOTTPREL: + case Mips::fixup_Mips_DTPREL_HI: + case Mips::fixup_Mips_DTPREL_LO: + case Mips::fixup_Mips_TLSGD: + case Mips::fixup_Mips_TLSLDM: + case Mips::fixup_Mips_TPREL_HI: + case Mips::fixup_Mips_TPREL_LO: + case Mips::fixup_MICROMIPS_CALL16: + case Mips::fixup_MICROMIPS_GOT_DISP: + case Mips::fixup_MICROMIPS_GOT_PAGE: + case Mips::fixup_MICROMIPS_GOT_OFST: + case Mips::fixup_MICROMIPS_GOT16: + case Mips::fixup_MICROMIPS_GOTTPREL: + case Mips::fixup_MICROMIPS_TLS_DTPREL_HI16: + case Mips::fixup_MICROMIPS_TLS_DTPREL_LO16: + case Mips::fixup_MICROMIPS_TLS_GD: + case Mips::fixup_MICROMIPS_TLS_LDM: + case Mips::fixup_MICROMIPS_TLS_TPREL_HI16: + case Mips::fixup_MICROMIPS_TLS_TPREL_LO16: + return true; + } +} + MCAsmBackend *llvm::createMipsAsmBackend(const Target &T, + const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, - const Triple &TT, StringRef CPU, const MCTargetOptions &Options) { - return new MipsAsmBackend(T, MRI, TT, CPU, Options.ABIName == "n32"); + return new MipsAsmBackend(T, MRI, STI.getTargetTriple(), STI.getCPU(), + Options.ABIName == "n32"); } |