mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-19 04:32:19 +00:00
Sketch TargetRegistry support for MCCodeEmitter abstract interface.
- Of course, nothing actually can provide this interface yet. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80188 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
81e400092f
commit
4a0abd80f1
32
include/llvm/MC/MCCodeEmitter.h
Normal file
32
include/llvm/MC/MCCodeEmitter.h
Normal file
@ -0,0 +1,32 @@
|
||||
//===-- llvm/MC/MCCodeEmitter.h - Instruction Encoding ----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_MC_MCCODEEMITTER_H
|
||||
#define LLVM_MC_MCCODEEMITTER_H
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// MCCodeEmitter - Generic instruction encoding interface.
|
||||
class MCCodeEmitter {
|
||||
MCCodeEmitter(const MCCodeEmitter &); // DO NOT IMPLEMENT
|
||||
void operator=(const MCCodeEmitter &); // DO NOT IMPLEMENT
|
||||
protected: // Can only create subclasses.
|
||||
MCCodeEmitter();
|
||||
|
||||
public:
|
||||
virtual ~MCCodeEmitter();
|
||||
|
||||
/// EncodeInstruction - Encode the given \arg Inst to bytes on the output
|
||||
/// stream \arg OS.
|
||||
virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS) = 0;
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
@ -18,14 +18,15 @@
|
||||
|
||||
namespace llvm {
|
||||
class AsmPrinter;
|
||||
class MCAsmInfo;
|
||||
class MCCodeEmitter;
|
||||
class MCContext;
|
||||
class MCValue;
|
||||
class MCInst;
|
||||
class MCSection;
|
||||
class MCSymbol;
|
||||
class MCValue;
|
||||
class StringRef;
|
||||
class raw_ostream;
|
||||
class MCAsmInfo;
|
||||
|
||||
/// MCStreamer - Streaming machine code generation interface. This interface
|
||||
/// is intended to provide a programatic interface that is very similar to the
|
||||
@ -241,7 +242,8 @@ namespace llvm {
|
||||
///
|
||||
/// \arg AP - If given, an AsmPrinter to use for printing instructions.
|
||||
MCStreamer *createAsmStreamer(MCContext &Ctx, raw_ostream &OS,
|
||||
const MCAsmInfo &MAI, AsmPrinter *AP = 0);
|
||||
const MCAsmInfo &MAI, AsmPrinter *AP = 0,
|
||||
MCCodeEmitter *CE = 0);
|
||||
|
||||
// FIXME: These two may end up getting rolled into a single
|
||||
// createObjectStreamer interface, which implements the assembler backend, and
|
||||
|
@ -26,6 +26,7 @@
|
||||
namespace llvm {
|
||||
class AsmPrinter;
|
||||
class MCAsmParser;
|
||||
class MCCodeEmitter;
|
||||
class Module;
|
||||
class MCAsmInfo;
|
||||
class TargetAsmParser;
|
||||
@ -57,6 +58,10 @@ namespace llvm {
|
||||
bool VerboseAsm);
|
||||
typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T,
|
||||
MCAsmParser &P);
|
||||
typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const Target &T,
|
||||
TargetMachine &TM,
|
||||
const MCAsmInfo &MAI);
|
||||
|
||||
private:
|
||||
/// Next - The next registered target in the linked list, maintained by the
|
||||
/// TargetRegistry.
|
||||
@ -89,7 +94,14 @@ namespace llvm {
|
||||
/// if registered.
|
||||
AsmParserCtorTy AsmParserCtorFn;
|
||||
|
||||
/// CodeEmitterCtorFn - Construction function for this target's CodeEmitter,
|
||||
/// if registered.
|
||||
CodeEmitterCtorTy CodeEmitterCtorFn;
|
||||
|
||||
public:
|
||||
/// @name Target Information
|
||||
/// @{
|
||||
|
||||
// getNext - Return the next registered target.
|
||||
const Target *getNext() const { return Next; }
|
||||
|
||||
@ -99,6 +111,11 @@ namespace llvm {
|
||||
/// getShortDescription - Get a short description of the target.
|
||||
const char *getShortDescription() const { return ShortDesc; }
|
||||
|
||||
/// @}
|
||||
/// @name Feature Predicates
|
||||
/// @{
|
||||
|
||||
/// hasJIT - Check if this targets supports the just-in-time compilation.
|
||||
bool hasJIT() const { return HasJIT; }
|
||||
|
||||
/// hasTargetMachine - Check if this target supports code generation.
|
||||
@ -110,6 +127,12 @@ namespace llvm {
|
||||
/// hasAsmParser - Check if this target supports .s parsing.
|
||||
bool hasAsmParser() const { return AsmParserCtorFn != 0; }
|
||||
|
||||
/// hasCodeEmitter - Check if this target supports instruction encoding.
|
||||
bool hasCodeEmitter() const { return CodeEmitterCtorFn != 0; }
|
||||
|
||||
/// @}
|
||||
/// @name Feature Constructors
|
||||
/// @{
|
||||
|
||||
/// createAsmInfo - Create a MCAsmInfo implementation for the specified
|
||||
/// target triple.
|
||||
@ -155,6 +178,16 @@ namespace llvm {
|
||||
return 0;
|
||||
return AsmParserCtorFn(*this, Parser);
|
||||
}
|
||||
|
||||
/// createCodeEmitter - Create a target specific code emitter.
|
||||
MCCodeEmitter *createCodeEmitter(TargetMachine &TM,
|
||||
const MCAsmInfo *MAI) const {
|
||||
if (!CodeEmitterCtorFn)
|
||||
return 0;
|
||||
return CodeEmitterCtorFn(*this, TM, *MAI);
|
||||
}
|
||||
|
||||
/// @}
|
||||
};
|
||||
|
||||
/// TargetRegistry - Generic interface to target specific features.
|
||||
@ -303,6 +336,20 @@ namespace llvm {
|
||||
T.AsmParserCtorFn = Fn;
|
||||
}
|
||||
|
||||
/// RegisterCodeEmitter - Register a MCCodeEmitter 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 AsmPrinter for the target.
|
||||
static void RegisterCodeEmitter(Target &T, Target::CodeEmitterCtorTy Fn) {
|
||||
if (!T.CodeEmitterCtorFn)
|
||||
T.CodeEmitterCtorFn = Fn;
|
||||
}
|
||||
|
||||
/// @}
|
||||
};
|
||||
|
||||
@ -431,6 +478,27 @@ namespace llvm {
|
||||
}
|
||||
};
|
||||
|
||||
/// RegisterCodeEmitter - Helper template for registering a target specific
|
||||
/// machine code emitter, for use in the target initialization
|
||||
/// function. Usage:
|
||||
///
|
||||
/// extern "C" void LLVMInitializeFooCodeEmitter() {
|
||||
/// extern Target TheFooTarget;
|
||||
/// RegisterCodeEmitter<FooCodeEmitter> X(TheFooTarget);
|
||||
/// }
|
||||
template<class CodeEmitterImpl>
|
||||
struct RegisterCodeEmitter {
|
||||
RegisterCodeEmitter(Target &T) {
|
||||
TargetRegistry::RegisterCodeEmitter(T, &Allocator);
|
||||
}
|
||||
|
||||
private:
|
||||
static MCCodeEmitter *Allocator(const Target &T, TargetMachine &TM,
|
||||
const MCAsmInfo &MAI) {
|
||||
return new CodeEmitterImpl(T, TM, MAI);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -8,7 +8,9 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
#include "llvm/MC/MCCodeEmitter.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCSectionMachO.h"
|
||||
@ -17,6 +19,7 @@
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
@ -26,10 +29,12 @@ class MCAsmStreamer : public MCStreamer {
|
||||
raw_ostream &OS;
|
||||
const MCAsmInfo &MAI;
|
||||
AsmPrinter *Printer;
|
||||
MCCodeEmitter *Emitter;
|
||||
public:
|
||||
MCAsmStreamer(MCContext &Context, raw_ostream &_OS, const MCAsmInfo &tai,
|
||||
AsmPrinter *_AsmPrinter)
|
||||
: MCStreamer(Context), OS(_OS), MAI(tai), Printer(_AsmPrinter) {}
|
||||
AsmPrinter *_Printer, MCCodeEmitter *_Emitter)
|
||||
: MCStreamer(Context), OS(_OS), MAI(tai), Printer(_Printer),
|
||||
Emitter(_Emitter) {}
|
||||
~MCAsmStreamer() {}
|
||||
|
||||
/// @name MCStreamer Interface
|
||||
@ -290,6 +295,23 @@ static raw_ostream &operator<<(raw_ostream &OS, const MCOperand &Op) {
|
||||
void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
|
||||
assert(CurSection && "Cannot emit contents before setting section!");
|
||||
|
||||
// Show the encoding if we have a code emitter.
|
||||
if (Emitter) {
|
||||
SmallString<256> Code;
|
||||
raw_svector_ostream VecOS(Code);
|
||||
Emitter->EncodeInstruction(Inst, VecOS);
|
||||
VecOS.flush();
|
||||
|
||||
OS.indent(20);
|
||||
OS << " # encoding: [";
|
||||
for (unsigned i = 0, e = Code.size(); i != e; ++i) {
|
||||
if (i + 1 != e)
|
||||
OS << ',';
|
||||
OS << format("%#04x", Code[i]);
|
||||
}
|
||||
OS << "]\n";
|
||||
}
|
||||
|
||||
// If we have an AsmPrinter, use that to print.
|
||||
if (Printer) {
|
||||
Printer->printMCInst(&Inst);
|
||||
@ -314,6 +336,7 @@ void MCAsmStreamer::Finish() {
|
||||
}
|
||||
|
||||
MCStreamer *llvm::createAsmStreamer(MCContext &Context, raw_ostream &OS,
|
||||
const MCAsmInfo &MAI, AsmPrinter *AP) {
|
||||
return new MCAsmStreamer(Context, OS, MAI, AP);
|
||||
const MCAsmInfo &MAI, AsmPrinter *AP,
|
||||
MCCodeEmitter *CE) {
|
||||
return new MCAsmStreamer(Context, OS, MAI, AP, CE);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCCodeEmitter.h"
|
||||
#include "llvm/MC/MCSectionMachO.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
@ -235,6 +236,7 @@ static int AssembleInput(const char *ProgName) {
|
||||
}
|
||||
|
||||
OwningPtr<AsmPrinter> AP;
|
||||
OwningPtr<MCCodeEmitter> CE;
|
||||
OwningPtr<MCStreamer> Str;
|
||||
|
||||
if (FileType == OFT_AssemblyFile) {
|
||||
@ -242,7 +244,8 @@ static int AssembleInput(const char *ProgName) {
|
||||
assert(TAI && "Unable to create target asm info!");
|
||||
|
||||
AP.reset(TheTarget->createAsmPrinter(*Out, *TM, TAI, true));
|
||||
Str.reset(createAsmStreamer(Ctx, *Out, *TAI, AP.get()));
|
||||
CE.reset(TheTarget->createCodeEmitter(*TM, TAI));
|
||||
Str.reset(createAsmStreamer(Ctx, *Out, *TAI, AP.get(), CE.get()));
|
||||
} else {
|
||||
assert(FileType == OFT_ObjectFile && "Invalid file type!");
|
||||
Str.reset(createMachOStreamer(Ctx, *Out));
|
||||
|
Loading…
x
Reference in New Issue
Block a user