diff options
author | orivej <orivej@yandex-team.ru> | 2022-02-10 16:44:49 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:49 +0300 |
commit | 718c552901d703c502ccbefdfc3c9028d608b947 (patch) | |
tree | 46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc | |
parent | e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff) | |
download | ydb-718c552901d703c502ccbefdfc3c9028d608b947.tar.gz |
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc')
19 files changed, 3289 insertions, 3289 deletions
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp index 72401668c8..96fbc7162d 100644 --- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp +++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp @@ -1,273 +1,273 @@ -//===-- PPCAsmBackend.cpp - PPC Assembler Backend -------------------------===// -// -// 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/PPCFixupKinds.h" -#include "MCTargetDesc/PPCMCTargetDesc.h" -#include "llvm/BinaryFormat/ELF.h" -#include "llvm/BinaryFormat/MachO.h" -#include "llvm/MC/MCAsmBackend.h" -#include "llvm/MC/MCAssembler.h" -#include "llvm/MC/MCELFObjectWriter.h" -#include "llvm/MC/MCFixupKindInfo.h" -#include "llvm/MC/MCMachObjectWriter.h" -#include "llvm/MC/MCObjectWriter.h" -#include "llvm/MC/MCSectionMachO.h" -#include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/MC/MCSymbolELF.h" -#include "llvm/MC/MCValue.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/TargetRegistry.h" -using namespace llvm; - -static uint64_t adjustFixupValue(unsigned Kind, uint64_t Value) { - switch (Kind) { - default: - llvm_unreachable("Unknown fixup kind!"); - case FK_Data_1: - case FK_Data_2: - case FK_Data_4: - case FK_Data_8: - case PPC::fixup_ppc_nofixup: - return Value; - case PPC::fixup_ppc_brcond14: - case PPC::fixup_ppc_brcond14abs: - 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: +//===-- PPCAsmBackend.cpp - PPC Assembler Backend -------------------------===// +// +// 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/PPCFixupKinds.h" +#include "MCTargetDesc/PPCMCTargetDesc.h" +#include "llvm/BinaryFormat/ELF.h" +#include "llvm/BinaryFormat/MachO.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCELFObjectWriter.h" +#include "llvm/MC/MCFixupKindInfo.h" +#include "llvm/MC/MCMachObjectWriter.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCSectionMachO.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/MCSymbolELF.h" +#include "llvm/MC/MCValue.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/TargetRegistry.h" +using namespace llvm; + +static uint64_t adjustFixupValue(unsigned Kind, uint64_t Value) { + switch (Kind) { + default: + llvm_unreachable("Unknown fixup kind!"); + case FK_Data_1: + case FK_Data_2: + case FK_Data_4: + case FK_Data_8: + case PPC::fixup_ppc_nofixup: + return Value; + case PPC::fixup_ppc_brcond14: + case PPC::fixup_ppc_brcond14abs: + 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: case PPC::fixup_ppc_imm34: - return Value & 0x3ffffffff; - } -} - -static unsigned getFixupKindNumBytes(unsigned Kind) { - switch (Kind) { - default: - llvm_unreachable("Unknown fixup kind!"); - case FK_Data_1: - return 1; - case FK_Data_2: - case PPC::fixup_ppc_half16: - case PPC::fixup_ppc_half16ds: - return 2; - case FK_Data_4: - case PPC::fixup_ppc_brcond14: - 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: + return Value & 0x3ffffffff; + } +} + +static unsigned getFixupKindNumBytes(unsigned Kind) { + switch (Kind) { + default: + llvm_unreachable("Unknown fixup kind!"); + case FK_Data_1: + return 1; + case FK_Data_2: + case PPC::fixup_ppc_half16: + case PPC::fixup_ppc_half16ds: + return 2; + case FK_Data_4: + case PPC::fixup_ppc_brcond14: + 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 PPC::fixup_ppc_imm34: - case FK_Data_8: - return 8; - case PPC::fixup_ppc_nofixup: - return 0; - } -} - -namespace { - -class PPCAsmBackend : public MCAsmBackend { -protected: - Triple TT; -public: - PPCAsmBackend(const Target &T, const Triple &TT) - : MCAsmBackend(TT.isLittleEndian() ? support::little : support::big), - TT(TT) {} - - unsigned getNumFixupKinds() const override { - return PPC::NumTargetFixupKinds; - } - - const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { - 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 }, + case FK_Data_8: + return 8; + case PPC::fixup_ppc_nofixup: + return 0; + } +} + +namespace { + +class PPCAsmBackend : public MCAsmBackend { +protected: + Triple TT; +public: + PPCAsmBackend(const Target &T, const Triple &TT) + : MCAsmBackend(TT.isLittleEndian() ? support::little : support::big), + TT(TT) {} + + unsigned getNumFixupKinds() const override { + return PPC::NumTargetFixupKinds; + } + + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { + 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_imm34", 0, 34, 0 }, - { "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 } + }; + 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_imm34", 0, 34, 0 }, - { "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); - - assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && - "Invalid kind!"); - return (Endian == support::little - ? InfosLE - : InfosBE)[Kind - FirstTargetFixupKind]; - } - - void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, MutableArrayRef<char> Data, - uint64_t Value, bool IsResolved, - const MCSubtargetInfo *STI) const override { - 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(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 - // bitfields above. - for (unsigned i = 0; i != NumBytes; ++i) { - unsigned Idx = Endian == support::little ? i : (NumBytes - 1 - i); - Data[Offset + i] |= uint8_t((Value >> (Idx * 8)) & 0xff); - } - } - - bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target) override { - MCFixupKind Kind = Fixup.getKind(); - switch ((unsigned)Kind) { - default: - 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. - if (const MCSymbolRefExpr *A = Target.getSymA()) { - if (const auto *S = dyn_cast<MCSymbolELF>(&A->getSymbol())) { - // The "other" values are stored in the last 6 bits of the second - // byte. The traditional defines for STO values assume the full byte - // and thus the shift to pack it. - unsigned Other = S->getOther() << 2; - if ((Other & ELF::STO_PPC64_LOCAL_MASK) != 0) - return true; - } - } - return false; - } - } - - bool fixupNeedsRelaxation(const MCFixup &Fixup, - uint64_t Value, - const MCRelaxableFragment *DF, - const MCAsmLayout &Layout) const override { - // FIXME. - llvm_unreachable("relaxInstruction() unimplemented"); - } - - void relaxInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) const override { - // FIXME. - llvm_unreachable("relaxInstruction() unimplemented"); - } - - bool writeNopData(raw_ostream &OS, uint64_t Count) const override { - uint64_t NumNops = Count / 4; - for (uint64_t i = 0; i != NumNops; ++i) - support::endian::write<uint32_t>(OS, 0x60000000, Endian); - - OS.write_zeros(Count % 4); - - return true; - } -}; -} // end anonymous namespace - - -// FIXME: This should be in a separate file. -namespace { - -class ELFPPCAsmBackend : public PPCAsmBackend { -public: - ELFPPCAsmBackend(const Target &T, const Triple &TT) : PPCAsmBackend(T, TT) {} - - std::unique_ptr<MCObjectTargetWriter> - createObjectTargetWriter() const override { - uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS()); - bool Is64 = TT.isPPC64(); - return createPPCELFObjectWriter(Is64, OSABI); - } - - Optional<MCFixupKind> getFixupKind(StringRef Name) const override; -}; - -class XCOFFPPCAsmBackend : public PPCAsmBackend { -public: - XCOFFPPCAsmBackend(const Target &T, const Triple &TT) - : PPCAsmBackend(T, TT) {} - - std::unique_ptr<MCObjectTargetWriter> - createObjectTargetWriter() const override { - return createPPCXCOFFObjectWriter(TT.isArch64Bit()); - } -}; - -} // end anonymous namespace - -Optional<MCFixupKind> ELFPPCAsmBackend::getFixupKind(StringRef Name) const { - 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 None; -} - -MCAsmBackend *llvm::createPPCAsmBackend(const Target &T, - const MCSubtargetInfo &STI, - const MCRegisterInfo &MRI, - const MCTargetOptions &Options) { - const Triple &TT = STI.getTargetTriple(); - if (TT.isOSBinFormatXCOFF()) - return new XCOFFPPCAsmBackend(T, TT); - - return new ELFPPCAsmBackend(T, TT); -} + { "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); + + assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && + "Invalid kind!"); + return (Endian == support::little + ? InfosLE + : InfosBE)[Kind - FirstTargetFixupKind]; + } + + void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, + const MCValue &Target, MutableArrayRef<char> Data, + uint64_t Value, bool IsResolved, + const MCSubtargetInfo *STI) const override { + 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(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 + // bitfields above. + for (unsigned i = 0; i != NumBytes; ++i) { + unsigned Idx = Endian == support::little ? i : (NumBytes - 1 - i); + Data[Offset + i] |= uint8_t((Value >> (Idx * 8)) & 0xff); + } + } + + bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, + const MCValue &Target) override { + MCFixupKind Kind = Fixup.getKind(); + switch ((unsigned)Kind) { + default: + 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. + if (const MCSymbolRefExpr *A = Target.getSymA()) { + if (const auto *S = dyn_cast<MCSymbolELF>(&A->getSymbol())) { + // The "other" values are stored in the last 6 bits of the second + // byte. The traditional defines for STO values assume the full byte + // and thus the shift to pack it. + unsigned Other = S->getOther() << 2; + if ((Other & ELF::STO_PPC64_LOCAL_MASK) != 0) + return true; + } + } + return false; + } + } + + bool fixupNeedsRelaxation(const MCFixup &Fixup, + uint64_t Value, + const MCRelaxableFragment *DF, + const MCAsmLayout &Layout) const override { + // FIXME. + llvm_unreachable("relaxInstruction() unimplemented"); + } + + void relaxInstruction(MCInst &Inst, + const MCSubtargetInfo &STI) const override { + // FIXME. + llvm_unreachable("relaxInstruction() unimplemented"); + } + + bool writeNopData(raw_ostream &OS, uint64_t Count) const override { + uint64_t NumNops = Count / 4; + for (uint64_t i = 0; i != NumNops; ++i) + support::endian::write<uint32_t>(OS, 0x60000000, Endian); + + OS.write_zeros(Count % 4); + + return true; + } +}; +} // end anonymous namespace + + +// FIXME: This should be in a separate file. +namespace { + +class ELFPPCAsmBackend : public PPCAsmBackend { +public: + ELFPPCAsmBackend(const Target &T, const Triple &TT) : PPCAsmBackend(T, TT) {} + + std::unique_ptr<MCObjectTargetWriter> + createObjectTargetWriter() const override { + uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS()); + bool Is64 = TT.isPPC64(); + return createPPCELFObjectWriter(Is64, OSABI); + } + + Optional<MCFixupKind> getFixupKind(StringRef Name) const override; +}; + +class XCOFFPPCAsmBackend : public PPCAsmBackend { +public: + XCOFFPPCAsmBackend(const Target &T, const Triple &TT) + : PPCAsmBackend(T, TT) {} + + std::unique_ptr<MCObjectTargetWriter> + createObjectTargetWriter() const override { + return createPPCXCOFFObjectWriter(TT.isArch64Bit()); + } +}; + +} // end anonymous namespace + +Optional<MCFixupKind> ELFPPCAsmBackend::getFixupKind(StringRef Name) const { + 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 None; +} + +MCAsmBackend *llvm::createPPCAsmBackend(const Target &T, + const MCSubtargetInfo &STI, + const MCRegisterInfo &MRI, + const MCTargetOptions &Options) { + const Triple &TT = STI.getTargetTriple(); + if (TT.isOSBinFormatXCOFF()) + return new XCOFFPPCAsmBackend(T, TT); + + return new ELFPPCAsmBackend(T, TT); +} diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp index 94ef7b4543..c408cb9ff4 100644 --- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp +++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp @@ -1,143 +1,143 @@ -//===-- PPCELFObjectWriter.cpp - PPC ELF Writer ---------------------------===// -// -// 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/PPCFixupKinds.h" -#include "MCTargetDesc/PPCMCExpr.h" -#include "MCTargetDesc/PPCMCTargetDesc.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/MC/MCELFObjectWriter.h" -#include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCObjectWriter.h" -#include "llvm/MC/MCSymbolELF.h" -#include "llvm/MC/MCValue.h" -#include "llvm/Support/ErrorHandling.h" - -using namespace llvm; - -namespace { - class PPCELFObjectWriter : public MCELFObjectTargetWriter { - public: - PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI); - - protected: - unsigned getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, bool IsPCRel) const override; - - bool needsRelocateWithSymbol(const MCSymbol &Sym, - unsigned Type) const override; - }; -} - -PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) - : MCELFObjectTargetWriter(Is64Bit, OSABI, - Is64Bit ? ELF::EM_PPC64 : ELF::EM_PPC, - /*HasRelocationAddend*/ true) {} - -static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target, - const MCFixup &Fixup) { - const MCExpr *Expr = Fixup.getValue(); - - if (Expr->getKind() != MCExpr::Target) - return Target.getAccessVariant(); - - switch (cast<PPCMCExpr>(Expr)->getKind()) { - case PPCMCExpr::VK_PPC_None: - return MCSymbolRefExpr::VK_None; - case PPCMCExpr::VK_PPC_LO: - return MCSymbolRefExpr::VK_PPC_LO; - case PPCMCExpr::VK_PPC_HI: - return MCSymbolRefExpr::VK_PPC_HI; - case PPCMCExpr::VK_PPC_HA: - return MCSymbolRefExpr::VK_PPC_HA; - case PPCMCExpr::VK_PPC_HIGH: - return MCSymbolRefExpr::VK_PPC_HIGH; - case PPCMCExpr::VK_PPC_HIGHA: - return MCSymbolRefExpr::VK_PPC_HIGHA; - case PPCMCExpr::VK_PPC_HIGHERA: - return MCSymbolRefExpr::VK_PPC_HIGHERA; - case PPCMCExpr::VK_PPC_HIGHER: - return MCSymbolRefExpr::VK_PPC_HIGHER; - case PPCMCExpr::VK_PPC_HIGHEST: - return MCSymbolRefExpr::VK_PPC_HIGHEST; - case PPCMCExpr::VK_PPC_HIGHESTA: - return MCSymbolRefExpr::VK_PPC_HIGHESTA; - } - llvm_unreachable("unknown PPCMCExpr kind"); -} - -unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, - bool IsPCRel) const { - MCFixupKind Kind = Fixup.getKind(); - if (Kind >= FirstLiteralRelocationKind) - return Kind - FirstLiteralRelocationKind; - MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup); - - // determine the type of the relocation - unsigned Type; - if (IsPCRel) { - switch (Fixup.getTargetKind()) { - default: - llvm_unreachable("Unimplemented"); - case PPC::fixup_ppc_br24: - case PPC::fixup_ppc_br24abs: - case PPC::fixup_ppc_br24_notoc: - switch (Modifier) { - default: llvm_unreachable("Unsupported Modifier"); - case MCSymbolRefExpr::VK_None: - Type = ELF::R_PPC_REL24; - break; - case MCSymbolRefExpr::VK_PLT: - Type = ELF::R_PPC_PLTREL24; - break; - case MCSymbolRefExpr::VK_PPC_LOCAL: - Type = ELF::R_PPC_LOCAL24PC; - break; - case MCSymbolRefExpr::VK_PPC_NOTOC: - Type = ELF::R_PPC64_REL24_NOTOC; - break; - } - break; - case PPC::fixup_ppc_brcond14: - case PPC::fixup_ppc_brcond14abs: - Type = ELF::R_PPC_REL14; - break; - case PPC::fixup_ppc_half16: - switch (Modifier) { - default: llvm_unreachable("Unsupported Modifier"); - case MCSymbolRefExpr::VK_None: - Type = ELF::R_PPC_REL16; - break; - case MCSymbolRefExpr::VK_PPC_LO: - Type = ELF::R_PPC_REL16_LO; - break; - case MCSymbolRefExpr::VK_PPC_HI: - Type = ELF::R_PPC_REL16_HI; - break; - case MCSymbolRefExpr::VK_PPC_HA: - Type = ELF::R_PPC_REL16_HA; - break; - } - break; - case PPC::fixup_ppc_half16ds: - Target.print(errs()); - errs() << '\n'; - report_fatal_error("Invalid PC-relative half16ds relocation"); - case PPC::fixup_ppc_pcrel34: - switch (Modifier) { - default: - llvm_unreachable("Unsupported Modifier for fixup_ppc_pcrel34"); - case MCSymbolRefExpr::VK_PCREL: - Type = ELF::R_PPC64_PCREL34; - break; - case MCSymbolRefExpr::VK_PPC_GOT_PCREL: - Type = ELF::R_PPC64_GOT_PCREL34; - break; +//===-- PPCELFObjectWriter.cpp - PPC ELF Writer ---------------------------===// +// +// 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/PPCFixupKinds.h" +#include "MCTargetDesc/PPCMCExpr.h" +#include "MCTargetDesc/PPCMCTargetDesc.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/MC/MCELFObjectWriter.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCSymbolELF.h" +#include "llvm/MC/MCValue.h" +#include "llvm/Support/ErrorHandling.h" + +using namespace llvm; + +namespace { + class PPCELFObjectWriter : public MCELFObjectTargetWriter { + public: + PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI); + + protected: + unsigned getRelocType(MCContext &Ctx, const MCValue &Target, + const MCFixup &Fixup, bool IsPCRel) const override; + + bool needsRelocateWithSymbol(const MCSymbol &Sym, + unsigned Type) const override; + }; +} + +PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) + : MCELFObjectTargetWriter(Is64Bit, OSABI, + Is64Bit ? ELF::EM_PPC64 : ELF::EM_PPC, + /*HasRelocationAddend*/ true) {} + +static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target, + const MCFixup &Fixup) { + const MCExpr *Expr = Fixup.getValue(); + + if (Expr->getKind() != MCExpr::Target) + return Target.getAccessVariant(); + + switch (cast<PPCMCExpr>(Expr)->getKind()) { + case PPCMCExpr::VK_PPC_None: + return MCSymbolRefExpr::VK_None; + case PPCMCExpr::VK_PPC_LO: + return MCSymbolRefExpr::VK_PPC_LO; + case PPCMCExpr::VK_PPC_HI: + return MCSymbolRefExpr::VK_PPC_HI; + case PPCMCExpr::VK_PPC_HA: + return MCSymbolRefExpr::VK_PPC_HA; + case PPCMCExpr::VK_PPC_HIGH: + return MCSymbolRefExpr::VK_PPC_HIGH; + case PPCMCExpr::VK_PPC_HIGHA: + return MCSymbolRefExpr::VK_PPC_HIGHA; + case PPCMCExpr::VK_PPC_HIGHERA: + return MCSymbolRefExpr::VK_PPC_HIGHERA; + case PPCMCExpr::VK_PPC_HIGHER: + return MCSymbolRefExpr::VK_PPC_HIGHER; + case PPCMCExpr::VK_PPC_HIGHEST: + return MCSymbolRefExpr::VK_PPC_HIGHEST; + case PPCMCExpr::VK_PPC_HIGHESTA: + return MCSymbolRefExpr::VK_PPC_HIGHESTA; + } + llvm_unreachable("unknown PPCMCExpr kind"); +} + +unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, + const MCFixup &Fixup, + bool IsPCRel) const { + MCFixupKind Kind = Fixup.getKind(); + if (Kind >= FirstLiteralRelocationKind) + return Kind - FirstLiteralRelocationKind; + MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup); + + // determine the type of the relocation + unsigned Type; + if (IsPCRel) { + switch (Fixup.getTargetKind()) { + default: + llvm_unreachable("Unimplemented"); + case PPC::fixup_ppc_br24: + case PPC::fixup_ppc_br24abs: + case PPC::fixup_ppc_br24_notoc: + switch (Modifier) { + default: llvm_unreachable("Unsupported Modifier"); + case MCSymbolRefExpr::VK_None: + Type = ELF::R_PPC_REL24; + break; + case MCSymbolRefExpr::VK_PLT: + Type = ELF::R_PPC_PLTREL24; + break; + case MCSymbolRefExpr::VK_PPC_LOCAL: + Type = ELF::R_PPC_LOCAL24PC; + break; + case MCSymbolRefExpr::VK_PPC_NOTOC: + Type = ELF::R_PPC64_REL24_NOTOC; + break; + } + break; + case PPC::fixup_ppc_brcond14: + case PPC::fixup_ppc_brcond14abs: + Type = ELF::R_PPC_REL14; + break; + case PPC::fixup_ppc_half16: + switch (Modifier) { + default: llvm_unreachable("Unsupported Modifier"); + case MCSymbolRefExpr::VK_None: + Type = ELF::R_PPC_REL16; + break; + case MCSymbolRefExpr::VK_PPC_LO: + Type = ELF::R_PPC_REL16_LO; + break; + case MCSymbolRefExpr::VK_PPC_HI: + Type = ELF::R_PPC_REL16_HI; + break; + case MCSymbolRefExpr::VK_PPC_HA: + Type = ELF::R_PPC_REL16_HA; + break; + } + break; + case PPC::fixup_ppc_half16ds: + Target.print(errs()); + errs() << '\n'; + report_fatal_error("Invalid PC-relative half16ds relocation"); + case PPC::fixup_ppc_pcrel34: + switch (Modifier) { + default: + llvm_unreachable("Unsupported Modifier for fixup_ppc_pcrel34"); + case MCSymbolRefExpr::VK_PCREL: + Type = ELF::R_PPC64_PCREL34; + break; + case MCSymbolRefExpr::VK_PPC_GOT_PCREL: + Type = ELF::R_PPC64_GOT_PCREL34; + break; case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL: Type = ELF::R_PPC64_GOT_TLSGD_PCREL34; break; @@ -147,280 +147,280 @@ unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, case MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL: Type = ELF::R_PPC64_GOT_TPREL_PCREL34; break; - } - break; - case FK_Data_4: - case FK_PCRel_4: - Type = ELF::R_PPC_REL32; - break; - case FK_Data_8: - case FK_PCRel_8: - Type = ELF::R_PPC64_REL64; - break; - } - } else { - switch (Fixup.getTargetKind()) { - default: llvm_unreachable("invalid fixup kind!"); - case PPC::fixup_ppc_br24abs: - Type = ELF::R_PPC_ADDR24; - break; - case PPC::fixup_ppc_brcond14abs: - Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_ - break; - case PPC::fixup_ppc_half16: - switch (Modifier) { - default: llvm_unreachable("Unsupported Modifier"); - case MCSymbolRefExpr::VK_None: - Type = ELF::R_PPC_ADDR16; - break; - case MCSymbolRefExpr::VK_PPC_LO: - Type = ELF::R_PPC_ADDR16_LO; - break; - case MCSymbolRefExpr::VK_PPC_HI: - Type = ELF::R_PPC_ADDR16_HI; - break; - case MCSymbolRefExpr::VK_PPC_HA: - Type = ELF::R_PPC_ADDR16_HA; - break; - case MCSymbolRefExpr::VK_PPC_HIGH: - Type = ELF::R_PPC64_ADDR16_HIGH; - break; - case MCSymbolRefExpr::VK_PPC_HIGHA: - Type = ELF::R_PPC64_ADDR16_HIGHA; - break; - case MCSymbolRefExpr::VK_PPC_HIGHER: - Type = ELF::R_PPC64_ADDR16_HIGHER; - break; - case MCSymbolRefExpr::VK_PPC_HIGHERA: - Type = ELF::R_PPC64_ADDR16_HIGHERA; - break; - case MCSymbolRefExpr::VK_PPC_HIGHEST: - Type = ELF::R_PPC64_ADDR16_HIGHEST; - break; - case MCSymbolRefExpr::VK_PPC_HIGHESTA: - Type = ELF::R_PPC64_ADDR16_HIGHESTA; - break; - case MCSymbolRefExpr::VK_GOT: - Type = ELF::R_PPC_GOT16; - break; - case MCSymbolRefExpr::VK_PPC_GOT_LO: - Type = ELF::R_PPC_GOT16_LO; - break; - case MCSymbolRefExpr::VK_PPC_GOT_HI: - Type = ELF::R_PPC_GOT16_HI; - break; - case MCSymbolRefExpr::VK_PPC_GOT_HA: - Type = ELF::R_PPC_GOT16_HA; - break; - case MCSymbolRefExpr::VK_PPC_TOC: - Type = ELF::R_PPC64_TOC16; - break; - case MCSymbolRefExpr::VK_PPC_TOC_LO: - Type = ELF::R_PPC64_TOC16_LO; - break; - case MCSymbolRefExpr::VK_PPC_TOC_HI: - Type = ELF::R_PPC64_TOC16_HI; - break; - case MCSymbolRefExpr::VK_PPC_TOC_HA: - Type = ELF::R_PPC64_TOC16_HA; - break; - case MCSymbolRefExpr::VK_TPREL: - Type = ELF::R_PPC_TPREL16; - break; - case MCSymbolRefExpr::VK_PPC_TPREL_LO: - Type = ELF::R_PPC_TPREL16_LO; - break; - case MCSymbolRefExpr::VK_PPC_TPREL_HI: - Type = ELF::R_PPC_TPREL16_HI; - break; - case MCSymbolRefExpr::VK_PPC_TPREL_HA: - Type = ELF::R_PPC_TPREL16_HA; - break; - case MCSymbolRefExpr::VK_PPC_TPREL_HIGH: - Type = ELF::R_PPC64_TPREL16_HIGH; - break; - case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA: - Type = ELF::R_PPC64_TPREL16_HIGHA; - break; - case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER: - Type = ELF::R_PPC64_TPREL16_HIGHER; - break; - case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA: - Type = ELF::R_PPC64_TPREL16_HIGHERA; - break; - case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST: - Type = ELF::R_PPC64_TPREL16_HIGHEST; - break; - case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA: - Type = ELF::R_PPC64_TPREL16_HIGHESTA; - break; - case MCSymbolRefExpr::VK_DTPREL: - Type = ELF::R_PPC64_DTPREL16; - break; - case MCSymbolRefExpr::VK_PPC_DTPREL_LO: - Type = ELF::R_PPC64_DTPREL16_LO; - break; - case MCSymbolRefExpr::VK_PPC_DTPREL_HI: - Type = ELF::R_PPC64_DTPREL16_HI; - break; - case MCSymbolRefExpr::VK_PPC_DTPREL_HA: - Type = ELF::R_PPC64_DTPREL16_HA; - break; - case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH: - Type = ELF::R_PPC64_DTPREL16_HIGH; - break; - case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA: - Type = ELF::R_PPC64_DTPREL16_HIGHA; - break; - case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER: - Type = ELF::R_PPC64_DTPREL16_HIGHER; - break; - case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA: - Type = ELF::R_PPC64_DTPREL16_HIGHERA; - break; - case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST: - Type = ELF::R_PPC64_DTPREL16_HIGHEST; - break; - case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA: - Type = ELF::R_PPC64_DTPREL16_HIGHESTA; - break; - case MCSymbolRefExpr::VK_PPC_GOT_TLSGD: - if (is64Bit()) - Type = ELF::R_PPC64_GOT_TLSGD16; - else - Type = ELF::R_PPC_GOT_TLSGD16; - break; - case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO: - Type = ELF::R_PPC64_GOT_TLSGD16_LO; - break; - case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI: - Type = ELF::R_PPC64_GOT_TLSGD16_HI; - break; - case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA: - Type = ELF::R_PPC64_GOT_TLSGD16_HA; - break; - case MCSymbolRefExpr::VK_PPC_GOT_TLSLD: - if (is64Bit()) - Type = ELF::R_PPC64_GOT_TLSLD16; - else - Type = ELF::R_PPC_GOT_TLSLD16; - break; - case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO: - Type = ELF::R_PPC64_GOT_TLSLD16_LO; - break; - case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI: - Type = ELF::R_PPC64_GOT_TLSLD16_HI; - break; - case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA: - Type = ELF::R_PPC64_GOT_TLSLD16_HA; - break; - case MCSymbolRefExpr::VK_PPC_GOT_TPREL: - /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets - are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS. */ - Type = ELF::R_PPC64_GOT_TPREL16_DS; - break; - case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: - /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets - are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS. */ - Type = ELF::R_PPC64_GOT_TPREL16_LO_DS; - break; - case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI: - Type = ELF::R_PPC64_GOT_TPREL16_HI; - break; - case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: - /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets - are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS. */ - Type = ELF::R_PPC64_GOT_DTPREL16_DS; - break; - case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: - /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets - are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS. */ - Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS; - break; - case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA: - Type = ELF::R_PPC64_GOT_TPREL16_HA; - break; - case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI: - Type = ELF::R_PPC64_GOT_DTPREL16_HI; - break; - case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA: - Type = ELF::R_PPC64_GOT_DTPREL16_HA; - break; - } - break; - case PPC::fixup_ppc_half16ds: - switch (Modifier) { - default: llvm_unreachable("Unsupported Modifier"); - case MCSymbolRefExpr::VK_None: - Type = ELF::R_PPC64_ADDR16_DS; - break; - case MCSymbolRefExpr::VK_PPC_LO: - Type = ELF::R_PPC64_ADDR16_LO_DS; - break; - case MCSymbolRefExpr::VK_GOT: - Type = ELF::R_PPC64_GOT16_DS; - break; - case MCSymbolRefExpr::VK_PPC_GOT_LO: - Type = ELF::R_PPC64_GOT16_LO_DS; - break; - case MCSymbolRefExpr::VK_PPC_TOC: - Type = ELF::R_PPC64_TOC16_DS; - break; - case MCSymbolRefExpr::VK_PPC_TOC_LO: - Type = ELF::R_PPC64_TOC16_LO_DS; - break; - case MCSymbolRefExpr::VK_TPREL: - Type = ELF::R_PPC64_TPREL16_DS; - break; - case MCSymbolRefExpr::VK_PPC_TPREL_LO: - Type = ELF::R_PPC64_TPREL16_LO_DS; - break; - case MCSymbolRefExpr::VK_DTPREL: - Type = ELF::R_PPC64_DTPREL16_DS; - break; - case MCSymbolRefExpr::VK_PPC_DTPREL_LO: - Type = ELF::R_PPC64_DTPREL16_LO_DS; - break; - case MCSymbolRefExpr::VK_PPC_GOT_TPREL: - Type = ELF::R_PPC64_GOT_TPREL16_DS; - break; - case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: - Type = ELF::R_PPC64_GOT_TPREL16_LO_DS; - break; - case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: - Type = ELF::R_PPC64_GOT_DTPREL16_DS; - break; - case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: - Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS; - break; - } - break; - case PPC::fixup_ppc_nofixup: - switch (Modifier) { - default: llvm_unreachable("Unsupported Modifier"); - case MCSymbolRefExpr::VK_PPC_TLSGD: - if (is64Bit()) - Type = ELF::R_PPC64_TLSGD; - else - Type = ELF::R_PPC_TLSGD; - break; - case MCSymbolRefExpr::VK_PPC_TLSLD: - if (is64Bit()) - Type = ELF::R_PPC64_TLSLD; - else - Type = ELF::R_PPC_TLSLD; - break; - case MCSymbolRefExpr::VK_PPC_TLS: - if (is64Bit()) - Type = ELF::R_PPC64_TLS; - else - Type = ELF::R_PPC_TLS; - break; + } + break; + case FK_Data_4: + case FK_PCRel_4: + Type = ELF::R_PPC_REL32; + break; + case FK_Data_8: + case FK_PCRel_8: + Type = ELF::R_PPC64_REL64; + break; + } + } else { + switch (Fixup.getTargetKind()) { + default: llvm_unreachable("invalid fixup kind!"); + case PPC::fixup_ppc_br24abs: + Type = ELF::R_PPC_ADDR24; + break; + case PPC::fixup_ppc_brcond14abs: + Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_ + break; + case PPC::fixup_ppc_half16: + switch (Modifier) { + default: llvm_unreachable("Unsupported Modifier"); + case MCSymbolRefExpr::VK_None: + Type = ELF::R_PPC_ADDR16; + break; + case MCSymbolRefExpr::VK_PPC_LO: + Type = ELF::R_PPC_ADDR16_LO; + break; + case MCSymbolRefExpr::VK_PPC_HI: + Type = ELF::R_PPC_ADDR16_HI; + break; + case MCSymbolRefExpr::VK_PPC_HA: + Type = ELF::R_PPC_ADDR16_HA; + break; + case MCSymbolRefExpr::VK_PPC_HIGH: + Type = ELF::R_PPC64_ADDR16_HIGH; + break; + case MCSymbolRefExpr::VK_PPC_HIGHA: + Type = ELF::R_PPC64_ADDR16_HIGHA; + break; + case MCSymbolRefExpr::VK_PPC_HIGHER: + Type = ELF::R_PPC64_ADDR16_HIGHER; + break; + case MCSymbolRefExpr::VK_PPC_HIGHERA: + Type = ELF::R_PPC64_ADDR16_HIGHERA; + break; + case MCSymbolRefExpr::VK_PPC_HIGHEST: + Type = ELF::R_PPC64_ADDR16_HIGHEST; + break; + case MCSymbolRefExpr::VK_PPC_HIGHESTA: + Type = ELF::R_PPC64_ADDR16_HIGHESTA; + break; + case MCSymbolRefExpr::VK_GOT: + Type = ELF::R_PPC_GOT16; + break; + case MCSymbolRefExpr::VK_PPC_GOT_LO: + Type = ELF::R_PPC_GOT16_LO; + break; + case MCSymbolRefExpr::VK_PPC_GOT_HI: + Type = ELF::R_PPC_GOT16_HI; + break; + case MCSymbolRefExpr::VK_PPC_GOT_HA: + Type = ELF::R_PPC_GOT16_HA; + break; + case MCSymbolRefExpr::VK_PPC_TOC: + Type = ELF::R_PPC64_TOC16; + break; + case MCSymbolRefExpr::VK_PPC_TOC_LO: + Type = ELF::R_PPC64_TOC16_LO; + break; + case MCSymbolRefExpr::VK_PPC_TOC_HI: + Type = ELF::R_PPC64_TOC16_HI; + break; + case MCSymbolRefExpr::VK_PPC_TOC_HA: + Type = ELF::R_PPC64_TOC16_HA; + break; + case MCSymbolRefExpr::VK_TPREL: + Type = ELF::R_PPC_TPREL16; + break; + case MCSymbolRefExpr::VK_PPC_TPREL_LO: + Type = ELF::R_PPC_TPREL16_LO; + break; + case MCSymbolRefExpr::VK_PPC_TPREL_HI: + Type = ELF::R_PPC_TPREL16_HI; + break; + case MCSymbolRefExpr::VK_PPC_TPREL_HA: + Type = ELF::R_PPC_TPREL16_HA; + break; + case MCSymbolRefExpr::VK_PPC_TPREL_HIGH: + Type = ELF::R_PPC64_TPREL16_HIGH; + break; + case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA: + Type = ELF::R_PPC64_TPREL16_HIGHA; + break; + case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER: + Type = ELF::R_PPC64_TPREL16_HIGHER; + break; + case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA: + Type = ELF::R_PPC64_TPREL16_HIGHERA; + break; + case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST: + Type = ELF::R_PPC64_TPREL16_HIGHEST; + break; + case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA: + Type = ELF::R_PPC64_TPREL16_HIGHESTA; + break; + case MCSymbolRefExpr::VK_DTPREL: + Type = ELF::R_PPC64_DTPREL16; + break; + case MCSymbolRefExpr::VK_PPC_DTPREL_LO: + Type = ELF::R_PPC64_DTPREL16_LO; + break; + case MCSymbolRefExpr::VK_PPC_DTPREL_HI: + Type = ELF::R_PPC64_DTPREL16_HI; + break; + case MCSymbolRefExpr::VK_PPC_DTPREL_HA: + Type = ELF::R_PPC64_DTPREL16_HA; + break; + case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH: + Type = ELF::R_PPC64_DTPREL16_HIGH; + break; + case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA: + Type = ELF::R_PPC64_DTPREL16_HIGHA; + break; + case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER: + Type = ELF::R_PPC64_DTPREL16_HIGHER; + break; + case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA: + Type = ELF::R_PPC64_DTPREL16_HIGHERA; + break; + case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST: + Type = ELF::R_PPC64_DTPREL16_HIGHEST; + break; + case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA: + Type = ELF::R_PPC64_DTPREL16_HIGHESTA; + break; + case MCSymbolRefExpr::VK_PPC_GOT_TLSGD: + if (is64Bit()) + Type = ELF::R_PPC64_GOT_TLSGD16; + else + Type = ELF::R_PPC_GOT_TLSGD16; + break; + case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO: + Type = ELF::R_PPC64_GOT_TLSGD16_LO; + break; + case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI: + Type = ELF::R_PPC64_GOT_TLSGD16_HI; + break; + case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA: + Type = ELF::R_PPC64_GOT_TLSGD16_HA; + break; + case MCSymbolRefExpr::VK_PPC_GOT_TLSLD: + if (is64Bit()) + Type = ELF::R_PPC64_GOT_TLSLD16; + else + Type = ELF::R_PPC_GOT_TLSLD16; + break; + case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO: + Type = ELF::R_PPC64_GOT_TLSLD16_LO; + break; + case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI: + Type = ELF::R_PPC64_GOT_TLSLD16_HI; + break; + case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA: + Type = ELF::R_PPC64_GOT_TLSLD16_HA; + break; + case MCSymbolRefExpr::VK_PPC_GOT_TPREL: + /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets + are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS. */ + Type = ELF::R_PPC64_GOT_TPREL16_DS; + break; + case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: + /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets + are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS. */ + Type = ELF::R_PPC64_GOT_TPREL16_LO_DS; + break; + case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI: + Type = ELF::R_PPC64_GOT_TPREL16_HI; + break; + case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: + /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets + are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS. */ + Type = ELF::R_PPC64_GOT_DTPREL16_DS; + break; + case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: + /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets + are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS. */ + Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS; + break; + case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA: + Type = ELF::R_PPC64_GOT_TPREL16_HA; + break; + case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI: + Type = ELF::R_PPC64_GOT_DTPREL16_HI; + break; + case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA: + Type = ELF::R_PPC64_GOT_DTPREL16_HA; + break; + } + break; + case PPC::fixup_ppc_half16ds: + switch (Modifier) { + default: llvm_unreachable("Unsupported Modifier"); + case MCSymbolRefExpr::VK_None: + Type = ELF::R_PPC64_ADDR16_DS; + break; + case MCSymbolRefExpr::VK_PPC_LO: + Type = ELF::R_PPC64_ADDR16_LO_DS; + break; + case MCSymbolRefExpr::VK_GOT: + Type = ELF::R_PPC64_GOT16_DS; + break; + case MCSymbolRefExpr::VK_PPC_GOT_LO: + Type = ELF::R_PPC64_GOT16_LO_DS; + break; + case MCSymbolRefExpr::VK_PPC_TOC: + Type = ELF::R_PPC64_TOC16_DS; + break; + case MCSymbolRefExpr::VK_PPC_TOC_LO: + Type = ELF::R_PPC64_TOC16_LO_DS; + break; + case MCSymbolRefExpr::VK_TPREL: + Type = ELF::R_PPC64_TPREL16_DS; + break; + case MCSymbolRefExpr::VK_PPC_TPREL_LO: + Type = ELF::R_PPC64_TPREL16_LO_DS; + break; + case MCSymbolRefExpr::VK_DTPREL: + Type = ELF::R_PPC64_DTPREL16_DS; + break; + case MCSymbolRefExpr::VK_PPC_DTPREL_LO: + Type = ELF::R_PPC64_DTPREL16_LO_DS; + break; + case MCSymbolRefExpr::VK_PPC_GOT_TPREL: + Type = ELF::R_PPC64_GOT_TPREL16_DS; + break; + case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: + Type = ELF::R_PPC64_GOT_TPREL16_LO_DS; + break; + case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: + Type = ELF::R_PPC64_GOT_DTPREL16_DS; + break; + case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: + Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS; + break; + } + break; + case PPC::fixup_ppc_nofixup: + switch (Modifier) { + default: llvm_unreachable("Unsupported Modifier"); + case MCSymbolRefExpr::VK_PPC_TLSGD: + if (is64Bit()) + Type = ELF::R_PPC64_TLSGD; + else + Type = ELF::R_PPC_TLSGD; + break; + case MCSymbolRefExpr::VK_PPC_TLSLD: + if (is64Bit()) + Type = ELF::R_PPC64_TLSLD; + else + Type = ELF::R_PPC_TLSLD; + break; + case MCSymbolRefExpr::VK_PPC_TLS: + if (is64Bit()) + Type = ELF::R_PPC64_TLS; + else + Type = ELF::R_PPC_TLS; + break; case MCSymbolRefExpr::VK_PPC_TLS_PCREL: Type = ELF::R_PPC64_TLS; break; - } - break; + } + break; case PPC::fixup_ppc_imm34: switch (Modifier) { default: @@ -433,56 +433,56 @@ unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, break; } break; - case FK_Data_8: - switch (Modifier) { - default: llvm_unreachable("Unsupported Modifier"); - case MCSymbolRefExpr::VK_PPC_TOCBASE: - Type = ELF::R_PPC64_TOC; - break; - case MCSymbolRefExpr::VK_None: - Type = ELF::R_PPC64_ADDR64; - break; - case MCSymbolRefExpr::VK_PPC_DTPMOD: - Type = ELF::R_PPC64_DTPMOD64; - break; - case MCSymbolRefExpr::VK_TPREL: - Type = ELF::R_PPC64_TPREL64; - break; - case MCSymbolRefExpr::VK_DTPREL: - Type = ELF::R_PPC64_DTPREL64; - break; - } - break; - case FK_Data_4: - Type = ELF::R_PPC_ADDR32; - break; - case FK_Data_2: - Type = ELF::R_PPC_ADDR16; - break; - } - } - return Type; -} - -bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, - unsigned Type) const { - switch (Type) { - default: - return false; - - case ELF::R_PPC_REL24: - case ELF::R_PPC64_REL24_NOTOC: - // If the target symbol has a local entry point, we must keep the - // target symbol to preserve that information for the linker. - // The "other" values are stored in the last 6 bits of the second byte. - // The traditional defines for STO values assume the full byte and thus - // the shift to pack it. - unsigned Other = cast<MCSymbolELF>(Sym).getOther() << 2; - return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0; - } -} - -std::unique_ptr<MCObjectTargetWriter> -llvm::createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) { - return std::make_unique<PPCELFObjectWriter>(Is64Bit, OSABI); -} + case FK_Data_8: + switch (Modifier) { + default: llvm_unreachable("Unsupported Modifier"); + case MCSymbolRefExpr::VK_PPC_TOCBASE: + Type = ELF::R_PPC64_TOC; + break; + case MCSymbolRefExpr::VK_None: + Type = ELF::R_PPC64_ADDR64; + break; + case MCSymbolRefExpr::VK_PPC_DTPMOD: + Type = ELF::R_PPC64_DTPMOD64; + break; + case MCSymbolRefExpr::VK_TPREL: + Type = ELF::R_PPC64_TPREL64; + break; + case MCSymbolRefExpr::VK_DTPREL: + Type = ELF::R_PPC64_DTPREL64; + break; + } + break; + case FK_Data_4: + Type = ELF::R_PPC_ADDR32; + break; + case FK_Data_2: + Type = ELF::R_PPC_ADDR16; + break; + } + } + return Type; +} + +bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, + unsigned Type) const { + switch (Type) { + default: + return false; + + case ELF::R_PPC_REL24: + case ELF::R_PPC64_REL24_NOTOC: + // If the target symbol has a local entry point, we must keep the + // target symbol to preserve that information for the linker. + // The "other" values are stored in the last 6 bits of the second byte. + // The traditional defines for STO values assume the full byte and thus + // the shift to pack it. + unsigned Other = cast<MCSymbolELF>(Sym).getOther() << 2; + return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0; + } +} + +std::unique_ptr<MCObjectTargetWriter> +llvm::createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) { + return std::make_unique<PPCELFObjectWriter>(Is64Bit, OSABI); +} diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp index 386d592660..b1c593daaa 100644 --- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp +++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp @@ -1,95 +1,95 @@ -//===-------- PPCELFStreamer.cpp - ELF Object Output ---------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This is a custom MCELFStreamer for PowerPC. -// -// The purpose of the custom ELF streamer is to allow us to intercept -// instructions as they are being emitted and align all 8 byte instructions -// to a 64 byte boundary if required (by adding a 4 byte nop). This is important -// because 8 byte instructions are not allowed to cross 64 byte boundaries -// and by aliging anything that is within 4 bytes of the boundary we can -// guarantee that the 8 byte instructions do not cross that boundary. -// -//===----------------------------------------------------------------------===// - - -#include "PPCELFStreamer.h" +//===-------- PPCELFStreamer.cpp - ELF Object Output ---------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is a custom MCELFStreamer for PowerPC. +// +// The purpose of the custom ELF streamer is to allow us to intercept +// instructions as they are being emitted and align all 8 byte instructions +// to a 64 byte boundary if required (by adding a 4 byte nop). This is important +// because 8 byte instructions are not allowed to cross 64 byte boundaries +// and by aliging anything that is within 4 bytes of the boundary we can +// guarantee that the 8 byte instructions do not cross that boundary. +// +//===----------------------------------------------------------------------===// + + +#include "PPCELFStreamer.h" #include "PPCFixupKinds.h" -#include "PPCInstrInfo.h" -#include "PPCMCCodeEmitter.h" -#include "llvm/BinaryFormat/ELF.h" -#include "llvm/MC/MCAsmBackend.h" -#include "llvm/MC/MCAssembler.h" -#include "llvm/MC/MCCodeEmitter.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCInst.h" -#include "llvm/MC/MCInstrDesc.h" -#include "llvm/MC/MCObjectWriter.h" -#include "llvm/MC/MCSymbolELF.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/SourceMgr.h" - -using namespace llvm; - -PPCELFStreamer::PPCELFStreamer(MCContext &Context, - std::unique_ptr<MCAsmBackend> MAB, - std::unique_ptr<MCObjectWriter> OW, - std::unique_ptr<MCCodeEmitter> Emitter) - : MCELFStreamer(Context, std::move(MAB), std::move(OW), - std::move(Emitter)), LastLabel(NULL) { -} - -void PPCELFStreamer::emitPrefixedInstruction(const MCInst &Inst, - const MCSubtargetInfo &STI) { - // Prefixed instructions must not cross a 64-byte boundary (i.e. prefix is - // before the boundary and the remaining 4-bytes are after the boundary). In - // order to achieve this, a nop is added prior to any such boundary-crossing - // prefixed instruction. Align to 64 bytes if possible but add a maximum of 4 - // bytes when trying to do that. If alignment requires adding more than 4 - // bytes then the instruction won't be aligned. When emitting a code alignment - // a new fragment is created for this alignment. This fragment will contain - // all of the nops required as part of the alignment operation. In the cases - // when no nops are added then The fragment is still created but it remains - // empty. - emitCodeAlignment(64, 4); - - // Emit the instruction. - // Since the previous emit created a new fragment then adding this instruction - // also forces the addition of a new fragment. Inst is now the first - // instruction in that new fragment. - MCELFStreamer::emitInstruction(Inst, STI); - - // The above instruction is forced to start a new fragment because it - // comes after a code alignment fragment. Get that new fragment. - MCFragment *InstructionFragment = getCurrentFragment(); - SMLoc InstLoc = Inst.getLoc(); - // Check if there was a last label emitted. - if (LastLabel && !LastLabel->isUnset() && LastLabelLoc.isValid() && - InstLoc.isValid()) { - const SourceMgr *SourceManager = getContext().getSourceManager(); - unsigned InstLine = SourceManager->FindLineNumber(InstLoc); - unsigned LabelLine = SourceManager->FindLineNumber(LastLabelLoc); - // If the Label and the Instruction are on the same line then move the - // label to the top of the fragment containing the aligned instruction that - // was just added. - if (InstLine == LabelLine) { - AssignFragment(LastLabel, InstructionFragment); - LastLabel->setOffset(0); - } - } -} - -void PPCELFStreamer::emitInstruction(const MCInst &Inst, - const MCSubtargetInfo &STI) { - PPCMCCodeEmitter *Emitter = - static_cast<PPCMCCodeEmitter*>(getAssembler().getEmitterPtr()); - +#include "PPCInstrInfo.h" +#include "PPCMCCodeEmitter.h" +#include "llvm/BinaryFormat/ELF.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrDesc.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCSymbolELF.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/SourceMgr.h" + +using namespace llvm; + +PPCELFStreamer::PPCELFStreamer(MCContext &Context, + std::unique_ptr<MCAsmBackend> MAB, + std::unique_ptr<MCObjectWriter> OW, + std::unique_ptr<MCCodeEmitter> Emitter) + : MCELFStreamer(Context, std::move(MAB), std::move(OW), + std::move(Emitter)), LastLabel(NULL) { +} + +void PPCELFStreamer::emitPrefixedInstruction(const MCInst &Inst, + const MCSubtargetInfo &STI) { + // Prefixed instructions must not cross a 64-byte boundary (i.e. prefix is + // before the boundary and the remaining 4-bytes are after the boundary). In + // order to achieve this, a nop is added prior to any such boundary-crossing + // prefixed instruction. Align to 64 bytes if possible but add a maximum of 4 + // bytes when trying to do that. If alignment requires adding more than 4 + // bytes then the instruction won't be aligned. When emitting a code alignment + // a new fragment is created for this alignment. This fragment will contain + // all of the nops required as part of the alignment operation. In the cases + // when no nops are added then The fragment is still created but it remains + // empty. + emitCodeAlignment(64, 4); + + // Emit the instruction. + // Since the previous emit created a new fragment then adding this instruction + // also forces the addition of a new fragment. Inst is now the first + // instruction in that new fragment. + MCELFStreamer::emitInstruction(Inst, STI); + + // The above instruction is forced to start a new fragment because it + // comes after a code alignment fragment. Get that new fragment. + MCFragment *InstructionFragment = getCurrentFragment(); + SMLoc InstLoc = Inst.getLoc(); + // Check if there was a last label emitted. + if (LastLabel && !LastLabel->isUnset() && LastLabelLoc.isValid() && + InstLoc.isValid()) { + const SourceMgr *SourceManager = getContext().getSourceManager(); + unsigned InstLine = SourceManager->FindLineNumber(InstLoc); + unsigned LabelLine = SourceManager->FindLineNumber(LastLabelLoc); + // If the Label and the Instruction are on the same line then move the + // label to the top of the fragment containing the aligned instruction that + // was just added. + if (InstLine == LabelLine) { + AssignFragment(LastLabel, InstructionFragment); + LastLabel->setOffset(0); + } + } +} + +void PPCELFStreamer::emitInstruction(const MCInst &Inst, + const MCSubtargetInfo &STI) { + PPCMCCodeEmitter *Emitter = + static_cast<PPCMCCodeEmitter*>(getAssembler().getEmitterPtr()); + // If the instruction is a part of the GOT to PC-Rel link time optimization // instruction pair, return a value, otherwise return None. A true returned // value means the instruction is the PLDpc and a false value means it is @@ -103,12 +103,12 @@ void PPCELFStreamer::emitInstruction(const MCInst &Inst, if (IsPartOfGOTToPCRelPair.hasValue() && !IsPartOfGOTToPCRelPair.getValue()) emitGOTToPCRelReloc(Inst); - // Special handling is only for prefixed instructions. - if (!Emitter->isPrefixedInstruction(Inst)) { - MCELFStreamer::emitInstruction(Inst, STI); - return; - } - emitPrefixedInstruction(Inst, STI); + // Special handling is only for prefixed instructions. + if (!Emitter->isPrefixedInstruction(Inst)) { + MCELFStreamer::emitInstruction(Inst, STI); + return; + } + emitPrefixedInstruction(Inst, STI); // Producer of the GOT-indirect address. // For example, the prefixed load from the got that will get the label as @@ -117,14 +117,14 @@ void PPCELFStreamer::emitInstruction(const MCInst &Inst, // .Lpcrel1: if (IsPartOfGOTToPCRelPair.hasValue() && IsPartOfGOTToPCRelPair.getValue()) emitGOTToPCRelLabel(Inst); -} - -void PPCELFStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) { - LastLabel = Symbol; - LastLabelLoc = Loc; - MCELFStreamer::emitLabel(Symbol); -} - +} + +void PPCELFStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) { + LastLabel = Symbol; + LastLabelLoc = Loc; + MCELFStreamer::emitLabel(Symbol); +} + // This linker time GOT PC Relative optimization relocation will look like this: // pld <reg> symbol@got@pcrel // <Label###>: @@ -221,10 +221,10 @@ Optional<bool> llvm::isPartOfGOTToPCRelPair(const MCInst &Inst, return (Inst.getOpcode() == PPC::PLDpc); } -MCELFStreamer *llvm::createPPCELFStreamer( - MCContext &Context, std::unique_ptr<MCAsmBackend> MAB, - std::unique_ptr<MCObjectWriter> OW, - std::unique_ptr<MCCodeEmitter> Emitter) { - return new PPCELFStreamer(Context, std::move(MAB), std::move(OW), - std::move(Emitter)); -} +MCELFStreamer *llvm::createPPCELFStreamer( + MCContext &Context, std::unique_ptr<MCAsmBackend> MAB, + std::unique_ptr<MCObjectWriter> OW, + std::unique_ptr<MCCodeEmitter> Emitter) { + return new PPCELFStreamer(Context, std::move(MAB), std::move(OW), + std::move(Emitter)); +} diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.h b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.h index f44200104f..3e07b7e5ff 100644 --- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.h +++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.h @@ -1,61 +1,61 @@ -//===- PPCELFStreamer.h - ELF Object Output --------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This is a custom MCELFStreamer for PowerPC. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_TARGET_PPC_MCELFSTREAMER_PPCELFSTREAMER_H -#define LLVM_LIB_TARGET_PPC_MCELFSTREAMER_PPCELFSTREAMER_H - -#include "llvm/ADT/SmallVector.h" -#include "llvm/MC/MCELFStreamer.h" -#include <memory> - -namespace llvm { - -class MCAsmBackend; -class MCCodeEmitter; -class MCContext; -class MCSubtargetInfo; - -class PPCELFStreamer : public MCELFStreamer { - // We need to keep track of the last label we emitted (only one) because - // depending on whether the label is on the same line as an aligned - // instruction or not, the label may refer to the instruction or the nop. - MCSymbol *LastLabel; - SMLoc LastLabelLoc; - -public: - PPCELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> MAB, - std::unique_ptr<MCObjectWriter> OW, - std::unique_ptr<MCCodeEmitter> Emitter); - - void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override; - - // EmitLabel updates LastLabel and LastLabelLoc when a new label is emitted. - void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; -private: - void emitPrefixedInstruction(const MCInst &Inst, const MCSubtargetInfo &STI); +//===- PPCELFStreamer.h - ELF Object Output --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is a custom MCELFStreamer for PowerPC. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_PPC_MCELFSTREAMER_PPCELFSTREAMER_H +#define LLVM_LIB_TARGET_PPC_MCELFSTREAMER_PPCELFSTREAMER_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/MC/MCELFStreamer.h" +#include <memory> + +namespace llvm { + +class MCAsmBackend; +class MCCodeEmitter; +class MCContext; +class MCSubtargetInfo; + +class PPCELFStreamer : public MCELFStreamer { + // We need to keep track of the last label we emitted (only one) because + // depending on whether the label is on the same line as an aligned + // instruction or not, the label may refer to the instruction or the nop. + MCSymbol *LastLabel; + SMLoc LastLabelLoc; + +public: + PPCELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> MAB, + std::unique_ptr<MCObjectWriter> OW, + std::unique_ptr<MCCodeEmitter> Emitter); + + void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override; + + // EmitLabel updates LastLabel and LastLabelLoc when a new label is emitted. + void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; +private: + void emitPrefixedInstruction(const MCInst &Inst, const MCSubtargetInfo &STI); void emitGOTToPCRelReloc(const MCInst &Inst); void emitGOTToPCRelLabel(const MCInst &Inst); -}; - +}; + // Check if the instruction Inst is part of a pair of instructions that make up // a link time GOT PC Rel optimization. Optional<bool> isPartOfGOTToPCRelPair(const MCInst &Inst, const MCSubtargetInfo &STI); -MCELFStreamer *createPPCELFStreamer(MCContext &Context, - std::unique_ptr<MCAsmBackend> MAB, - std::unique_ptr<MCObjectWriter> OW, - std::unique_ptr<MCCodeEmitter> Emitter); -} // end namespace llvm - -#endif // LLVM_LIB_TARGET_PPC_MCELFSTREAMER_PPCELFSTREAMER_H +MCELFStreamer *createPPCELFStreamer(MCContext &Context, + std::unique_ptr<MCAsmBackend> MAB, + std::unique_ptr<MCObjectWriter> OW, + std::unique_ptr<MCCodeEmitter> Emitter); +} // end namespace llvm + +#endif // LLVM_LIB_TARGET_PPC_MCELFSTREAMER_PPCELFSTREAMER_H diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h index 73292f7b79..6f3eabab1c 100644 --- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h +++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h @@ -1,61 +1,61 @@ -//===-- PPCFixupKinds.h - PPC Specific Fixup Entries ------------*- 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCFIXUPKINDS_H -#define LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCFIXUPKINDS_H - -#include "llvm/MC/MCFixup.h" - -#undef PPC - -namespace llvm { -namespace PPC { -enum Fixups { - // 24-bit PC relative relocation for direct branches like 'b' and 'bl'. - fixup_ppc_br24 = FirstTargetFixupKind, - - // 24-bit PC relative relocation for direct branches like 'b' and 'bl' where - // the caller does not use the TOC. - fixup_ppc_br24_notoc, - - /// 14-bit PC relative relocation for conditional branches. - fixup_ppc_brcond14, - - /// 24-bit absolute relocation for direct branches like 'ba' and 'bla'. - fixup_ppc_br24abs, - - /// 14-bit absolute relocation for conditional branches. - fixup_ppc_brcond14abs, - - /// A 16-bit fixup corresponding to lo16(_foo) or ha16(_foo) for instrs like - /// 'li' or 'addis'. - fixup_ppc_half16, - - /// A 14-bit fixup corresponding to lo16(_foo) with implied 2 zero bits for - /// instrs like 'std'. - fixup_ppc_half16ds, - - // A 34-bit fixup corresponding to PC-relative paddi. - fixup_ppc_pcrel34, - +//===-- PPCFixupKinds.h - PPC Specific Fixup Entries ------------*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCFIXUPKINDS_H +#define LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCFIXUPKINDS_H + +#include "llvm/MC/MCFixup.h" + +#undef PPC + +namespace llvm { +namespace PPC { +enum Fixups { + // 24-bit PC relative relocation for direct branches like 'b' and 'bl'. + fixup_ppc_br24 = FirstTargetFixupKind, + + // 24-bit PC relative relocation for direct branches like 'b' and 'bl' where + // the caller does not use the TOC. + fixup_ppc_br24_notoc, + + /// 14-bit PC relative relocation for conditional branches. + fixup_ppc_brcond14, + + /// 24-bit absolute relocation for direct branches like 'ba' and 'bla'. + fixup_ppc_br24abs, + + /// 14-bit absolute relocation for conditional branches. + fixup_ppc_brcond14abs, + + /// A 16-bit fixup corresponding to lo16(_foo) or ha16(_foo) for instrs like + /// 'li' or 'addis'. + fixup_ppc_half16, + + /// A 14-bit fixup corresponding to lo16(_foo) with implied 2 zero bits for + /// instrs like 'std'. + fixup_ppc_half16ds, + + // A 34-bit fixup corresponding to PC-relative paddi. + fixup_ppc_pcrel34, + // A 34-bit fixup corresponding to Non-PC-relative paddi. fixup_ppc_imm34, - /// Not a true fixup, but ties a symbol to a call to __tls_get_addr for the - /// TLS general and local dynamic models, or inserts the thread-pointer - /// register number. - fixup_ppc_nofixup, - - // Marker - LastTargetFixupKind, - NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind -}; -} -} - -#endif + /// Not a true fixup, but ties a symbol to a call to __tls_get_addr for the + /// TLS general and local dynamic models, or inserts the thread-pointer + /// register number. + fixup_ppc_nofixup, + + // Marker + LastTargetFixupKind, + NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind +}; +} +} + +#endif diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp index a291a34d4c..386edc684e 100644 --- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp +++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp @@ -1,85 +1,85 @@ -//===-- PPCInstPrinter.cpp - Convert PPC MCInst to assembly syntax --------===// -// -// 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 -// -//===----------------------------------------------------------------------===// -// -// This class prints an PPC MCInst to a .s file. -// -//===----------------------------------------------------------------------===// - -#include "MCTargetDesc/PPCInstPrinter.h" -#include "MCTargetDesc/PPCMCTargetDesc.h" -#include "MCTargetDesc/PPCPredicates.h" -#include "PPCInstrInfo.h" -#include "llvm/CodeGen/TargetOpcodes.h" -#include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCInst.h" -#include "llvm/MC/MCInstrInfo.h" -#include "llvm/MC/MCRegisterInfo.h" -#include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/raw_ostream.h" -using namespace llvm; - -#define DEBUG_TYPE "asm-printer" - -// FIXME: Once the integrated assembler supports full register names, tie this -// to the verbose-asm setting. -static cl::opt<bool> -FullRegNames("ppc-asm-full-reg-names", cl::Hidden, cl::init(false), - cl::desc("Use full register names when printing assembly")); - -// Useful for testing purposes. Prints vs{31-63} as v{0-31} respectively. -static cl::opt<bool> -ShowVSRNumsAsVR("ppc-vsr-nums-as-vr", cl::Hidden, cl::init(false), - cl::desc("Prints full register names with vs{31-63} as v{0-31}")); - -// Prints full register names with percent symbol. -static cl::opt<bool> -FullRegNamesWithPercent("ppc-reg-with-percent-prefix", cl::Hidden, - cl::init(false), - cl::desc("Prints full register names with percent")); - -#define PRINT_ALIAS_INSTR -#include "PPCGenAsmWriter.inc" - -void PPCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { - const char *RegName = getRegisterName(RegNo); - OS << RegName; -} - -void PPCInstPrinter::printInst(const MCInst *MI, uint64_t Address, - StringRef Annot, const MCSubtargetInfo &STI, - raw_ostream &O) { - // Customize printing of the addis instruction on AIX. When an operand is a - // symbol reference, the instruction syntax is changed to look like a load - // operation, i.e: - // Transform: addis $rD, $rA, $src --> addis $rD, $src($rA). - if (TT.isOSAIX() && - (MI->getOpcode() == PPC::ADDIS8 || MI->getOpcode() == PPC::ADDIS) && - MI->getOperand(2).isExpr()) { - assert((MI->getOperand(0).isReg() && MI->getOperand(1).isReg()) && - "The first and the second operand of an addis instruction" - " should be registers."); - - assert(isa<MCSymbolRefExpr>(MI->getOperand(2).getExpr()) && - "The third operand of an addis instruction should be a symbol " - "reference expression if it is an expression at all."); - - O << "\taddis "; +//===-- PPCInstPrinter.cpp - Convert PPC MCInst to assembly syntax --------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This class prints an PPC MCInst to a .s file. +// +//===----------------------------------------------------------------------===// + +#include "MCTargetDesc/PPCInstPrinter.h" +#include "MCTargetDesc/PPCMCTargetDesc.h" +#include "MCTargetDesc/PPCPredicates.h" +#include "PPCInstrInfo.h" +#include "llvm/CodeGen/TargetOpcodes.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +#define DEBUG_TYPE "asm-printer" + +// FIXME: Once the integrated assembler supports full register names, tie this +// to the verbose-asm setting. +static cl::opt<bool> +FullRegNames("ppc-asm-full-reg-names", cl::Hidden, cl::init(false), + cl::desc("Use full register names when printing assembly")); + +// Useful for testing purposes. Prints vs{31-63} as v{0-31} respectively. +static cl::opt<bool> +ShowVSRNumsAsVR("ppc-vsr-nums-as-vr", cl::Hidden, cl::init(false), + cl::desc("Prints full register names with vs{31-63} as v{0-31}")); + +// Prints full register names with percent symbol. +static cl::opt<bool> +FullRegNamesWithPercent("ppc-reg-with-percent-prefix", cl::Hidden, + cl::init(false), + cl::desc("Prints full register names with percent")); + +#define PRINT_ALIAS_INSTR +#include "PPCGenAsmWriter.inc" + +void PPCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { + const char *RegName = getRegisterName(RegNo); + OS << RegName; +} + +void PPCInstPrinter::printInst(const MCInst *MI, uint64_t Address, + StringRef Annot, const MCSubtargetInfo &STI, + raw_ostream &O) { + // Customize printing of the addis instruction on AIX. When an operand is a + // symbol reference, the instruction syntax is changed to look like a load + // operation, i.e: + // Transform: addis $rD, $rA, $src --> addis $rD, $src($rA). + if (TT.isOSAIX() && + (MI->getOpcode() == PPC::ADDIS8 || MI->getOpcode() == PPC::ADDIS) && + MI->getOperand(2).isExpr()) { + assert((MI->getOperand(0).isReg() && MI->getOperand(1).isReg()) && + "The first and the second operand of an addis instruction" + " should be registers."); + + assert(isa<MCSymbolRefExpr>(MI->getOperand(2).getExpr()) && + "The third operand of an addis instruction should be a symbol " + "reference expression if it is an expression at all."); + + O << "\taddis "; printOperand(MI, 0, STI, O); - O << ", "; + O << ", "; printOperand(MI, 2, STI, O); - O << "("; + O << "("; printOperand(MI, 1, STI, O); - O << ")"; - return; - } - + O << ")"; + return; + } + // Check if the last operand is an expression with the variant kind // VK_PPC_PCREL_OPT. If this is the case then this is a linker optimization // relocation and the .reloc directive needs to be added. @@ -110,547 +110,547 @@ void PPCInstPrinter::printInst(const MCInst *MI, uint64_t Address, } } - // Check for slwi/srwi mnemonics. - if (MI->getOpcode() == PPC::RLWINM) { - unsigned char SH = MI->getOperand(2).getImm(); - unsigned char MB = MI->getOperand(3).getImm(); - unsigned char ME = MI->getOperand(4).getImm(); - bool useSubstituteMnemonic = false; - if (SH <= 31 && MB == 0 && ME == (31-SH)) { - O << "\tslwi "; useSubstituteMnemonic = true; - } - if (SH <= 31 && MB == (32-SH) && ME == 31) { - O << "\tsrwi "; useSubstituteMnemonic = true; - SH = 32-SH; - } - if (useSubstituteMnemonic) { + // Check for slwi/srwi mnemonics. + if (MI->getOpcode() == PPC::RLWINM) { + unsigned char SH = MI->getOperand(2).getImm(); + unsigned char MB = MI->getOperand(3).getImm(); + unsigned char ME = MI->getOperand(4).getImm(); + bool useSubstituteMnemonic = false; + if (SH <= 31 && MB == 0 && ME == (31-SH)) { + O << "\tslwi "; useSubstituteMnemonic = true; + } + if (SH <= 31 && MB == (32-SH) && ME == 31) { + O << "\tsrwi "; useSubstituteMnemonic = true; + SH = 32-SH; + } + if (useSubstituteMnemonic) { printOperand(MI, 0, STI, O); - O << ", "; + O << ", "; printOperand(MI, 1, STI, O); - O << ", " << (unsigned int)SH; - - printAnnotation(O, Annot); - return; - } - } - - if (MI->getOpcode() == PPC::RLDICR || - MI->getOpcode() == PPC::RLDICR_32) { - unsigned char SH = MI->getOperand(2).getImm(); - unsigned char ME = MI->getOperand(3).getImm(); - // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH - if (63-SH == ME) { - O << "\tsldi "; + O << ", " << (unsigned int)SH; + + printAnnotation(O, Annot); + return; + } + } + + if (MI->getOpcode() == PPC::RLDICR || + MI->getOpcode() == PPC::RLDICR_32) { + unsigned char SH = MI->getOperand(2).getImm(); + unsigned char ME = MI->getOperand(3).getImm(); + // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH + if (63-SH == ME) { + O << "\tsldi "; printOperand(MI, 0, STI, O); - O << ", "; + O << ", "; printOperand(MI, 1, STI, O); - O << ", " << (unsigned int)SH; - printAnnotation(O, Annot); - return; - } - } - - // dcbt[st] is printed manually here because: - // 1. The assembly syntax is different between embedded and server targets - // 2. We must print the short mnemonics for TH == 0 because the - // embedded/server syntax default will not be stable across assemblers - // The syntax for dcbt is: - // dcbt ra, rb, th [server] - // dcbt th, ra, rb [embedded] - // where th can be omitted when it is 0. dcbtst is the same. - if (MI->getOpcode() == PPC::DCBT || MI->getOpcode() == PPC::DCBTST) { - unsigned char TH = MI->getOperand(0).getImm(); - O << "\tdcbt"; - if (MI->getOpcode() == PPC::DCBTST) - O << "st"; - if (TH == 16) - O << "t"; - O << " "; - - bool IsBookE = STI.getFeatureBits()[PPC::FeatureBookE]; - if (IsBookE && TH != 0 && TH != 16) - O << (unsigned int) TH << ", "; - + O << ", " << (unsigned int)SH; + printAnnotation(O, Annot); + return; + } + } + + // dcbt[st] is printed manually here because: + // 1. The assembly syntax is different between embedded and server targets + // 2. We must print the short mnemonics for TH == 0 because the + // embedded/server syntax default will not be stable across assemblers + // The syntax for dcbt is: + // dcbt ra, rb, th [server] + // dcbt th, ra, rb [embedded] + // where th can be omitted when it is 0. dcbtst is the same. + if (MI->getOpcode() == PPC::DCBT || MI->getOpcode() == PPC::DCBTST) { + unsigned char TH = MI->getOperand(0).getImm(); + O << "\tdcbt"; + if (MI->getOpcode() == PPC::DCBTST) + O << "st"; + if (TH == 16) + O << "t"; + O << " "; + + bool IsBookE = STI.getFeatureBits()[PPC::FeatureBookE]; + if (IsBookE && TH != 0 && TH != 16) + O << (unsigned int) TH << ", "; + printOperand(MI, 1, STI, O); - O << ", "; + O << ", "; printOperand(MI, 2, STI, O); - - if (!IsBookE && TH != 0 && TH != 16) - O << ", " << (unsigned int) TH; - - printAnnotation(O, Annot); - return; - } - - if (MI->getOpcode() == PPC::DCBF) { - unsigned char L = MI->getOperand(0).getImm(); + + if (!IsBookE && TH != 0 && TH != 16) + O << ", " << (unsigned int) TH; + + printAnnotation(O, Annot); + return; + } + + if (MI->getOpcode() == PPC::DCBF) { + unsigned char L = MI->getOperand(0).getImm(); if (!L || L == 1 || L == 3 || L == 4 || L == 6) { O << "\tdcb"; if (L != 6) O << "f"; if (L == 1) - O << "l"; - if (L == 3) + O << "l"; + if (L == 3) O << "lp"; if (L == 4) O << "ps"; if (L == 6) O << "stps"; - O << " "; - + O << " "; + printOperand(MI, 1, STI, O); - O << ", "; + O << ", "; printOperand(MI, 2, STI, O); - - printAnnotation(O, Annot); - return; - } - } - + + printAnnotation(O, Annot); + return; + } + } + if (!printAliasInstr(MI, Address, STI, O)) printInstruction(MI, Address, STI, O); - printAnnotation(O, Annot); -} - -void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo, + printAnnotation(O, Annot); +} + +void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O, - const char *Modifier) { - unsigned Code = MI->getOperand(OpNo).getImm(); - - if (StringRef(Modifier) == "cc") { - switch ((PPC::Predicate)Code) { - case PPC::PRED_LT_MINUS: - case PPC::PRED_LT_PLUS: - case PPC::PRED_LT: - O << "lt"; - return; - case PPC::PRED_LE_MINUS: - case PPC::PRED_LE_PLUS: - case PPC::PRED_LE: - O << "le"; - return; - case PPC::PRED_EQ_MINUS: - case PPC::PRED_EQ_PLUS: - case PPC::PRED_EQ: - O << "eq"; - return; - case PPC::PRED_GE_MINUS: - case PPC::PRED_GE_PLUS: - case PPC::PRED_GE: - O << "ge"; - return; - case PPC::PRED_GT_MINUS: - case PPC::PRED_GT_PLUS: - case PPC::PRED_GT: - O << "gt"; - return; - case PPC::PRED_NE_MINUS: - case PPC::PRED_NE_PLUS: - case PPC::PRED_NE: - O << "ne"; - return; - case PPC::PRED_UN_MINUS: - case PPC::PRED_UN_PLUS: - case PPC::PRED_UN: - O << "un"; - return; - case PPC::PRED_NU_MINUS: - case PPC::PRED_NU_PLUS: - case PPC::PRED_NU: - O << "nu"; - return; - case PPC::PRED_BIT_SET: - case PPC::PRED_BIT_UNSET: - llvm_unreachable("Invalid use of bit predicate code"); - } - llvm_unreachable("Invalid predicate code"); - } - - if (StringRef(Modifier) == "pm") { - switch ((PPC::Predicate)Code) { - case PPC::PRED_LT: - case PPC::PRED_LE: - case PPC::PRED_EQ: - case PPC::PRED_GE: - case PPC::PRED_GT: - case PPC::PRED_NE: - case PPC::PRED_UN: - case PPC::PRED_NU: - return; - case PPC::PRED_LT_MINUS: - case PPC::PRED_LE_MINUS: - case PPC::PRED_EQ_MINUS: - case PPC::PRED_GE_MINUS: - case PPC::PRED_GT_MINUS: - case PPC::PRED_NE_MINUS: - case PPC::PRED_UN_MINUS: - case PPC::PRED_NU_MINUS: - O << "-"; - return; - case PPC::PRED_LT_PLUS: - case PPC::PRED_LE_PLUS: - case PPC::PRED_EQ_PLUS: - case PPC::PRED_GE_PLUS: - case PPC::PRED_GT_PLUS: - case PPC::PRED_NE_PLUS: - case PPC::PRED_UN_PLUS: - case PPC::PRED_NU_PLUS: - O << "+"; - return; - case PPC::PRED_BIT_SET: - case PPC::PRED_BIT_UNSET: - llvm_unreachable("Invalid use of bit predicate code"); - } - llvm_unreachable("Invalid predicate code"); - } - - assert(StringRef(Modifier) == "reg" && - "Need to specify 'cc', 'pm' or 'reg' as predicate op modifier!"); + raw_ostream &O, + const char *Modifier) { + unsigned Code = MI->getOperand(OpNo).getImm(); + + if (StringRef(Modifier) == "cc") { + switch ((PPC::Predicate)Code) { + case PPC::PRED_LT_MINUS: + case PPC::PRED_LT_PLUS: + case PPC::PRED_LT: + O << "lt"; + return; + case PPC::PRED_LE_MINUS: + case PPC::PRED_LE_PLUS: + case PPC::PRED_LE: + O << "le"; + return; + case PPC::PRED_EQ_MINUS: + case PPC::PRED_EQ_PLUS: + case PPC::PRED_EQ: + O << "eq"; + return; + case PPC::PRED_GE_MINUS: + case PPC::PRED_GE_PLUS: + case PPC::PRED_GE: + O << "ge"; + return; + case PPC::PRED_GT_MINUS: + case PPC::PRED_GT_PLUS: + case PPC::PRED_GT: + O << "gt"; + return; + case PPC::PRED_NE_MINUS: + case PPC::PRED_NE_PLUS: + case PPC::PRED_NE: + O << "ne"; + return; + case PPC::PRED_UN_MINUS: + case PPC::PRED_UN_PLUS: + case PPC::PRED_UN: + O << "un"; + return; + case PPC::PRED_NU_MINUS: + case PPC::PRED_NU_PLUS: + case PPC::PRED_NU: + O << "nu"; + return; + case PPC::PRED_BIT_SET: + case PPC::PRED_BIT_UNSET: + llvm_unreachable("Invalid use of bit predicate code"); + } + llvm_unreachable("Invalid predicate code"); + } + + if (StringRef(Modifier) == "pm") { + switch ((PPC::Predicate)Code) { + case PPC::PRED_LT: + case PPC::PRED_LE: + case PPC::PRED_EQ: + case PPC::PRED_GE: + case PPC::PRED_GT: + case PPC::PRED_NE: + case PPC::PRED_UN: + case PPC::PRED_NU: + return; + case PPC::PRED_LT_MINUS: + case PPC::PRED_LE_MINUS: + case PPC::PRED_EQ_MINUS: + case PPC::PRED_GE_MINUS: + case PPC::PRED_GT_MINUS: + case PPC::PRED_NE_MINUS: + case PPC::PRED_UN_MINUS: + case PPC::PRED_NU_MINUS: + O << "-"; + return; + case PPC::PRED_LT_PLUS: + case PPC::PRED_LE_PLUS: + case PPC::PRED_EQ_PLUS: + case PPC::PRED_GE_PLUS: + case PPC::PRED_GT_PLUS: + case PPC::PRED_NE_PLUS: + case PPC::PRED_UN_PLUS: + case PPC::PRED_NU_PLUS: + O << "+"; + return; + case PPC::PRED_BIT_SET: + case PPC::PRED_BIT_UNSET: + llvm_unreachable("Invalid use of bit predicate code"); + } + llvm_unreachable("Invalid predicate code"); + } + + assert(StringRef(Modifier) == "reg" && + "Need to specify 'cc', 'pm' or 'reg' as predicate op modifier!"); printOperand(MI, OpNo + 1, STI, O); -} - -void PPCInstPrinter::printATBitsAsHint(const MCInst *MI, unsigned OpNo, +} + +void PPCInstPrinter::printATBitsAsHint(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O) { - unsigned Code = MI->getOperand(OpNo).getImm(); - if (Code == 2) - O << "-"; - else if (Code == 3) - O << "+"; -} - -void PPCInstPrinter::printU1ImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + unsigned Code = MI->getOperand(OpNo).getImm(); + if (Code == 2) + O << "-"; + else if (Code == 3) + O << "+"; +} + +void PPCInstPrinter::printU1ImmOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O) { - unsigned int Value = MI->getOperand(OpNo).getImm(); - assert(Value <= 1 && "Invalid u1imm argument!"); - O << (unsigned int)Value; -} - -void PPCInstPrinter::printU2ImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + unsigned int Value = MI->getOperand(OpNo).getImm(); + assert(Value <= 1 && "Invalid u1imm argument!"); + O << (unsigned int)Value; +} + +void PPCInstPrinter::printU2ImmOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O) { - unsigned int Value = MI->getOperand(OpNo).getImm(); - assert(Value <= 3 && "Invalid u2imm argument!"); - O << (unsigned int)Value; -} - -void PPCInstPrinter::printU3ImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + unsigned int Value = MI->getOperand(OpNo).getImm(); + assert(Value <= 3 && "Invalid u2imm argument!"); + O << (unsigned int)Value; +} + +void PPCInstPrinter::printU3ImmOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O) { - unsigned int Value = MI->getOperand(OpNo).getImm(); - assert(Value <= 8 && "Invalid u3imm argument!"); - O << (unsigned int)Value; -} - -void PPCInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + unsigned int Value = MI->getOperand(OpNo).getImm(); + assert(Value <= 8 && "Invalid u3imm argument!"); + O << (unsigned int)Value; +} + +void PPCInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O) { - unsigned int Value = MI->getOperand(OpNo).getImm(); - assert(Value <= 15 && "Invalid u4imm argument!"); - O << (unsigned int)Value; -} - -void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + unsigned int Value = MI->getOperand(OpNo).getImm(); + assert(Value <= 15 && "Invalid u4imm argument!"); + O << (unsigned int)Value; +} + +void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O) { - int Value = MI->getOperand(OpNo).getImm(); - Value = SignExtend32<5>(Value); - O << (int)Value; -} - -void PPCInstPrinter::printImmZeroOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + int Value = MI->getOperand(OpNo).getImm(); + Value = SignExtend32<5>(Value); + O << (int)Value; +} + +void PPCInstPrinter::printImmZeroOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O) { - unsigned int Value = MI->getOperand(OpNo).getImm(); - assert(Value == 0 && "Operand must be zero"); - O << (unsigned int)Value; -} - -void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + unsigned int Value = MI->getOperand(OpNo).getImm(); + assert(Value == 0 && "Operand must be zero"); + O << (unsigned int)Value; +} + +void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O) { - unsigned int Value = MI->getOperand(OpNo).getImm(); - assert(Value <= 31 && "Invalid u5imm argument!"); - O << (unsigned int)Value; -} - -void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + unsigned int Value = MI->getOperand(OpNo).getImm(); + assert(Value <= 31 && "Invalid u5imm argument!"); + O << (unsigned int)Value; +} + +void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O) { - unsigned int Value = MI->getOperand(OpNo).getImm(); - assert(Value <= 63 && "Invalid u6imm argument!"); - O << (unsigned int)Value; -} - -void PPCInstPrinter::printU7ImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + unsigned int Value = MI->getOperand(OpNo).getImm(); + assert(Value <= 63 && "Invalid u6imm argument!"); + O << (unsigned int)Value; +} + +void PPCInstPrinter::printU7ImmOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O) { - unsigned int Value = MI->getOperand(OpNo).getImm(); - assert(Value <= 127 && "Invalid u7imm argument!"); - O << (unsigned int)Value; -} - -// Operands of BUILD_VECTOR are signed and we use this to print operands -// of XXSPLTIB which are unsigned. So we simply truncate to 8 bits and -// print as unsigned. -void PPCInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + unsigned int Value = MI->getOperand(OpNo).getImm(); + assert(Value <= 127 && "Invalid u7imm argument!"); + O << (unsigned int)Value; +} + +// Operands of BUILD_VECTOR are signed and we use this to print operands +// of XXSPLTIB which are unsigned. So we simply truncate to 8 bits and +// print as unsigned. +void PPCInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O) { - unsigned char Value = MI->getOperand(OpNo).getImm(); - O << (unsigned int)Value; -} - -void PPCInstPrinter::printU10ImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + unsigned char Value = MI->getOperand(OpNo).getImm(); + O << (unsigned int)Value; +} + +void PPCInstPrinter::printU10ImmOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O) { - unsigned short Value = MI->getOperand(OpNo).getImm(); - assert(Value <= 1023 && "Invalid u10imm argument!"); - O << (unsigned short)Value; -} - -void PPCInstPrinter::printU12ImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + unsigned short Value = MI->getOperand(OpNo).getImm(); + assert(Value <= 1023 && "Invalid u10imm argument!"); + O << (unsigned short)Value; +} + +void PPCInstPrinter::printU12ImmOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O) { - unsigned short Value = MI->getOperand(OpNo).getImm(); - assert(Value <= 4095 && "Invalid u12imm argument!"); - O << (unsigned short)Value; -} - -void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + unsigned short Value = MI->getOperand(OpNo).getImm(); + assert(Value <= 4095 && "Invalid u12imm argument!"); + O << (unsigned short)Value; +} + +void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O) { - if (MI->getOperand(OpNo).isImm()) - O << (short)MI->getOperand(OpNo).getImm(); - else + raw_ostream &O) { + if (MI->getOperand(OpNo).isImm()) + O << (short)MI->getOperand(OpNo).getImm(); + else printOperand(MI, OpNo, STI, O); -} - -void PPCInstPrinter::printS34ImmOperand(const MCInst *MI, unsigned OpNo, +} + +void PPCInstPrinter::printS34ImmOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O) { - if (MI->getOperand(OpNo).isImm()) { - long long Value = MI->getOperand(OpNo).getImm(); - assert(isInt<34>(Value) && "Invalid s34imm argument!"); - O << (long long)Value; - } - else + raw_ostream &O) { + if (MI->getOperand(OpNo).isImm()) { + long long Value = MI->getOperand(OpNo).getImm(); + assert(isInt<34>(Value) && "Invalid s34imm argument!"); + O << (long long)Value; + } + else printOperand(MI, OpNo, STI, O); -} - -void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo, +} + +void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O) { - if (MI->getOperand(OpNo).isImm()) - O << (unsigned short)MI->getOperand(OpNo).getImm(); - else + raw_ostream &O) { + if (MI->getOperand(OpNo).isImm()) + O << (unsigned short)MI->getOperand(OpNo).getImm(); + else printOperand(MI, OpNo, STI, O); -} - -void PPCInstPrinter::printBranchOperand(const MCInst *MI, uint64_t Address, +} + +void PPCInstPrinter::printBranchOperand(const MCInst *MI, uint64_t Address, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O) { - if (!MI->getOperand(OpNo).isImm()) + if (!MI->getOperand(OpNo).isImm()) return printOperand(MI, OpNo, STI, O); - int32_t Imm = SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2); - if (PrintBranchImmAsAddress) { - uint64_t Target = Address + Imm; - if (!TT.isPPC64()) - Target &= 0xffffffff; - O << formatHex(Target); - } else { - // Branches can take an immediate operand. This is used by the branch - // selection pass to print, for example `.+8` (for ELF) or `$+8` (for AIX) - // to express an eight byte displacement from the program counter. - if (!TT.isOSAIX()) - O << "."; - else - O << "$"; - - if (Imm >= 0) - O << "+"; - O << Imm; - } -} - -void PPCInstPrinter::printAbsBranchOperand(const MCInst *MI, unsigned OpNo, + int32_t Imm = SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2); + if (PrintBranchImmAsAddress) { + uint64_t Target = Address + Imm; + if (!TT.isPPC64()) + Target &= 0xffffffff; + O << formatHex(Target); + } else { + // Branches can take an immediate operand. This is used by the branch + // selection pass to print, for example `.+8` (for ELF) or `$+8` (for AIX) + // to express an eight byte displacement from the program counter. + if (!TT.isOSAIX()) + O << "."; + else + O << "$"; + + if (Imm >= 0) + O << "+"; + O << Imm; + } +} + +void PPCInstPrinter::printAbsBranchOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O) { - if (!MI->getOperand(OpNo).isImm()) + raw_ostream &O) { + if (!MI->getOperand(OpNo).isImm()) return printOperand(MI, OpNo, STI, O); - - O << SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2); -} - -void PPCInstPrinter::printcrbitm(const MCInst *MI, unsigned OpNo, + + O << SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2); +} + +void PPCInstPrinter::printcrbitm(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O) { - unsigned CCReg = MI->getOperand(OpNo).getReg(); - unsigned RegNo; - switch (CCReg) { - default: llvm_unreachable("Unknown CR register"); - case PPC::CR0: RegNo = 0; break; - case PPC::CR1: RegNo = 1; break; - case PPC::CR2: RegNo = 2; break; - case PPC::CR3: RegNo = 3; break; - case PPC::CR4: RegNo = 4; break; - case PPC::CR5: RegNo = 5; break; - case PPC::CR6: RegNo = 6; break; - case PPC::CR7: RegNo = 7; break; - } - O << (0x80 >> RegNo); -} - -void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo, + unsigned CCReg = MI->getOperand(OpNo).getReg(); + unsigned RegNo; + switch (CCReg) { + default: llvm_unreachable("Unknown CR register"); + case PPC::CR0: RegNo = 0; break; + case PPC::CR1: RegNo = 1; break; + case PPC::CR2: RegNo = 2; break; + case PPC::CR3: RegNo = 3; break; + case PPC::CR4: RegNo = 4; break; + case PPC::CR5: RegNo = 5; break; + case PPC::CR6: RegNo = 6; break; + case PPC::CR7: RegNo = 7; break; + } + O << (0x80 >> RegNo); +} + +void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O) { + raw_ostream &O) { printS16ImmOperand(MI, OpNo, STI, O); - O << '('; - if (MI->getOperand(OpNo+1).getReg() == PPC::R0) - O << "0"; - else + O << '('; + if (MI->getOperand(OpNo+1).getReg() == PPC::R0) + O << "0"; + else printOperand(MI, OpNo + 1, STI, O); - O << ')'; -} - -void PPCInstPrinter::printMemRegImm34PCRel(const MCInst *MI, unsigned OpNo, + O << ')'; +} + +void PPCInstPrinter::printMemRegImm34PCRel(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O) { + raw_ostream &O) { printS34ImmOperand(MI, OpNo, STI, O); - O << '('; + O << '('; printImmZeroOperand(MI, OpNo + 1, STI, O); - O << ')'; -} - -void PPCInstPrinter::printMemRegImm34(const MCInst *MI, unsigned OpNo, + O << ')'; +} + +void PPCInstPrinter::printMemRegImm34(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O) { printS34ImmOperand(MI, OpNo, STI, O); - O << '('; + O << '('; printOperand(MI, OpNo + 1, STI, O); - O << ')'; -} - -void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo, + O << ')'; +} + +void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, - raw_ostream &O) { - // When used as the base register, r0 reads constant zero rather than - // the value contained in the register. For this reason, the darwin - // assembler requires that we print r0 as 0 (no r) when used as the base. - if (MI->getOperand(OpNo).getReg() == PPC::R0) - O << "0"; - else + raw_ostream &O) { + // When used as the base register, r0 reads constant zero rather than + // the value contained in the register. For this reason, the darwin + // assembler requires that we print r0 as 0 (no r) when used as the base. + if (MI->getOperand(OpNo).getReg() == PPC::R0) + O << "0"; + else printOperand(MI, OpNo, STI, O); - O << ", "; + O << ", "; printOperand(MI, OpNo + 1, STI, O); -} - -void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo, +} + +void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O) { - // On PPC64, VariantKind is VK_None, but on PPC32, it's VK_PLT, and it must - // come at the _end_ of the expression. - const MCOperand &Op = MI->getOperand(OpNo); - const MCSymbolRefExpr *RefExp = nullptr; - const MCConstantExpr *ConstExp = nullptr; - if (const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Op.getExpr())) { - RefExp = cast<MCSymbolRefExpr>(BinExpr->getLHS()); - ConstExp = cast<MCConstantExpr>(BinExpr->getRHS()); - } else - RefExp = cast<MCSymbolRefExpr>(Op.getExpr()); - - O << RefExp->getSymbol().getName(); + // On PPC64, VariantKind is VK_None, but on PPC32, it's VK_PLT, and it must + // come at the _end_ of the expression. + const MCOperand &Op = MI->getOperand(OpNo); + const MCSymbolRefExpr *RefExp = nullptr; + const MCConstantExpr *ConstExp = nullptr; + if (const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Op.getExpr())) { + RefExp = cast<MCSymbolRefExpr>(BinExpr->getLHS()); + ConstExp = cast<MCConstantExpr>(BinExpr->getRHS()); + } else + RefExp = cast<MCSymbolRefExpr>(Op.getExpr()); + + O << RefExp->getSymbol().getName(); // The variant kind VK_PPC_NOTOC needs to be handled as a special case // because we do not want the assembly to print out the @notoc at the // end like __tls_get_addr(x@tlsgd)@notoc. Instead we want it to look // like __tls_get_addr@notoc(x@tlsgd). if (RefExp->getKind() == MCSymbolRefExpr::VK_PPC_NOTOC) O << '@' << MCSymbolRefExpr::getVariantKindName(RefExp->getKind()); - O << '('; + O << '('; printOperand(MI, OpNo + 1, STI, O); - O << ')'; + O << ')'; if (RefExp->getKind() != MCSymbolRefExpr::VK_None && RefExp->getKind() != MCSymbolRefExpr::VK_PPC_NOTOC) - O << '@' << MCSymbolRefExpr::getVariantKindName(RefExp->getKind()); - if (ConstExp != nullptr) - O << '+' << ConstExp->getValue(); -} - -/// showRegistersWithPercentPrefix - Check if this register name should be -/// printed with a percentage symbol as prefix. -bool PPCInstPrinter::showRegistersWithPercentPrefix(const char *RegName) const { + O << '@' << MCSymbolRefExpr::getVariantKindName(RefExp->getKind()); + if (ConstExp != nullptr) + O << '+' << ConstExp->getValue(); +} + +/// showRegistersWithPercentPrefix - Check if this register name should be +/// printed with a percentage symbol as prefix. +bool PPCInstPrinter::showRegistersWithPercentPrefix(const char *RegName) const { if (!FullRegNamesWithPercent || TT.getOS() == Triple::AIX) - return false; - - switch (RegName[0]) { - default: - return false; - case 'r': - case 'f': - case 'q': - case 'v': - case 'c': - return true; - } -} - -/// getVerboseConditionalRegName - This method expands the condition register -/// when requested explicitly or targetting Darwin. -const char *PPCInstPrinter::getVerboseConditionRegName(unsigned RegNum, - unsigned RegEncoding) - const { + return false; + + switch (RegName[0]) { + default: + return false; + case 'r': + case 'f': + case 'q': + case 'v': + case 'c': + return true; + } +} + +/// getVerboseConditionalRegName - This method expands the condition register +/// when requested explicitly or targetting Darwin. +const char *PPCInstPrinter::getVerboseConditionRegName(unsigned RegNum, + unsigned RegEncoding) + const { if (!FullRegNames) - return nullptr; - if (RegNum < PPC::CR0EQ || RegNum > PPC::CR7UN) - return nullptr; - const char *CRBits[] = { - "lt", "gt", "eq", "un", - "4*cr1+lt", "4*cr1+gt", "4*cr1+eq", "4*cr1+un", - "4*cr2+lt", "4*cr2+gt", "4*cr2+eq", "4*cr2+un", - "4*cr3+lt", "4*cr3+gt", "4*cr3+eq", "4*cr3+un", - "4*cr4+lt", "4*cr4+gt", "4*cr4+eq", "4*cr4+un", - "4*cr5+lt", "4*cr5+gt", "4*cr5+eq", "4*cr5+un", - "4*cr6+lt", "4*cr6+gt", "4*cr6+eq", "4*cr6+un", - "4*cr7+lt", "4*cr7+gt", "4*cr7+eq", "4*cr7+un" - }; - return CRBits[RegEncoding]; -} - -// showRegistersWithPrefix - This method determines whether registers -// should be number-only or include the prefix. -bool PPCInstPrinter::showRegistersWithPrefix() const { - if (TT.getOS() == Triple::AIX) - return false; + return nullptr; + if (RegNum < PPC::CR0EQ || RegNum > PPC::CR7UN) + return nullptr; + const char *CRBits[] = { + "lt", "gt", "eq", "un", + "4*cr1+lt", "4*cr1+gt", "4*cr1+eq", "4*cr1+un", + "4*cr2+lt", "4*cr2+gt", "4*cr2+eq", "4*cr2+un", + "4*cr3+lt", "4*cr3+gt", "4*cr3+eq", "4*cr3+un", + "4*cr4+lt", "4*cr4+gt", "4*cr4+eq", "4*cr4+un", + "4*cr5+lt", "4*cr5+gt", "4*cr5+eq", "4*cr5+un", + "4*cr6+lt", "4*cr6+gt", "4*cr6+eq", "4*cr6+un", + "4*cr7+lt", "4*cr7+gt", "4*cr7+eq", "4*cr7+un" + }; + return CRBits[RegEncoding]; +} + +// showRegistersWithPrefix - This method determines whether registers +// should be number-only or include the prefix. +bool PPCInstPrinter::showRegistersWithPrefix() const { + if (TT.getOS() == Triple::AIX) + return false; return FullRegNamesWithPercent || FullRegNames; -} - -void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, +} + +void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O) { - const MCOperand &Op = MI->getOperand(OpNo); - if (Op.isReg()) { - unsigned Reg = Op.getReg(); - if (!ShowVSRNumsAsVR) - Reg = PPCInstrInfo::getRegNumForOperand(MII.get(MI->getOpcode()), - Reg, OpNo); - - const char *RegName; - RegName = getVerboseConditionRegName(Reg, MRI.getEncodingValue(Reg)); - if (RegName == nullptr) - RegName = getRegisterName(Reg); - if (showRegistersWithPercentPrefix(RegName)) - O << "%"; - if (!showRegistersWithPrefix()) - RegName = PPCRegisterInfo::stripRegisterPrefix(RegName); - - O << RegName; - return; - } - - if (Op.isImm()) { - O << Op.getImm(); - return; - } - - assert(Op.isExpr() && "unknown operand kind in printOperand"); - Op.getExpr()->print(O, &MAI); -} + const MCOperand &Op = MI->getOperand(OpNo); + if (Op.isReg()) { + unsigned Reg = Op.getReg(); + if (!ShowVSRNumsAsVR) + Reg = PPCInstrInfo::getRegNumForOperand(MII.get(MI->getOpcode()), + Reg, OpNo); + + const char *RegName; + RegName = getVerboseConditionRegName(Reg, MRI.getEncodingValue(Reg)); + if (RegName == nullptr) + RegName = getRegisterName(Reg); + if (showRegistersWithPercentPrefix(RegName)) + O << "%"; + if (!showRegistersWithPrefix()) + RegName = PPCRegisterInfo::stripRegisterPrefix(RegName); + + O << RegName; + return; + } + + if (Op.isImm()) { + O << Op.getImm(); + return; + } + + assert(Op.isExpr() && "unknown operand kind in printOperand"); + Op.getExpr()->print(O, &MAI); +} diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h index 5e9b014944..8e16f33ba5 100644 --- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h +++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h @@ -1,60 +1,60 @@ -//===- PPCInstPrinter.h - Convert PPC MCInst to assembly syntax -*- 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 -// -//===----------------------------------------------------------------------===// -// -// This class prints an PPC MCInst to a .s file. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCINSTPRINTER_H -#define LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCINSTPRINTER_H - -#include "llvm/ADT/Triple.h" -#include "llvm/MC/MCInstPrinter.h" - -namespace llvm { - -class PPCInstPrinter : public MCInstPrinter { - Triple TT; -private: - bool showRegistersWithPercentPrefix(const char *RegName) const; - bool showRegistersWithPrefix() const; - const char *getVerboseConditionRegName(unsigned RegNum, - unsigned RegEncoding) const; - -public: - PPCInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, - const MCRegisterInfo &MRI, Triple T) - : MCInstPrinter(MAI, MII, MRI), TT(T) {} - - void printRegName(raw_ostream &OS, unsigned RegNo) const override; - void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, - const MCSubtargetInfo &STI, raw_ostream &O) override; - - // Autogenerated by tblgen. +//===- PPCInstPrinter.h - Convert PPC MCInst to assembly syntax -*- 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 +// +//===----------------------------------------------------------------------===// +// +// This class prints an PPC MCInst to a .s file. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCINSTPRINTER_H +#define LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCINSTPRINTER_H + +#include "llvm/ADT/Triple.h" +#include "llvm/MC/MCInstPrinter.h" + +namespace llvm { + +class PPCInstPrinter : public MCInstPrinter { + Triple TT; +private: + bool showRegistersWithPercentPrefix(const char *RegName) const; + bool showRegistersWithPrefix() const; + const char *getVerboseConditionRegName(unsigned RegNum, + unsigned RegEncoding) const; + +public: + PPCInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, + const MCRegisterInfo &MRI, Triple T) + : MCInstPrinter(MAI, MII, MRI), TT(T) {} + + void printRegName(raw_ostream &OS, unsigned RegNo) const override; + void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, + const MCSubtargetInfo &STI, raw_ostream &O) override; + + // Autogenerated by tblgen. std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O); - static const char *getRegisterName(unsigned RegNo); - + static const char *getRegisterName(unsigned RegNo); + bool printAliasInstr(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &OS); - void printCustomAliasOperand(const MCInst *MI, uint64_t Address, - unsigned OpIdx, unsigned PrintMethodIdx, + void printCustomAliasOperand(const MCInst *MI, uint64_t Address, + unsigned OpIdx, unsigned PrintMethodIdx, const MCSubtargetInfo &STI, raw_ostream &OS); - + void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); - void printPredicateOperand(const MCInst *MI, unsigned OpNo, + void printPredicateOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O, const char *Modifier = nullptr); void printATBitsAsHint(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); - + void printU1ImmOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); void printU2ImmOperand(const MCInst *MI, unsigned OpNo, @@ -85,16 +85,16 @@ public: const MCSubtargetInfo &STI, raw_ostream &O); void printImmZeroOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); - void printBranchOperand(const MCInst *MI, uint64_t Address, unsigned OpNo, + void printBranchOperand(const MCInst *MI, uint64_t Address, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); void printAbsBranchOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); void printTLSCall(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); - + void printcrbitm(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); - + void printMemRegImm(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); void printMemRegImm34PCRel(const MCInst *MI, unsigned OpNo, @@ -103,7 +103,7 @@ public: const MCSubtargetInfo &STI, raw_ostream &O); void printMemRegReg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); -}; -} // end namespace llvm - -#endif +}; +} // end namespace llvm + +#endif diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp index 2b76af279c..3e8e3a63ec 100644 --- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp +++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp @@ -1,66 +1,66 @@ -//===-- PPCMCAsmInfo.cpp - PPC asm properties -----------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// -// -// This file contains the declarations of the MCAsmInfoDarwin properties. -// -//===----------------------------------------------------------------------===// - -#include "PPCMCAsmInfo.h" -#include "llvm/ADT/Triple.h" -#include <cassert> - -using namespace llvm; - -void PPCELFMCAsmInfo::anchor() { } - -PPCELFMCAsmInfo::PPCELFMCAsmInfo(bool is64Bit, const Triple& T) { - // FIXME: This is not always needed. For example, it is not needed in the - // v2 abi. - NeedsLocalForSize = true; - - if (is64Bit) { - CodePointerSize = CalleeSaveStackSlotSize = 8; - } +//===-- PPCMCAsmInfo.cpp - PPC asm properties -----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file contains the declarations of the MCAsmInfoDarwin properties. +// +//===----------------------------------------------------------------------===// + +#include "PPCMCAsmInfo.h" +#include "llvm/ADT/Triple.h" +#include <cassert> + +using namespace llvm; + +void PPCELFMCAsmInfo::anchor() { } + +PPCELFMCAsmInfo::PPCELFMCAsmInfo(bool is64Bit, const Triple& T) { + // FIXME: This is not always needed. For example, it is not needed in the + // v2 abi. + NeedsLocalForSize = true; + + if (is64Bit) { + CodePointerSize = CalleeSaveStackSlotSize = 8; + } IsLittleEndian = T.getArch() == Triple::ppc64le || T.getArch() == Triple::ppcle; - - // ".comm align is in bytes but .align is pow-2." - AlignmentIsInBytes = false; - - CommentString = "#"; - - // Uses '.section' before '.bss' directive - UsesELFSectionDirectiveForBSS = true; - - // Debug Information - SupportsDebugInformation = true; - - DollarIsPC = true; - - // Set up DWARF directives - MinInstAlignment = 4; - - // Exceptions handling - ExceptionsType = ExceptionHandling::DwarfCFI; - - ZeroDirective = "\t.space\t"; - Data64bitsDirective = is64Bit ? "\t.quad\t" : nullptr; - AssemblerDialect = 1; // New-Style mnemonics. - LCOMMDirectiveAlignmentType = LCOMM::ByteAlignment; -} - -void PPCXCOFFMCAsmInfo::anchor() {} - -PPCXCOFFMCAsmInfo::PPCXCOFFMCAsmInfo(bool Is64Bit, const Triple &T) { + + // ".comm align is in bytes but .align is pow-2." + AlignmentIsInBytes = false; + + CommentString = "#"; + + // Uses '.section' before '.bss' directive + UsesELFSectionDirectiveForBSS = true; + + // Debug Information + SupportsDebugInformation = true; + + DollarIsPC = true; + + // Set up DWARF directives + MinInstAlignment = 4; + + // Exceptions handling + ExceptionsType = ExceptionHandling::DwarfCFI; + + ZeroDirective = "\t.space\t"; + Data64bitsDirective = is64Bit ? "\t.quad\t" : nullptr; + AssemblerDialect = 1; // New-Style mnemonics. + LCOMMDirectiveAlignmentType = LCOMM::ByteAlignment; +} + +void PPCXCOFFMCAsmInfo::anchor() {} + +PPCXCOFFMCAsmInfo::PPCXCOFFMCAsmInfo(bool Is64Bit, const Triple &T) { if (T.getArch() == Triple::ppc64le || T.getArch() == Triple::ppcle) - report_fatal_error("XCOFF is not supported for little-endian targets"); - CodePointerSize = CalleeSaveStackSlotSize = Is64Bit ? 8 : 4; - - // A size of 8 is only supported by the assembler under 64-bit. - Data64bitsDirective = Is64Bit ? "\t.vbyte\t8, " : nullptr; -} + report_fatal_error("XCOFF is not supported for little-endian targets"); + CodePointerSize = CalleeSaveStackSlotSize = Is64Bit ? 8 : 4; + + // A size of 8 is only supported by the assembler under 64-bit. + Data64bitsDirective = Is64Bit ? "\t.vbyte\t8, " : nullptr; +} diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.h b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.h index 48806051f5..c0e2b9fb35 100644 --- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.h +++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.h @@ -1,38 +1,38 @@ -//===-- PPCMCAsmInfo.h - PPC asm properties --------------------*- 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 -// -//===----------------------------------------------------------------------===// -// -// This file contains the declarations of the PowerPC MCAsmInfo classes. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCMCASMINFO_H -#define LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCMCASMINFO_H - -#include "llvm/MC/MCAsmInfoELF.h" -#include "llvm/MC/MCAsmInfoXCOFF.h" - -namespace llvm { -class Triple; - -class PPCELFMCAsmInfo : public MCAsmInfoELF { - void anchor() override; - -public: - explicit PPCELFMCAsmInfo(bool is64Bit, const Triple &); -}; - -class PPCXCOFFMCAsmInfo : public MCAsmInfoXCOFF { - void anchor() override; - -public: - explicit PPCXCOFFMCAsmInfo(bool is64Bit, const Triple &); -}; - -} // namespace llvm - -#endif +//===-- PPCMCAsmInfo.h - PPC asm properties --------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file contains the declarations of the PowerPC MCAsmInfo classes. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCMCASMINFO_H +#define LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCMCASMINFO_H + +#include "llvm/MC/MCAsmInfoELF.h" +#include "llvm/MC/MCAsmInfoXCOFF.h" + +namespace llvm { +class Triple; + +class PPCELFMCAsmInfo : public MCAsmInfoELF { + void anchor() override; + +public: + explicit PPCELFMCAsmInfo(bool is64Bit, const Triple &); +}; + +class PPCXCOFFMCAsmInfo : public MCAsmInfoXCOFF { + void anchor() override; + +public: + explicit PPCXCOFFMCAsmInfo(bool is64Bit, const Triple &); +}; + +} // namespace llvm + +#endif diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp index 5f0769fd21..b870561393 100644 --- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp +++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp @@ -1,99 +1,99 @@ -//===-- PPCMCCodeEmitter.cpp - Convert PPC code to machine code -----------===// -// -// 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 -// -//===----------------------------------------------------------------------===// -// -// This file implements the PPCMCCodeEmitter class. -// -//===----------------------------------------------------------------------===// - -#include "MCTargetDesc/PPCFixupKinds.h" -#include "PPCInstrInfo.h" -#include "PPCMCCodeEmitter.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/Triple.h" -#include "llvm/MC/MCFixup.h" -#include "llvm/MC/MCInstrDesc.h" -#include "llvm/MC/MCRegisterInfo.h" -#include "llvm/Support/Endian.h" -#include "llvm/Support/EndianStream.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/Support/raw_ostream.h" -#include <cassert> -#include <cstdint> - -using namespace llvm; - -#define DEBUG_TYPE "mccodeemitter" - -STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); - -MCCodeEmitter *llvm::createPPCMCCodeEmitter(const MCInstrInfo &MCII, - const MCRegisterInfo &MRI, - MCContext &Ctx) { - return new PPCMCCodeEmitter(MCII, Ctx); -} - -unsigned PPCMCCodeEmitter:: -getDirectBrEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { - const MCOperand &MO = MI.getOperand(OpNo); - +//===-- PPCMCCodeEmitter.cpp - Convert PPC code to machine code -----------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file implements the PPCMCCodeEmitter class. +// +//===----------------------------------------------------------------------===// + +#include "MCTargetDesc/PPCFixupKinds.h" +#include "PPCInstrInfo.h" +#include "PPCMCCodeEmitter.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/ADT/Triple.h" +#include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCInstrDesc.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/EndianStream.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/raw_ostream.h" +#include <cassert> +#include <cstdint> + +using namespace llvm; + +#define DEBUG_TYPE "mccodeemitter" + +STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); + +MCCodeEmitter *llvm::createPPCMCCodeEmitter(const MCInstrInfo &MCII, + const MCRegisterInfo &MRI, + MCContext &Ctx) { + return new PPCMCCodeEmitter(MCII, Ctx); +} + +unsigned PPCMCCodeEmitter:: +getDirectBrEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); - // Add a fixup for the branch target. - Fixups.push_back(MCFixup::create(0, MO.getExpr(), + // Add a fixup for the branch target. + Fixups.push_back(MCFixup::create(0, MO.getExpr(), ((MI.getOpcode() == PPC::BL8_NOTOC || MI.getOpcode() == PPC::BL8_NOTOC_TLS) - ? (MCFixupKind)PPC::fixup_ppc_br24_notoc - : (MCFixupKind)PPC::fixup_ppc_br24))); - return 0; -} - -unsigned PPCMCCodeEmitter::getCondBrEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { - const MCOperand &MO = MI.getOperand(OpNo); - if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); - - // Add a fixup for the branch target. - Fixups.push_back(MCFixup::create(0, MO.getExpr(), - (MCFixupKind)PPC::fixup_ppc_brcond14)); - return 0; -} - -unsigned PPCMCCodeEmitter:: -getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { - const MCOperand &MO = MI.getOperand(OpNo); - if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); - - // Add a fixup for the branch target. - Fixups.push_back(MCFixup::create(0, MO.getExpr(), - (MCFixupKind)PPC::fixup_ppc_br24abs)); - return 0; -} - -unsigned PPCMCCodeEmitter:: -getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { - const MCOperand &MO = MI.getOperand(OpNo); - if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); - - // Add a fixup for the branch target. - Fixups.push_back(MCFixup::create(0, MO.getExpr(), - (MCFixupKind)PPC::fixup_ppc_brcond14abs)); - return 0; -} - + ? (MCFixupKind)PPC::fixup_ppc_br24_notoc + : (MCFixupKind)PPC::fixup_ppc_br24))); + return 0; +} + +unsigned PPCMCCodeEmitter::getCondBrEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); + + // Add a fixup for the branch target. + Fixups.push_back(MCFixup::create(0, MO.getExpr(), + (MCFixupKind)PPC::fixup_ppc_brcond14)); + return 0; +} + +unsigned PPCMCCodeEmitter:: +getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); + + // Add a fixup for the branch target. + Fixups.push_back(MCFixup::create(0, MO.getExpr(), + (MCFixupKind)PPC::fixup_ppc_br24abs)); + return 0; +} + +unsigned PPCMCCodeEmitter:: +getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); + + // Add a fixup for the branch target. + Fixups.push_back(MCFixup::create(0, MO.getExpr(), + (MCFixupKind)PPC::fixup_ppc_brcond14abs)); + return 0; +} + unsigned PPCMCCodeEmitter::getVSRpEvenEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, @@ -104,32 +104,32 @@ PPCMCCodeEmitter::getVSRpEvenEncoding(const MCInst &MI, unsigned OpNo, return RegBits; } -unsigned PPCMCCodeEmitter::getImm16Encoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { - const MCOperand &MO = MI.getOperand(OpNo); - if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); - - // Add a fixup for the immediate field. - Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(), - (MCFixupKind)PPC::fixup_ppc_half16)); - return 0; -} - +unsigned PPCMCCodeEmitter::getImm16Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); + + // Add a fixup for the immediate field. + Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(), + (MCFixupKind)PPC::fixup_ppc_half16)); + return 0; +} + uint64_t PPCMCCodeEmitter::getImm34Encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI, MCFixupKind Fixup) const { - const MCOperand &MO = MI.getOperand(OpNo); + const MCOperand &MO = MI.getOperand(OpNo); assert(!MO.isReg() && "Not expecting a register for this operand."); if (MO.isImm()) - return getMachineOpValue(MI, MO, Fixups, STI); - - // Add a fixup for the immediate field. + return getMachineOpValue(MI, MO, Fixups, STI); + + // Add a fixup for the immediate field. Fixups.push_back(MCFixup::create(0, MO.getExpr(), Fixup)); - return 0; -} - + return 0; +} + uint64_t PPCMCCodeEmitter::getImm34EncodingNoPCRel(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, @@ -146,101 +146,101 @@ PPCMCCodeEmitter::getImm34EncodingPCRel(const MCInst &MI, unsigned OpNo, (MCFixupKind)PPC::fixup_ppc_pcrel34); } -unsigned PPCMCCodeEmitter::getMemRIEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { - // Encode (imm, reg) as a memri, which has the low 16-bits as the - // displacement and the next 5 bits as the register #. - assert(MI.getOperand(OpNo+1).isReg()); - unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 16; - - const MCOperand &MO = MI.getOperand(OpNo); - if (MO.isImm()) - return (getMachineOpValue(MI, MO, Fixups, STI) & 0xFFFF) | RegBits; - - // Add a fixup for the displacement field. - Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(), - (MCFixupKind)PPC::fixup_ppc_half16)); - return RegBits; -} - -unsigned PPCMCCodeEmitter::getMemRIXEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { - // Encode (imm, reg) as a memrix, which has the low 14-bits as the - // displacement and the next 5 bits as the register #. - assert(MI.getOperand(OpNo+1).isReg()); - unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 14; - - const MCOperand &MO = MI.getOperand(OpNo); - if (MO.isImm()) - return ((getMachineOpValue(MI, MO, Fixups, STI) >> 2) & 0x3FFF) | RegBits; - - // Add a fixup for the displacement field. - Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(), - (MCFixupKind)PPC::fixup_ppc_half16ds)); - return RegBits; -} - -unsigned PPCMCCodeEmitter::getMemRIX16Encoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { - // Encode (imm, reg) as a memrix16, which has the low 12-bits as the - // displacement and the next 5 bits as the register #. - assert(MI.getOperand(OpNo+1).isReg()); - unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 12; - - const MCOperand &MO = MI.getOperand(OpNo); - if (MO.isImm()) { - assert(!(MO.getImm() % 16) && - "Expecting an immediate that is a multiple of 16"); - return ((getMachineOpValue(MI, MO, Fixups, STI) >> 4) & 0xFFF) | RegBits; - } - - // Otherwise add a fixup for the displacement field. - Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(), - (MCFixupKind)PPC::fixup_ppc_half16ds)); - return RegBits; -} - -uint64_t -PPCMCCodeEmitter::getMemRI34PCRelEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { - // Encode the PCRelative version of memri34: imm34(r0). - // In the PC relative version the register for the address must be zero. - // The 34 bit immediate can fall into one of three cases: - // 1) It is a relocation to be filled in by the linker represented as: - // (MCExpr::SymbolRef) - // 2) It is a relocation + SignedOffset represented as: - // (MCExpr::Binary(MCExpr::SymbolRef + MCExpr::Constant)) - // 3) It is a known value at compile time. - - // Make sure that the register is a zero as expected. - assert(MI.getOperand(OpNo + 1).isImm() && "Expecting an immediate."); - uint64_t RegBits = - getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI) << 34; - assert(RegBits == 0 && "Operand must be 0."); - - // If this is not a MCExpr then we are in case 3) and we are dealing with - // a value known at compile time, not a relocation. - const MCOperand &MO = MI.getOperand(OpNo); - if (!MO.isExpr()) - return ((getMachineOpValue(MI, MO, Fixups, STI)) & 0x3FFFFFFFFUL) | RegBits; - - // At this point in the function it is known that MO is of type MCExpr. - // Therefore we are dealing with either case 1) a symbol ref or - // case 2) a symbol ref plus a constant. - const MCExpr *Expr = MO.getExpr(); - switch (Expr->getKind()) { - default: - llvm_unreachable("Unsupported MCExpr for getMemRI34PCRelEncoding."); - case MCExpr::SymbolRef: { - // Relocation alone. - const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(Expr); - (void)SRE; - // Currently these are the only valid PCRelative Relocations. - assert((SRE->getKind() == MCSymbolRefExpr::VK_PCREL || +unsigned PPCMCCodeEmitter::getMemRIEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + // Encode (imm, reg) as a memri, which has the low 16-bits as the + // displacement and the next 5 bits as the register #. + assert(MI.getOperand(OpNo+1).isReg()); + unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 16; + + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isImm()) + return (getMachineOpValue(MI, MO, Fixups, STI) & 0xFFFF) | RegBits; + + // Add a fixup for the displacement field. + Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(), + (MCFixupKind)PPC::fixup_ppc_half16)); + return RegBits; +} + +unsigned PPCMCCodeEmitter::getMemRIXEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + // Encode (imm, reg) as a memrix, which has the low 14-bits as the + // displacement and the next 5 bits as the register #. + assert(MI.getOperand(OpNo+1).isReg()); + unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 14; + + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isImm()) + return ((getMachineOpValue(MI, MO, Fixups, STI) >> 2) & 0x3FFF) | RegBits; + + // Add a fixup for the displacement field. + Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(), + (MCFixupKind)PPC::fixup_ppc_half16ds)); + return RegBits; +} + +unsigned PPCMCCodeEmitter::getMemRIX16Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + // Encode (imm, reg) as a memrix16, which has the low 12-bits as the + // displacement and the next 5 bits as the register #. + assert(MI.getOperand(OpNo+1).isReg()); + unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 12; + + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isImm()) { + assert(!(MO.getImm() % 16) && + "Expecting an immediate that is a multiple of 16"); + return ((getMachineOpValue(MI, MO, Fixups, STI) >> 4) & 0xFFF) | RegBits; + } + + // Otherwise add a fixup for the displacement field. + Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(), + (MCFixupKind)PPC::fixup_ppc_half16ds)); + return RegBits; +} + +uint64_t +PPCMCCodeEmitter::getMemRI34PCRelEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + // Encode the PCRelative version of memri34: imm34(r0). + // In the PC relative version the register for the address must be zero. + // The 34 bit immediate can fall into one of three cases: + // 1) It is a relocation to be filled in by the linker represented as: + // (MCExpr::SymbolRef) + // 2) It is a relocation + SignedOffset represented as: + // (MCExpr::Binary(MCExpr::SymbolRef + MCExpr::Constant)) + // 3) It is a known value at compile time. + + // Make sure that the register is a zero as expected. + assert(MI.getOperand(OpNo + 1).isImm() && "Expecting an immediate."); + uint64_t RegBits = + getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI) << 34; + assert(RegBits == 0 && "Operand must be 0."); + + // If this is not a MCExpr then we are in case 3) and we are dealing with + // a value known at compile time, not a relocation. + const MCOperand &MO = MI.getOperand(OpNo); + if (!MO.isExpr()) + return ((getMachineOpValue(MI, MO, Fixups, STI)) & 0x3FFFFFFFFUL) | RegBits; + + // At this point in the function it is known that MO is of type MCExpr. + // Therefore we are dealing with either case 1) a symbol ref or + // case 2) a symbol ref plus a constant. + const MCExpr *Expr = MO.getExpr(); + switch (Expr->getKind()) { + default: + llvm_unreachable("Unsupported MCExpr for getMemRI34PCRelEncoding."); + case MCExpr::SymbolRef: { + // Relocation alone. + const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(Expr); + (void)SRE; + // Currently these are the only valid PCRelative Relocations. + assert((SRE->getKind() == MCSymbolRefExpr::VK_PCREL || SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_PCREL || SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL || SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL || @@ -248,230 +248,230 @@ PPCMCCodeEmitter::getMemRI34PCRelEncoding(const MCInst &MI, unsigned OpNo, "VariantKind must be VK_PCREL or VK_PPC_GOT_PCREL or " "VK_PPC_GOT_TLSGD_PCREL or VK_PPC_GOT_TLSLD_PCREL or " "VK_PPC_GOT_TPREL_PCREL."); - // Generate the fixup for the relocation. - Fixups.push_back( - MCFixup::create(0, Expr, - static_cast<MCFixupKind>(PPC::fixup_ppc_pcrel34))); - // Put zero in the location of the immediate. The linker will fill in the - // correct value based on the relocation. - return 0; - } - case MCExpr::Binary: { - // Relocation plus some offset. - const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr); - assert(BE->getOpcode() == MCBinaryExpr::Add && - "Binary expression opcode must be an add."); - - const MCExpr *LHS = BE->getLHS(); - const MCExpr *RHS = BE->getRHS(); - - // Need to check in both directions. Reloc+Offset and Offset+Reloc. - if (LHS->getKind() != MCExpr::SymbolRef) - std::swap(LHS, RHS); - - if (LHS->getKind() != MCExpr::SymbolRef || - RHS->getKind() != MCExpr::Constant) - llvm_unreachable("Expecting to have one constant and one relocation."); - - const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(LHS); - (void)SRE; - assert(isInt<34>(cast<MCConstantExpr>(RHS)->getValue()) && - "Value must fit in 34 bits."); - - // Currently these are the only valid PCRelative Relocations. - assert((SRE->getKind() == MCSymbolRefExpr::VK_PCREL || - SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_PCREL) && - "VariantKind must be VK_PCREL or VK_PPC_GOT_PCREL"); - // Generate the fixup for the relocation. - Fixups.push_back( - MCFixup::create(0, Expr, - static_cast<MCFixupKind>(PPC::fixup_ppc_pcrel34))); - // Put zero in the location of the immediate. The linker will fill in the - // correct value based on the relocation. - return 0; - } - } -} - -uint64_t -PPCMCCodeEmitter::getMemRI34Encoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { - // Encode (imm, reg) as a memri34, which has the low 34-bits as the - // displacement and the next 5 bits as the register #. - assert(MI.getOperand(OpNo + 1).isReg() && "Expecting a register."); - uint64_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI) - << 34; - const MCOperand &MO = MI.getOperand(OpNo); - return ((getMachineOpValue(MI, MO, Fixups, STI)) & 0x3FFFFFFFFUL) | RegBits; -} - -unsigned PPCMCCodeEmitter::getSPE8DisEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) - const { - // Encode (imm, reg) as a spe8dis, which has the low 5-bits of (imm / 8) - // as the displacement and the next 5 bits as the register #. - assert(MI.getOperand(OpNo+1).isReg()); - uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 5; - - const MCOperand &MO = MI.getOperand(OpNo); - assert(MO.isImm()); - uint32_t Imm = getMachineOpValue(MI, MO, Fixups, STI) >> 3; - return reverseBits(Imm | RegBits) >> 22; -} - -unsigned PPCMCCodeEmitter::getSPE4DisEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) - const { - // Encode (imm, reg) as a spe4dis, which has the low 5-bits of (imm / 4) - // as the displacement and the next 5 bits as the register #. - assert(MI.getOperand(OpNo+1).isReg()); - uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 5; - - const MCOperand &MO = MI.getOperand(OpNo); - assert(MO.isImm()); - uint32_t Imm = getMachineOpValue(MI, MO, Fixups, STI) >> 2; - return reverseBits(Imm | RegBits) >> 22; -} - -unsigned PPCMCCodeEmitter::getSPE2DisEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) - const { - // Encode (imm, reg) as a spe2dis, which has the low 5-bits of (imm / 2) - // as the displacement and the next 5 bits as the register #. - assert(MI.getOperand(OpNo+1).isReg()); - uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 5; - - const MCOperand &MO = MI.getOperand(OpNo); - assert(MO.isImm()); - uint32_t Imm = getMachineOpValue(MI, MO, Fixups, STI) >> 1; - return reverseBits(Imm | RegBits) >> 22; -} - -unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { - const MCOperand &MO = MI.getOperand(OpNo); - if (MO.isReg()) return getMachineOpValue(MI, MO, Fixups, STI); - - // Add a fixup for the TLS register, which simply provides a relocation - // hint to the linker that this statement is part of a relocation sequence. + // Generate the fixup for the relocation. + Fixups.push_back( + MCFixup::create(0, Expr, + static_cast<MCFixupKind>(PPC::fixup_ppc_pcrel34))); + // Put zero in the location of the immediate. The linker will fill in the + // correct value based on the relocation. + return 0; + } + case MCExpr::Binary: { + // Relocation plus some offset. + const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr); + assert(BE->getOpcode() == MCBinaryExpr::Add && + "Binary expression opcode must be an add."); + + const MCExpr *LHS = BE->getLHS(); + const MCExpr *RHS = BE->getRHS(); + + // Need to check in both directions. Reloc+Offset and Offset+Reloc. + if (LHS->getKind() != MCExpr::SymbolRef) + std::swap(LHS, RHS); + + if (LHS->getKind() != MCExpr::SymbolRef || + RHS->getKind() != MCExpr::Constant) + llvm_unreachable("Expecting to have one constant and one relocation."); + + const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(LHS); + (void)SRE; + assert(isInt<34>(cast<MCConstantExpr>(RHS)->getValue()) && + "Value must fit in 34 bits."); + + // Currently these are the only valid PCRelative Relocations. + assert((SRE->getKind() == MCSymbolRefExpr::VK_PCREL || + SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_PCREL) && + "VariantKind must be VK_PCREL or VK_PPC_GOT_PCREL"); + // Generate the fixup for the relocation. + Fixups.push_back( + MCFixup::create(0, Expr, + static_cast<MCFixupKind>(PPC::fixup_ppc_pcrel34))); + // Put zero in the location of the immediate. The linker will fill in the + // correct value based on the relocation. + return 0; + } + } +} + +uint64_t +PPCMCCodeEmitter::getMemRI34Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + // Encode (imm, reg) as a memri34, which has the low 34-bits as the + // displacement and the next 5 bits as the register #. + assert(MI.getOperand(OpNo + 1).isReg() && "Expecting a register."); + uint64_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI) + << 34; + const MCOperand &MO = MI.getOperand(OpNo); + return ((getMachineOpValue(MI, MO, Fixups, STI)) & 0x3FFFFFFFFUL) | RegBits; +} + +unsigned PPCMCCodeEmitter::getSPE8DisEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) + const { + // Encode (imm, reg) as a spe8dis, which has the low 5-bits of (imm / 8) + // as the displacement and the next 5 bits as the register #. + assert(MI.getOperand(OpNo+1).isReg()); + uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 5; + + const MCOperand &MO = MI.getOperand(OpNo); + assert(MO.isImm()); + uint32_t Imm = getMachineOpValue(MI, MO, Fixups, STI) >> 3; + return reverseBits(Imm | RegBits) >> 22; +} + +unsigned PPCMCCodeEmitter::getSPE4DisEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) + const { + // Encode (imm, reg) as a spe4dis, which has the low 5-bits of (imm / 4) + // as the displacement and the next 5 bits as the register #. + assert(MI.getOperand(OpNo+1).isReg()); + uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 5; + + const MCOperand &MO = MI.getOperand(OpNo); + assert(MO.isImm()); + uint32_t Imm = getMachineOpValue(MI, MO, Fixups, STI) >> 2; + return reverseBits(Imm | RegBits) >> 22; +} + +unsigned PPCMCCodeEmitter::getSPE2DisEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) + const { + // Encode (imm, reg) as a spe2dis, which has the low 5-bits of (imm / 2) + // as the displacement and the next 5 bits as the register #. + assert(MI.getOperand(OpNo+1).isReg()); + uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 5; + + const MCOperand &MO = MI.getOperand(OpNo); + assert(MO.isImm()); + uint32_t Imm = getMachineOpValue(MI, MO, Fixups, STI) >> 1; + return reverseBits(Imm | RegBits) >> 22; +} + +unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isReg()) return getMachineOpValue(MI, MO, Fixups, STI); + + // Add a fixup for the TLS register, which simply provides a relocation + // hint to the linker that this statement is part of a relocation sequence. // Return the thread-pointer register's encoding. Add a one byte displacement // if using PC relative memops. const MCExpr *Expr = MO.getExpr(); const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(Expr); bool IsPCRel = SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS_PCREL; Fixups.push_back(MCFixup::create(IsPCRel ? 1 : 0, Expr, - (MCFixupKind)PPC::fixup_ppc_nofixup)); - const Triple &TT = STI.getTargetTriple(); - bool isPPC64 = TT.isPPC64(); - return CTX.getRegisterInfo()->getEncodingValue(isPPC64 ? PPC::X13 : PPC::R2); -} - -unsigned PPCMCCodeEmitter::getTLSCallEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { - // For special TLS calls, we need two fixups; one for the branch target - // (__tls_get_addr), which we create via getDirectBrEncoding as usual, - // and one for the TLSGD or TLSLD symbol, which is emitted here. - const MCOperand &MO = MI.getOperand(OpNo+1); - Fixups.push_back(MCFixup::create(0, MO.getExpr(), - (MCFixupKind)PPC::fixup_ppc_nofixup)); - return getDirectBrEncoding(MI, OpNo, Fixups, STI); -} - -unsigned PPCMCCodeEmitter:: -get_crbitm_encoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { - const MCOperand &MO = MI.getOperand(OpNo); - assert((MI.getOpcode() == PPC::MTOCRF || MI.getOpcode() == PPC::MTOCRF8 || - MI.getOpcode() == PPC::MFOCRF || MI.getOpcode() == PPC::MFOCRF8) && - (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7)); - return 0x80 >> CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); -} - -// Get the index for this operand in this instruction. This is needed for -// computing the register number in PPCInstrInfo::getRegNumForOperand() for -// any instructions that use a different numbering scheme for registers in -// different operands. -static unsigned getOpIdxForMO(const MCInst &MI, const MCOperand &MO) { - for (unsigned i = 0; i < MI.getNumOperands(); i++) { - const MCOperand &Op = MI.getOperand(i); - if (&Op == &MO) - return i; - } - llvm_unreachable("This operand is not part of this instruction"); - return ~0U; // Silence any warnings about no return. -} - -uint64_t PPCMCCodeEmitter:: -getMachineOpValue(const MCInst &MI, const MCOperand &MO, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { - if (MO.isReg()) { - // MTOCRF/MFOCRF should go through get_crbitm_encoding for the CR operand. - // The GPR operand should come through here though. - assert((MI.getOpcode() != PPC::MTOCRF && MI.getOpcode() != PPC::MTOCRF8 && - MI.getOpcode() != PPC::MFOCRF && MI.getOpcode() != PPC::MFOCRF8) || - MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7); - unsigned OpNo = getOpIdxForMO(MI, MO); - unsigned Reg = - PPCInstrInfo::getRegNumForOperand(MCII.get(MI.getOpcode()), - MO.getReg(), OpNo); - return CTX.getRegisterInfo()->getEncodingValue(Reg); - } - - assert(MO.isImm() && - "Relocation required in an instruction that we cannot encode!"); - return MO.getImm(); -} - -void PPCMCCodeEmitter::encodeInstruction( - const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { - verifyInstructionPredicates(MI, - computeAvailableFeatures(STI.getFeatureBits())); - - uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); - - // Output the constant in big/little endian byte order. - unsigned Size = getInstSizeInBytes(MI); - support::endianness E = IsLittleEndian ? support::little : support::big; - switch (Size) { - case 0: - break; - case 4: - support::endian::write<uint32_t>(OS, Bits, E); - break; - case 8: - // If we emit a pair of instructions, the first one is - // always in the top 32 bits, even on little-endian. - support::endian::write<uint32_t>(OS, Bits >> 32, E); - support::endian::write<uint32_t>(OS, Bits, E); - break; - default: - llvm_unreachable("Invalid instruction size"); - } - - ++MCNumEmitted; // Keep track of the # of mi's emitted. -} - -// Get the number of bytes used to encode the given MCInst. -unsigned PPCMCCodeEmitter::getInstSizeInBytes(const MCInst &MI) const { - unsigned Opcode = MI.getOpcode(); - const MCInstrDesc &Desc = MCII.get(Opcode); - return Desc.getSize(); -} - -bool PPCMCCodeEmitter::isPrefixedInstruction(const MCInst &MI) const { - unsigned Opcode = MI.getOpcode(); - const PPCInstrInfo *InstrInfo = static_cast<const PPCInstrInfo*>(&MCII); - return InstrInfo->isPrefixed(Opcode); -} - -#define ENABLE_INSTR_PREDICATE_VERIFIER -#include "PPCGenMCCodeEmitter.inc" + (MCFixupKind)PPC::fixup_ppc_nofixup)); + const Triple &TT = STI.getTargetTriple(); + bool isPPC64 = TT.isPPC64(); + return CTX.getRegisterInfo()->getEncodingValue(isPPC64 ? PPC::X13 : PPC::R2); +} + +unsigned PPCMCCodeEmitter::getTLSCallEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + // For special TLS calls, we need two fixups; one for the branch target + // (__tls_get_addr), which we create via getDirectBrEncoding as usual, + // and one for the TLSGD or TLSLD symbol, which is emitted here. + const MCOperand &MO = MI.getOperand(OpNo+1); + Fixups.push_back(MCFixup::create(0, MO.getExpr(), + (MCFixupKind)PPC::fixup_ppc_nofixup)); + return getDirectBrEncoding(MI, OpNo, Fixups, STI); +} + +unsigned PPCMCCodeEmitter:: +get_crbitm_encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + assert((MI.getOpcode() == PPC::MTOCRF || MI.getOpcode() == PPC::MTOCRF8 || + MI.getOpcode() == PPC::MFOCRF || MI.getOpcode() == PPC::MFOCRF8) && + (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7)); + return 0x80 >> CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); +} + +// Get the index for this operand in this instruction. This is needed for +// computing the register number in PPCInstrInfo::getRegNumForOperand() for +// any instructions that use a different numbering scheme for registers in +// different operands. +static unsigned getOpIdxForMO(const MCInst &MI, const MCOperand &MO) { + for (unsigned i = 0; i < MI.getNumOperands(); i++) { + const MCOperand &Op = MI.getOperand(i); + if (&Op == &MO) + return i; + } + llvm_unreachable("This operand is not part of this instruction"); + return ~0U; // Silence any warnings about no return. +} + +uint64_t PPCMCCodeEmitter:: +getMachineOpValue(const MCInst &MI, const MCOperand &MO, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + if (MO.isReg()) { + // MTOCRF/MFOCRF should go through get_crbitm_encoding for the CR operand. + // The GPR operand should come through here though. + assert((MI.getOpcode() != PPC::MTOCRF && MI.getOpcode() != PPC::MTOCRF8 && + MI.getOpcode() != PPC::MFOCRF && MI.getOpcode() != PPC::MFOCRF8) || + MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7); + unsigned OpNo = getOpIdxForMO(MI, MO); + unsigned Reg = + PPCInstrInfo::getRegNumForOperand(MCII.get(MI.getOpcode()), + MO.getReg(), OpNo); + return CTX.getRegisterInfo()->getEncodingValue(Reg); + } + + assert(MO.isImm() && + "Relocation required in an instruction that we cannot encode!"); + return MO.getImm(); +} + +void PPCMCCodeEmitter::encodeInstruction( + const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + verifyInstructionPredicates(MI, + computeAvailableFeatures(STI.getFeatureBits())); + + uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); + + // Output the constant in big/little endian byte order. + unsigned Size = getInstSizeInBytes(MI); + support::endianness E = IsLittleEndian ? support::little : support::big; + switch (Size) { + case 0: + break; + case 4: + support::endian::write<uint32_t>(OS, Bits, E); + break; + case 8: + // If we emit a pair of instructions, the first one is + // always in the top 32 bits, even on little-endian. + support::endian::write<uint32_t>(OS, Bits >> 32, E); + support::endian::write<uint32_t>(OS, Bits, E); + break; + default: + llvm_unreachable("Invalid instruction size"); + } + + ++MCNumEmitted; // Keep track of the # of mi's emitted. +} + +// Get the number of bytes used to encode the given MCInst. +unsigned PPCMCCodeEmitter::getInstSizeInBytes(const MCInst &MI) const { + unsigned Opcode = MI.getOpcode(); + const MCInstrDesc &Desc = MCII.get(Opcode); + return Desc.getSize(); +} + +bool PPCMCCodeEmitter::isPrefixedInstruction(const MCInst &MI) const { + unsigned Opcode = MI.getOpcode(); + const PPCInstrInfo *InstrInfo = static_cast<const PPCInstrInfo*>(&MCII); + return InstrInfo->isPrefixed(Opcode); +} + +#define ENABLE_INSTR_PREDICATE_VERIFIER +#include "PPCGenMCCodeEmitter.inc" diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h index 347e163c95..cf14a6010d 100644 --- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h +++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h @@ -1,57 +1,57 @@ -//===-- PPCMCCodeEmitter.h - Convert PPC code to machine code -------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// -// -// This file implements the PPCMCCodeEmitter class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_TARGET_PPC_MCCODEEMITTER_PPCCODEEMITTER_H -#define LLVM_LIB_TARGET_PPC_MCCODEEMITTER_PPCCODEEMITTER_H - -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCCodeEmitter.h" -#include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/MC/MCInstrInfo.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCInst.h" - -namespace llvm { - -class PPCMCCodeEmitter : public MCCodeEmitter { - const MCInstrInfo &MCII; - const MCContext &CTX; - bool IsLittleEndian; - -public: - PPCMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx) - : MCII(mcii), CTX(ctx), - IsLittleEndian(ctx.getAsmInfo()->isLittleEndian()) {} - PPCMCCodeEmitter(const PPCMCCodeEmitter &) = delete; - void operator=(const PPCMCCodeEmitter &) = delete; - ~PPCMCCodeEmitter() override = default; - - unsigned getDirectBrEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; - unsigned getCondBrEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; - unsigned getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; - unsigned getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; - unsigned getImm16Encoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; - uint64_t getImm34Encoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, +//===-- PPCMCCodeEmitter.h - Convert PPC code to machine code -------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file implements the PPCMCCodeEmitter class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_PPC_MCCODEEMITTER_PPCCODEEMITTER_H +#define LLVM_LIB_TARGET_PPC_MCCODEEMITTER_PPCCODEEMITTER_H + +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCInst.h" + +namespace llvm { + +class PPCMCCodeEmitter : public MCCodeEmitter { + const MCInstrInfo &MCII; + const MCContext &CTX; + bool IsLittleEndian; + +public: + PPCMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx) + : MCII(mcii), CTX(ctx), + IsLittleEndian(ctx.getAsmInfo()->isLittleEndian()) {} + PPCMCCodeEmitter(const PPCMCCodeEmitter &) = delete; + void operator=(const PPCMCCodeEmitter &) = delete; + ~PPCMCCodeEmitter() override = default; + + unsigned getDirectBrEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getCondBrEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getImm16Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + uint64_t getImm34Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI, MCFixupKind Fixup) const; uint64_t getImm34EncodingNoPCRel(const MCInst &MI, unsigned OpNo, @@ -60,72 +60,72 @@ public: uint64_t getImm34EncodingPCRel(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const; - unsigned getMemRIEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; - unsigned getMemRIXEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; - unsigned getMemRIX16Encoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; - uint64_t getMemRI34PCRelEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; - uint64_t getMemRI34Encoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; - unsigned getSPE8DisEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; - unsigned getSPE4DisEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; - unsigned getSPE2DisEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; - unsigned getTLSRegEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; - unsigned getTLSCallEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; - unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; + unsigned getMemRIEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getMemRIXEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getMemRIX16Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + uint64_t getMemRI34PCRelEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + uint64_t getMemRI34Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getSPE8DisEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getSPE4DisEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getSPE2DisEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getTLSRegEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getTLSCallEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; unsigned getVSRpEvenEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const; - - /// getMachineOpValue - Return binary encoding of operand. If the machine - /// operand requires relocation, record the relocation and return zero. - uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; - - // getBinaryCodeForInstr - TableGen'erated function for getting the - // binary encoding for an instruction. - uint64_t getBinaryCodeForInstr(const MCInst &MI, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; - - void encodeInstruction(const MCInst &MI, raw_ostream &OS, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const override; - - // Get the number of bytes used to encode the given MCInst. - unsigned getInstSizeInBytes(const MCInst &MI) const; - - // Is this instruction a prefixed instruction. - bool isPrefixedInstruction(const MCInst &MI) const; - -private: - FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const; - void - verifyInstructionPredicates(const MCInst &MI, - const FeatureBitset &AvailableFeatures) const; -}; - -} // namespace llvm - -#endif // LLVM_LIB_TARGET_PPC_MCCODEEMITTER_PPCCODEEMITTER_H + + /// getMachineOpValue - Return binary encoding of operand. If the machine + /// operand requires relocation, record the relocation and return zero. + uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + + // getBinaryCodeForInstr - TableGen'erated function for getting the + // binary encoding for an instruction. + uint64_t getBinaryCodeForInstr(const MCInst &MI, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + + void encodeInstruction(const MCInst &MI, raw_ostream &OS, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const override; + + // Get the number of bytes used to encode the given MCInst. + unsigned getInstSizeInBytes(const MCInst &MI) const; + + // Is this instruction a prefixed instruction. + bool isPrefixedInstruction(const MCInst &MI) const; + +private: + FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const; + void + verifyInstructionPredicates(const MCInst &MI, + const FeatureBitset &AvailableFeatures) const; +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_PPC_MCCODEEMITTER_PPCCODEEMITTER_H diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp index abff444491..e77c6d9b3d 100644 --- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp +++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp @@ -1,166 +1,166 @@ -//===-- PPCMCExpr.cpp - PPC specific MC expression classes ----------------===// -// -// 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 "PPCMCExpr.h" -#include "PPCFixupKinds.h" -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCAssembler.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCObjectStreamer.h" - -using namespace llvm; - -#define DEBUG_TYPE "ppcmcexpr" - -const PPCMCExpr *PPCMCExpr::create(VariantKind Kind, const MCExpr *Expr, - MCContext &Ctx) { - return new (Ctx) PPCMCExpr(Kind, Expr); -} - -void PPCMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { - getSubExpr()->print(OS, MAI); - - switch (Kind) { - default: - llvm_unreachable("Invalid kind!"); - case VK_PPC_LO: - OS << "@l"; - break; - case VK_PPC_HI: - OS << "@h"; - break; - case VK_PPC_HA: - OS << "@ha"; - break; - case VK_PPC_HIGH: - OS << "@high"; - break; - case VK_PPC_HIGHA: - OS << "@higha"; - break; - case VK_PPC_HIGHER: - OS << "@higher"; - break; - case VK_PPC_HIGHERA: - OS << "@highera"; - break; - case VK_PPC_HIGHEST: - OS << "@highest"; - break; - case VK_PPC_HIGHESTA: - OS << "@highesta"; - break; - } -} - -bool -PPCMCExpr::evaluateAsConstant(int64_t &Res) const { - MCValue Value; - - if (!getSubExpr()->evaluateAsRelocatable(Value, nullptr, nullptr)) - return false; - - if (!Value.isAbsolute()) - return false; - - Res = evaluateAsInt64(Value.getConstant()); - return true; -} - -int64_t -PPCMCExpr::evaluateAsInt64(int64_t Value) const { - switch (Kind) { - case VK_PPC_LO: - return Value & 0xffff; - case VK_PPC_HI: - return (Value >> 16) & 0xffff; - case VK_PPC_HA: - return ((Value + 0x8000) >> 16) & 0xffff; - case VK_PPC_HIGH: - return (Value >> 16) & 0xffff; - case VK_PPC_HIGHA: - return ((Value + 0x8000) >> 16) & 0xffff; - case VK_PPC_HIGHER: - return (Value >> 32) & 0xffff; - case VK_PPC_HIGHERA: - return ((Value + 0x8000) >> 32) & 0xffff; - case VK_PPC_HIGHEST: - return (Value >> 48) & 0xffff; - case VK_PPC_HIGHESTA: - return ((Value + 0x8000) >> 48) & 0xffff; - case VK_PPC_None: - break; - } - llvm_unreachable("Invalid kind!"); -} - -bool -PPCMCExpr::evaluateAsRelocatableImpl(MCValue &Res, - const MCAsmLayout *Layout, - const MCFixup *Fixup) const { - MCValue Value; - - if (!getSubExpr()->evaluateAsRelocatable(Value, Layout, Fixup)) - return false; - - if (Value.isAbsolute()) { - int64_t Result = evaluateAsInt64(Value.getConstant()); - if ((Fixup == nullptr || (unsigned)Fixup->getKind() != PPC::fixup_ppc_half16) && - (Result >= 0x8000)) - return false; - Res = MCValue::get(Result); - } else { - if (!Layout) - return false; - - MCContext &Context = Layout->getAssembler().getContext(); - const MCSymbolRefExpr *Sym = Value.getSymA(); - MCSymbolRefExpr::VariantKind Modifier = Sym->getKind(); - if (Modifier != MCSymbolRefExpr::VK_None) - return false; - switch (Kind) { - default: - llvm_unreachable("Invalid kind!"); - case VK_PPC_LO: - Modifier = MCSymbolRefExpr::VK_PPC_LO; - break; - case VK_PPC_HI: - Modifier = MCSymbolRefExpr::VK_PPC_HI; - break; - case VK_PPC_HA: - Modifier = MCSymbolRefExpr::VK_PPC_HA; - break; - case VK_PPC_HIGH: - Modifier = MCSymbolRefExpr::VK_PPC_HIGH; - break; - case VK_PPC_HIGHA: - Modifier = MCSymbolRefExpr::VK_PPC_HIGHA; - break; - case VK_PPC_HIGHERA: - Modifier = MCSymbolRefExpr::VK_PPC_HIGHERA; - break; - case VK_PPC_HIGHER: - Modifier = MCSymbolRefExpr::VK_PPC_HIGHER; - break; - case VK_PPC_HIGHEST: - Modifier = MCSymbolRefExpr::VK_PPC_HIGHEST; - break; - case VK_PPC_HIGHESTA: - Modifier = MCSymbolRefExpr::VK_PPC_HIGHESTA; - break; - } - Sym = MCSymbolRefExpr::create(&Sym->getSymbol(), Modifier, Context); - Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant()); - } - - return true; -} - -void PPCMCExpr::visitUsedExpr(MCStreamer &Streamer) const { - Streamer.visitUsedExpr(*getSubExpr()); -} +//===-- PPCMCExpr.cpp - PPC specific MC expression classes ----------------===// +// +// 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 "PPCMCExpr.h" +#include "PPCFixupKinds.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCObjectStreamer.h" + +using namespace llvm; + +#define DEBUG_TYPE "ppcmcexpr" + +const PPCMCExpr *PPCMCExpr::create(VariantKind Kind, const MCExpr *Expr, + MCContext &Ctx) { + return new (Ctx) PPCMCExpr(Kind, Expr); +} + +void PPCMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { + getSubExpr()->print(OS, MAI); + + switch (Kind) { + default: + llvm_unreachable("Invalid kind!"); + case VK_PPC_LO: + OS << "@l"; + break; + case VK_PPC_HI: + OS << "@h"; + break; + case VK_PPC_HA: + OS << "@ha"; + break; + case VK_PPC_HIGH: + OS << "@high"; + break; + case VK_PPC_HIGHA: + OS << "@higha"; + break; + case VK_PPC_HIGHER: + OS << "@higher"; + break; + case VK_PPC_HIGHERA: + OS << "@highera"; + break; + case VK_PPC_HIGHEST: + OS << "@highest"; + break; + case VK_PPC_HIGHESTA: + OS << "@highesta"; + break; + } +} + +bool +PPCMCExpr::evaluateAsConstant(int64_t &Res) const { + MCValue Value; + + if (!getSubExpr()->evaluateAsRelocatable(Value, nullptr, nullptr)) + return false; + + if (!Value.isAbsolute()) + return false; + + Res = evaluateAsInt64(Value.getConstant()); + return true; +} + +int64_t +PPCMCExpr::evaluateAsInt64(int64_t Value) const { + switch (Kind) { + case VK_PPC_LO: + return Value & 0xffff; + case VK_PPC_HI: + return (Value >> 16) & 0xffff; + case VK_PPC_HA: + return ((Value + 0x8000) >> 16) & 0xffff; + case VK_PPC_HIGH: + return (Value >> 16) & 0xffff; + case VK_PPC_HIGHA: + return ((Value + 0x8000) >> 16) & 0xffff; + case VK_PPC_HIGHER: + return (Value >> 32) & 0xffff; + case VK_PPC_HIGHERA: + return ((Value + 0x8000) >> 32) & 0xffff; + case VK_PPC_HIGHEST: + return (Value >> 48) & 0xffff; + case VK_PPC_HIGHESTA: + return ((Value + 0x8000) >> 48) & 0xffff; + case VK_PPC_None: + break; + } + llvm_unreachable("Invalid kind!"); +} + +bool +PPCMCExpr::evaluateAsRelocatableImpl(MCValue &Res, + const MCAsmLayout *Layout, + const MCFixup *Fixup) const { + MCValue Value; + + if (!getSubExpr()->evaluateAsRelocatable(Value, Layout, Fixup)) + return false; + + if (Value.isAbsolute()) { + int64_t Result = evaluateAsInt64(Value.getConstant()); + if ((Fixup == nullptr || (unsigned)Fixup->getKind() != PPC::fixup_ppc_half16) && + (Result >= 0x8000)) + return false; + Res = MCValue::get(Result); + } else { + if (!Layout) + return false; + + MCContext &Context = Layout->getAssembler().getContext(); + const MCSymbolRefExpr *Sym = Value.getSymA(); + MCSymbolRefExpr::VariantKind Modifier = Sym->getKind(); + if (Modifier != MCSymbolRefExpr::VK_None) + return false; + switch (Kind) { + default: + llvm_unreachable("Invalid kind!"); + case VK_PPC_LO: + Modifier = MCSymbolRefExpr::VK_PPC_LO; + break; + case VK_PPC_HI: + Modifier = MCSymbolRefExpr::VK_PPC_HI; + break; + case VK_PPC_HA: + Modifier = MCSymbolRefExpr::VK_PPC_HA; + break; + case VK_PPC_HIGH: + Modifier = MCSymbolRefExpr::VK_PPC_HIGH; + break; + case VK_PPC_HIGHA: + Modifier = MCSymbolRefExpr::VK_PPC_HIGHA; + break; + case VK_PPC_HIGHERA: + Modifier = MCSymbolRefExpr::VK_PPC_HIGHERA; + break; + case VK_PPC_HIGHER: + Modifier = MCSymbolRefExpr::VK_PPC_HIGHER; + break; + case VK_PPC_HIGHEST: + Modifier = MCSymbolRefExpr::VK_PPC_HIGHEST; + break; + case VK_PPC_HIGHESTA: + Modifier = MCSymbolRefExpr::VK_PPC_HIGHESTA; + break; + } + Sym = MCSymbolRefExpr::create(&Sym->getSymbol(), Modifier, Context); + Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant()); + } + + return true; +} + +void PPCMCExpr::visitUsedExpr(MCStreamer &Streamer) const { + Streamer.visitUsedExpr(*getSubExpr()); +} diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h index 1dbc7eae63..bd5a54ce5a 100644 --- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h +++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h @@ -1,93 +1,93 @@ -//===-- PPCMCExpr.h - PPC specific MC expression classes --------*- 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCMCEXPR_H -#define LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCMCEXPR_H - -#include "llvm/MC/MCAsmLayout.h" -#include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCValue.h" - -namespace llvm { - -class PPCMCExpr : public MCTargetExpr { -public: - enum VariantKind { - VK_PPC_None, - VK_PPC_LO, - VK_PPC_HI, - VK_PPC_HA, - VK_PPC_HIGH, - VK_PPC_HIGHA, - VK_PPC_HIGHER, - VK_PPC_HIGHERA, - VK_PPC_HIGHEST, - VK_PPC_HIGHESTA - }; - -private: - const VariantKind Kind; - const MCExpr *Expr; - - int64_t evaluateAsInt64(int64_t Value) const; - - explicit PPCMCExpr(VariantKind Kind, const MCExpr *Expr) - : Kind(Kind), Expr(Expr) {} - -public: - /// @name Construction - /// @{ - - static const PPCMCExpr *create(VariantKind Kind, const MCExpr *Expr, - MCContext &Ctx); - - static const PPCMCExpr *createLo(const MCExpr *Expr, MCContext &Ctx) { - return create(VK_PPC_LO, Expr, Ctx); - } - - static const PPCMCExpr *createHi(const MCExpr *Expr, MCContext &Ctx) { - return create(VK_PPC_HI, Expr, Ctx); - } - - static const PPCMCExpr *createHa(const MCExpr *Expr, MCContext &Ctx) { - return create(VK_PPC_HA, Expr, Ctx); - } - - /// @} - /// @name Accessors - /// @{ - - /// getOpcode - Get the kind of this expression. - VariantKind getKind() const { return Kind; } - - /// getSubExpr - Get the child of this expression. - const MCExpr *getSubExpr() const { return Expr; } - - /// @} - - void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override; - bool evaluateAsRelocatableImpl(MCValue &Res, - const MCAsmLayout *Layout, - const MCFixup *Fixup) const override; - void visitUsedExpr(MCStreamer &Streamer) const override; - MCFragment *findAssociatedFragment() const override { - return getSubExpr()->findAssociatedFragment(); - } - - // There are no TLS PPCMCExprs at the moment. - void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override {} - - bool evaluateAsConstant(int64_t &Res) const; - - static bool classof(const MCExpr *E) { - return E->getKind() == MCExpr::Target; - } -}; -} // end namespace llvm - -#endif +//===-- PPCMCExpr.h - PPC specific MC expression classes --------*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCMCEXPR_H +#define LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCMCEXPR_H + +#include "llvm/MC/MCAsmLayout.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCValue.h" + +namespace llvm { + +class PPCMCExpr : public MCTargetExpr { +public: + enum VariantKind { + VK_PPC_None, + VK_PPC_LO, + VK_PPC_HI, + VK_PPC_HA, + VK_PPC_HIGH, + VK_PPC_HIGHA, + VK_PPC_HIGHER, + VK_PPC_HIGHERA, + VK_PPC_HIGHEST, + VK_PPC_HIGHESTA + }; + +private: + const VariantKind Kind; + const MCExpr *Expr; + + int64_t evaluateAsInt64(int64_t Value) const; + + explicit PPCMCExpr(VariantKind Kind, const MCExpr *Expr) + : Kind(Kind), Expr(Expr) {} + +public: + /// @name Construction + /// @{ + + static const PPCMCExpr *create(VariantKind Kind, const MCExpr *Expr, + MCContext &Ctx); + + static const PPCMCExpr *createLo(const MCExpr *Expr, MCContext &Ctx) { + return create(VK_PPC_LO, Expr, Ctx); + } + + static const PPCMCExpr *createHi(const MCExpr *Expr, MCContext &Ctx) { + return create(VK_PPC_HI, Expr, Ctx); + } + + static const PPCMCExpr *createHa(const MCExpr *Expr, MCContext &Ctx) { + return create(VK_PPC_HA, Expr, Ctx); + } + + /// @} + /// @name Accessors + /// @{ + + /// getOpcode - Get the kind of this expression. + VariantKind getKind() const { return Kind; } + + /// getSubExpr - Get the child of this expression. + const MCExpr *getSubExpr() const { return Expr; } + + /// @} + + void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override; + bool evaluateAsRelocatableImpl(MCValue &Res, + const MCAsmLayout *Layout, + const MCFixup *Fixup) const override; + void visitUsedExpr(MCStreamer &Streamer) const override; + MCFragment *findAssociatedFragment() const override { + return getSubExpr()->findAssociatedFragment(); + } + + // There are no TLS PPCMCExprs at the moment. + void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override {} + + bool evaluateAsConstant(int64_t &Res) const; + + static bool classof(const MCExpr *E) { + return E->getKind() == MCExpr::Target; + } +}; +} // end namespace llvm + +#endif diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp index bf9c6feb54..1e5d97d78a 100644 --- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp +++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp @@ -1,83 +1,83 @@ -//===-- PPCMCTargetDesc.cpp - PowerPC Target Descriptions -----------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// -// -// This file provides PowerPC specific target descriptions. -// -//===----------------------------------------------------------------------===// - -#include "MCTargetDesc/PPCMCTargetDesc.h" -#include "MCTargetDesc/PPCInstPrinter.h" -#include "MCTargetDesc/PPCMCAsmInfo.h" -#include "PPCELFStreamer.h" -#include "PPCTargetStreamer.h" -#include "TargetInfo/PowerPCTargetInfo.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Triple.h" -#include "llvm/BinaryFormat/ELF.h" +//===-- PPCMCTargetDesc.cpp - PowerPC Target Descriptions -----------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file provides PowerPC specific target descriptions. +// +//===----------------------------------------------------------------------===// + +#include "MCTargetDesc/PPCMCTargetDesc.h" +#include "MCTargetDesc/PPCInstPrinter.h" +#include "MCTargetDesc/PPCMCAsmInfo.h" +#include "PPCELFStreamer.h" +#include "PPCTargetStreamer.h" +#include "TargetInfo/PowerPCTargetInfo.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Triple.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/MCAsmBackend.h" -#include "llvm/MC/MCAssembler.h" -#include "llvm/MC/MCCodeEmitter.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCDwarf.h" -#include "llvm/MC/MCELFStreamer.h" -#include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCInstrInfo.h" -#include "llvm/MC/MCObjectWriter.h" -#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDwarf.h" +#include "llvm/MC/MCELFStreamer.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSectionXCOFF.h" -#include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/MC/MCSymbolELF.h" -#include "llvm/MC/MCSymbolXCOFF.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/CodeGen.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/FormattedStream.h" -#include "llvm/Support/TargetRegistry.h" -#include "llvm/Support/raw_ostream.h" - -using namespace llvm; - -#define GET_INSTRINFO_MC_DESC -#include "PPCGenInstrInfo.inc" - -#define GET_SUBTARGETINFO_MC_DESC -#include "PPCGenSubtargetInfo.inc" - -#define GET_REGINFO_MC_DESC -#include "PPCGenRegisterInfo.inc" - -PPCTargetStreamer::PPCTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} - -// Pin the vtable to this file. -PPCTargetStreamer::~PPCTargetStreamer() = default; - -static MCInstrInfo *createPPCMCInstrInfo() { - MCInstrInfo *X = new MCInstrInfo(); - InitPPCMCInstrInfo(X); - return X; -} - -static MCRegisterInfo *createPPCMCRegisterInfo(const Triple &TT) { - bool isPPC64 = - (TT.getArch() == Triple::ppc64 || TT.getArch() == Triple::ppc64le); - unsigned Flavour = isPPC64 ? 0 : 1; - unsigned RA = isPPC64 ? PPC::LR8 : PPC::LR; - - MCRegisterInfo *X = new MCRegisterInfo(); - InitPPCMCRegisterInfo(X, RA, Flavour, Flavour); - return X; -} - -static MCSubtargetInfo *createPPCMCSubtargetInfo(const Triple &TT, - StringRef CPU, StringRef FS) { +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCSymbolELF.h" +#include "llvm/MC/MCSymbolXCOFF.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/CodeGen.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormattedStream.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +#define GET_INSTRINFO_MC_DESC +#include "PPCGenInstrInfo.inc" + +#define GET_SUBTARGETINFO_MC_DESC +#include "PPCGenSubtargetInfo.inc" + +#define GET_REGINFO_MC_DESC +#include "PPCGenRegisterInfo.inc" + +PPCTargetStreamer::PPCTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} + +// Pin the vtable to this file. +PPCTargetStreamer::~PPCTargetStreamer() = default; + +static MCInstrInfo *createPPCMCInstrInfo() { + MCInstrInfo *X = new MCInstrInfo(); + InitPPCMCInstrInfo(X); + return X; +} + +static MCRegisterInfo *createPPCMCRegisterInfo(const Triple &TT) { + bool isPPC64 = + (TT.getArch() == Triple::ppc64 || TT.getArch() == Triple::ppc64le); + unsigned Flavour = isPPC64 ? 0 : 1; + unsigned RA = isPPC64 ? PPC::LR8 : PPC::LR; + + MCRegisterInfo *X = new MCRegisterInfo(); + InitPPCMCRegisterInfo(X, RA, Flavour, Flavour); + return X; +} + +static MCSubtargetInfo *createPPCMCSubtargetInfo(const Triple &TT, + StringRef CPU, StringRef FS) { // Set some default feature to MC layer. std::string FullFS = std::string(FS); @@ -89,294 +89,294 @@ static MCSubtargetInfo *createPPCMCSubtargetInfo(const Triple &TT, } return createPPCMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FullFS); -} - -static MCAsmInfo *createPPCMCAsmInfo(const MCRegisterInfo &MRI, - const Triple &TheTriple, - const MCTargetOptions &Options) { - bool isPPC64 = (TheTriple.getArch() == Triple::ppc64 || - TheTriple.getArch() == Triple::ppc64le); - - MCAsmInfo *MAI; - if (TheTriple.isOSBinFormatXCOFF()) - MAI = new PPCXCOFFMCAsmInfo(isPPC64, TheTriple); - else - MAI = new PPCELFMCAsmInfo(isPPC64, TheTriple); - - // Initial state of the frame pointer is R1. - unsigned Reg = isPPC64 ? PPC::X1 : PPC::R1; - MCCFIInstruction Inst = - MCCFIInstruction::cfiDefCfa(nullptr, MRI.getDwarfRegNum(Reg, true), 0); - MAI->addInitialFrameState(Inst); - - return MAI; -} - -static MCStreamer *createPPCMCStreamer(const Triple &T, MCContext &Context, - std::unique_ptr<MCAsmBackend> &&MAB, - std::unique_ptr<MCObjectWriter> &&OW, - std::unique_ptr<MCCodeEmitter> &&Emitter, - bool RelaxAll) { - return createPPCELFStreamer(Context, std::move(MAB), std::move(OW), - std::move(Emitter)); -} - -namespace { - -class PPCTargetAsmStreamer : public PPCTargetStreamer { - formatted_raw_ostream &OS; - -public: - PPCTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS) - : PPCTargetStreamer(S), OS(OS) {} - - void emitTCEntry(const MCSymbol &S) override { - if (const MCSymbolXCOFF *XSym = dyn_cast<MCSymbolXCOFF>(&S)) { - MCSymbolXCOFF *TCSym = +} + +static MCAsmInfo *createPPCMCAsmInfo(const MCRegisterInfo &MRI, + const Triple &TheTriple, + const MCTargetOptions &Options) { + bool isPPC64 = (TheTriple.getArch() == Triple::ppc64 || + TheTriple.getArch() == Triple::ppc64le); + + MCAsmInfo *MAI; + if (TheTriple.isOSBinFormatXCOFF()) + MAI = new PPCXCOFFMCAsmInfo(isPPC64, TheTriple); + else + MAI = new PPCELFMCAsmInfo(isPPC64, TheTriple); + + // Initial state of the frame pointer is R1. + unsigned Reg = isPPC64 ? PPC::X1 : PPC::R1; + MCCFIInstruction Inst = + MCCFIInstruction::cfiDefCfa(nullptr, MRI.getDwarfRegNum(Reg, true), 0); + MAI->addInitialFrameState(Inst); + + return MAI; +} + +static MCStreamer *createPPCMCStreamer(const Triple &T, MCContext &Context, + std::unique_ptr<MCAsmBackend> &&MAB, + std::unique_ptr<MCObjectWriter> &&OW, + std::unique_ptr<MCCodeEmitter> &&Emitter, + bool RelaxAll) { + return createPPCELFStreamer(Context, std::move(MAB), std::move(OW), + std::move(Emitter)); +} + +namespace { + +class PPCTargetAsmStreamer : public PPCTargetStreamer { + formatted_raw_ostream &OS; + +public: + PPCTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS) + : PPCTargetStreamer(S), OS(OS) {} + + void emitTCEntry(const MCSymbol &S) override { + if (const MCSymbolXCOFF *XSym = dyn_cast<MCSymbolXCOFF>(&S)) { + MCSymbolXCOFF *TCSym = cast<MCSectionXCOFF>(Streamer.getCurrentSectionOnly()) ->getQualNameSymbol(); OS << "\t.tc " << TCSym->getName() << "," << XSym->getName() << '\n'; - if (TCSym->hasRename()) - Streamer.emitXCOFFRenameDirective(TCSym, TCSym->getSymbolTableName()); - return; - } - - OS << "\t.tc " << S.getName() << "[TC]," << S.getName() << '\n'; - } - - void emitMachine(StringRef CPU) override { - OS << "\t.machine " << CPU << '\n'; - } - - void emitAbiVersion(int AbiVersion) override { - OS << "\t.abiversion " << AbiVersion << '\n'; - } - - void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override { - const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo(); - - OS << "\t.localentry\t"; - S->print(OS, MAI); - OS << ", "; - LocalOffset->print(OS, MAI); - OS << '\n'; - } -}; - -class PPCTargetELFStreamer : public PPCTargetStreamer { -public: - PPCTargetELFStreamer(MCStreamer &S) : PPCTargetStreamer(S) {} - - MCELFStreamer &getStreamer() { - return static_cast<MCELFStreamer &>(Streamer); - } - - void emitTCEntry(const MCSymbol &S) override { - // Creates a R_PPC64_TOC relocation - Streamer.emitValueToAlignment(8); - Streamer.emitSymbolValue(&S, 8); - } - - void emitMachine(StringRef CPU) override { - // FIXME: Is there anything to do in here or does this directive only - // limit the parser? - } - - void emitAbiVersion(int AbiVersion) override { - MCAssembler &MCA = getStreamer().getAssembler(); - unsigned Flags = MCA.getELFHeaderEFlags(); - Flags &= ~ELF::EF_PPC64_ABI; - Flags |= (AbiVersion & ELF::EF_PPC64_ABI); - MCA.setELFHeaderEFlags(Flags); - } - - void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override { - MCAssembler &MCA = getStreamer().getAssembler(); - - // encodePPC64LocalEntryOffset will report an error if it cannot - // encode LocalOffset. - unsigned Encoded = encodePPC64LocalEntryOffset(LocalOffset); - - unsigned Other = S->getOther(); - Other &= ~ELF::STO_PPC64_LOCAL_MASK; - Other |= Encoded; - S->setOther(Other); - - // For GAS compatibility, unless we already saw a .abiversion directive, - // set e_flags to indicate ELFv2 ABI. - unsigned Flags = MCA.getELFHeaderEFlags(); - if ((Flags & ELF::EF_PPC64_ABI) == 0) - MCA.setELFHeaderEFlags(Flags | 2); - } - - void emitAssignment(MCSymbol *S, const MCExpr *Value) override { - auto *Symbol = cast<MCSymbolELF>(S); - - // When encoding an assignment to set symbol A to symbol B, also copy - // the st_other bits encoding the local entry point offset. - if (copyLocalEntry(Symbol, Value)) - UpdateOther.insert(Symbol); - else - UpdateOther.erase(Symbol); - } - - void finish() override { - for (auto *Sym : UpdateOther) - if (Sym->isVariable()) - copyLocalEntry(Sym, Sym->getVariableValue()); - - // Clear the set of symbols that needs to be updated so the streamer can - // be reused without issues. - UpdateOther.clear(); - } - -private: - SmallPtrSet<MCSymbolELF *, 32> UpdateOther; - - bool copyLocalEntry(MCSymbolELF *D, const MCExpr *S) { - auto *Ref = dyn_cast<const MCSymbolRefExpr>(S); - if (!Ref) - return false; - const auto &RhsSym = cast<MCSymbolELF>(Ref->getSymbol()); - unsigned Other = D->getOther(); - Other &= ~ELF::STO_PPC64_LOCAL_MASK; - Other |= RhsSym.getOther() & ELF::STO_PPC64_LOCAL_MASK; - D->setOther(Other); - return true; - } - - unsigned encodePPC64LocalEntryOffset(const MCExpr *LocalOffset) { - MCAssembler &MCA = getStreamer().getAssembler(); - int64_t Offset; - if (!LocalOffset->evaluateAsAbsolute(Offset, MCA)) - MCA.getContext().reportFatalError( - LocalOffset->getLoc(), ".localentry expression must be absolute."); - - switch (Offset) { - default: - MCA.getContext().reportFatalError( - LocalOffset->getLoc(), - ".localentry expression is not a valid power of 2."); - case 0: - return 0; - case 1: - return 1 << ELF::STO_PPC64_LOCAL_BIT; - case 4: - case 8: - case 16: - case 32: - case 64: - return (int)Log2(Offset) << (int)ELF::STO_PPC64_LOCAL_BIT; - } - } -}; - -class PPCTargetMachOStreamer : public PPCTargetStreamer { -public: - PPCTargetMachOStreamer(MCStreamer &S) : PPCTargetStreamer(S) {} - - void emitTCEntry(const MCSymbol &S) override { - llvm_unreachable("Unknown pseudo-op: .tc"); - } - - void emitMachine(StringRef CPU) override { - // FIXME: We should update the CPUType, CPUSubType in the Object file if - // the new values are different from the defaults. - } - - void emitAbiVersion(int AbiVersion) override { - llvm_unreachable("Unknown pseudo-op: .abiversion"); - } - - void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override { - llvm_unreachable("Unknown pseudo-op: .localentry"); - } -}; - -class PPCTargetXCOFFStreamer : public PPCTargetStreamer { -public: - PPCTargetXCOFFStreamer(MCStreamer &S) : PPCTargetStreamer(S) {} - - void emitTCEntry(const MCSymbol &S) override { - const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo(); - const unsigned PointerSize = MAI->getCodePointerSize(); - Streamer.emitValueToAlignment(PointerSize); - Streamer.emitSymbolValue(&S, PointerSize); - } - - void emitMachine(StringRef CPU) override { - llvm_unreachable("Machine pseudo-ops are invalid for XCOFF."); - } - - void emitAbiVersion(int AbiVersion) override { - llvm_unreachable("ABI-version pseudo-ops are invalid for XCOFF."); - } - - void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override { - llvm_unreachable("Local-entry pseudo-ops are invalid for XCOFF."); - } -}; - -} // end anonymous namespace - -static MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S, - formatted_raw_ostream &OS, - MCInstPrinter *InstPrint, - bool isVerboseAsm) { - return new PPCTargetAsmStreamer(S, OS); -} - -static MCTargetStreamer * -createObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { - const Triple &TT = STI.getTargetTriple(); - if (TT.isOSBinFormatELF()) - return new PPCTargetELFStreamer(S); - if (TT.isOSBinFormatXCOFF()) - return new PPCTargetXCOFFStreamer(S); - return new PPCTargetMachOStreamer(S); -} - -static MCInstPrinter *createPPCMCInstPrinter(const Triple &T, - unsigned SyntaxVariant, - const MCAsmInfo &MAI, - const MCInstrInfo &MII, - const MCRegisterInfo &MRI) { - return new PPCInstPrinter(MAI, MII, MRI, T); -} - -extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTargetMC() { + if (TCSym->hasRename()) + Streamer.emitXCOFFRenameDirective(TCSym, TCSym->getSymbolTableName()); + return; + } + + OS << "\t.tc " << S.getName() << "[TC]," << S.getName() << '\n'; + } + + void emitMachine(StringRef CPU) override { + OS << "\t.machine " << CPU << '\n'; + } + + void emitAbiVersion(int AbiVersion) override { + OS << "\t.abiversion " << AbiVersion << '\n'; + } + + void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override { + const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo(); + + OS << "\t.localentry\t"; + S->print(OS, MAI); + OS << ", "; + LocalOffset->print(OS, MAI); + OS << '\n'; + } +}; + +class PPCTargetELFStreamer : public PPCTargetStreamer { +public: + PPCTargetELFStreamer(MCStreamer &S) : PPCTargetStreamer(S) {} + + MCELFStreamer &getStreamer() { + return static_cast<MCELFStreamer &>(Streamer); + } + + void emitTCEntry(const MCSymbol &S) override { + // Creates a R_PPC64_TOC relocation + Streamer.emitValueToAlignment(8); + Streamer.emitSymbolValue(&S, 8); + } + + void emitMachine(StringRef CPU) override { + // FIXME: Is there anything to do in here or does this directive only + // limit the parser? + } + + void emitAbiVersion(int AbiVersion) override { + MCAssembler &MCA = getStreamer().getAssembler(); + unsigned Flags = MCA.getELFHeaderEFlags(); + Flags &= ~ELF::EF_PPC64_ABI; + Flags |= (AbiVersion & ELF::EF_PPC64_ABI); + MCA.setELFHeaderEFlags(Flags); + } + + void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override { + MCAssembler &MCA = getStreamer().getAssembler(); + + // encodePPC64LocalEntryOffset will report an error if it cannot + // encode LocalOffset. + unsigned Encoded = encodePPC64LocalEntryOffset(LocalOffset); + + unsigned Other = S->getOther(); + Other &= ~ELF::STO_PPC64_LOCAL_MASK; + Other |= Encoded; + S->setOther(Other); + + // For GAS compatibility, unless we already saw a .abiversion directive, + // set e_flags to indicate ELFv2 ABI. + unsigned Flags = MCA.getELFHeaderEFlags(); + if ((Flags & ELF::EF_PPC64_ABI) == 0) + MCA.setELFHeaderEFlags(Flags | 2); + } + + void emitAssignment(MCSymbol *S, const MCExpr *Value) override { + auto *Symbol = cast<MCSymbolELF>(S); + + // When encoding an assignment to set symbol A to symbol B, also copy + // the st_other bits encoding the local entry point offset. + if (copyLocalEntry(Symbol, Value)) + UpdateOther.insert(Symbol); + else + UpdateOther.erase(Symbol); + } + + void finish() override { + for (auto *Sym : UpdateOther) + if (Sym->isVariable()) + copyLocalEntry(Sym, Sym->getVariableValue()); + + // Clear the set of symbols that needs to be updated so the streamer can + // be reused without issues. + UpdateOther.clear(); + } + +private: + SmallPtrSet<MCSymbolELF *, 32> UpdateOther; + + bool copyLocalEntry(MCSymbolELF *D, const MCExpr *S) { + auto *Ref = dyn_cast<const MCSymbolRefExpr>(S); + if (!Ref) + return false; + const auto &RhsSym = cast<MCSymbolELF>(Ref->getSymbol()); + unsigned Other = D->getOther(); + Other &= ~ELF::STO_PPC64_LOCAL_MASK; + Other |= RhsSym.getOther() & ELF::STO_PPC64_LOCAL_MASK; + D->setOther(Other); + return true; + } + + unsigned encodePPC64LocalEntryOffset(const MCExpr *LocalOffset) { + MCAssembler &MCA = getStreamer().getAssembler(); + int64_t Offset; + if (!LocalOffset->evaluateAsAbsolute(Offset, MCA)) + MCA.getContext().reportFatalError( + LocalOffset->getLoc(), ".localentry expression must be absolute."); + + switch (Offset) { + default: + MCA.getContext().reportFatalError( + LocalOffset->getLoc(), + ".localentry expression is not a valid power of 2."); + case 0: + return 0; + case 1: + return 1 << ELF::STO_PPC64_LOCAL_BIT; + case 4: + case 8: + case 16: + case 32: + case 64: + return (int)Log2(Offset) << (int)ELF::STO_PPC64_LOCAL_BIT; + } + } +}; + +class PPCTargetMachOStreamer : public PPCTargetStreamer { +public: + PPCTargetMachOStreamer(MCStreamer &S) : PPCTargetStreamer(S) {} + + void emitTCEntry(const MCSymbol &S) override { + llvm_unreachable("Unknown pseudo-op: .tc"); + } + + void emitMachine(StringRef CPU) override { + // FIXME: We should update the CPUType, CPUSubType in the Object file if + // the new values are different from the defaults. + } + + void emitAbiVersion(int AbiVersion) override { + llvm_unreachable("Unknown pseudo-op: .abiversion"); + } + + void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override { + llvm_unreachable("Unknown pseudo-op: .localentry"); + } +}; + +class PPCTargetXCOFFStreamer : public PPCTargetStreamer { +public: + PPCTargetXCOFFStreamer(MCStreamer &S) : PPCTargetStreamer(S) {} + + void emitTCEntry(const MCSymbol &S) override { + const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo(); + const unsigned PointerSize = MAI->getCodePointerSize(); + Streamer.emitValueToAlignment(PointerSize); + Streamer.emitSymbolValue(&S, PointerSize); + } + + void emitMachine(StringRef CPU) override { + llvm_unreachable("Machine pseudo-ops are invalid for XCOFF."); + } + + void emitAbiVersion(int AbiVersion) override { + llvm_unreachable("ABI-version pseudo-ops are invalid for XCOFF."); + } + + void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override { + llvm_unreachable("Local-entry pseudo-ops are invalid for XCOFF."); + } +}; + +} // end anonymous namespace + +static MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S, + formatted_raw_ostream &OS, + MCInstPrinter *InstPrint, + bool isVerboseAsm) { + return new PPCTargetAsmStreamer(S, OS); +} + +static MCTargetStreamer * +createObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { + const Triple &TT = STI.getTargetTriple(); + if (TT.isOSBinFormatELF()) + return new PPCTargetELFStreamer(S); + if (TT.isOSBinFormatXCOFF()) + return new PPCTargetXCOFFStreamer(S); + return new PPCTargetMachOStreamer(S); +} + +static MCInstPrinter *createPPCMCInstPrinter(const Triple &T, + unsigned SyntaxVariant, + const MCAsmInfo &MAI, + const MCInstrInfo &MII, + const MCRegisterInfo &MRI) { + return new PPCInstPrinter(MAI, MII, MRI, T); +} + +extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTargetMC() { for (Target *T : {&getThePPC32Target(), &getThePPC32LETarget(), &getThePPC64Target(), &getThePPC64LETarget()}) { - // Register the MC asm info. - RegisterMCAsmInfoFn C(*T, createPPCMCAsmInfo); - - // Register the MC instruction info. - TargetRegistry::RegisterMCInstrInfo(*T, createPPCMCInstrInfo); - - // Register the MC register info. - TargetRegistry::RegisterMCRegInfo(*T, createPPCMCRegisterInfo); - - // Register the MC subtarget info. - TargetRegistry::RegisterMCSubtargetInfo(*T, createPPCMCSubtargetInfo); - - // Register the MC Code Emitter - TargetRegistry::RegisterMCCodeEmitter(*T, createPPCMCCodeEmitter); - - // Register the asm backend. - TargetRegistry::RegisterMCAsmBackend(*T, createPPCAsmBackend); - - // Register the elf streamer. - TargetRegistry::RegisterELFStreamer(*T, createPPCMCStreamer); - - // Register the object target streamer. - TargetRegistry::RegisterObjectTargetStreamer(*T, - createObjectTargetStreamer); - - // Register the asm target streamer. - TargetRegistry::RegisterAsmTargetStreamer(*T, createAsmTargetStreamer); - - // Register the MCInstPrinter. - TargetRegistry::RegisterMCInstPrinter(*T, createPPCMCInstPrinter); - } -} + // Register the MC asm info. + RegisterMCAsmInfoFn C(*T, createPPCMCAsmInfo); + + // Register the MC instruction info. + TargetRegistry::RegisterMCInstrInfo(*T, createPPCMCInstrInfo); + + // Register the MC register info. + TargetRegistry::RegisterMCRegInfo(*T, createPPCMCRegisterInfo); + + // Register the MC subtarget info. + TargetRegistry::RegisterMCSubtargetInfo(*T, createPPCMCSubtargetInfo); + + // Register the MC Code Emitter + TargetRegistry::RegisterMCCodeEmitter(*T, createPPCMCCodeEmitter); + + // Register the asm backend. + TargetRegistry::RegisterMCAsmBackend(*T, createPPCAsmBackend); + + // Register the elf streamer. + TargetRegistry::RegisterELFStreamer(*T, createPPCMCStreamer); + + // Register the object target streamer. + TargetRegistry::RegisterObjectTargetStreamer(*T, + createObjectTargetStreamer); + + // Register the asm target streamer. + TargetRegistry::RegisterAsmTargetStreamer(*T, createAsmTargetStreamer); + + // Register the MCInstPrinter. + TargetRegistry::RegisterMCInstPrinter(*T, createPPCMCInstPrinter); + } +} diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h index 03b3163417..abe948b6f8 100644 --- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h +++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h @@ -1,189 +1,189 @@ -//===-- PPCMCTargetDesc.h - PowerPC Target Descriptions ---------*- 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 -// -//===----------------------------------------------------------------------===// -// -// This file provides PowerPC specific target descriptions. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCMCTARGETDESC_H -#define LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCMCTARGETDESC_H - -// GCC #defines PPC on Linux but we use it as our namespace name -#undef PPC - -#include "llvm/MC/MCRegisterInfo.h" -#include "llvm/Support/MathExtras.h" -#include <cstdint> -#include <memory> - -namespace llvm { - -class MCAsmBackend; -class MCCodeEmitter; -class MCContext; -class MCInstrInfo; -class MCObjectTargetWriter; -class MCRegisterInfo; -class MCSubtargetInfo; -class MCTargetOptions; -class Target; - -MCCodeEmitter *createPPCMCCodeEmitter(const MCInstrInfo &MCII, - const MCRegisterInfo &MRI, - MCContext &Ctx); - -MCAsmBackend *createPPCAsmBackend(const Target &T, const MCSubtargetInfo &STI, - const MCRegisterInfo &MRI, - const MCTargetOptions &Options); - -/// Construct an PPC ELF object writer. -std::unique_ptr<MCObjectTargetWriter> createPPCELFObjectWriter(bool Is64Bit, - uint8_t OSABI); -/// Construct a PPC Mach-O object writer. -std::unique_ptr<MCObjectTargetWriter> -createPPCMachObjectWriter(bool Is64Bit, uint32_t CPUType, uint32_t CPUSubtype); - -/// Construct a PPC XCOFF object writer. -std::unique_ptr<MCObjectTargetWriter> createPPCXCOFFObjectWriter(bool Is64Bit); - -/// Returns true iff Val consists of one contiguous run of 1s with any number of -/// 0s on either side. The 1s are allowed to wrap from LSB to MSB, so -/// 0x000FFF0, 0x0000FFFF, and 0xFF0000FF are all runs. 0x0F0F0000 is not, -/// since all 1s are not contiguous. -static inline bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME) { - if (!Val) - return false; - - if (isShiftedMask_32(Val)) { - // look for the first non-zero bit - MB = countLeadingZeros(Val); - // look for the first zero bit after the run of ones - ME = countLeadingZeros((Val - 1) ^ Val); - return true; - } else { - Val = ~Val; // invert mask - if (isShiftedMask_32(Val)) { - // effectively look for the first zero bit - ME = countLeadingZeros(Val) - 1; - // effectively look for the first one bit after the run of zeros - MB = countLeadingZeros((Val - 1) ^ Val) + 1; - return true; - } - } - // no run present - return false; -} - -static inline bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME) { - if (!Val) - return false; - - if (isShiftedMask_64(Val)) { - // look for the first non-zero bit - MB = countLeadingZeros(Val); - // look for the first zero bit after the run of ones - ME = countLeadingZeros((Val - 1) ^ Val); - return true; - } else { - Val = ~Val; // invert mask - if (isShiftedMask_64(Val)) { - // effectively look for the first zero bit - ME = countLeadingZeros(Val) - 1; - // effectively look for the first one bit after the run of zeros - MB = countLeadingZeros((Val - 1) ^ Val) + 1; - return true; - } - } - // no run present - return false; -} - -} // end namespace llvm - -// Generated files will use "namespace PPC". To avoid symbol clash, -// undefine PPC here. PPC may be predefined on some hosts. -#undef PPC - -// Defines symbolic names for PowerPC registers. This defines a mapping from -// register name to register number. -// -#define GET_REGINFO_ENUM -#include "PPCGenRegisterInfo.inc" - -// Defines symbolic names for the PowerPC instructions. -// -#define GET_INSTRINFO_ENUM -#define GET_INSTRINFO_SCHED_ENUM -#include "PPCGenInstrInfo.inc" - -#define GET_SUBTARGETINFO_ENUM -#include "PPCGenSubtargetInfo.inc" - +//===-- PPCMCTargetDesc.h - PowerPC Target Descriptions ---------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file provides PowerPC specific target descriptions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCMCTARGETDESC_H +#define LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCMCTARGETDESC_H + +// GCC #defines PPC on Linux but we use it as our namespace name +#undef PPC + +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/Support/MathExtras.h" +#include <cstdint> +#include <memory> + +namespace llvm { + +class MCAsmBackend; +class MCCodeEmitter; +class MCContext; +class MCInstrInfo; +class MCObjectTargetWriter; +class MCRegisterInfo; +class MCSubtargetInfo; +class MCTargetOptions; +class Target; + +MCCodeEmitter *createPPCMCCodeEmitter(const MCInstrInfo &MCII, + const MCRegisterInfo &MRI, + MCContext &Ctx); + +MCAsmBackend *createPPCAsmBackend(const Target &T, const MCSubtargetInfo &STI, + const MCRegisterInfo &MRI, + const MCTargetOptions &Options); + +/// Construct an PPC ELF object writer. +std::unique_ptr<MCObjectTargetWriter> createPPCELFObjectWriter(bool Is64Bit, + uint8_t OSABI); +/// Construct a PPC Mach-O object writer. +std::unique_ptr<MCObjectTargetWriter> +createPPCMachObjectWriter(bool Is64Bit, uint32_t CPUType, uint32_t CPUSubtype); + +/// Construct a PPC XCOFF object writer. +std::unique_ptr<MCObjectTargetWriter> createPPCXCOFFObjectWriter(bool Is64Bit); + +/// Returns true iff Val consists of one contiguous run of 1s with any number of +/// 0s on either side. The 1s are allowed to wrap from LSB to MSB, so +/// 0x000FFF0, 0x0000FFFF, and 0xFF0000FF are all runs. 0x0F0F0000 is not, +/// since all 1s are not contiguous. +static inline bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME) { + if (!Val) + return false; + + if (isShiftedMask_32(Val)) { + // look for the first non-zero bit + MB = countLeadingZeros(Val); + // look for the first zero bit after the run of ones + ME = countLeadingZeros((Val - 1) ^ Val); + return true; + } else { + Val = ~Val; // invert mask + if (isShiftedMask_32(Val)) { + // effectively look for the first zero bit + ME = countLeadingZeros(Val) - 1; + // effectively look for the first one bit after the run of zeros + MB = countLeadingZeros((Val - 1) ^ Val) + 1; + return true; + } + } + // no run present + return false; +} + +static inline bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME) { + if (!Val) + return false; + + if (isShiftedMask_64(Val)) { + // look for the first non-zero bit + MB = countLeadingZeros(Val); + // look for the first zero bit after the run of ones + ME = countLeadingZeros((Val - 1) ^ Val); + return true; + } else { + Val = ~Val; // invert mask + if (isShiftedMask_64(Val)) { + // effectively look for the first zero bit + ME = countLeadingZeros(Val) - 1; + // effectively look for the first one bit after the run of zeros + MB = countLeadingZeros((Val - 1) ^ Val) + 1; + return true; + } + } + // no run present + return false; +} + +} // end namespace llvm + +// Generated files will use "namespace PPC". To avoid symbol clash, +// undefine PPC here. PPC may be predefined on some hosts. +#undef PPC + +// Defines symbolic names for PowerPC registers. This defines a mapping from +// register name to register number. +// +#define GET_REGINFO_ENUM +#include "PPCGenRegisterInfo.inc" + +// Defines symbolic names for the PowerPC instructions. +// +#define GET_INSTRINFO_ENUM +#define GET_INSTRINFO_SCHED_ENUM +#include "PPCGenInstrInfo.inc" + +#define GET_SUBTARGETINFO_ENUM +#include "PPCGenSubtargetInfo.inc" + #define PPC_REGS0_7(X) \ { \ X##0, X##1, X##2, X##3, X##4, X##5, X##6, X##7 \ } -#define PPC_REGS0_31(X) \ - { \ - X##0, X##1, X##2, X##3, X##4, X##5, X##6, X##7, X##8, X##9, X##10, X##11, \ - X##12, X##13, X##14, X##15, X##16, X##17, X##18, X##19, X##20, X##21, \ - X##22, X##23, X##24, X##25, X##26, X##27, X##28, X##29, X##30, X##31 \ - } - -#define PPC_REGS_NO0_31(Z, X) \ - { \ - Z, X##1, X##2, X##3, X##4, X##5, X##6, X##7, X##8, X##9, X##10, X##11, \ - X##12, X##13, X##14, X##15, X##16, X##17, X##18, X##19, X##20, X##21, \ - X##22, X##23, X##24, X##25, X##26, X##27, X##28, X##29, X##30, X##31 \ - } - -#define PPC_REGS_LO_HI(LO, HI) \ - { \ - LO##0, LO##1, LO##2, LO##3, LO##4, LO##5, LO##6, LO##7, LO##8, LO##9, \ - LO##10, LO##11, LO##12, LO##13, LO##14, LO##15, LO##16, LO##17, \ - LO##18, LO##19, LO##20, LO##21, LO##22, LO##23, LO##24, LO##25, \ - LO##26, LO##27, LO##28, LO##29, LO##30, LO##31, HI##0, HI##1, HI##2, \ - HI##3, HI##4, HI##5, HI##6, HI##7, HI##8, HI##9, HI##10, HI##11, \ - HI##12, HI##13, HI##14, HI##15, HI##16, HI##17, HI##18, HI##19, \ - HI##20, HI##21, HI##22, HI##23, HI##24, HI##25, HI##26, HI##27, \ - HI##28, HI##29, HI##30, HI##31 \ - } - -using llvm::MCPhysReg; - -#define DEFINE_PPC_REGCLASSES \ - static const MCPhysReg RRegs[32] = PPC_REGS0_31(PPC::R); \ - static const MCPhysReg XRegs[32] = PPC_REGS0_31(PPC::X); \ - static const MCPhysReg FRegs[32] = PPC_REGS0_31(PPC::F); \ +#define PPC_REGS0_31(X) \ + { \ + X##0, X##1, X##2, X##3, X##4, X##5, X##6, X##7, X##8, X##9, X##10, X##11, \ + X##12, X##13, X##14, X##15, X##16, X##17, X##18, X##19, X##20, X##21, \ + X##22, X##23, X##24, X##25, X##26, X##27, X##28, X##29, X##30, X##31 \ + } + +#define PPC_REGS_NO0_31(Z, X) \ + { \ + Z, X##1, X##2, X##3, X##4, X##5, X##6, X##7, X##8, X##9, X##10, X##11, \ + X##12, X##13, X##14, X##15, X##16, X##17, X##18, X##19, X##20, X##21, \ + X##22, X##23, X##24, X##25, X##26, X##27, X##28, X##29, X##30, X##31 \ + } + +#define PPC_REGS_LO_HI(LO, HI) \ + { \ + LO##0, LO##1, LO##2, LO##3, LO##4, LO##5, LO##6, LO##7, LO##8, LO##9, \ + LO##10, LO##11, LO##12, LO##13, LO##14, LO##15, LO##16, LO##17, \ + LO##18, LO##19, LO##20, LO##21, LO##22, LO##23, LO##24, LO##25, \ + LO##26, LO##27, LO##28, LO##29, LO##30, LO##31, HI##0, HI##1, HI##2, \ + HI##3, HI##4, HI##5, HI##6, HI##7, HI##8, HI##9, HI##10, HI##11, \ + HI##12, HI##13, HI##14, HI##15, HI##16, HI##17, HI##18, HI##19, \ + HI##20, HI##21, HI##22, HI##23, HI##24, HI##25, HI##26, HI##27, \ + HI##28, HI##29, HI##30, HI##31 \ + } + +using llvm::MCPhysReg; + +#define DEFINE_PPC_REGCLASSES \ + static const MCPhysReg RRegs[32] = PPC_REGS0_31(PPC::R); \ + static const MCPhysReg XRegs[32] = PPC_REGS0_31(PPC::X); \ + static const MCPhysReg FRegs[32] = PPC_REGS0_31(PPC::F); \ static const MCPhysReg VSRpRegs[32] = PPC_REGS0_31(PPC::VSRp); \ - static const MCPhysReg SPERegs[32] = PPC_REGS0_31(PPC::S); \ - static const MCPhysReg VFRegs[32] = PPC_REGS0_31(PPC::VF); \ - static const MCPhysReg VRegs[32] = PPC_REGS0_31(PPC::V); \ - static const MCPhysReg RRegsNoR0[32] = \ - PPC_REGS_NO0_31(PPC::ZERO, PPC::R); \ - static const MCPhysReg XRegsNoX0[32] = \ - PPC_REGS_NO0_31(PPC::ZERO8, PPC::X); \ - static const MCPhysReg VSRegs[64] = \ - PPC_REGS_LO_HI(PPC::VSL, PPC::V); \ - static const MCPhysReg VSFRegs[64] = \ - PPC_REGS_LO_HI(PPC::F, PPC::VF); \ - static const MCPhysReg VSSRegs[64] = \ - PPC_REGS_LO_HI(PPC::F, PPC::VF); \ - static const MCPhysReg CRBITRegs[32] = { \ - PPC::CR0LT, PPC::CR0GT, PPC::CR0EQ, PPC::CR0UN, \ - PPC::CR1LT, PPC::CR1GT, PPC::CR1EQ, PPC::CR1UN, \ - PPC::CR2LT, PPC::CR2GT, PPC::CR2EQ, PPC::CR2UN, \ - PPC::CR3LT, PPC::CR3GT, PPC::CR3EQ, PPC::CR3UN, \ - PPC::CR4LT, PPC::CR4GT, PPC::CR4EQ, PPC::CR4UN, \ - PPC::CR5LT, PPC::CR5GT, PPC::CR5EQ, PPC::CR5UN, \ - PPC::CR6LT, PPC::CR6GT, PPC::CR6EQ, PPC::CR6UN, \ - PPC::CR7LT, PPC::CR7GT, PPC::CR7EQ, PPC::CR7UN}; \ + static const MCPhysReg SPERegs[32] = PPC_REGS0_31(PPC::S); \ + static const MCPhysReg VFRegs[32] = PPC_REGS0_31(PPC::VF); \ + static const MCPhysReg VRegs[32] = PPC_REGS0_31(PPC::V); \ + static const MCPhysReg RRegsNoR0[32] = \ + PPC_REGS_NO0_31(PPC::ZERO, PPC::R); \ + static const MCPhysReg XRegsNoX0[32] = \ + PPC_REGS_NO0_31(PPC::ZERO8, PPC::X); \ + static const MCPhysReg VSRegs[64] = \ + PPC_REGS_LO_HI(PPC::VSL, PPC::V); \ + static const MCPhysReg VSFRegs[64] = \ + PPC_REGS_LO_HI(PPC::F, PPC::VF); \ + static const MCPhysReg VSSRegs[64] = \ + PPC_REGS_LO_HI(PPC::F, PPC::VF); \ + static const MCPhysReg CRBITRegs[32] = { \ + PPC::CR0LT, PPC::CR0GT, PPC::CR0EQ, PPC::CR0UN, \ + PPC::CR1LT, PPC::CR1GT, PPC::CR1EQ, PPC::CR1UN, \ + PPC::CR2LT, PPC::CR2GT, PPC::CR2EQ, PPC::CR2UN, \ + PPC::CR3LT, PPC::CR3GT, PPC::CR3EQ, PPC::CR3UN, \ + PPC::CR4LT, PPC::CR4GT, PPC::CR4EQ, PPC::CR4UN, \ + PPC::CR5LT, PPC::CR5GT, PPC::CR5EQ, PPC::CR5UN, \ + PPC::CR6LT, PPC::CR6GT, PPC::CR6EQ, PPC::CR6UN, \ + PPC::CR7LT, PPC::CR7GT, PPC::CR7EQ, PPC::CR7UN}; \ static const MCPhysReg CRRegs[8] = PPC_REGS0_7(PPC::CR); \ static const MCPhysReg ACCRegs[8] = PPC_REGS0_7(PPC::ACC) -#endif // LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCMCTARGETDESC_H +#endif // LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCMCTARGETDESC_H diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.cpp index 284e52c298..220dbdc46a 100644 --- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.cpp +++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.cpp @@ -1,85 +1,85 @@ -//===-- PPCPredicates.cpp - PPC Branch Predicate Information --------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// -// -// This file implements the PowerPC branch predicates. -// -//===----------------------------------------------------------------------===// - -#include "PPCPredicates.h" -#include "llvm/Support/ErrorHandling.h" -#include <cassert> -using namespace llvm; - -PPC::Predicate PPC::InvertPredicate(PPC::Predicate Opcode) { - switch (Opcode) { - case PPC::PRED_EQ: return PPC::PRED_NE; - case PPC::PRED_NE: return PPC::PRED_EQ; - case PPC::PRED_LT: return PPC::PRED_GE; - case PPC::PRED_GE: return PPC::PRED_LT; - case PPC::PRED_GT: return PPC::PRED_LE; - case PPC::PRED_LE: return PPC::PRED_GT; - case PPC::PRED_NU: return PPC::PRED_UN; - case PPC::PRED_UN: return PPC::PRED_NU; - case PPC::PRED_EQ_MINUS: return PPC::PRED_NE_PLUS; - case PPC::PRED_NE_MINUS: return PPC::PRED_EQ_PLUS; - case PPC::PRED_LT_MINUS: return PPC::PRED_GE_PLUS; - case PPC::PRED_GE_MINUS: return PPC::PRED_LT_PLUS; - case PPC::PRED_GT_MINUS: return PPC::PRED_LE_PLUS; - case PPC::PRED_LE_MINUS: return PPC::PRED_GT_PLUS; - case PPC::PRED_NU_MINUS: return PPC::PRED_UN_PLUS; - case PPC::PRED_UN_MINUS: return PPC::PRED_NU_PLUS; - case PPC::PRED_EQ_PLUS: return PPC::PRED_NE_MINUS; - case PPC::PRED_NE_PLUS: return PPC::PRED_EQ_MINUS; - case PPC::PRED_LT_PLUS: return PPC::PRED_GE_MINUS; - case PPC::PRED_GE_PLUS: return PPC::PRED_LT_MINUS; - case PPC::PRED_GT_PLUS: return PPC::PRED_LE_MINUS; - case PPC::PRED_LE_PLUS: return PPC::PRED_GT_MINUS; - case PPC::PRED_NU_PLUS: return PPC::PRED_UN_MINUS; - case PPC::PRED_UN_PLUS: return PPC::PRED_NU_MINUS; - - // Simple predicates for single condition-register bits. - case PPC::PRED_BIT_SET: return PPC::PRED_BIT_UNSET; - case PPC::PRED_BIT_UNSET: return PPC::PRED_BIT_SET; - } - llvm_unreachable("Unknown PPC branch opcode!"); -} - -PPC::Predicate PPC::getSwappedPredicate(PPC::Predicate Opcode) { - switch (Opcode) { - case PPC::PRED_EQ: return PPC::PRED_EQ; - case PPC::PRED_NE: return PPC::PRED_NE; - case PPC::PRED_LT: return PPC::PRED_GT; - case PPC::PRED_GE: return PPC::PRED_LE; - case PPC::PRED_GT: return PPC::PRED_LT; - case PPC::PRED_LE: return PPC::PRED_GE; - case PPC::PRED_NU: return PPC::PRED_NU; - case PPC::PRED_UN: return PPC::PRED_UN; - case PPC::PRED_EQ_MINUS: return PPC::PRED_EQ_MINUS; - case PPC::PRED_NE_MINUS: return PPC::PRED_NE_MINUS; - case PPC::PRED_LT_MINUS: return PPC::PRED_GT_MINUS; - case PPC::PRED_GE_MINUS: return PPC::PRED_LE_MINUS; - case PPC::PRED_GT_MINUS: return PPC::PRED_LT_MINUS; - case PPC::PRED_LE_MINUS: return PPC::PRED_GE_MINUS; - case PPC::PRED_NU_MINUS: return PPC::PRED_NU_MINUS; - case PPC::PRED_UN_MINUS: return PPC::PRED_UN_MINUS; - case PPC::PRED_EQ_PLUS: return PPC::PRED_EQ_PLUS; - case PPC::PRED_NE_PLUS: return PPC::PRED_NE_PLUS; - case PPC::PRED_LT_PLUS: return PPC::PRED_GT_PLUS; - case PPC::PRED_GE_PLUS: return PPC::PRED_LE_PLUS; - case PPC::PRED_GT_PLUS: return PPC::PRED_LT_PLUS; - case PPC::PRED_LE_PLUS: return PPC::PRED_GE_PLUS; - case PPC::PRED_NU_PLUS: return PPC::PRED_NU_PLUS; - case PPC::PRED_UN_PLUS: return PPC::PRED_UN_PLUS; - - case PPC::PRED_BIT_SET: - case PPC::PRED_BIT_UNSET: - llvm_unreachable("Invalid use of bit predicate code"); - } - llvm_unreachable("Unknown PPC branch opcode!"); -} - +//===-- PPCPredicates.cpp - PPC Branch Predicate Information --------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file implements the PowerPC branch predicates. +// +//===----------------------------------------------------------------------===// + +#include "PPCPredicates.h" +#include "llvm/Support/ErrorHandling.h" +#include <cassert> +using namespace llvm; + +PPC::Predicate PPC::InvertPredicate(PPC::Predicate Opcode) { + switch (Opcode) { + case PPC::PRED_EQ: return PPC::PRED_NE; + case PPC::PRED_NE: return PPC::PRED_EQ; + case PPC::PRED_LT: return PPC::PRED_GE; + case PPC::PRED_GE: return PPC::PRED_LT; + case PPC::PRED_GT: return PPC::PRED_LE; + case PPC::PRED_LE: return PPC::PRED_GT; + case PPC::PRED_NU: return PPC::PRED_UN; + case PPC::PRED_UN: return PPC::PRED_NU; + case PPC::PRED_EQ_MINUS: return PPC::PRED_NE_PLUS; + case PPC::PRED_NE_MINUS: return PPC::PRED_EQ_PLUS; + case PPC::PRED_LT_MINUS: return PPC::PRED_GE_PLUS; + case PPC::PRED_GE_MINUS: return PPC::PRED_LT_PLUS; + case PPC::PRED_GT_MINUS: return PPC::PRED_LE_PLUS; + case PPC::PRED_LE_MINUS: return PPC::PRED_GT_PLUS; + case PPC::PRED_NU_MINUS: return PPC::PRED_UN_PLUS; + case PPC::PRED_UN_MINUS: return PPC::PRED_NU_PLUS; + case PPC::PRED_EQ_PLUS: return PPC::PRED_NE_MINUS; + case PPC::PRED_NE_PLUS: return PPC::PRED_EQ_MINUS; + case PPC::PRED_LT_PLUS: return PPC::PRED_GE_MINUS; + case PPC::PRED_GE_PLUS: return PPC::PRED_LT_MINUS; + case PPC::PRED_GT_PLUS: return PPC::PRED_LE_MINUS; + case PPC::PRED_LE_PLUS: return PPC::PRED_GT_MINUS; + case PPC::PRED_NU_PLUS: return PPC::PRED_UN_MINUS; + case PPC::PRED_UN_PLUS: return PPC::PRED_NU_MINUS; + + // Simple predicates for single condition-register bits. + case PPC::PRED_BIT_SET: return PPC::PRED_BIT_UNSET; + case PPC::PRED_BIT_UNSET: return PPC::PRED_BIT_SET; + } + llvm_unreachable("Unknown PPC branch opcode!"); +} + +PPC::Predicate PPC::getSwappedPredicate(PPC::Predicate Opcode) { + switch (Opcode) { + case PPC::PRED_EQ: return PPC::PRED_EQ; + case PPC::PRED_NE: return PPC::PRED_NE; + case PPC::PRED_LT: return PPC::PRED_GT; + case PPC::PRED_GE: return PPC::PRED_LE; + case PPC::PRED_GT: return PPC::PRED_LT; + case PPC::PRED_LE: return PPC::PRED_GE; + case PPC::PRED_NU: return PPC::PRED_NU; + case PPC::PRED_UN: return PPC::PRED_UN; + case PPC::PRED_EQ_MINUS: return PPC::PRED_EQ_MINUS; + case PPC::PRED_NE_MINUS: return PPC::PRED_NE_MINUS; + case PPC::PRED_LT_MINUS: return PPC::PRED_GT_MINUS; + case PPC::PRED_GE_MINUS: return PPC::PRED_LE_MINUS; + case PPC::PRED_GT_MINUS: return PPC::PRED_LT_MINUS; + case PPC::PRED_LE_MINUS: return PPC::PRED_GE_MINUS; + case PPC::PRED_NU_MINUS: return PPC::PRED_NU_MINUS; + case PPC::PRED_UN_MINUS: return PPC::PRED_UN_MINUS; + case PPC::PRED_EQ_PLUS: return PPC::PRED_EQ_PLUS; + case PPC::PRED_NE_PLUS: return PPC::PRED_NE_PLUS; + case PPC::PRED_LT_PLUS: return PPC::PRED_GT_PLUS; + case PPC::PRED_GE_PLUS: return PPC::PRED_LE_PLUS; + case PPC::PRED_GT_PLUS: return PPC::PRED_LT_PLUS; + case PPC::PRED_LE_PLUS: return PPC::PRED_GE_PLUS; + case PPC::PRED_NU_PLUS: return PPC::PRED_NU_PLUS; + case PPC::PRED_UN_PLUS: return PPC::PRED_UN_PLUS; + + case PPC::PRED_BIT_SET: + case PPC::PRED_BIT_UNSET: + llvm_unreachable("Invalid use of bit predicate code"); + } + llvm_unreachable("Unknown PPC branch opcode!"); +} + diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h index d686a8ea2a..ce9c42dc7f 100644 --- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h +++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h @@ -1,94 +1,94 @@ -//===-- PPCPredicates.h - PPC Branch Predicate Information ------*- 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 -// -//===----------------------------------------------------------------------===// -// -// This file describes the PowerPC branch predicates. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCPREDICATES_H -#define LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCPREDICATES_H - -// GCC #defines PPC on Linux but we use it as our namespace name -#undef PPC - -// Generated files will use "namespace PPC". To avoid symbol clash, -// undefine PPC here. PPC may be predefined on some hosts. -#undef PPC - -namespace llvm { -namespace PPC { - /// Predicate - These are "(BI << 5) | BO" for various predicates. - enum Predicate { - PRED_LT = (0 << 5) | 12, - PRED_LE = (1 << 5) | 4, - PRED_EQ = (2 << 5) | 12, - PRED_GE = (0 << 5) | 4, - PRED_GT = (1 << 5) | 12, - PRED_NE = (2 << 5) | 4, - PRED_UN = (3 << 5) | 12, - PRED_NU = (3 << 5) | 4, - PRED_LT_MINUS = (0 << 5) | 14, - PRED_LE_MINUS = (1 << 5) | 6, - PRED_EQ_MINUS = (2 << 5) | 14, - PRED_GE_MINUS = (0 << 5) | 6, - PRED_GT_MINUS = (1 << 5) | 14, - PRED_NE_MINUS = (2 << 5) | 6, - PRED_UN_MINUS = (3 << 5) | 14, - PRED_NU_MINUS = (3 << 5) | 6, - PRED_LT_PLUS = (0 << 5) | 15, - PRED_LE_PLUS = (1 << 5) | 7, - PRED_EQ_PLUS = (2 << 5) | 15, - PRED_GE_PLUS = (0 << 5) | 7, - PRED_GT_PLUS = (1 << 5) | 15, - PRED_NE_PLUS = (2 << 5) | 7, - PRED_UN_PLUS = (3 << 5) | 15, - PRED_NU_PLUS = (3 << 5) | 7, - - // SPE scalar compare instructions always set the GT bit. - PRED_SPE = PRED_GT, - - // When dealing with individual condition-register bits, we have simple set - // and unset predicates. - PRED_BIT_SET = 1024, - PRED_BIT_UNSET = 1025 - }; - - // Bit for branch taken (plus) or not-taken (minus) hint - enum BranchHintBit { - BR_NO_HINT = 0x0, - BR_NONTAKEN_HINT = 0x2, - BR_TAKEN_HINT = 0x3, - BR_HINT_MASK = 0X3 - }; - - /// Invert the specified predicate. != -> ==, < -> >=. - Predicate InvertPredicate(Predicate Opcode); - - /// Assume the condition register is set by MI(a,b), return the predicate if - /// we modify the instructions such that condition register is set by MI(b,a). - Predicate getSwappedPredicate(Predicate Opcode); - - /// Return the condition without hint bits. - inline unsigned getPredicateCondition(Predicate Opcode) { - return (unsigned)(Opcode & ~BR_HINT_MASK); - } - - /// Return the hint bits of the predicate. - inline unsigned getPredicateHint(Predicate Opcode) { - return (unsigned)(Opcode & BR_HINT_MASK); - } - - /// Return predicate consisting of specified condition and hint bits. - inline Predicate getPredicate(unsigned Condition, unsigned Hint) { - return (Predicate)((Condition & ~BR_HINT_MASK) | - (Hint & BR_HINT_MASK)); - } -} -} - -#endif +//===-- PPCPredicates.h - PPC Branch Predicate Information ------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file describes the PowerPC branch predicates. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCPREDICATES_H +#define LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCPREDICATES_H + +// GCC #defines PPC on Linux but we use it as our namespace name +#undef PPC + +// Generated files will use "namespace PPC". To avoid symbol clash, +// undefine PPC here. PPC may be predefined on some hosts. +#undef PPC + +namespace llvm { +namespace PPC { + /// Predicate - These are "(BI << 5) | BO" for various predicates. + enum Predicate { + PRED_LT = (0 << 5) | 12, + PRED_LE = (1 << 5) | 4, + PRED_EQ = (2 << 5) | 12, + PRED_GE = (0 << 5) | 4, + PRED_GT = (1 << 5) | 12, + PRED_NE = (2 << 5) | 4, + PRED_UN = (3 << 5) | 12, + PRED_NU = (3 << 5) | 4, + PRED_LT_MINUS = (0 << 5) | 14, + PRED_LE_MINUS = (1 << 5) | 6, + PRED_EQ_MINUS = (2 << 5) | 14, + PRED_GE_MINUS = (0 << 5) | 6, + PRED_GT_MINUS = (1 << 5) | 14, + PRED_NE_MINUS = (2 << 5) | 6, + PRED_UN_MINUS = (3 << 5) | 14, + PRED_NU_MINUS = (3 << 5) | 6, + PRED_LT_PLUS = (0 << 5) | 15, + PRED_LE_PLUS = (1 << 5) | 7, + PRED_EQ_PLUS = (2 << 5) | 15, + PRED_GE_PLUS = (0 << 5) | 7, + PRED_GT_PLUS = (1 << 5) | 15, + PRED_NE_PLUS = (2 << 5) | 7, + PRED_UN_PLUS = (3 << 5) | 15, + PRED_NU_PLUS = (3 << 5) | 7, + + // SPE scalar compare instructions always set the GT bit. + PRED_SPE = PRED_GT, + + // When dealing with individual condition-register bits, we have simple set + // and unset predicates. + PRED_BIT_SET = 1024, + PRED_BIT_UNSET = 1025 + }; + + // Bit for branch taken (plus) or not-taken (minus) hint + enum BranchHintBit { + BR_NO_HINT = 0x0, + BR_NONTAKEN_HINT = 0x2, + BR_TAKEN_HINT = 0x3, + BR_HINT_MASK = 0X3 + }; + + /// Invert the specified predicate. != -> ==, < -> >=. + Predicate InvertPredicate(Predicate Opcode); + + /// Assume the condition register is set by MI(a,b), return the predicate if + /// we modify the instructions such that condition register is set by MI(b,a). + Predicate getSwappedPredicate(Predicate Opcode); + + /// Return the condition without hint bits. + inline unsigned getPredicateCondition(Predicate Opcode) { + return (unsigned)(Opcode & ~BR_HINT_MASK); + } + + /// Return the hint bits of the predicate. + inline unsigned getPredicateHint(Predicate Opcode) { + return (unsigned)(Opcode & BR_HINT_MASK); + } + + /// Return predicate consisting of specified condition and hint bits. + inline Predicate getPredicate(unsigned Condition, unsigned Hint) { + return (Predicate)((Condition & ~BR_HINT_MASK) | + (Hint & BR_HINT_MASK)); + } +} +} + +#endif diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp index 77b0331bb1..c796f66c7c 100644 --- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp +++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp @@ -1,81 +1,81 @@ -//===-- PPCXCOFFObjectWriter.cpp - PowerPC XCOFF Writer -------------------===// -// -// -// 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/PPCFixupKinds.h" -#include "MCTargetDesc/PPCMCTargetDesc.h" -#include "llvm/BinaryFormat/XCOFF.h" -#include "llvm/MC/MCFixup.h" -#include "llvm/MC/MCFixupKindInfo.h" -#include "llvm/MC/MCValue.h" -#include "llvm/MC/MCXCOFFObjectWriter.h" - -using namespace llvm; - -namespace { -class PPCXCOFFObjectWriter : public MCXCOFFObjectTargetWriter { - static constexpr uint8_t SignBitMask = 0x80; - -public: - PPCXCOFFObjectWriter(bool Is64Bit); - - std::pair<uint8_t, uint8_t> - getRelocTypeAndSignSize(const MCValue &Target, const MCFixup &Fixup, - bool IsPCRel) const override; -}; -} // end anonymous namespace - -PPCXCOFFObjectWriter::PPCXCOFFObjectWriter(bool Is64Bit) - : MCXCOFFObjectTargetWriter(Is64Bit) {} - -std::unique_ptr<MCObjectTargetWriter> -llvm::createPPCXCOFFObjectWriter(bool Is64Bit) { - return std::make_unique<PPCXCOFFObjectWriter>(Is64Bit); -} - -std::pair<uint8_t, uint8_t> PPCXCOFFObjectWriter::getRelocTypeAndSignSize( - const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const { - const MCSymbolRefExpr::VariantKind Modifier = - Target.isAbsolute() ? MCSymbolRefExpr::VK_None - : Target.getSymA()->getKind(); - // People from AIX OS team says AIX link editor does not care about - // the sign bit in the relocation entry "most" of the time. - // The system assembler seems to set the sign bit on relocation entry - // based on similar property of IsPCRel. So we will do the same here. - // TODO: More investigation on how assembler decides to set the sign - // bit, and we might want to match that. - const uint8_t EncodedSignednessIndicator = IsPCRel ? SignBitMask : 0u; - - // The magic number we use in SignAndSize has a strong relationship with - // the corresponding MCFixupKind. In most cases, it's the MCFixupKind - // number - 1, because SignAndSize encodes the bit length being - // relocated minus 1. - switch ((unsigned)Fixup.getKind()) { - default: - report_fatal_error("Unimplemented fixup kind."); +//===-- PPCXCOFFObjectWriter.cpp - PowerPC XCOFF Writer -------------------===// +// +// +// 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/PPCFixupKinds.h" +#include "MCTargetDesc/PPCMCTargetDesc.h" +#include "llvm/BinaryFormat/XCOFF.h" +#include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCFixupKindInfo.h" +#include "llvm/MC/MCValue.h" +#include "llvm/MC/MCXCOFFObjectWriter.h" + +using namespace llvm; + +namespace { +class PPCXCOFFObjectWriter : public MCXCOFFObjectTargetWriter { + static constexpr uint8_t SignBitMask = 0x80; + +public: + PPCXCOFFObjectWriter(bool Is64Bit); + + std::pair<uint8_t, uint8_t> + getRelocTypeAndSignSize(const MCValue &Target, const MCFixup &Fixup, + bool IsPCRel) const override; +}; +} // end anonymous namespace + +PPCXCOFFObjectWriter::PPCXCOFFObjectWriter(bool Is64Bit) + : MCXCOFFObjectTargetWriter(Is64Bit) {} + +std::unique_ptr<MCObjectTargetWriter> +llvm::createPPCXCOFFObjectWriter(bool Is64Bit) { + return std::make_unique<PPCXCOFFObjectWriter>(Is64Bit); +} + +std::pair<uint8_t, uint8_t> PPCXCOFFObjectWriter::getRelocTypeAndSignSize( + const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const { + const MCSymbolRefExpr::VariantKind Modifier = + Target.isAbsolute() ? MCSymbolRefExpr::VK_None + : Target.getSymA()->getKind(); + // People from AIX OS team says AIX link editor does not care about + // the sign bit in the relocation entry "most" of the time. + // The system assembler seems to set the sign bit on relocation entry + // based on similar property of IsPCRel. So we will do the same here. + // TODO: More investigation on how assembler decides to set the sign + // bit, and we might want to match that. + const uint8_t EncodedSignednessIndicator = IsPCRel ? SignBitMask : 0u; + + // The magic number we use in SignAndSize has a strong relationship with + // the corresponding MCFixupKind. In most cases, it's the MCFixupKind + // number - 1, because SignAndSize encodes the bit length being + // relocated minus 1. + switch ((unsigned)Fixup.getKind()) { + default: + report_fatal_error("Unimplemented fixup kind."); case PPC::fixup_ppc_half16: { const uint8_t SignAndSizeForHalf16 = EncodedSignednessIndicator | 15; - switch (Modifier) { - default: - report_fatal_error("Unsupported modifier for half16 fixup."); - case MCSymbolRefExpr::VK_None: + switch (Modifier) { + default: + report_fatal_error("Unsupported modifier for half16 fixup."); + case MCSymbolRefExpr::VK_None: return {XCOFF::RelocationType::R_TOC, SignAndSizeForHalf16}; case MCSymbolRefExpr::VK_PPC_U: return {XCOFF::RelocationType::R_TOCU, SignAndSizeForHalf16}; case MCSymbolRefExpr::VK_PPC_L: return {XCOFF::RelocationType::R_TOCL, SignAndSizeForHalf16}; - } + } } break; - case PPC::fixup_ppc_br24: - // Branches are 4 byte aligned, so the 24 bits we encode in - // the instruction actually represents a 26 bit offset. - return {XCOFF::RelocationType::R_RBR, EncodedSignednessIndicator | 25}; - case FK_Data_4: - return {XCOFF::RelocationType::R_POS, EncodedSignednessIndicator | 31}; - } -} + case PPC::fixup_ppc_br24: + // Branches are 4 byte aligned, so the 24 bits we encode in + // the instruction actually represents a 26 bit offset. + return {XCOFF::RelocationType::R_RBR, EncodedSignednessIndicator | 25}; + case FK_Data_4: + return {XCOFF::RelocationType::R_POS, EncodedSignednessIndicator | 31}; + } +} diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/ya.make b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/ya.make index 903dc6ec7f..4c4de3eb3d 100644 --- a/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/ya.make +++ b/contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc/ya.make @@ -1,12 +1,12 @@ -# Generated by devtools/yamaker. - -LIBRARY() - +# Generated by devtools/yamaker. + +LIBRARY() + OWNER( orivej g:cpp-contrib ) - + LICENSE( Apache-2.0 WITH LLVM-exception AND NCSA @@ -14,36 +14,36 @@ LICENSE( LICENSE_TEXTS(.yandex_meta/licenses.list.txt) -PEERDIR( +PEERDIR( contrib/libs/llvm12 contrib/libs/llvm12/include contrib/libs/llvm12/lib/BinaryFormat contrib/libs/llvm12/lib/MC contrib/libs/llvm12/lib/Support contrib/libs/llvm12/lib/Target/PowerPC/TargetInfo -) - -ADDINCL( +) + +ADDINCL( ${ARCADIA_BUILD_ROOT}/contrib/libs/llvm12/lib/Target/PowerPC contrib/libs/llvm12/lib/Target/PowerPC contrib/libs/llvm12/lib/Target/PowerPC/MCTargetDesc -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -SRCS( - PPCAsmBackend.cpp - PPCELFObjectWriter.cpp - PPCELFStreamer.cpp - PPCInstPrinter.cpp - PPCMCAsmInfo.cpp - PPCMCCodeEmitter.cpp - PPCMCExpr.cpp - PPCMCTargetDesc.cpp - PPCPredicates.cpp - PPCXCOFFObjectWriter.cpp -) - -END() +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +SRCS( + PPCAsmBackend.cpp + PPCELFObjectWriter.cpp + PPCELFStreamer.cpp + PPCInstPrinter.cpp + PPCMCAsmInfo.cpp + PPCMCCodeEmitter.cpp + PPCMCExpr.cpp + PPCMCTargetDesc.cpp + PPCPredicates.cpp + PPCXCOFFObjectWriter.cpp +) + +END() |