aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp')
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp128
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");
}