diff options
Diffstat (limited to 'lib/Target/PowerPC/MCTargetDesc')
17 files changed, 835 insertions, 116 deletions
diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp index a405dd70c307..8778e916f7e4 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp @@ -1,9 +1,8 @@ //===-- PPCAsmBackend.cpp - PPC Assembler Backend -------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -29,6 +28,7 @@ static uint64_t adjustFixupValue(unsigned Kind, uint64_t Value) { switch (Kind) { default: llvm_unreachable("Unknown fixup kind!"); + case FK_NONE: case FK_Data_1: case FK_Data_2: case FK_Data_4: @@ -52,6 +52,8 @@ static unsigned getFixupKindNumBytes(unsigned Kind) { switch (Kind) { default: llvm_unreachable("Unknown fixup kind!"); + case FK_NONE: + return 0; case FK_Data_1: return 1; case FK_Data_2: @@ -74,10 +76,12 @@ static unsigned getFixupKindNumBytes(unsigned Kind) { namespace { class PPCAsmBackend : public MCAsmBackend { - const Target &TheTarget; +protected: + Triple TT; public: - PPCAsmBackend(const Target &T, support::endianness Endian) - : MCAsmBackend(Endian), TheTarget(T) {} + PPCAsmBackend(const Target &T, const Triple &TT) + : MCAsmBackend(TT.isLittleEndian() ? support::little : support::big), + TT(TT) {} unsigned getNumFixupKinds() const override { return PPC::NumTargetFixupKinds; @@ -136,9 +140,11 @@ public: bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target) override { - switch ((PPC::Fixups)Fixup.getKind()) { + switch ((unsigned)Fixup.getKind()) { default: return false; + case FK_NONE: + return true; case PPC::fixup_ppc_br24: case PPC::fixup_ppc_br24abs: // If the target symbol has a local entry point we must not attempt @@ -187,59 +193,76 @@ public: return true; } - - unsigned getPointerSize() const { - StringRef Name = TheTarget.getName(); - if (Name == "ppc64" || Name == "ppc64le") return 8; - assert(Name == "ppc32" && "Unknown target name!"); - return 4; - } }; } // end anonymous namespace // FIXME: This should be in a separate file. namespace { - class DarwinPPCAsmBackend : public PPCAsmBackend { - public: - DarwinPPCAsmBackend(const Target &T) : PPCAsmBackend(T, support::big) { } - - std::unique_ptr<MCObjectTargetWriter> - createObjectTargetWriter() const override { - bool is64 = getPointerSize() == 8; - return createPPCMachObjectWriter( - /*Is64Bit=*/is64, - (is64 ? MachO::CPU_TYPE_POWERPC64 : MachO::CPU_TYPE_POWERPC), - MachO::CPU_SUBTYPE_POWERPC_ALL); - } - }; - - class ELFPPCAsmBackend : public PPCAsmBackend { - uint8_t OSABI; - public: - ELFPPCAsmBackend(const Target &T, support::endianness Endian, - uint8_t OSABI) - : PPCAsmBackend(T, Endian), OSABI(OSABI) {} - - std::unique_ptr<MCObjectTargetWriter> - createObjectTargetWriter() const override { - bool is64 = getPointerSize() == 8; - return createPPCELFObjectWriter(is64, OSABI); - } - }; + +class DarwinPPCAsmBackend : public PPCAsmBackend { +public: + DarwinPPCAsmBackend(const Target &T, const Triple &TT) + : PPCAsmBackend(T, TT) {} + + std::unique_ptr<MCObjectTargetWriter> + createObjectTargetWriter() const override { + bool Is64 = TT.isPPC64(); + return createPPCMachObjectWriter( + /*Is64Bit=*/Is64, + (Is64 ? MachO::CPU_TYPE_POWERPC64 : MachO::CPU_TYPE_POWERPC), + MachO::CPU_SUBTYPE_POWERPC_ALL); + } +}; + +class ELFPPCAsmBackend : public PPCAsmBackend { +public: + ELFPPCAsmBackend(const Target &T, const Triple &TT) : PPCAsmBackend(T, TT) {} + + 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.isPPC64()) { + if (Name == "R_PPC64_NONE") + return FK_NONE; + } else { + if (Name == "R_PPC_NONE") + return FK_NONE; + } + return MCAsmBackend::getFixupKind(Name); +} + MCAsmBackend *llvm::createPPCAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options) { const Triple &TT = STI.getTargetTriple(); if (TT.isOSDarwin()) - return new DarwinPPCAsmBackend(T); + return new DarwinPPCAsmBackend(T, TT); + + if (TT.isOSBinFormatXCOFF()) + return new XCOFFPPCAsmBackend(T, TT); - uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS()); - bool IsLittleEndian = TT.getArch() == Triple::ppc64le; - return new ELFPPCAsmBackend( - T, IsLittleEndian ? support::little : support::big, OSABI); + return new ELFPPCAsmBackend(T, TT); } diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp index a3caf9a7a5ee..042ddf48d5df 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp @@ -1,9 +1,8 @@ //===-- PPCELFObjectWriter.cpp - PPC ELF Writer ---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -134,6 +133,9 @@ unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, } else { switch ((unsigned)Fixup.getKind()) { default: llvm_unreachable("invalid fixup kind!"); + case FK_NONE: + Type = ELF::R_PPC_NONE; + break; case PPC::fixup_ppc_br24abs: Type = ELF::R_PPC_ADDR24; break; diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h b/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h index dce443997ea5..845489788c86 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h +++ b/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h @@ -1,9 +1,8 @@ //===-- PPCFixupKinds.h - PPC Specific Fixup Entries ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp new file mode 100644 index 000000000000..0e64ae55ab1c --- /dev/null +++ b/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp @@ -0,0 +1,543 @@ +//===-- 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); + if (RegName[0] == 'q' /* QPX */) { + // The system toolchain on the BG/Q does not understand QPX register names + // in .cfi_* directives, so print the name of the floating-point + // subregister instead. + std::string RN(RegName); + + RN[0] = 'f'; + OS << RN; + + return; + } + + OS << RegName; +} + +void PPCInstPrinter::printInst(const MCInst *MI, raw_ostream &O, + StringRef Annot, const MCSubtargetInfo &STI) { + // 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, O); + O << ", "; + printOperand(MI, 1, O); + O << ", " << (unsigned int)SH; + + printAnnotation(O, Annot); + return; + } + } + + if ((MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) && + MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) { + O << "\tmr "; + printOperand(MI, 0, O); + O << ", "; + printOperand(MI, 1, O); + 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, O); + O << ", "; + printOperand(MI, 1, 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 << ", "; + + printOperand(MI, 1, O); + O << ", "; + printOperand(MI, 2, 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 (!L || L == 1 || L == 3) { + O << "\tdcbf"; + if (L == 1 || L == 3) + O << "l"; + if (L == 3) + O << "p"; + O << " "; + + printOperand(MI, 1, O); + O << ", "; + printOperand(MI, 2, O); + + printAnnotation(O, Annot); + return; + } + } + + if (!printAliasInstr(MI, O)) + printInstruction(MI, O); + printAnnotation(O, Annot); +} + + +void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo, + 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, O); +} + +void PPCInstPrinter::printATBitsAsHint(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, + 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 <= 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 <= 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 <= 15 && "Invalid u4imm argument!"); + O << (unsigned int)Value; +} + +void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + int Value = MI->getOperand(OpNo).getImm(); + Value = SignExtend32<5>(Value); + O << (int)Value; +} + +void PPCInstPrinter::printU5ImmOperand(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, + 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 <= 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 char Value = MI->getOperand(OpNo).getImm(); + O << (unsigned int)Value; +} + +void PPCInstPrinter::printU10ImmOperand(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, + 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) { + if (MI->getOperand(OpNo).isImm()) + O << (short)MI->getOperand(OpNo).getImm(); + else + printOperand(MI, OpNo, O); +} + +void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + if (MI->getOperand(OpNo).isImm()) + O << (unsigned short)MI->getOperand(OpNo).getImm(); + else + printOperand(MI, OpNo, O); +} + +void PPCInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + if (!MI->getOperand(OpNo).isImm()) + return printOperand(MI, OpNo, O); + + // Branches can take an immediate operand. This is used by the branch + // selection pass to print .+8, an eight byte displacement from the PC. + O << "."; + int32_t Imm = SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2); + if (Imm >= 0) + O << "+"; + O << Imm; +} + +void PPCInstPrinter::printAbsBranchOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + if (!MI->getOperand(OpNo).isImm()) + return printOperand(MI, OpNo, O); + + O << SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2); +} + + +void PPCInstPrinter::printcrbitm(const MCInst *MI, unsigned OpNo, + 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, + raw_ostream &O) { + printS16ImmOperand(MI, OpNo, O); + O << '('; + if (MI->getOperand(OpNo+1).getReg() == PPC::R0) + O << "0"; + else + printOperand(MI, OpNo+1, O); + O << ')'; +} + +void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo, + 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, O); + O << ", "; + printOperand(MI, OpNo+1, O); +} + +void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo, + 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(); + O << '('; + printOperand(MI, OpNo+1, O); + O << ')'; + if (RefExp->getKind() != MCSymbolRefExpr::VK_None) + 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.isOSDarwin() || 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 { + if (!TT.isOSDarwin() && !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 TT.isOSDarwin() || FullRegNamesWithPercent || FullRegNames; +} + +void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, + 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); +} + diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h b/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h new file mode 100644 index 000000000000..725ae2a7081b --- /dev/null +++ b/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h @@ -0,0 +1,76 @@ +//===- 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, raw_ostream &O, StringRef Annot, + const MCSubtargetInfo &STI) override; + + // Autogenerated by tblgen. + void printInstruction(const MCInst *MI, raw_ostream &O); + static const char *getRegisterName(unsigned RegNo); + + bool printAliasInstr(const MCInst *MI, raw_ostream &OS); + void printCustomAliasOperand(const MCInst *MI, unsigned OpIdx, + unsigned PrintMethodIdx, + raw_ostream &OS); + + void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printPredicateOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O, const char *Modifier = nullptr); + void printATBitsAsHint(const MCInst *MI, unsigned OpNo, raw_ostream &O); + + void printU1ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printU2ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printU3ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printU4ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printS5ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printU5ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printU6ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printU7ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printU8ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printU10ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printU12ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printS16ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printU16ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printBranchOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printAbsBranchOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printTLSCall(const MCInst *MI, unsigned OpNo, raw_ostream &O); + + void printcrbitm(const MCInst *MI, unsigned OpNo, raw_ostream &O); + + void printMemRegImm(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printMemRegReg(const MCInst *MI, unsigned OpNo, raw_ostream &O); +}; +} // end namespace llvm + +#endif diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp index fb7bf23509c7..5f0005ea1d7b 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp @@ -1,9 +1,8 @@ //===-- PPCMCAsmInfo.cpp - PPC asm properties -----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -82,3 +81,9 @@ PPCELFMCAsmInfo::PPCELFMCAsmInfo(bool is64Bit, const Triple& T) { UseIntegratedAssembler = true; } +void PPCXCOFFMCAsmInfo::anchor() {} + +PPCXCOFFMCAsmInfo::PPCXCOFFMCAsmInfo(bool Is64Bit, const Triple &T) { + assert(!IsLittleEndian && "Little-endian XCOFF not supported."); + CodePointerSize = CalleeSaveStackSlotSize = Is64Bit ? 8 : 4; +} diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.h b/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.h index e252ac944d40..42cb62ad26a4 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.h +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.h @@ -1,13 +1,12 @@ //===-- PPCMCAsmInfo.h - PPC asm properties --------------------*- C++ -*--===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 declaration of the MCAsmInfoDarwin class. +// This file contains the declarations of the PowerPC MCAsmInfo classes. // //===----------------------------------------------------------------------===// @@ -16,6 +15,7 @@ #include "llvm/MC/MCAsmInfoDarwin.h" #include "llvm/MC/MCAsmInfoELF.h" +#include "llvm/MC/MCAsmInfoXCOFF.h" namespace llvm { class Triple; @@ -34,6 +34,13 @@ public: explicit PPCELFMCAsmInfo(bool is64Bit, const Triple &); }; +class PPCXCOFFMCAsmInfo : public MCAsmInfoXCOFF { + virtual void anchor(); + +public: + explicit PPCXCOFFMCAsmInfo(bool is64Bit, const Triple &); +}; + } // namespace llvm #endif diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp index 8c15ade6f9c4..676efc500455 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp @@ -1,9 +1,8 @@ //===-- PPCMCCodeEmitter.cpp - Convert PPC code to machine code -----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -217,7 +216,7 @@ unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst &MI, unsigned OpNo, Fixups.push_back(MCFixup::create(0, MO.getExpr(), (MCFixupKind)PPC::fixup_ppc_nofixup)); const Triple &TT = STI.getTargetTriple(); - bool isPPC64 = TT.getArch() == Triple::ppc64 || TT.getArch() == Triple::ppc64le; + bool isPPC64 = TT.isPPC64(); return CTX.getRegisterInfo()->getEncodingValue(isPPC64 ? PPC::X13 : PPC::R2); } diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h b/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h index a4bcff4b9450..1324faa12553 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h @@ -1,9 +1,8 @@ //===-- PPCMCCodeEmitter.h - Convert PPC code to machine code -------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -99,9 +98,10 @@ public: unsigned getInstSizeInBytes(const MCInst &MI) const; private: - uint64_t computeAvailableFeatures(const FeatureBitset &FB) const; - void verifyInstructionPredicates(const MCInst &MI, - uint64_t AvailableFeatures) const; + FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const; + void + verifyInstructionPredicates(const MCInst &MI, + const FeatureBitset &AvailableFeatures) const; }; } // namespace llvm diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp index 32e6a0bdd65f..d467f5c4a439 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp @@ -1,9 +1,8 @@ //===-- PPCMCExpr.cpp - PPC specific MC expression classes ----------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h b/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h index 8bb4791d13dd..449e2c34f74d 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h @@ -1,9 +1,8 @@ //===-- PPCMCExpr.h - PPC specific MC expression classes --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp index a1e4e07b25af..90c3c8d20edb 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp @@ -1,9 +1,8 @@ //===-- PPCMCTargetDesc.cpp - PowerPC Target Descriptions -----------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -12,9 +11,11 @@ //===----------------------------------------------------------------------===// #include "MCTargetDesc/PPCMCTargetDesc.h" -#include "InstPrinter/PPCInstPrinter.h" +#include "MCTargetDesc/PPCInstPrinter.h" #include "MCTargetDesc/PPCMCAsmInfo.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" @@ -47,9 +48,9 @@ using namespace llvm; #define GET_REGINFO_MC_DESC #include "PPCGenRegisterInfo.inc" -// Pin the vtable to this file. PPCTargetStreamer::PPCTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} +// Pin the vtable to this file. PPCTargetStreamer::~PPCTargetStreamer() = default; static MCInstrInfo *createPPCMCInstrInfo() { @@ -82,6 +83,8 @@ static MCAsmInfo *createPPCMCAsmInfo(const MCRegisterInfo &MRI, MCAsmInfo *MAI; if (TheTriple.isOSDarwin()) MAI = new PPCMCAsmInfoDarwin(isPPC64, TheTriple); + else if (TheTriple.isOSBinFormatXCOFF()) + MAI = new PPCXCOFFMCAsmInfo(isPPC64, TheTriple); else MAI = new PPCELFMCAsmInfo(isPPC64, TheTriple); @@ -182,16 +185,33 @@ public: 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 (Value->getKind() != MCExpr::SymbolRef) - return; - const auto &RhsSym = cast<MCSymbolELF>( - static_cast<const MCSymbolRefExpr *>(Value)->getSymbol()); - unsigned Other = Symbol->getOther(); + if (copyLocalEntry(Symbol, Value)) + UpdateOther.insert(Symbol); + else + UpdateOther.erase(Symbol); + } + + void finish() override { + for (auto *Sym : UpdateOther) + copyLocalEntry(Sym, Sym->getVariableValue()); + } + +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; - Symbol->setOther(Other); + D->setOther(Other); + return true; } }; @@ -217,6 +237,27 @@ public: } }; +class PPCTargetXCOFFStreamer : public PPCTargetStreamer { +public: + PPCTargetXCOFFStreamer(MCStreamer &S) : PPCTargetStreamer(S) {} + + void emitTCEntry(const MCSymbol &S) override { + report_fatal_error("TOC entries not supported yet."); + } + + 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, @@ -231,6 +272,8 @@ 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); } diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h b/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h index d6e450cba0d7..74b67bd2e928 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h @@ -1,9 +1,8 @@ //===-- PPCMCTargetDesc.h - PowerPC Target Descriptions ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -37,10 +36,6 @@ class Triple; class StringRef; class raw_pwrite_stream; -Target &getThePPC32Target(); -Target &getThePPC64Target(); -Target &getThePPC64LETarget(); - MCCodeEmitter *createPPCMCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, MCContext &Ctx); @@ -56,6 +51,9 @@ std::unique_ptr<MCObjectTargetWriter> createPPCELFObjectWriter(bool Is64Bit, 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, diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp index ff6cf584da23..4cf7fd15fa75 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp @@ -1,9 +1,8 @@ //===-- PPCMachObjectWriter.cpp - PPC Mach-O Writer -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.cpp index c2987b641c04..284e52c298a2 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.cpp @@ -1,9 +1,8 @@ //===-- PPCPredicates.cpp - PPC Branch Predicate Information --------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h b/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h index 481ba3f09cc7..d686a8ea2a22 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h +++ b/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h @@ -1,9 +1,8 @@ //===-- PPCPredicates.h - PPC Branch Predicate Information ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp new file mode 100644 index 000000000000..9c661286d455 --- /dev/null +++ b/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp @@ -0,0 +1,29 @@ +//===-- 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 "PPCMCTargetDesc.h" +#include "llvm/MC/MCXCOFFObjectWriter.h" + +using namespace llvm; + +namespace { +class PPCXCOFFObjectWriter : public MCXCOFFObjectTargetWriter { + +public: + PPCXCOFFObjectWriter(bool Is64Bit); +}; +} // end anonymous namespace + +PPCXCOFFObjectWriter::PPCXCOFFObjectWriter(bool Is64Bit) + : MCXCOFFObjectTargetWriter(Is64Bit) {} + +std::unique_ptr<MCObjectTargetWriter> +llvm::createPPCXCOFFObjectWriter(bool Is64Bit) { + return llvm::make_unique<PPCXCOFFObjectWriter>(Is64Bit); +} |