From b46443a686c29a1aa8f881c48c35d3f61a35f7ac Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 15 Nov 2010 08:49:58 +0000 Subject: [PATCH] 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 --- lib/Target/PowerPC/CMakeLists.txt | 1 + lib/Target/PowerPC/PPC.h | 4 + lib/Target/PowerPC/PPCAsmBackend.cpp | 104 ++++++++++++++++++++++++ lib/Target/PowerPC/PPCAsmPrinter.cpp | 5 +- lib/Target/PowerPC/PPCTargetMachine.cpp | 24 ++++++ 5 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 lib/Target/PowerPC/PPCAsmBackend.cpp diff --git a/lib/Target/PowerPC/CMakeLists.txt b/lib/Target/PowerPC/CMakeLists.txt index 923c079e79b..06132b33e72 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 dbe98a68dbe..7242f3aa845 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 + // 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 00000000000..a6d1426daf0 --- /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(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 8d0e43610dd..8ed5d7f0ee7 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 7946837e06c..4666d7772a6 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 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); }