aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-11-15 08:49:58 +0000
committerChris Lattner <sabre@nondot.org>2010-11-15 08:49:58 +0000
commitb46443a686c29a1aa8f881c48c35d3f61a35f7ac (patch)
tree4a030e935ba154bad63657ea79afa22422aa5d62
parentb7035d04421112a4585245f67bc564170ec45b29 (diff)
Wire up primitive support in the assembler backend for writing .o files
directly on the mac. This is very early, doesn't support relocations and has a terrible hack to avoid .machine from being printed, but despite that it generates an bitwise-identical-to-cctools .o file for stuff like this: define i32 @test() nounwind { ret i32 42 } I don't plan to continue pushing this forward, but if anyone else was interested in doing it, it should be really straight-forward. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119136 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/PowerPC/CMakeLists.txt1
-rw-r--r--lib/Target/PowerPC/PPC.h4
-rw-r--r--lib/Target/PowerPC/PPCAsmBackend.cpp104
-rw-r--r--lib/Target/PowerPC/PPCAsmPrinter.cpp5
-rw-r--r--lib/Target/PowerPC/PPCTargetMachine.cpp24
5 files changed, 137 insertions, 1 deletions
diff --git a/lib/Target/PowerPC/CMakeLists.txt b/lib/Target/PowerPC/CMakeLists.txt
index 923c079e79..06132b33e7 100644
--- a/lib/Target/PowerPC/CMakeLists.txt
+++ b/lib/Target/PowerPC/CMakeLists.txt
@@ -13,6 +13,7 @@ tablegen(PPCGenCallingConv.inc -gen-callingconv)
tablegen(PPCGenSubtarget.inc -gen-subtarget)
add_llvm_target(PowerPCCodeGen
+ PPCAsmBackend.cpp
PPCAsmPrinter.cpp
PPCBranchSelector.cpp
PPCCodeEmitter.cpp
diff --git a/lib/Target/PowerPC/PPC.h b/lib/Target/PowerPC/PPC.h
index dbe98a68db..7242f3aa84 100644
--- a/lib/Target/PowerPC/PPC.h
+++ b/lib/Target/PowerPC/PPC.h
@@ -15,6 +15,8 @@
#ifndef LLVM_TARGET_POWERPC_H
#define LLVM_TARGET_POWERPC_H
+#include <string>
+
// GCC #defines PPC on Linux but we use it as our namespace name
#undef PPC
@@ -30,6 +32,7 @@ namespace llvm {
class MCCodeEmitter;
class MCContext;
class TargetMachine;
+ class TargetAsmBackend;
FunctionPass *createPPCBranchSelectionPass();
FunctionPass *createPPCISelDag(PPCTargetMachine &TM);
@@ -37,6 +40,7 @@ namespace llvm {
JITCodeEmitter &MCE);
MCCodeEmitter *createPPCMCCodeEmitter(const Target &, TargetMachine &TM,
MCContext &Ctx);
+ TargetAsmBackend *createPPCAsmBackend(const Target &, const std::string &);
void LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
AsmPrinter &AP);
diff --git a/lib/Target/PowerPC/PPCAsmBackend.cpp b/lib/Target/PowerPC/PPCAsmBackend.cpp
new file mode 100644
index 0000000000..a6d1426daf
--- /dev/null
+++ b/lib/Target/PowerPC/PPCAsmBackend.cpp
@@ -0,0 +1,104 @@
+//===-- 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Target/TargetAsmBackend.h"
+#include "PPC.h"
+#include "PPCFixupKinds.h"
+#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/MC/MCObjectFormat.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/Target/TargetRegistry.h"
+#include "llvm/Support/MachO.h"
+using namespace llvm;
+
+namespace {
+ class PPCAsmBackend : public TargetAsmBackend {
+ public:
+ PPCAsmBackend(const Target &T) : TargetAsmBackend(T) {}
+
+ bool MayNeedRelaxation(const MCInst &Inst) const {
+ // FIXME.
+ return false;
+ }
+
+ void RelaxInstruction(const MCInst &Inst, MCInst &Res) const {
+ // FIXME.
+ assert(0 && "RelaxInstruction() unimplemented");
+ }
+
+ bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const {
+ // FIXME: Zero fill for now. That's not right, but at least will get the
+ // section size right.
+ for (uint64_t i = 0; i != Count; ++i)
+ OW->Write8(0);
+ return true;
+ }
+
+ unsigned getPointerSize() const {
+ StringRef Name = TheTarget.getName();
+ if (Name == "ppc64") 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 {
+ MCMachOObjectFormat Format;
+ public:
+ DarwinPPCAsmBackend(const Target &T) : PPCAsmBackend(T) {
+ HasScatteredSymbols = true;
+ }
+
+ virtual const MCObjectFormat &getObjectFormat() const {
+ return Format;
+ }
+
+ void ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
+ uint64_t Value) const {
+ assert(0 && "UNIMP");
+ }
+
+ bool isVirtualSection(const MCSection &Section) const {
+ const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section);
+ return (SMO.getType() == MCSectionMachO::S_ZEROFILL ||
+ SMO.getType() == MCSectionMachO::S_GB_ZEROFILL ||
+ SMO.getType() == MCSectionMachO::S_THREAD_LOCAL_ZEROFILL);
+ }
+
+ MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
+ bool is64 = getPointerSize() == 8;
+ return createMachObjectWriter(OS, /*Is64Bit=*/is64,
+ is64 ? MachO::CPUTypePowerPC64 :
+ MachO::CPUTypePowerPC64,
+ MachO::CPUSubType_POWERPC_ALL,
+ /*IsLittleEndian=*/false);
+ }
+
+ virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
+ return false;
+ }
+ };
+} // end anonymous namespace
+
+
+
+
+TargetAsmBackend *llvm::createPPCAsmBackend(const Target &T,
+ const std::string &TT) {
+ switch (Triple(TT).getOS()) {
+ case Triple::Darwin:
+ return new DarwinPPCAsmBackend(T);
+ default:
+ return 0;
+ }
+}
diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 8d0e43610d..8ed5d7f0ee 100644
--- a/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -438,7 +438,10 @@ void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
if (Subtarget.isPPC64() && Directive < PPC::DIR_970)
Directive = PPC::DIR_64;
assert(Directive <= PPC::DIR_64 && "Directive out of range.");
- OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive]));
+
+ // FIXME: This is a total hack, finish mc'izing the PPC backend.
+ if (OutStreamer.hasRawTextSupport())
+ OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive]));
// Prime text sections so they are adjacent. This reduces the likelihood a
// large data or debug section causes a branch to exceed 16M limit.
diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp
index 7946837e06..4666d7772a 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.cpp
+++ b/lib/Target/PowerPC/PPCTargetMachine.cpp
@@ -15,6 +15,7 @@
#include "PPCMCAsmInfo.h"
#include "PPCTargetMachine.h"
#include "llvm/PassManager.h"
+#include "llvm/MC/MCStreamer.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Support/FormattedStream.h"
@@ -29,6 +30,20 @@ static MCAsmInfo *createMCAsmInfo(const Target &T, StringRef TT) {
}
+// This is duplicated code. Refactor this.
+static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
+ MCContext &Ctx, TargetAsmBackend &TAB,
+ raw_ostream &OS,
+ MCCodeEmitter *Emitter,
+ bool RelaxAll) {
+ switch (Triple(TT).getOS()) {
+ case Triple::Darwin:
+ return createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
+ default:
+ return NULL;
+ }
+}
+
extern "C" void LLVMInitializePowerPCTarget() {
// Register the targets
RegisterTargetMachine<PPC32TargetMachine> A(ThePPC32Target);
@@ -40,6 +55,15 @@ extern "C" void LLVMInitializePowerPCTarget() {
// Register the MC Code Emitter
TargetRegistry::RegisterCodeEmitter(ThePPC32Target, createPPCMCCodeEmitter);
TargetRegistry::RegisterCodeEmitter(ThePPC64Target, createPPCMCCodeEmitter);
+
+
+ // Register the asm backend.
+ TargetRegistry::RegisterAsmBackend(ThePPC32Target, createPPCAsmBackend);
+ TargetRegistry::RegisterAsmBackend(ThePPC64Target, createPPCAsmBackend);
+
+ // Register the object streamer.
+ TargetRegistry::RegisterObjectStreamer(ThePPC32Target, createMCStreamer);
+ TargetRegistry::RegisterObjectStreamer(ThePPC64Target, createMCStreamer);
}