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
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/PowerPC/MCTargetDesc/CMakeLists.txt
index 147e0ef..5a2f605 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/CMakeLists.txt
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/CMakeLists.txt
@@ -8,4 +8,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
index ec4eb70..8778e91 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
@@ -229,6 +229,17 @@
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 {
@@ -250,5 +261,8 @@
if (TT.isOSDarwin())
return new DarwinPPCAsmBackend(T, TT);
+ if (TT.isOSBinFormatXCOFF())
+ return new XCOFFPPCAsmBackend(T, TT);
+
return new ELFPPCAsmBackend(T, TT);
}
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp
index b9e35124..5f0005e 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp
@@ -81,3 +81,9 @@
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/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.h b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.h
index 6a10b6e..42cb62a 100644
--- 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(bool is64Bit, const Triple &);
+};
+
} // namespace llvm
#endif
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
index c980d27..90c3c8d 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
@@ -83,6 +83,8 @@
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);
@@ -235,6 +237,27 @@
}
};
+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,
@@ -249,6 +272,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/PPCMCTargetDesc.h b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h
index 4829fed..74b67bd 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h
@@ -51,6 +51,9 @@
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/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp
new file mode 100644
index 0000000..9c66128
--- /dev/null
+++ b/llvm/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);
+}
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 0d8c848..bd87ce0 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -158,6 +158,14 @@
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
void PPCAsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
@@ -1644,6 +1652,9 @@
std::unique_ptr<MCStreamer> &&Streamer) {
if (tm.getTargetTriple().isMacOSX())
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));
}