mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
Boilerplate for producing XCOFF object files from the PowerPC backend.
Stubs out a number of the classes needed to produce a new object file format (XCOFF) for the powerpc-aix target. For testing input is an empty module which produces an object file with just a file header. Differential Revision: https://reviews.llvm.org/D61694 llvm-svn: 365541
This commit is contained in:
parent
f3124bc7aa
commit
64a23513ff
@ -22,6 +22,36 @@ namespace XCOFF {
|
|||||||
enum { SectionNameSize = 8, SymbolNameSize = 8 };
|
enum { SectionNameSize = 8, SymbolNameSize = 8 };
|
||||||
enum ReservedSectionNum { N_DEBUG = -2, N_ABS = -1, N_UNDEF = 0 };
|
enum ReservedSectionNum { N_DEBUG = -2, N_ABS = -1, N_UNDEF = 0 };
|
||||||
|
|
||||||
|
// x_smclas field of x_csect from system header: /usr/include/syms.h
|
||||||
|
/// Storage Mapping Class definitions.
|
||||||
|
enum StorageMappingClass {
|
||||||
|
// READ ONLY CLASSES
|
||||||
|
XMC_PR = 0, ///< Program Code
|
||||||
|
XMC_RO = 1, ///< Read Only Constant
|
||||||
|
XMC_DB = 2, ///< Debug Dictionary Table
|
||||||
|
XMC_GL = 6, ///< Global Linkage (Interfile Interface Code)
|
||||||
|
XMC_XO = 7, ///< Extended Operation (Pseudo Machine Instruction)
|
||||||
|
XMC_SV = 8, ///< Supervisor Call (32-bit process only)
|
||||||
|
XMC_SV64 = 17, ///< Supervisor Call for 64-bit process
|
||||||
|
XMC_SV3264 = 18, ///< Supervisor Call for both 32- and 64-bit processes
|
||||||
|
XMC_TI = 12, ///< Traceback Index csect
|
||||||
|
XMC_TB = 13, ///< Traceback Table csect
|
||||||
|
|
||||||
|
// READ WRITE CLASSES
|
||||||
|
XMC_RW = 5, ///< Read Write Data
|
||||||
|
XMC_TC0 = 15, ///< TOC Anchor for TOC Addressability
|
||||||
|
XMC_TC = 3, ///< General TOC item
|
||||||
|
XMC_TD = 16, ///< Scalar data item in the TOC
|
||||||
|
XMC_DS = 10, ///< Descriptor csect
|
||||||
|
XMC_UA = 4, ///< Unclassified - Treated as Read Write
|
||||||
|
XMC_BS = 9, ///< BSS class (uninitialized static internal)
|
||||||
|
XMC_UC = 11, ///< Un-named Fortran Common
|
||||||
|
|
||||||
|
XMC_TL = 20, ///< Initialized thread-local variable
|
||||||
|
XMC_UL = 21, ///< Uninitialized thread-local variable
|
||||||
|
XMC_TE = 22 ///< Symbol mapped at the end of TOC
|
||||||
|
};
|
||||||
|
|
||||||
// Flags for defining the section type. Used for the s_flags field of
|
// Flags for defining the section type. Used for the s_flags field of
|
||||||
// the section header structure. Defined in the system header `scnhdr.h`.
|
// the section header structure. Defined in the system header `scnhdr.h`.
|
||||||
enum SectionTypeFlags {
|
enum SectionTypeFlags {
|
||||||
|
25
include/llvm/MC/MCAsmInfoXCOFF.h
Normal file
25
include/llvm/MC/MCAsmInfoXCOFF.h
Normal file
@ -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
|
@ -18,6 +18,7 @@
|
|||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/ADT/Twine.h"
|
#include "llvm/ADT/Twine.h"
|
||||||
#include "llvm/BinaryFormat/Dwarf.h"
|
#include "llvm/BinaryFormat/Dwarf.h"
|
||||||
|
#include "llvm/BinaryFormat/XCOFF.h"
|
||||||
#include "llvm/MC/MCAsmMacro.h"
|
#include "llvm/MC/MCAsmMacro.h"
|
||||||
#include "llvm/MC/MCDwarf.h"
|
#include "llvm/MC/MCDwarf.h"
|
||||||
#include "llvm/MC/MCSubtargetInfo.h"
|
#include "llvm/MC/MCSubtargetInfo.h"
|
||||||
@ -49,6 +50,7 @@ namespace llvm {
|
|||||||
class MCSectionELF;
|
class MCSectionELF;
|
||||||
class MCSectionMachO;
|
class MCSectionMachO;
|
||||||
class MCSectionWasm;
|
class MCSectionWasm;
|
||||||
|
class MCSectionXCOFF;
|
||||||
class MCStreamer;
|
class MCStreamer;
|
||||||
class MCSymbol;
|
class MCSymbol;
|
||||||
class MCSymbolELF;
|
class MCSymbolELF;
|
||||||
@ -91,6 +93,7 @@ namespace llvm {
|
|||||||
SpecificBumpPtrAllocator<MCSectionELF> ELFAllocator;
|
SpecificBumpPtrAllocator<MCSectionELF> ELFAllocator;
|
||||||
SpecificBumpPtrAllocator<MCSectionMachO> MachOAllocator;
|
SpecificBumpPtrAllocator<MCSectionMachO> MachOAllocator;
|
||||||
SpecificBumpPtrAllocator<MCSectionWasm> WasmAllocator;
|
SpecificBumpPtrAllocator<MCSectionWasm> WasmAllocator;
|
||||||
|
SpecificBumpPtrAllocator<MCSectionXCOFF> XCOFFAllocator;
|
||||||
|
|
||||||
/// Bindings of names to symbols.
|
/// Bindings of names to symbols.
|
||||||
SymbolTable Symbols;
|
SymbolTable Symbols;
|
||||||
@ -246,10 +249,25 @@ namespace llvm {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct XCOFFSectionKey {
|
||||||
|
std::string SectionName;
|
||||||
|
XCOFF::StorageMappingClass MappingClass;
|
||||||
|
|
||||||
|
XCOFFSectionKey(StringRef SectionName,
|
||||||
|
XCOFF::StorageMappingClass MappingClass)
|
||||||
|
: SectionName(SectionName), MappingClass(MappingClass) {}
|
||||||
|
|
||||||
|
bool operator<(const XCOFFSectionKey &Other) const {
|
||||||
|
return std::tie(SectionName, MappingClass) <
|
||||||
|
std::tie(Other.SectionName, Other.MappingClass);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
StringMap<MCSectionMachO *> MachOUniquingMap;
|
StringMap<MCSectionMachO *> MachOUniquingMap;
|
||||||
std::map<ELFSectionKey, MCSectionELF *> ELFUniquingMap;
|
std::map<ELFSectionKey, MCSectionELF *> ELFUniquingMap;
|
||||||
std::map<COFFSectionKey, MCSectionCOFF *> COFFUniquingMap;
|
std::map<COFFSectionKey, MCSectionCOFF *> COFFUniquingMap;
|
||||||
std::map<WasmSectionKey, MCSectionWasm *> WasmUniquingMap;
|
std::map<WasmSectionKey, MCSectionWasm *> WasmUniquingMap;
|
||||||
|
std::map<XCOFFSectionKey, MCSectionXCOFF *> XCOFFUniquingMap;
|
||||||
StringMap<bool> RelSecNames;
|
StringMap<bool> RelSecNames;
|
||||||
|
|
||||||
SpecificBumpPtrAllocator<MCSubtargetInfo> MCSubtargetAllocator;
|
SpecificBumpPtrAllocator<MCSubtargetInfo> MCSubtargetAllocator;
|
||||||
@ -470,6 +488,11 @@ namespace llvm {
|
|||||||
const MCSymbolWasm *Group, unsigned UniqueID,
|
const MCSymbolWasm *Group, unsigned UniqueID,
|
||||||
const char *BeginSymName);
|
const char *BeginSymName);
|
||||||
|
|
||||||
|
MCSectionXCOFF *getXCOFFSection(StringRef Section,
|
||||||
|
XCOFF::StorageMappingClass MappingClass,
|
||||||
|
SectionKind K,
|
||||||
|
const char *BeginSymName = nullptr);
|
||||||
|
|
||||||
// Create and save a copy of STI and return a reference to the copy.
|
// Create and save a copy of STI and return a reference to the copy.
|
||||||
MCSubtargetInfo &getSubtargetCopy(const MCSubtargetInfo &STI);
|
MCSubtargetInfo &getSubtargetCopy(const MCSubtargetInfo &STI);
|
||||||
|
|
||||||
|
@ -400,6 +400,7 @@ private:
|
|||||||
void initELFMCObjectFileInfo(const Triple &T, bool Large);
|
void initELFMCObjectFileInfo(const Triple &T, bool Large);
|
||||||
void initCOFFMCObjectFileInfo(const Triple &T);
|
void initCOFFMCObjectFileInfo(const Triple &T);
|
||||||
void initWasmMCObjectFileInfo(const Triple &T);
|
void initWasmMCObjectFileInfo(const Triple &T);
|
||||||
|
void initXCOFFMCObjectFileInfo(const Triple &T);
|
||||||
MCSection *getDwarfComdatSection(const char *Name, uint64_t Hash) const;
|
MCSection *getDwarfComdatSection(const char *Name, uint64_t Hash) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -37,7 +37,7 @@ template <> struct ilist_alloc_traits<MCFragment> {
|
|||||||
/// current translation unit. The MCContext class uniques and creates these.
|
/// current translation unit. The MCContext class uniques and creates these.
|
||||||
class MCSection {
|
class MCSection {
|
||||||
public:
|
public:
|
||||||
enum SectionVariant { SV_COFF = 0, SV_ELF, SV_MachO, SV_Wasm };
|
enum SectionVariant { SV_COFF = 0, SV_ELF, SV_MachO, SV_Wasm, SV_XCOFF };
|
||||||
|
|
||||||
/// Express the state of bundle locked groups while emitting code.
|
/// Express the state of bundle locked groups while emitting code.
|
||||||
enum BundleLockStateType {
|
enum BundleLockStateType {
|
||||||
|
56
include/llvm/MC/MCSectionXCOFF.h
Normal file
56
include/llvm/MC/MCSectionXCOFF.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
//===- MCSectionXCOFF.h - XCOFF Machine Code Sections -----------*- 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 declares the MCSectionXCOFF class.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_MC_MCSECTIONXCOFF_H
|
||||||
|
#define LLVM_MC_MCSECTIONXCOFF_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/Twine.h"
|
||||||
|
#include "llvm/BinaryFormat/XCOFF.h"
|
||||||
|
#include "llvm/MC/MCSection.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
class MCSymbol;
|
||||||
|
|
||||||
|
// This class represents an XCOFF `Control Section`, more commonly referred to
|
||||||
|
// as a csect. A csect represents the smallest possible unit of data/code which
|
||||||
|
// will be relocated as a single block.
|
||||||
|
class MCSectionXCOFF final : public MCSection {
|
||||||
|
friend class MCContext;
|
||||||
|
|
||||||
|
StringRef Name;
|
||||||
|
XCOFF::StorageMappingClass MappingClass;
|
||||||
|
|
||||||
|
MCSectionXCOFF(StringRef Section, XCOFF::StorageMappingClass SMC,
|
||||||
|
SectionKind K, MCSymbol *Begin)
|
||||||
|
: MCSection(SV_XCOFF, K, Begin), Name(Section), MappingClass(SMC) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
~MCSectionXCOFF();
|
||||||
|
|
||||||
|
static bool classof(const MCSection *S) {
|
||||||
|
return S->getVariant() == SV_XCOFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringRef getSectionName() const { return Name; }
|
||||||
|
XCOFF::StorageMappingClass getMappingClass() const { return MappingClass; }
|
||||||
|
|
||||||
|
void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
|
||||||
|
raw_ostream &OS,
|
||||||
|
const MCExpr *Subsection) const override;
|
||||||
|
bool UseCodeAlign() const override;
|
||||||
|
bool isVirtualSection() const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace llvm
|
||||||
|
|
||||||
|
#endif
|
41
include/llvm/MC/MCXCOFFObjectWriter.h
Normal file
41
include/llvm/MC/MCXCOFFObjectWriter.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
//===-- 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(bool Is64Bit);
|
||||||
|
|
||||||
|
public:
|
||||||
|
~MCXCOFFObjectTargetWriter() override;
|
||||||
|
|
||||||
|
Triple::ObjectFormatType getFormat() const override { return Triple::XCOFF; }
|
||||||
|
static bool classof(const MCObjectTargetWriter *W) {
|
||||||
|
return W->getFormat() == Triple::XCOFF;
|
||||||
|
}
|
||||||
|
bool is64Bit() const { return Is64Bit; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool Is64Bit;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<MCObjectWriter>
|
||||||
|
createXCOFFObjectWriter(std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW,
|
||||||
|
raw_pwrite_stream &OS);
|
||||||
|
|
||||||
|
} // end namespace llvm
|
||||||
|
|
||||||
|
#endif // LLVM_MC_MCXCOFFOBJECTWRITER_H
|
33
include/llvm/MC/MCXCOFFStreamer.h
Normal file
33
include/llvm/MC/MCXCOFFStreamer.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
//===- 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<MCAsmBackend> MAB,
|
||||||
|
std::unique_ptr<MCObjectWriter> OW,
|
||||||
|
std::unique_ptr<MCCodeEmitter> 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace llvm
|
||||||
|
|
||||||
|
#endif // LLVM_MC_MCXCOFFSTREAMER_H
|
@ -100,6 +100,11 @@ MCStreamer *createWasmStreamer(MCContext &Ctx,
|
|||||||
std::unique_ptr<MCObjectWriter> &&OW,
|
std::unique_ptr<MCObjectWriter> &&OW,
|
||||||
std::unique_ptr<MCCodeEmitter> &&CE,
|
std::unique_ptr<MCCodeEmitter> &&CE,
|
||||||
bool RelaxAll);
|
bool RelaxAll);
|
||||||
|
MCStreamer *createXCOFFStreamer(MCContext &Ctx,
|
||||||
|
std::unique_ptr<MCAsmBackend> &&TAB,
|
||||||
|
std::unique_ptr<MCObjectWriter> &&OW,
|
||||||
|
std::unique_ptr<MCCodeEmitter> &&CE,
|
||||||
|
bool RelaxAll);
|
||||||
|
|
||||||
MCRelocationInfo *createMCRelocationInfo(const Triple &TT, MCContext &Ctx);
|
MCRelocationInfo *createMCRelocationInfo(const Triple &TT, MCContext &Ctx);
|
||||||
|
|
||||||
@ -505,7 +510,9 @@ public:
|
|||||||
std::move(Emitter), RelaxAll);
|
std::move(Emitter), RelaxAll);
|
||||||
break;
|
break;
|
||||||
case Triple::XCOFF:
|
case Triple::XCOFF:
|
||||||
report_fatal_error("XCOFF MCObjectStreamer not implemented yet.");
|
S = createXCOFFStreamer(Ctx, std::move(TAB), std::move(OW),
|
||||||
|
std::move(Emitter), RelaxAll);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (ObjectTargetStreamerCtorFn)
|
if (ObjectTargetStreamerCtorFn)
|
||||||
ObjectTargetStreamerCtorFn(*S, STI);
|
ObjectTargetStreamerCtorFn(*S, STI);
|
||||||
|
@ -7,6 +7,7 @@ add_llvm_library(LLVMMC
|
|||||||
MCAsmInfoDarwin.cpp
|
MCAsmInfoDarwin.cpp
|
||||||
MCAsmInfoELF.cpp
|
MCAsmInfoELF.cpp
|
||||||
MCAsmInfoWasm.cpp
|
MCAsmInfoWasm.cpp
|
||||||
|
MCAsmInfoXCOFF.cpp
|
||||||
MCAsmMacro.cpp
|
MCAsmMacro.cpp
|
||||||
MCAsmStreamer.cpp
|
MCAsmStreamer.cpp
|
||||||
MCAssembler.cpp
|
MCAssembler.cpp
|
||||||
@ -38,6 +39,7 @@ add_llvm_library(LLVMMC
|
|||||||
MCSectionELF.cpp
|
MCSectionELF.cpp
|
||||||
MCSectionMachO.cpp
|
MCSectionMachO.cpp
|
||||||
MCSectionWasm.cpp
|
MCSectionWasm.cpp
|
||||||
|
MCSectionXCOFF.cpp
|
||||||
MCStreamer.cpp
|
MCStreamer.cpp
|
||||||
MCSubtargetInfo.cpp
|
MCSubtargetInfo.cpp
|
||||||
MCSymbol.cpp
|
MCSymbol.cpp
|
||||||
@ -49,11 +51,14 @@ add_llvm_library(LLVMMC
|
|||||||
MCWin64EH.cpp
|
MCWin64EH.cpp
|
||||||
MCWinCOFFStreamer.cpp
|
MCWinCOFFStreamer.cpp
|
||||||
MCWinEH.cpp
|
MCWinEH.cpp
|
||||||
|
MCXCOFFObjectTargetWriter.cpp
|
||||||
|
MCXCOFFStreamer.cpp
|
||||||
MachObjectWriter.cpp
|
MachObjectWriter.cpp
|
||||||
StringTableBuilder.cpp
|
StringTableBuilder.cpp
|
||||||
SubtargetFeature.cpp
|
SubtargetFeature.cpp
|
||||||
WasmObjectWriter.cpp
|
WasmObjectWriter.cpp
|
||||||
WinCOFFObjectWriter.cpp
|
WinCOFFObjectWriter.cpp
|
||||||
|
XCOFFObjectWriter.cpp
|
||||||
|
|
||||||
ADDITIONAL_HEADER_DIRS
|
ADDITIONAL_HEADER_DIRS
|
||||||
${LLVM_MAIN_INCLUDE_DIR}/llvm/MC
|
${LLVM_MAIN_INCLUDE_DIR}/llvm/MC
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "llvm/MC/MCObjectWriter.h"
|
#include "llvm/MC/MCObjectWriter.h"
|
||||||
#include "llvm/MC/MCWasmObjectWriter.h"
|
#include "llvm/MC/MCWasmObjectWriter.h"
|
||||||
#include "llvm/MC/MCWinCOFFObjectWriter.h"
|
#include "llvm/MC/MCWinCOFFObjectWriter.h"
|
||||||
|
#include "llvm/MC/MCXCOFFObjectWriter.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@ -43,6 +44,9 @@ MCAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {
|
|||||||
case Triple::Wasm:
|
case Triple::Wasm:
|
||||||
return createWasmObjectWriter(cast<MCWasmObjectTargetWriter>(std::move(TW)),
|
return createWasmObjectWriter(cast<MCWasmObjectTargetWriter>(std::move(TW)),
|
||||||
OS);
|
OS);
|
||||||
|
case Triple::XCOFF:
|
||||||
|
return createXCOFFObjectWriter(
|
||||||
|
cast<MCXCOFFObjectTargetWriter>(std::move(TW)), OS);
|
||||||
default:
|
default:
|
||||||
llvm_unreachable("unexpected object format");
|
llvm_unreachable("unexpected object format");
|
||||||
}
|
}
|
||||||
|
18
lib/MC/MCAsmInfoXCOFF.cpp
Normal file
18
lib/MC/MCAsmInfoXCOFF.cpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
//===- 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() {
|
||||||
|
IsLittleEndian = false;
|
||||||
|
HasDotTypeDotSizeDirective = false;
|
||||||
|
}
|
@ -26,6 +26,7 @@
|
|||||||
#include "llvm/MC/MCSectionELF.h"
|
#include "llvm/MC/MCSectionELF.h"
|
||||||
#include "llvm/MC/MCSectionMachO.h"
|
#include "llvm/MC/MCSectionMachO.h"
|
||||||
#include "llvm/MC/MCSectionWasm.h"
|
#include "llvm/MC/MCSectionWasm.h"
|
||||||
|
#include "llvm/MC/MCSectionXCOFF.h"
|
||||||
#include "llvm/MC/MCStreamer.h"
|
#include "llvm/MC/MCStreamer.h"
|
||||||
#include "llvm/MC/MCSymbol.h"
|
#include "llvm/MC/MCSymbol.h"
|
||||||
#include "llvm/MC/MCSymbolCOFF.h"
|
#include "llvm/MC/MCSymbolCOFF.h"
|
||||||
@ -86,6 +87,7 @@ void MCContext::reset() {
|
|||||||
COFFAllocator.DestroyAll();
|
COFFAllocator.DestroyAll();
|
||||||
ELFAllocator.DestroyAll();
|
ELFAllocator.DestroyAll();
|
||||||
MachOAllocator.DestroyAll();
|
MachOAllocator.DestroyAll();
|
||||||
|
XCOFFAllocator.DestroyAll();
|
||||||
|
|
||||||
MCSubtargetAllocator.DestroyAll();
|
MCSubtargetAllocator.DestroyAll();
|
||||||
UsedNames.clear();
|
UsedNames.clear();
|
||||||
@ -107,6 +109,7 @@ void MCContext::reset() {
|
|||||||
ELFUniquingMap.clear();
|
ELFUniquingMap.clear();
|
||||||
COFFUniquingMap.clear();
|
COFFUniquingMap.clear();
|
||||||
WasmUniquingMap.clear();
|
WasmUniquingMap.clear();
|
||||||
|
XCOFFUniquingMap.clear();
|
||||||
|
|
||||||
NextID.clear();
|
NextID.clear();
|
||||||
AllowTemporaryLabels = true;
|
AllowTemporaryLabels = true;
|
||||||
@ -526,6 +529,38 @@ MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind,
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MCSectionXCOFF *MCContext::getXCOFFSection(StringRef Section,
|
||||||
|
XCOFF::StorageMappingClass SMC,
|
||||||
|
SectionKind Kind,
|
||||||
|
const char *BeginSymName) {
|
||||||
|
// Do the lookup. If we have a hit, return it.
|
||||||
|
auto IterBool = XCOFFUniquingMap.insert(
|
||||||
|
std::make_pair(XCOFFSectionKey{Section.str(), SMC}, nullptr));
|
||||||
|
auto &Entry = *IterBool.first;
|
||||||
|
if (!IterBool.second)
|
||||||
|
return Entry.second;
|
||||||
|
|
||||||
|
// Otherwise, return a new section.
|
||||||
|
StringRef CachedName = Entry.first.SectionName;
|
||||||
|
|
||||||
|
MCSymbol *Begin = nullptr;
|
||||||
|
if (BeginSymName)
|
||||||
|
Begin = createTempSymbol(BeginSymName, false);
|
||||||
|
|
||||||
|
MCSectionXCOFF *Result = new (XCOFFAllocator.Allocate())
|
||||||
|
MCSectionXCOFF(CachedName, SMC, Kind, Begin);
|
||||||
|
Entry.second = Result;
|
||||||
|
|
||||||
|
auto *F = new MCDataFragment();
|
||||||
|
Result->getFragmentList().insert(Result->begin(), F);
|
||||||
|
F->setParent(Result);
|
||||||
|
|
||||||
|
if (Begin)
|
||||||
|
Begin->setFragment(F);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) {
|
MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) {
|
||||||
return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI);
|
return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI);
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "llvm/MC/MCSectionELF.h"
|
#include "llvm/MC/MCSectionELF.h"
|
||||||
#include "llvm/MC/MCSectionMachO.h"
|
#include "llvm/MC/MCSectionMachO.h"
|
||||||
#include "llvm/MC/MCSectionWasm.h"
|
#include "llvm/MC/MCSectionWasm.h"
|
||||||
|
#include "llvm/MC/MCSectionXCOFF.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
@ -761,6 +762,15 @@ void MCObjectFileInfo::initWasmMCObjectFileInfo(const Triple &T) {
|
|||||||
// TODO: Define more sections.
|
// TODO: Define more sections.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MCObjectFileInfo::initXCOFFMCObjectFileInfo(const Triple &T) {
|
||||||
|
// The default csect for program code. Functions without a specified section
|
||||||
|
// get placed into this csect. The choice of csect name is not a property of
|
||||||
|
// the ABI or object file format. For example, the XL compiler uses an unnamed
|
||||||
|
// csect for program code.
|
||||||
|
TextSection = Ctx->getXCOFFSection(
|
||||||
|
".text", XCOFF::StorageMappingClass::XMC_PR, SectionKind::getText());
|
||||||
|
}
|
||||||
|
|
||||||
void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC,
|
void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC,
|
||||||
MCContext &ctx,
|
MCContext &ctx,
|
||||||
bool LargeCodeModel) {
|
bool LargeCodeModel) {
|
||||||
@ -809,8 +819,7 @@ void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC,
|
|||||||
break;
|
break;
|
||||||
case Triple::XCOFF:
|
case Triple::XCOFF:
|
||||||
Env = IsXCOFF;
|
Env = IsXCOFF;
|
||||||
// TODO: Initialize MCObjectFileInfo for XCOFF format when
|
initXCOFFMCObjectFileInfo(TT);
|
||||||
// MCSectionXCOFF is ready.
|
|
||||||
break;
|
break;
|
||||||
case Triple::UnknownObjectFormat:
|
case Triple::UnknownObjectFormat:
|
||||||
report_fatal_error("Cannot initialize MC for unknown object file format.");
|
report_fatal_error("Cannot initialize MC for unknown object file format.");
|
||||||
|
33
lib/MC/MCSectionXCOFF.cpp
Normal file
33
lib/MC/MCSectionXCOFF.cpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
//===- lib/MC/MCSectionXCOFF.cpp - XCOFF Code Section Representation ------===//
|
||||||
|
//
|
||||||
|
// 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/MCSectionXCOFF.h"
|
||||||
|
#include "llvm/MC/MCAsmInfo.h"
|
||||||
|
#include "llvm/MC/MCExpr.h"
|
||||||
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
|
||||||
|
MCSectionXCOFF::~MCSectionXCOFF() = default;
|
||||||
|
|
||||||
|
void MCSectionXCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
|
||||||
|
raw_ostream &OS,
|
||||||
|
const MCExpr *Subsection) const {
|
||||||
|
if (getKind().isText()) {
|
||||||
|
OS << "\t.csect " << getSectionName() << "["
|
||||||
|
<< "PR"
|
||||||
|
<< "]" << '\n';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
report_fatal_error("Printing for this SectionKind is unimplemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MCSectionXCOFF::UseCodeAlign() const { return getKind().isText(); }
|
||||||
|
|
||||||
|
bool MCSectionXCOFF::isVirtualSection() const { return !getKind().isCommon(); }
|
16
lib/MC/MCXCOFFObjectTargetWriter.cpp
Normal file
16
lib/MC/MCXCOFFObjectTargetWriter.cpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
//===- 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(bool Is64Bit)
|
||||||
|
: Is64Bit(Is64Bit) {}
|
||||||
|
|
||||||
|
MCXCOFFObjectTargetWriter::~MCXCOFFObjectTargetWriter() = default;
|
59
lib/MC/MCXCOFFStreamer.cpp
Normal file
59
lib/MC/MCXCOFFStreamer.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
//===- 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<MCAsmBackend> MAB,
|
||||||
|
std::unique_ptr<MCObjectWriter> OW,
|
||||||
|
std::unique_ptr<MCCodeEmitter> Emitter)
|
||||||
|
: MCObjectStreamer(Context, std::move(MAB), std::move(OW),
|
||||||
|
std::move(Emitter)) {}
|
||||||
|
|
||||||
|
bool MCXCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
|
||||||
|
MCSymbolAttr Attribute) {
|
||||||
|
report_fatal_error("Symbol attributes not implemented for XCOFF.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MCXCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
||||||
|
unsigned ByteAlignment) {
|
||||||
|
report_fatal_error("Emiting common symbols not implemented for XCOFF.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MCXCOFFStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
|
||||||
|
uint64_t Size, unsigned ByteAlignment,
|
||||||
|
SMLoc Loc) {
|
||||||
|
report_fatal_error("Zero fill not implemented for XCOFF.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MCXCOFFStreamer::EmitInstToData(const MCInst &Inst,
|
||||||
|
const MCSubtargetInfo &) {
|
||||||
|
report_fatal_error("Instruction emission not implemented for XCOFF.");
|
||||||
|
}
|
||||||
|
|
||||||
|
MCStreamer *llvm::createXCOFFStreamer(MCContext &Context,
|
||||||
|
std::unique_ptr<MCAsmBackend> &&MAB,
|
||||||
|
std::unique_ptr<MCObjectWriter> &&OW,
|
||||||
|
std::unique_ptr<MCCodeEmitter> &&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;
|
||||||
|
}
|
94
lib/MC/XCOFFObjectWriter.cpp
Normal file
94
lib/MC/XCOFFObjectWriter.cpp
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
//===-- 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/MCAssembler.h"
|
||||||
|
#include "llvm/MC/MCObjectWriter.h"
|
||||||
|
#include "llvm/MC/MCValue.h"
|
||||||
|
#include "llvm/MC/MCXCOFFObjectWriter.h"
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class XCOFFObjectWriter : public MCObjectWriter {
|
||||||
|
support::endian::Writer W;
|
||||||
|
std::unique_ptr<MCXCOFFObjectTargetWriter> TargetObjectWriter;
|
||||||
|
|
||||||
|
void executePostLayoutBinding(MCAssembler &, const MCAsmLayout &) override;
|
||||||
|
|
||||||
|
void recordRelocation(MCAssembler &, const MCAsmLayout &, const MCFragment *,
|
||||||
|
const MCFixup &, MCValue, uint64_t &) override;
|
||||||
|
|
||||||
|
uint64_t writeObject(MCAssembler &, const MCAsmLayout &) override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
XCOFFObjectWriter(std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW,
|
||||||
|
raw_pwrite_stream &OS);
|
||||||
|
};
|
||||||
|
|
||||||
|
XCOFFObjectWriter::XCOFFObjectWriter(
|
||||||
|
std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS)
|
||||||
|
: W(OS, support::big), TargetObjectWriter(std::move(MOTW)) {}
|
||||||
|
|
||||||
|
void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &,
|
||||||
|
const MCAsmLayout &) {
|
||||||
|
// TODO Implement once we have sections and symbols to handle.
|
||||||
|
}
|
||||||
|
|
||||||
|
void XCOFFObjectWriter::recordRelocation(MCAssembler &, const MCAsmLayout &,
|
||||||
|
const MCFragment *, const MCFixup &,
|
||||||
|
MCValue, uint64_t &) {
|
||||||
|
report_fatal_error("XCOFF relocations not supported.");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t XCOFFObjectWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &) {
|
||||||
|
// We always emit a timestamp of 0 for reproducibility, so ensure incremental
|
||||||
|
// linking is not enabled, in case, like with Windows COFF, such a timestamp
|
||||||
|
// is incompatible with incremental linking of XCOFF.
|
||||||
|
if (Asm.isIncrementalLinkerCompatible())
|
||||||
|
report_fatal_error("Incremental linking not supported for XCOFF.");
|
||||||
|
|
||||||
|
if (TargetObjectWriter->is64Bit())
|
||||||
|
report_fatal_error("64-bit XCOFF object files are not supported yet.");
|
||||||
|
|
||||||
|
uint64_t StartOffset = W.OS.tell();
|
||||||
|
|
||||||
|
// TODO FIXME Assign section numbers/finalize sections.
|
||||||
|
|
||||||
|
// TODO FIXME Finalize symbols.
|
||||||
|
|
||||||
|
// Magic.
|
||||||
|
W.write<uint16_t>(0x01df);
|
||||||
|
// Number of sections.
|
||||||
|
W.write<uint16_t>(0);
|
||||||
|
// Timestamp field. For reproducible output we write a 0, which represents no
|
||||||
|
// timestamp.
|
||||||
|
W.write<int32_t>(0);
|
||||||
|
// Byte Offset to the start of the symbol table.
|
||||||
|
W.write<uint32_t>(0);
|
||||||
|
// Number of entries in the symbol table.
|
||||||
|
W.write<int32_t>(0);
|
||||||
|
// Size of the optional header.
|
||||||
|
W.write<uint16_t>(0);
|
||||||
|
// Flags.
|
||||||
|
W.write<uint16_t>(0);
|
||||||
|
|
||||||
|
return W.OS.tell() - StartOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end anonymous namespace
|
||||||
|
|
||||||
|
std::unique_ptr<MCObjectWriter>
|
||||||
|
llvm::createXCOFFObjectWriter(std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW,
|
||||||
|
raw_pwrite_stream &OS) {
|
||||||
|
return make_unique<XCOFFObjectWriter>(std::move(MOTW), OS);
|
||||||
|
}
|
@ -8,4 +8,5 @@ add_llvm_library(LLVMPowerPCDesc
|
|||||||
PPCPredicates.cpp
|
PPCPredicates.cpp
|
||||||
PPCMachObjectWriter.cpp
|
PPCMachObjectWriter.cpp
|
||||||
PPCELFObjectWriter.cpp
|
PPCELFObjectWriter.cpp
|
||||||
|
PPCXCOFFObjectWriter.cpp
|
||||||
)
|
)
|
||||||
|
@ -229,6 +229,17 @@ public:
|
|||||||
Optional<MCFixupKind> getFixupKind(StringRef Name) const override;
|
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
|
} // end anonymous namespace
|
||||||
|
|
||||||
Optional<MCFixupKind> ELFPPCAsmBackend::getFixupKind(StringRef Name) const {
|
Optional<MCFixupKind> ELFPPCAsmBackend::getFixupKind(StringRef Name) const {
|
||||||
@ -250,5 +261,8 @@ MCAsmBackend *llvm::createPPCAsmBackend(const Target &T,
|
|||||||
if (TT.isOSDarwin())
|
if (TT.isOSDarwin())
|
||||||
return new DarwinPPCAsmBackend(T, TT);
|
return new DarwinPPCAsmBackend(T, TT);
|
||||||
|
|
||||||
|
if (TT.isOSBinFormatXCOFF())
|
||||||
|
return new XCOFFPPCAsmBackend(T, TT);
|
||||||
|
|
||||||
return new ELFPPCAsmBackend(T, TT);
|
return new ELFPPCAsmBackend(T, TT);
|
||||||
}
|
}
|
||||||
|
@ -81,3 +81,9 @@ PPCELFMCAsmInfo::PPCELFMCAsmInfo(bool is64Bit, const Triple& T) {
|
|||||||
UseIntegratedAssembler = true;
|
UseIntegratedAssembler = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PPCXCOFFMCAsmInfo::anchor() {}
|
||||||
|
|
||||||
|
PPCXCOFFMCAsmInfo::PPCXCOFFMCAsmInfo(bool Is64Bit, const Triple &T) {
|
||||||
|
assert(!IsLittleEndian && "Little-endian XCOFF not supported.");
|
||||||
|
CodePointerSize = CalleeSaveStackSlotSize = Is64Bit ? 8 : 4;
|
||||||
|
}
|
||||||
|
@ -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/MCAsmInfoDarwin.h"
|
||||||
#include "llvm/MC/MCAsmInfoELF.h"
|
#include "llvm/MC/MCAsmInfoELF.h"
|
||||||
|
#include "llvm/MC/MCAsmInfoXCOFF.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class Triple;
|
class Triple;
|
||||||
@ -33,6 +34,13 @@ public:
|
|||||||
explicit PPCELFMCAsmInfo(bool is64Bit, const Triple &);
|
explicit PPCELFMCAsmInfo(bool is64Bit, const Triple &);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PPCXCOFFMCAsmInfo : public MCAsmInfoXCOFF {
|
||||||
|
virtual void anchor();
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PPCXCOFFMCAsmInfo(bool is64Bit, const Triple &);
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace llvm
|
} // namespace llvm
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -83,6 +83,8 @@ static MCAsmInfo *createPPCMCAsmInfo(const MCRegisterInfo &MRI,
|
|||||||
MCAsmInfo *MAI;
|
MCAsmInfo *MAI;
|
||||||
if (TheTriple.isOSDarwin())
|
if (TheTriple.isOSDarwin())
|
||||||
MAI = new PPCMCAsmInfoDarwin(isPPC64, TheTriple);
|
MAI = new PPCMCAsmInfoDarwin(isPPC64, TheTriple);
|
||||||
|
else if (TheTriple.isOSBinFormatXCOFF())
|
||||||
|
MAI = new PPCXCOFFMCAsmInfo(isPPC64, TheTriple);
|
||||||
else
|
else
|
||||||
MAI = new PPCELFMCAsmInfo(isPPC64, TheTriple);
|
MAI = new PPCELFMCAsmInfo(isPPC64, TheTriple);
|
||||||
|
|
||||||
@ -235,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
|
} // end anonymous namespace
|
||||||
|
|
||||||
static MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S,
|
static MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S,
|
||||||
@ -249,6 +272,8 @@ createObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
|
|||||||
const Triple &TT = STI.getTargetTriple();
|
const Triple &TT = STI.getTargetTriple();
|
||||||
if (TT.isOSBinFormatELF())
|
if (TT.isOSBinFormatELF())
|
||||||
return new PPCTargetELFStreamer(S);
|
return new PPCTargetELFStreamer(S);
|
||||||
|
if (TT.isOSBinFormatXCOFF())
|
||||||
|
return new PPCTargetXCOFFStreamer(S);
|
||||||
return new PPCTargetMachOStreamer(S);
|
return new PPCTargetMachOStreamer(S);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +51,9 @@ std::unique_ptr<MCObjectTargetWriter> createPPCELFObjectWriter(bool Is64Bit,
|
|||||||
std::unique_ptr<MCObjectTargetWriter>
|
std::unique_ptr<MCObjectTargetWriter>
|
||||||
createPPCMachObjectWriter(bool Is64Bit, uint32_t CPUType, uint32_t CPUSubtype);
|
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
|
/// 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
|
/// 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,
|
/// 0x000FFF0, 0x0000FFFF, and 0xFF0000FF are all runs. 0x0F0F0000 is not,
|
||||||
|
29
lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp
Normal file
29
lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp
Normal file
@ -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);
|
||||||
|
}
|
@ -158,6 +158,14 @@ public:
|
|||||||
void EmitStartOfAsmFile(Module &M) override;
|
void EmitStartOfAsmFile(Module &M) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PPCAIXAsmPrinter : public PPCAsmPrinter {
|
||||||
|
public:
|
||||||
|
PPCAIXAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
|
||||||
|
: PPCAsmPrinter(TM, std::move(Streamer)) {}
|
||||||
|
|
||||||
|
StringRef getPassName() const override { return "AIX PPC Assembly Printer"; }
|
||||||
|
};
|
||||||
|
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
void PPCAsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
|
void PPCAsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
|
||||||
@ -1644,6 +1652,9 @@ createPPCAsmPrinterPass(TargetMachine &tm,
|
|||||||
std::unique_ptr<MCStreamer> &&Streamer) {
|
std::unique_ptr<MCStreamer> &&Streamer) {
|
||||||
if (tm.getTargetTriple().isMacOSX())
|
if (tm.getTargetTriple().isMacOSX())
|
||||||
return new PPCDarwinAsmPrinter(tm, std::move(Streamer));
|
return new PPCDarwinAsmPrinter(tm, std::move(Streamer));
|
||||||
|
if (tm.getTargetTriple().isOSAIX())
|
||||||
|
return new PPCAIXAsmPrinter(tm, std::move(Streamer));
|
||||||
|
|
||||||
return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
|
return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
37
test/CodeGen/PowerPC/aix-xcoff-basic.ll
Normal file
37
test/CodeGen/PowerPC/aix-xcoff-basic.ll
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
; 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
|
||||||
|
|
||||||
|
; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | \
|
||||||
|
; RUN: FileCheck --check-prefix=ASM %s
|
||||||
|
|
||||||
|
; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | \
|
||||||
|
; RUN: FileCheck --check-prefix=ASM %s
|
||||||
|
|
||||||
|
target datalayout = "E-m:e-p:32:32-i64:64-n32"
|
||||||
|
target triple = "powerpc-unknown-aix"
|
||||||
|
|
||||||
|
; NOTE: The object file output and the assembly file output do not describe the
|
||||||
|
; same abstract XCOFF content due to the limited amount of functionality
|
||||||
|
; implemented.
|
||||||
|
|
||||||
|
; 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: None (0x0)
|
||||||
|
; 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.
|
||||||
|
|
||||||
|
; The csect does not need to be present, but LLVM's default behavior when
|
||||||
|
; emitting asm is to start the file with the .text section.
|
||||||
|
; ASM: .csect .text[PR]
|
Loading…
Reference in New Issue
Block a user