Currently, createMachOStreamer() is invoked directly in llvm-mc which

isn't ideal if we want to be able to use another object file format.

Add a createObjectStreamer() factory method so that the correct object
file streamer can be instantiated for a given target triple.

llvm-svn: 104318
This commit is contained in:
Matt Fleming 2010-05-21 12:54:43 +00:00
parent 6a5cb8c84a
commit 5d40d53cab
3 changed files with 68 additions and 1 deletions

View File

@ -73,6 +73,13 @@ namespace llvm {
typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const Target &T,
TargetMachine &TM,
MCContext &Ctx);
typedef MCStreamer *(*ObjectStreamerCtorTy)(const Target &T,
const std::string &TT,
MCContext &Ctx,
TargetAsmBackend &TAB,
raw_ostream &_OS,
MCCodeEmitter *_Emitter,
bool RelaxAll);
private:
/// Next - The next registered target in the linked list, maintained by the
@ -126,6 +133,10 @@ namespace llvm {
/// if registered.
CodeEmitterCtorTy CodeEmitterCtorFn;
/// ObjectStreamerCtorFn - Construction function for this target's
/// ObjectStreamer, if registered.
ObjectStreamerCtorTy ObjectStreamerCtorFn;
public:
/// @name Target Information
/// @{
@ -170,6 +181,9 @@ namespace llvm {
/// hasCodeEmitter - Check if this target supports instruction encoding.
bool hasCodeEmitter() const { return CodeEmitterCtorFn != 0; }
/// hasObjectStreamer - Check if this target supports streaming to files.
bool hasObjectStreamer() const { return ObjectStreamerCtorFn != 0; }
/// @}
/// @name Feature Constructors
/// @{
@ -258,6 +272,24 @@ namespace llvm {
return CodeEmitterCtorFn(*this, TM, Ctx);
}
/// createObjectStreamer - Create a target specific MCStreamer.
///
/// \arg TT - The target triple.
/// \arg Ctx - The target context.
/// \arg TAB - The target assembler backend object.
/// \arg _OS - The stream object.
/// \arg _Emitter - The target independent assembler object.
/// \arg RelaxAll - Relax all fixups?
MCStreamer *createObjectStreamer(const std::string &TT, MCContext &Ctx,
TargetAsmBackend &TAB,
raw_ostream &_OS,
MCCodeEmitter *_Emitter,
bool RelaxAll) const {
if (!ObjectStreamerCtorFn)
return 0;
return ObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, RelaxAll);
}
/// @}
};
@ -479,6 +511,20 @@ namespace llvm {
T.CodeEmitterCtorFn = Fn;
}
/// RegisterObjectStreamer - Register an MCStreamer implementation
/// for the given target.
///
/// Clients are responsible for ensuring that registration doesn't occur
/// while another thread is attempting to access the registry. Typically
/// this is done by initializing all targets at program startup.
///
/// @param T - The target being registered.
/// @param Fn - A function to construct an MCStreamer for the target.
static void RegisterObjectStreamer(Target &T, Target::ObjectStreamerCtorTy Fn) {
if (!T.ObjectStreamerCtorFn)
T.ObjectStreamerCtorFn = Fn;
}
/// @}
};

View File

@ -17,6 +17,8 @@
#include "llvm/PassManager.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
@ -37,6 +39,18 @@ static MCAsmInfo *createMCAsmInfo(const Target &T, StringRef TT) {
}
}
static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
MCContext &Ctx, TargetAsmBackend &TAB,
raw_ostream &_OS,
MCCodeEmitter *_Emitter,
bool RelaxAll) {
Triple TheTriple(TT);
switch (TheTriple.getOS()) {
default:
return createMachOStreamer(Ctx, TAB, _OS, _Emitter, RelaxAll);
}
}
extern "C" void LLVMInitializeX86Target() {
// Register the target.
RegisterTargetMachine<X86_32TargetMachine> X(TheX86_32Target);
@ -57,6 +71,12 @@ extern "C" void LLVMInitializeX86Target() {
createX86_32AsmBackend);
TargetRegistry::RegisterAsmBackend(TheX86_64Target,
createX86_64AsmBackend);
// Register the object streamer.
TargetRegistry::RegisterObjectStreamer(TheX86_32Target,
createMCStreamer);
TargetRegistry::RegisterObjectStreamer(TheX86_64Target,
createMCStreamer);
}

View File

@ -301,7 +301,8 @@ static int AssembleInput(const char *ProgName) {
assert(FileType == OFT_ObjectFile && "Invalid file type!");
CE.reset(TheTarget->createCodeEmitter(*TM, Ctx));
TAB.reset(TheTarget->createAsmBackend(TripleName));
Str.reset(createMachOStreamer(Ctx, *TAB, *Out, CE.get(), RelaxAll));
Str.reset(TheTarget->createObjectStreamer(TripleName, Ctx, *TAB,
*Out, CE.get(), RelaxAll));
}
AsmParser Parser(SrcMgr, Ctx, *Str.get(), *MAI);