diff options
Diffstat (limited to 'llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp')
-rw-r--r-- | llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp | 79 |
1 files changed, 43 insertions, 36 deletions
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp index 8778e916f7e4..dbaf221db9fc 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp @@ -28,7 +28,6 @@ static uint64_t adjustFixupValue(unsigned Kind, uint64_t Value) { switch (Kind) { default: llvm_unreachable("Unknown fixup kind!"); - case FK_NONE: case FK_Data_1: case FK_Data_2: case FK_Data_4: @@ -40,11 +39,14 @@ static uint64_t adjustFixupValue(unsigned Kind, uint64_t Value) { return Value & 0xfffc; case PPC::fixup_ppc_br24: case PPC::fixup_ppc_br24abs: + case PPC::fixup_ppc_br24_notoc: return Value & 0x3fffffc; case PPC::fixup_ppc_half16: return Value & 0xffff; case PPC::fixup_ppc_half16ds: return Value & 0xfffc; + case PPC::fixup_ppc_pcrel34: + return Value & 0x3ffffffff; } } @@ -52,8 +54,6 @@ static unsigned getFixupKindNumBytes(unsigned Kind) { switch (Kind) { default: llvm_unreachable("Unknown fixup kind!"); - case FK_NONE: - return 0; case FK_Data_1: return 1; case FK_Data_2: @@ -65,7 +65,9 @@ static unsigned getFixupKindNumBytes(unsigned Kind) { case PPC::fixup_ppc_brcond14abs: case PPC::fixup_ppc_br24: case PPC::fixup_ppc_br24abs: + case PPC::fixup_ppc_br24_notoc: return 4; + case PPC::fixup_ppc_pcrel34: case FK_Data_8: return 8; case PPC::fixup_ppc_nofixup: @@ -91,24 +93,33 @@ public: const static MCFixupKindInfo InfosBE[PPC::NumTargetFixupKinds] = { // name offset bits flags { "fixup_ppc_br24", 6, 24, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_ppc_br24_notoc", 6, 24, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_ppc_brcond14", 16, 14, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_ppc_br24abs", 6, 24, 0 }, { "fixup_ppc_brcond14abs", 16, 14, 0 }, { "fixup_ppc_half16", 0, 16, 0 }, { "fixup_ppc_half16ds", 0, 14, 0 }, + { "fixup_ppc_pcrel34", 0, 34, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_ppc_nofixup", 0, 0, 0 } }; const static MCFixupKindInfo InfosLE[PPC::NumTargetFixupKinds] = { // name offset bits flags { "fixup_ppc_br24", 2, 24, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_ppc_br24_notoc", 2, 24, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_ppc_brcond14", 2, 14, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_ppc_br24abs", 2, 24, 0 }, { "fixup_ppc_brcond14abs", 2, 14, 0 }, { "fixup_ppc_half16", 0, 16, 0 }, { "fixup_ppc_half16ds", 2, 14, 0 }, + { "fixup_ppc_pcrel34", 0, 34, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_ppc_nofixup", 0, 0, 0 } }; + // Fixup kinds from .reloc directive are like R_PPC_NONE/R_PPC64_NONE. They + // do not require any extra processing. + if (Kind >= FirstLiteralRelocationKind) + return MCAsmBackend::getFixupKindInfo(FK_NONE); + if (Kind < FirstTargetFixupKind) return MCAsmBackend::getFixupKindInfo(Kind); @@ -123,11 +134,14 @@ public: const MCValue &Target, MutableArrayRef<char> Data, uint64_t Value, bool IsResolved, const MCSubtargetInfo *STI) const override { - Value = adjustFixupValue(Fixup.getKind(), Value); + MCFixupKind Kind = Fixup.getKind(); + if (Kind >= FirstLiteralRelocationKind) + return; + Value = adjustFixupValue(Kind, Value); if (!Value) return; // Doesn't change encoding. unsigned Offset = Fixup.getOffset(); - unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind()); + unsigned NumBytes = getFixupKindNumBytes(Kind); // For each byte of the fragment that the fixup touches, mask in the bits // from the fixup value. The Value has been "split up" into the appropriate @@ -140,13 +154,13 @@ public: bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target) override { - switch ((unsigned)Fixup.getKind()) { + MCFixupKind Kind = Fixup.getKind(); + switch ((unsigned)Kind) { default: - return false; - case FK_NONE: - return true; + return Kind >= FirstLiteralRelocationKind; case PPC::fixup_ppc_br24: case PPC::fixup_ppc_br24abs: + case PPC::fixup_ppc_br24_notoc: // If the target symbol has a local entry point we must not attempt // to resolve the fixup directly. Emit a relocation and leave // resolution of the final target address to the linker. @@ -178,8 +192,8 @@ public: llvm_unreachable("relaxInstruction() unimplemented"); } - void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, - MCInst &Res) const override { + void relaxInstruction(MCInst &Inst, + const MCSubtargetInfo &STI) const override { // FIXME. llvm_unreachable("relaxInstruction() unimplemented"); } @@ -200,21 +214,6 @@ public: // FIXME: This should be in a separate file. namespace { -class DarwinPPCAsmBackend : public PPCAsmBackend { -public: - DarwinPPCAsmBackend(const Target &T, const Triple &TT) - : PPCAsmBackend(T, TT) {} - - std::unique_ptr<MCObjectTargetWriter> - createObjectTargetWriter() const override { - bool Is64 = TT.isPPC64(); - return createPPCMachObjectWriter( - /*Is64Bit=*/Is64, - (Is64 ? MachO::CPU_TYPE_POWERPC64 : MachO::CPU_TYPE_POWERPC), - MachO::CPU_SUBTYPE_POWERPC_ALL); - } -}; - class ELFPPCAsmBackend : public PPCAsmBackend { public: ELFPPCAsmBackend(const Target &T, const Triple &TT) : PPCAsmBackend(T, TT) {} @@ -243,14 +242,25 @@ public: } // end anonymous namespace Optional<MCFixupKind> ELFPPCAsmBackend::getFixupKind(StringRef Name) const { - if (TT.isPPC64()) { - if (Name == "R_PPC64_NONE") - return FK_NONE; - } else { - if (Name == "R_PPC_NONE") - return FK_NONE; + if (TT.isOSBinFormatELF()) { + unsigned Type; + if (TT.isPPC64()) { + Type = llvm::StringSwitch<unsigned>(Name) +#define ELF_RELOC(X, Y) .Case(#X, Y) +#include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def" +#undef ELF_RELOC + .Default(-1u); + } else { + Type = llvm::StringSwitch<unsigned>(Name) +#define ELF_RELOC(X, Y) .Case(#X, Y) +#include "llvm/BinaryFormat/ELFRelocs/PowerPC.def" +#undef ELF_RELOC + .Default(-1u); + } + if (Type != -1u) + return static_cast<MCFixupKind>(FirstLiteralRelocationKind + Type); } - return MCAsmBackend::getFixupKind(Name); + return None; } MCAsmBackend *llvm::createPPCAsmBackend(const Target &T, @@ -258,9 +268,6 @@ MCAsmBackend *llvm::createPPCAsmBackend(const Target &T, const MCRegisterInfo &MRI, const MCTargetOptions &Options) { const Triple &TT = STI.getTargetTriple(); - if (TT.isOSDarwin()) - return new DarwinPPCAsmBackend(T, TT); - if (TT.isOSBinFormatXCOFF()) return new XCOFFPPCAsmBackend(T, TT); |