diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index bc7f5433225..c49f2582d09 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -251,7 +251,8 @@ namespace llvm { /// createMachOStream - Create a machine code streamer which will generative /// Mach-O format object files. - MCStreamer *createMachOStreamer(MCContext &Ctx, raw_ostream &OS); + MCStreamer *createMachOStreamer(MCContext &Ctx, raw_ostream &OS, + MCCodeEmitter *CE = 0); /// createELFStreamer - Create a machine code streamer which will generative /// ELF format object files. diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index ef5a99fb37a..f5887dbc817 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -11,9 +11,12 @@ #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCInst.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; namespace { @@ -42,6 +45,8 @@ class MCMachOStreamer : public MCStreamer { private: MCAssembler Assembler; + MCCodeEmitter *Emitter; + MCSectionData *CurSectionData; DenseMap SectionMap; @@ -68,8 +73,9 @@ private: } public: - MCMachOStreamer(MCContext &Context, raw_ostream &_OS) - : MCStreamer(Context), Assembler(_OS), CurSectionData(0) {} + MCMachOStreamer(MCContext &Context, raw_ostream &_OS, MCCodeEmitter *_Emitter) + : MCStreamer(Context), Assembler(_OS), Emitter(_Emitter), + CurSectionData(0) {} ~MCMachOStreamer() {} const MCValue &AddValueSymbols(const MCValue &Value) { @@ -302,13 +308,26 @@ void MCMachOStreamer::EmitValueToOffset(const MCValue &Offset, } void MCMachOStreamer::EmitInstruction(const MCInst &Inst) { - llvm_unreachable("FIXME: Not yet implemented!"); + // Scan for values. + for (unsigned i = 0; i != Inst.getNumOperands(); ++i) + if (Inst.getOperand(i).isMCValue()) + AddValueSymbols(Inst.getOperand(i).getMCValue()); + + if (!Emitter) + llvm_unreachable("no code emitter available!"); + + // FIXME: Relocations! + SmallString<256> Code; + raw_svector_ostream VecOS(Code); + Emitter->EncodeInstruction(Inst, VecOS); + EmitBytes(VecOS.str()); } void MCMachOStreamer::Finish() { Assembler.Finish(); } -MCStreamer *llvm::createMachOStreamer(MCContext &Context, raw_ostream &OS) { - return new MCMachOStreamer(Context, OS); +MCStreamer *llvm::createMachOStreamer(MCContext &Context, raw_ostream &OS, + MCCodeEmitter *CE) { + return new MCMachOStreamer(Context, OS, CE); } diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index f995a63d8ee..b9cf0de5f9a 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -252,7 +252,8 @@ static int AssembleInput(const char *ProgName) { Str.reset(createAsmStreamer(Ctx, *Out, *TAI, AP.get(), CE.get())); } else { assert(FileType == OFT_ObjectFile && "Invalid file type!"); - Str.reset(createMachOStreamer(Ctx, *Out)); + CE.reset(TheTarget->createCodeEmitter(*TM)); + Str.reset(createMachOStreamer(Ctx, *Out, CE.get())); } AsmParser Parser(SrcMgr, Ctx, *Str.get());