diff --git a/llvm/include/llvm/MC/MCAsmInfoXCOFF.h b/llvm/include/llvm/MC/MCAsmInfoXCOFF.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/MC/MCAsmInfoXCOFF.h @@ -0,0 +1,25 @@ +//===- MCAsmInfoXCOFF.h XCOFF 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCASMINFOXCOFF_H +#define LLVM_MC_MCASMINFOXCOFF_H + +#include "llvm/MC/MCAsmInfo.h" + +namespace llvm { + +class MCAsmInfoXCOFF : public MCAsmInfo { + virtual void anchor(); + +protected: + MCAsmInfoXCOFF(); +}; + +} // end namespace llvm + +#endif // LLVM_MC_MCASMINFOXCOFF_H diff --git a/llvm/include/llvm/MC/MCXCOFFObjectWriter.h b/llvm/include/llvm/MC/MCXCOFFObjectWriter.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/MC/MCXCOFFObjectWriter.h @@ -0,0 +1,36 @@ +//===-- llvm/MC/MCXCOFFObjectWriter.h - XCOFF Object 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCXCOFFOBJECTWRITER_H +#define LLVM_MC_MCXCOFFOBJECTWRITER_H + +#include "llvm/MC/MCObjectWriter.h" + +namespace llvm { + +class raw_pwrite_stream; + +class MCXCOFFObjectTargetWriter : public MCObjectTargetWriter { +protected: + MCXCOFFObjectTargetWriter(); + +public: + virtual ~MCXCOFFObjectTargetWriter(); + + virtual Triple::ObjectFormatType getFormat() const { return Triple::XCOFF; } + static bool classof(const MCObjectTargetWriter *W) { + return W->getFormat() == Triple::XCOFF; + } +}; + +std::unique_ptr +createXCOFFObjectWriter(std::unique_ptr MOTW, + raw_pwrite_stream &OS); +} // namespace llvm + +#endif // LLVM_MC_MCXCOFFOBJECTWRITER_H diff --git a/llvm/include/llvm/MC/MCXCOFFStreamer.h b/llvm/include/llvm/MC/MCXCOFFStreamer.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/MC/MCXCOFFStreamer.h @@ -0,0 +1,35 @@ +//===- MCXCOFFObjectStreamer.h - MCStreamer XCOFF Object File Interface ---===// +// +// 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_MC_MCXCOFFSTREAMER_H +#define LLVM_MC_MCXCOFFSTREAMER_H + +#include "llvm/MC/MCObjectStreamer.h" + +namespace llvm { + +class MCXCOFFStreamer : public MCObjectStreamer { +public: + MCXCOFFStreamer(MCContext &Context, std::unique_ptr MAB, + std::unique_ptr OW, + std::unique_ptr Emitter); + + bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; + void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) override; + void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr, + uint64_t Size = 0, unsigned ByteAlignment = 0, + SMLoc Loc = SMLoc()) override; + void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override; + + void reset() override { MCObjectStreamer::reset(); } +}; + +} // end namespace llvm + +#endif // LLVM_MC_MCXCOFFSTREAMER_H diff --git a/llvm/include/llvm/Support/TargetRegistry.h b/llvm/include/llvm/Support/TargetRegistry.h --- a/llvm/include/llvm/Support/TargetRegistry.h +++ b/llvm/include/llvm/Support/TargetRegistry.h @@ -100,6 +100,11 @@ std::unique_ptr &&OW, std::unique_ptr &&CE, bool RelaxAll); +MCStreamer *createXCOFFStreamer(MCContext &Ctx, + std::unique_ptr &&TAB, + std::unique_ptr &&OW, + std::unique_ptr &&CE, + bool RelaxAll); MCRelocationInfo *createMCRelocationInfo(const Triple &TT, MCContext &Ctx); @@ -177,6 +182,12 @@ std::unique_ptr &&TAB, std::unique_ptr &&OW, std::unique_ptr &&Emitter, bool RelaxAll); + using XCOFFStreamerCtorTy = + MCStreamer *(*)(const Triple &T, MCContext &Ctx, + std::unique_ptr &&TAB, + std::unique_ptr &&OW, + std::unique_ptr &&CE, bool RelaxAll); + using NullTargetStreamerCtorTy = MCTargetStreamer *(*)(MCStreamer &S); using AsmTargetStreamerCtorTy = MCTargetStreamer *(*)( MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrint, @@ -264,6 +275,7 @@ MachOStreamerCtorTy MachOStreamerCtorFn = nullptr; ELFStreamerCtorTy ELFStreamerCtorFn = nullptr; WasmStreamerCtorTy WasmStreamerCtorFn = nullptr; + XCOFFStreamerCtorTy XCOFFStreamerCtorFn = nullptr; /// Construction function for this target's null TargetStreamer, if /// registered (default = nullptr). @@ -504,6 +516,14 @@ S = createWasmStreamer(Ctx, std::move(TAB), std::move(OW), std::move(Emitter), RelaxAll); break; + case Triple::XCOFF: + if (XCOFFStreamerCtorFn) + S = XCOFFStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW), + std::move(Emitter), RelaxAll); + else + S = createXCOFFStreamer(Ctx, std::move(TAB), std::move(OW), + std::move(Emitter), RelaxAll); + break; } if (ObjectTargetStreamerCtorFn) ObjectTargetStreamerCtorFn(*S, STI); @@ -851,6 +871,10 @@ T.WasmStreamerCtorFn = Fn; } + static void RegisterXCOFFStreamer(Target &T, Target::XCOFFStreamerCtorTy Fn) { + T.XCOFFStreamerCtorFn = Fn; + } + static void RegisterNullTargetStreamer(Target &T, Target::NullTargetStreamerCtorTy Fn) { T.NullTargetStreamerCtorFn = Fn; diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt --- a/llvm/lib/MC/CMakeLists.txt +++ b/llvm/lib/MC/CMakeLists.txt @@ -7,6 +7,7 @@ MCAsmInfoDarwin.cpp MCAsmInfoELF.cpp MCAsmInfoWasm.cpp + MCAsmInfoXCOFF.cpp MCAsmMacro.cpp MCAsmStreamer.cpp MCAssembler.cpp @@ -49,11 +50,14 @@ MCWin64EH.cpp MCWinCOFFStreamer.cpp MCWinEH.cpp + MCXCOFFObjectTargetWriter.cpp + MCXCOFFStreamer.cpp MachObjectWriter.cpp StringTableBuilder.cpp SubtargetFeature.cpp WasmObjectWriter.cpp WinCOFFObjectWriter.cpp + XCOFFObjectWriter.cpp ADDITIONAL_HEADER_DIRS ${LLVM_MAIN_INCLUDE_DIR}/llvm/MC diff --git a/llvm/lib/MC/MCAsmBackend.cpp b/llvm/lib/MC/MCAsmBackend.cpp --- a/llvm/lib/MC/MCAsmBackend.cpp +++ b/llvm/lib/MC/MCAsmBackend.cpp @@ -16,6 +16,7 @@ #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCWasmObjectWriter.h" #include "llvm/MC/MCWinCOFFObjectWriter.h" +#include "llvm/MC/MCXCOFFObjectWriter.h" #include #include #include @@ -43,6 +44,9 @@ case Triple::Wasm: return createWasmObjectWriter(cast(std::move(TW)), OS); + case Triple::XCOFF: + return createXCOFFObjectWriter( + cast(std::move(TW)), OS); default: llvm_unreachable("unexpected object format"); } diff --git a/llvm/lib/MC/MCAsmInfoXCOFF.cpp b/llvm/lib/MC/MCAsmInfoXCOFF.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/MC/MCAsmInfoXCOFF.cpp @@ -0,0 +1,15 @@ +//===- MC/MCAsmInfoXCOFF.cpp XCOFF 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 +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCAsmInfoXCOFF.h" + +using namespace llvm; + +void MCAsmInfoXCOFF::anchor() {} + +MCAsmInfoXCOFF::MCAsmInfoXCOFF() { HasDotTypeDotSizeDirective = false; } diff --git a/llvm/lib/MC/MCXCOFFObjectTargetWriter.cpp b/llvm/lib/MC/MCXCOFFObjectTargetWriter.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/MC/MCXCOFFObjectTargetWriter.cpp @@ -0,0 +1,14 @@ +//===- MCXCOFFObjectTargetWriter.cpp - XCOFF Target Writer Subclass -------===// +// +// 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 "llvm/MC/MCXCOFFObjectWriter.h" + +using namespace llvm; + +MCXCOFFObjectTargetWriter::MCXCOFFObjectTargetWriter() = default; +MCXCOFFObjectTargetWriter::~MCXCOFFObjectTargetWriter() = default; diff --git a/llvm/lib/MC/MCXCOFFStreamer.cpp b/llvm/lib/MC/MCXCOFFStreamer.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/MC/MCXCOFFStreamer.cpp @@ -0,0 +1,60 @@ +//===- lib/MC/MCXCOFFStreamer.cpp - XCOFF Object Output -------------------===// +// +// 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 assembles .s files and emits XCOFF .o object files. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCXCOFFStreamer.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/Support/TargetRegistry.h" + +using namespace llvm; + +MCXCOFFStreamer::MCXCOFFStreamer(MCContext &Context, + std::unique_ptr MAB, + std::unique_ptr OW, + std::unique_ptr Emitter) + : MCObjectStreamer(Context, std::move(MAB), std::move(OW), + std::move(Emitter)) {} + +bool MCXCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, + MCSymbolAttr Attribute) { + llvm_unreachable("Not implemented yet"); + return false; +} + +void MCXCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) { + llvm_unreachable("Not implemented yet"); +} + +void MCXCOFFStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol, + uint64_t Size, unsigned ByteAlignment, + SMLoc Loc) { + llvm_unreachable("Not implemented yet"); +} + +void MCXCOFFStreamer::EmitInstToData(const MCInst &Inst, + const MCSubtargetInfo &) { + llvm_unreachable("Not implemented yet"); +} + +MCStreamer *llvm::createXCOFFStreamer(MCContext &Context, + std::unique_ptr &&MAB, + std::unique_ptr &&OW, + std::unique_ptr &&CE, + bool RelaxAll) { + MCXCOFFStreamer *S = new MCXCOFFStreamer(Context, std::move(MAB), + std::move(OW), std::move(CE)); + if (RelaxAll) + S->getAssembler().setRelaxAll(true); + return S; +} diff --git a/llvm/lib/MC/XCOFFObjectWriter.cpp b/llvm/lib/MC/XCOFFObjectWriter.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/MC/XCOFFObjectWriter.cpp @@ -0,0 +1,85 @@ +//===-- lib/MC/XCOFFObjectWriter.cpp - XCOFF file 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 +// +//===----------------------------------------------------------------------===// +// +// This file implements XCOFF object file writer information. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCValue.h" +#include "llvm/MC/MCXCOFFObjectWriter.h" + +using namespace llvm; + +class XCOFFObjectWriter : public MCObjectWriter { + support::endian::Writer W; + std::unique_ptr TargetObjectWriter; + + virtual void executePostLayoutBinding(llvm::MCAssembler &, + const llvm::MCAsmLayout &) override; + + virtual void recordRelocation(llvm::MCAssembler &, const llvm::MCAsmLayout &, + const llvm::MCFragment *, const llvm::MCFixup &, + llvm::MCValue, uint64_t &) override; + + virtual uint64_t writeObject(llvm::MCAssembler &, + const llvm::MCAsmLayout &) override; + +public: + XCOFFObjectWriter(std::unique_ptr MOTW, + raw_pwrite_stream &OS); +}; + +XCOFFObjectWriter::XCOFFObjectWriter( + std::unique_ptr MOTW, raw_pwrite_stream &OS) + : W(OS, support::big), TargetObjectWriter(std::move(MOTW)) {} + +void XCOFFObjectWriter::executePostLayoutBinding(llvm::MCAssembler &, + const llvm::MCAsmLayout &) { } + +void XCOFFObjectWriter::recordRelocation(llvm::MCAssembler &, + const llvm::MCAsmLayout &, + const llvm::MCFragment *, + const llvm::MCFixup &, llvm::MCValue, + uint64_t &) { + llvm_unreachable("Not yet implemented!"); +} + +uint64_t XCOFFObjectWriter::writeObject(llvm::MCAssembler &, + const llvm::MCAsmLayout &) { + uint64_t StartOffset = W.OS.tell(); + + // TODO FIXME Assign section numbers/finalize sections. + + // TODO FIXME Finialize symbols. + + // Write header. + time_t Now = time(nullptr); + // Magic. + W.write(0x01df); + // Number of sections. + W.write(0); + // Timestamp converted to an int32_t. + W.write(Now); + // Byte Offset to the start of the symbol table. + W.write(0); + // Number of entries in the symbol table. + W.write(0); + // Size of the optional header. + W.write(0); + // Flags. + W.write(0); + + return W.OS.tell() - StartOffset; +} + +std::unique_ptr +llvm::createXCOFFObjectWriter(std::unique_ptr MOTW, + raw_pwrite_stream &OS) { + return llvm::make_unique(std::move(MOTW), OS); +} diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/PowerPC/MCTargetDesc/CMakeLists.txt --- a/llvm/lib/Target/PowerPC/MCTargetDesc/CMakeLists.txt +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/CMakeLists.txt @@ -7,4 +7,5 @@ PPCPredicates.cpp PPCMachObjectWriter.cpp PPCELFObjectWriter.cpp + PPCXCOFFObjectWriter.cpp ) diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp @@ -227,6 +227,18 @@ } }; + class XCOFFPPCAsmBackend : public PPCAsmBackend { + public: + XCOFFPPCAsmBackend(const Target &T) : PPCAsmBackend(T, support::big) {} + + std::unique_ptr + createObjectTargetWriter() const override { + if (getPointerSize() == 8) + report_fatal_error("64-bit XCOFF object files are not supported yet."); + return createPPCXCOFFObjectWriter(); + } + }; + } // end anonymous namespace MCAsmBackend *llvm::createPPCAsmBackend(const Target &T, @@ -237,6 +249,9 @@ if (TT.isOSDarwin()) return new DarwinPPCAsmBackend(T); + if (TT.isOSBinFormatXCOFF()) + return new XCOFFPPCAsmBackend(T); + uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS()); bool IsLittleEndian = TT.getArch() == Triple::ppc64le; return new ELFPPCAsmBackend( diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.h b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.h --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.h +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.h @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This file contains the declaration of the MCAsmInfoDarwin class. +// This file contains the declarations of the PowerPC MCAsmInfo classes. // //===----------------------------------------------------------------------===// @@ -15,6 +15,7 @@ #include "llvm/MC/MCAsmInfoDarwin.h" #include "llvm/MC/MCAsmInfoELF.h" +#include "llvm/MC/MCAsmInfoXCOFF.h" namespace llvm { class Triple; @@ -33,6 +34,13 @@ explicit PPCELFMCAsmInfo(bool is64Bit, const Triple &); }; +class PPCXCOFFMCAsmInfo : public MCAsmInfoXCOFF { + virtual void anchor(); + +public: + explicit PPCXCOFFMCAsmInfo(); +}; + } // namespace llvm #endif diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp @@ -81,3 +81,6 @@ UseIntegratedAssembler = true; } +void PPCXCOFFMCAsmInfo::anchor() {} + +PPCXCOFFMCAsmInfo::PPCXCOFFMCAsmInfo() {} diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h @@ -55,6 +55,9 @@ std::unique_ptr createPPCMachObjectWriter(bool Is64Bit, uint32_t CPUType, uint32_t CPUSubtype); +/// Construct a PPC XCOFF object writer. +std::unique_ptr createPPCXCOFFObjectWriter(); + /// 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/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp @@ -81,8 +81,10 @@ MCAsmInfo *MAI; if (TheTriple.isOSDarwin()) MAI = new PPCMCAsmInfoDarwin(isPPC64, TheTriple); - else + else if (TheTriple.isOSBinFormatELF()) MAI = new PPCELFMCAsmInfo(isPPC64, TheTriple); + else + MAI = new PPCXCOFFMCAsmInfo(); // Initial state of the frame pointer is R1. unsigned Reg = isPPC64 ? PPC::X1 : PPC::R1; @@ -216,6 +218,27 @@ } }; +class PPCTargetXCOFFStreamer : public PPCTargetStreamer { +public: + PPCTargetXCOFFStreamer(MCStreamer &S) : PPCTargetStreamer(S) {} + + void emitTCEntry(const MCSymbol &S) override { + llvm_unreachable("Unknown pseudo-op: .tc"); + } + + void emitMachine(StringRef CPU) override { + llvm_unreachable("Not implemented yet."); + } + + 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"); + } +}; + } // end anonymous namespace static MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S, @@ -230,6 +253,8 @@ 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/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp @@ -0,0 +1,26 @@ +//===-- 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(); +}; +} // namespace + +PPCXCOFFObjectWriter::PPCXCOFFObjectWriter() : MCXCOFFObjectTargetWriter() {} + +std::unique_ptr llvm::createPPCXCOFFObjectWriter() { + return llvm::make_unique(); +} diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -157,6 +157,18 @@ void EmitStartOfAsmFile(Module &M) override; }; + class PPCAIXAsmPrinter : public PPCAsmPrinter { + public: + PPCAIXAsmPrinter(TargetMachine &TM, std::unique_ptr Streamer) + : PPCAsmPrinter(TM, std::move(Streamer)) {} + + StringRef getPassName() const override { + return "AIX PPC Assembly Printer"; + } + + bool doFinalization(Module &M) override; + }; + } // end anonymous namespace void PPCAsmPrinter::PrintSymbolOperand(const MachineOperand &MO, @@ -1637,6 +1649,10 @@ return AsmPrinter::doFinalization(M); } +bool PPCAIXAsmPrinter::doFinalization(Module &M) { + return AsmPrinter::doFinalization(M); +} + /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code /// for a MachineFunction to the given output stream, in a format that the /// Darwin assembler can deal with. @@ -1646,7 +1662,9 @@ std::unique_ptr &&Streamer) { if (tm.getTargetTriple().isMacOSX()) return new PPCDarwinAsmPrinter(tm, std::move(Streamer)); - return new PPCLinuxAsmPrinter(tm, std::move(Streamer)); + if (tm.getTargetTriple().isOSLinux()) + return new PPCLinuxAsmPrinter(tm, std::move(Streamer)); + return new PPCAIXAsmPrinter(tm, std::move(Streamer)); } // Force static initialization. diff --git a/llvm/test/CodeGen/PowerPC/aix-xcoff-basic.ll b/llvm/test/CodeGen/PowerPC/aix-xcoff-basic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-xcoff-basic.ll @@ -0,0 +1,23 @@ +; RUN: llc -mtriple powerpc-ibm-aix-xcoff -filetype=obj -o %t.o < %s +; RUN: llvm-readobj --file-headers %t.o | FileCheck %s + +; RUN: not llc -mtriple powerpc64-ibm-aix-xcoff -filetype=obj < %s 2>&1 | \ +; RUN: FileCheck --check-prefix=64BIT %s + +target datalayout = "E-m:e-p:32:32-i64:64-n32" +target triple = "powerpc-unknown-aix" + +; CHECK: Format: aixcoff-rs6000 +; CHECK-NEXT: Arch: powerpc +; CHECK-NEXT: AddressSize: 32bit +; CHECK-NEXT: FileHeader { +; CHECK-NEXT: Magic: 0x1DF +; CHECK-NEXT: NumberOfSections: 0 +; CHECK-NEXT: TimeStamp: +; CHECK-NEXT: SymbolTableOffset: 0x0 +; CHECK-NEXT: SymbolTableEntries: 0 +; CHECK-NEXT: OptionalHeaderSize: 0x0 +; CHECK-NEXT: Flags: 0x0 +; CHECK-NEXT: } + +; 64BIT: LLVM ERROR: 64-bit XCOFF object files are not supported yet.