Index: include/llvm/ExecutionEngine/MCJITStreamer.h
===================================================================
--- include/llvm/ExecutionEngine/MCJITStreamer.h	(revision 0)
+++ include/llvm/ExecutionEngine/MCJITStreamer.h	(revision 0)
@@ -0,0 +1,122 @@
+//===-- MCJITStreamer.h - MC Streamer for the JIT     -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains definition of the MC Streamer used by the MCJIT.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTION_ENGINE_MCJITSTREAMER_H
+#define LLVM_EXECUTION_ENGINE_MCJITSTREAMER_H
+
+#include "llvm/MC/MCStreamer.h"
+
+namespace llvm {
+
+class mem_raw_ostream;
+class MCJITMemoryManager;
+class MCJITObjectWriter;
+class MCJITFunctionInfo;
+class MCJITState;
+class MCCodeEmitter;
+class MCAssembler;
+class MCSectionData;
+class MCDataFragment;
+class MCFragment;
+class TargetAsmBackend;
+
+class MCJITStreamer : public MCStreamer {
+private:
+  MCJITState &JITState;
+
+  MCAssembler *Assembler;
+
+  /// The current section data created by the assembler.
+  MCSectionData *CurSectionData;
+
+  MCJITObjectWriter *Writer;
+
+  /// The memory stream used by the MCJIT object writer.
+  mem_raw_ostream *OS;
+
+  MCJITFunctionInfo *FunctionInfo;
+
+  MCJITMemoryManager &MemoryManager;
+public:
+
+  /// MCJITStreamer - Implementation of the streamer interface for
+  /// code generation into memory.
+  MCJITStreamer(MCJITState &JITState_, MCJITMemoryManager &MemoryManager_,
+                MCContext &Context, TargetAsmBackend &TAB,
+                MCCodeEmitter *Emitter);
+
+  void setFunctionInfo(MCJITFunctionInfo *FunctionInfo_) {
+    FunctionInfo = FunctionInfo_;
+  }
+  
+  /// @ name MCJJITStreamer Implementation of MCStreamer Interface 
+  /// @{
+  virtual void SwitchSection(const MCSection *Section);
+  virtual void EmitLabel(MCSymbol *Symbol);
+  virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
+  virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
+  virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
+  virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
+  virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+                                unsigned ByteAlignment);
+  virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size);
+  virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
+                            unsigned Size = 0,unsigned ByteAlignment = 0);
+  virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
+                              uint64_t Size, unsigned ByteAlignment = 0);
+  virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
+  virtual void EmitValue(const MCExpr *Value, unsigned Size,
+                         unsigned AddrSpace);
+  virtual void EmitGPRel32Value(const MCExpr *Value);
+  virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
+                                    unsigned ValueSize = 1,
+                                    unsigned MaxBytesToEmit = 0);
+  virtual void EmitCodeAlignment(unsigned ByteAlignment,
+                                 unsigned MaxBytesToEmit = 0);
+  virtual void EmitValueToOffset(const MCExpr *Offset,
+                                 unsigned char Value = 0);
+  virtual void EmitInstruction(const MCInst &Inst);
+  
+  virtual void Finish();
+  /// @}
+
+  /// @ name Unsupported MCStreamer Interface Methods
+  /// @{
+  virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol);
+  virtual void EmitCOFFSymbolStorageClass(int StorageClass);
+  virtual void EmitCOFFSymbolType(int Type);
+  virtual void EndCOFFSymbolDef();
+  virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
+  virtual void EmitFileDirective(StringRef Filename);
+  virtual void EmitDwarfFileDirective(unsigned FileNo,StringRef Filename);
+  /// @}
+
+  /// Get the native assembler.
+  MCAssembler &getAssembler() { return *Assembler; }
+protected:
+
+  // From MachoStreamer
+  const MCExpr *AddValueSymbols(const MCExpr *Value);
+  void EmitInstToFragment(const MCInst &Inst);
+  void EmitInstToData(const MCInst &Inst);
+  MCDataFragment *getOrCreateDataFragment() const;
+  MCFragment *getCurrentFragment() const;
+
+  MCSectionData *getCurrentSectionData() const {
+    return CurSectionData;
+  }
+};
+
+} // End llvm namespace
+
+#endif
Index: lib/ExecutionEngine/MCJIT/MCJITStreamer.cpp
===================================================================
--- lib/ExecutionEngine/MCJIT/MCJITStreamer.cpp	(revision 0)
+++ lib/ExecutionEngine/MCJIT/MCJITStreamer.cpp	(revision 0)
@@ -0,0 +1,370 @@
+//===- lib/ExecutionEngine/MCJITStreamer.cpp - JIT Streamer ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ExecutionEngine/MCJITStreamer.h"
+#include "llvm/ExecutionEngine/MCJITFunctionInfo.h"
+#include "llvm/ExecutionEngine/mem_raw_ostream.h"
+#include "llvm/MC/MCStreamer.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/MC/MCExpr.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Target/TargetAsmBackend.h"
+
+using namespace llvm;
+
+class MCJITObjectWriter;
+class MCJITState;
+
+MCJITStreamer::MCJITStreamer(MCJITState &JITState_,
+                             MCJITMemoryManager &MemoryManager_,
+                             MCContext &Context, TargetAsmBackend &TAB,
+                             MCCodeEmitter *Emitter)
+  : MCStreamer(Context), JITState(JITState_),
+    Assembler(new MCAssembler(Context, TAB, *Emitter, errs())),
+    Writer(0), OS(0), MemoryManager(MemoryManager_) {
+
+    OS = new mem_raw_ostream();
+    // FIXME: Disable use of MCJITObjectWriter to allow separate patches.
+    Writer = NULL; //new MCJITObjectWriter(JITState, MemoryManager, *OS);
+}
+
+MCFragment *MCJITStreamer::getCurrentFragment() const {
+  assert(getCurrentSectionData() && "No current section!");
+
+  if (!getCurrentSectionData()->empty())
+    return &getCurrentSectionData()->getFragmentList().back();
+
+  return 0;
+}
+
+MCDataFragment *MCJITStreamer::getOrCreateDataFragment() const {
+  MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
+  if (!F)
+    F = new MCDataFragment(getCurrentSectionData());
+  return F;
+}
+
+void MCJITStreamer::EmitInstToFragment(const MCInst &Inst) {
+  MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
+
+  // Add the fixups and data.
+  //
+  // FIXME: Revisit this design decision when relaxation is done, we may be
+  // able to get away with not storing any extra data in the MCInst.
+  SmallVector<MCFixup, 4> Fixups;
+  SmallString<256> Code;
+  raw_svector_ostream VecOS(Code);
+  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
+  VecOS.flush();
+
+  IF->getCode() = Code;
+  IF->getFixups() = Fixups;
+}
+
+void MCJITStreamer::EmitInstToData(const MCInst &Inst) {
+  MCDataFragment *DF = getOrCreateDataFragment();
+
+  SmallVector<MCFixup, 4> Fixups;
+  SmallString<256> Code;
+  raw_svector_ostream VecOS(Code);
+  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
+  VecOS.flush();
+
+  // Add the fixups and data.
+  for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
+    Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
+    DF->addFixup(Fixups[i]);
+  }
+  DF->getContents().append(Code.begin(), Code.end());
+}
+
+const MCExpr *MCJITStreamer::AddValueSymbols(const MCExpr *Value) {
+  switch (Value->getKind()) {
+  case MCExpr::Target: assert(0 && "Can't handle target exprs yet!");
+  case MCExpr::Constant:
+    break;
+
+  case MCExpr::Binary: {
+    const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
+    AddValueSymbols(BE->getLHS());
+    AddValueSymbols(BE->getRHS());
+    break;
+  }
+
+  case MCExpr::SymbolRef:
+    getAssembler().getOrCreateSymbolData(
+      cast<MCSymbolRefExpr>(Value)->getSymbol());
+    break;
+
+  case MCExpr::Unary:
+    AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr());
+    break;
+  }
+
+  return Value;
+}
+
+void MCJITStreamer::SwitchSection(const MCSection *Section) {
+    assert(Section && "Cannot switch to a null section!");
+
+    // If already in this section, then this is a noop.
+    if (Section == CurSection) return;
+
+    CurSection = Section;
+    CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
+}
+
+void MCJITStreamer::EmitLabel(MCSymbol *Symbol) {
+  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
+  assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
+  assert(CurSection && "Cannot emit before setting section!");
+
+  Symbol->setSection(*CurSection);
+
+  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
+
+  // We have to create a new fragment if this is an atom defining symbol,
+  // fragments cannot span atoms.
+  if (getAssembler().isSymbolLinkerVisible(SD.getSymbol()))
+    new MCDataFragment(getCurrentSectionData());
+
+  // FIXME: This is wasteful, we don't necessarily need to create a data
+  // fragment. Instead, we should mark the symbol as pointing into the data
+  // fragment if it exists, otherwise we should just queue the label and set its
+  // fragment pointer when we emit the next fragment.
+  MCDataFragment *F = getOrCreateDataFragment();
+  assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
+  SD.setFragment(F);
+  SD.setOffset(F->getContents().size());
+}
+
+void MCJITStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
+  switch (Flag) {
+  case MCAF_SubsectionsViaSymbols:
+    getAssembler().setSubsectionsViaSymbols(true);
+    return;
+  }
+
+  assert(0 && "invalid assembler flag!");
+}
+
+void MCJITStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
+  // FIXME: Lift context changes into super class.
+  getAssembler().getOrCreateSymbolData(*Symbol);
+  Symbol->setVariableValue(AddValueSymbols(Value));
+}
+
+void MCJITStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
+                                        MCSymbolAttr Attribute) {
+  // Indirect symbols are handled differently, to match how 'as' handles
+  // them. This makes writing matching .o files easier.
+  if (Attribute == MCSA_IndirectSymbol) {
+    // Note that we intentionally cannot use the symbol data here; this is
+    // important for matching the string table that 'as' generates.
+    IndirectSymbolData ISD;
+    ISD.Symbol = Symbol;
+    ISD.SectionData = getCurrentSectionData();
+    getAssembler().getIndirectSymbols().push_back(ISD);
+    return;
+  }
+
+  // Adding a symbol attribute always introduces the symbol, note that an
+  // important side effect of calling getOrCreateSymbolData here is to register
+  // the symbol with the assembler.
+  getAssembler().getOrCreateSymbolData(*Symbol);
+}
+
+void MCJITStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
+  // Encode the 'desc' value into the lowest implementation defined bits.
+  getAssembler().getOrCreateSymbolData(*Symbol).setFlags(DescValue);
+}
+
+
+void MCJITStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+                                     unsigned ByteAlignment) {
+  // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself.
+  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
+
+  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
+  SD.setExternal(true);
+  SD.setCommon(Size, ByteAlignment);
+}
+
+void MCJITStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) {
+  assert("Not supported by MCJIT");
+}
+
+void MCJITStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
+                                 unsigned Size, unsigned ByteAlignment) {
+  MCSectionData &SectData = getAssembler().getOrCreateSectionData(*Section);
+
+  // The symbol may not be present, which only creates the section.
+  if (!Symbol)
+    return;
+
+  // FIXME: Assert that this section has the zerofill type.
+
+  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
+
+  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
+
+  // Emit an align fragment if necessary.
+  if (ByteAlignment != 1)
+    new MCAlignFragment(ByteAlignment, 0, 0, ByteAlignment, &SectData);
+
+  MCFragment *F = new MCFillFragment(0, 0, Size, &SectData);
+  SD.setFragment(F);
+
+  Symbol->setSection(*Section);
+
+  // Update the maximum alignment on the zero fill section if necessary.
+  if (ByteAlignment > SectData.getAlignment())
+    SectData.setAlignment(ByteAlignment);
+}
+
+void MCJITStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
+                                   uint64_t Size, unsigned ByteAlignment) {
+  EmitZerofill(Section, Symbol, Size, ByteAlignment);
+  return;
+}
+
+void MCJITStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
+  getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
+}
+
+void MCJITStreamer::EmitValue(const MCExpr *Value, unsigned Size,
+                              unsigned AddrSpace) {
+  MCDataFragment *DF = getOrCreateDataFragment();
+
+  // Avoid fixups when possible.
+  int64_t AbsValue;
+  if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue)) {
+    // FIXME: Endianness assumption.
+    for (unsigned i = 0; i != Size; ++i)
+      DF->getContents().push_back(uint8_t(AbsValue >> (i * 8)));
+  } else {
+    DF->addFixup(MCFixup::Create(DF->getContents().size(),
+                                 AddValueSymbols(Value),
+                                 MCFixup::getKindForSize(Size)));
+    DF->getContents().resize(DF->getContents().size() + Size, 0);
+  }
+}
+
+void MCJITStreamer::EmitGPRel32Value(const MCExpr *Value) {
+  // FIXME: Implement if needed.
+  assert("Not yet implemented");
+}
+
+void MCJITStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
+                                         unsigned ValueSize, 
+                                         unsigned MaxBytesToEmit) {
+  if (MaxBytesToEmit == 0)
+    MaxBytesToEmit = ByteAlignment;
+  new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
+                      getCurrentSectionData());
+
+  // Update the maximum alignment on the current section if necessary.
+  if (ByteAlignment > getCurrentSectionData()->getAlignment())
+    getCurrentSectionData()->setAlignment(ByteAlignment);
+}
+
+void MCJITStreamer::EmitCodeAlignment(unsigned ByteAlignment,
+                                      unsigned MaxBytesToEmit) {
+  if (MaxBytesToEmit == 0)
+    MaxBytesToEmit = ByteAlignment;
+  MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit,
+                                           getCurrentSectionData());
+  F->setEmitNops(true);
+
+  // Update the maximum alignment on the current section if necessary.
+  if (ByteAlignment > getCurrentSectionData()->getAlignment())
+    getCurrentSectionData()->setAlignment(ByteAlignment);
+}
+
+void MCJITStreamer::EmitValueToOffset(const MCExpr *Offset,
+                                      unsigned char Value) {
+  new MCOrgFragment(*Offset, Value, getCurrentSectionData());
+}
+
+void MCJITStreamer::EmitInstruction(const MCInst &Inst) {
+  // Scan for values.
+  for (unsigned i = Inst.getNumOperands(); i--; )
+    if (Inst.getOperand(i).isExpr())
+      AddValueSymbols(Inst.getOperand(i).getExpr());
+
+  getCurrentSectionData()->setHasInstructions(true);
+
+  // If this instruction doesn't need relaxation, just emit it as data.
+  if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) {
+    EmitInstToData(Inst);
+    return;
+  }
+
+  // Otherwise, if we are relaxing everything, relax the instruction as much as
+  // possible and emit it as data.
+  if (getAssembler().getRelaxAll()) {
+    MCInst Relaxed;
+    getAssembler().getBackend().RelaxInstruction(Inst, Relaxed);
+    while (getAssembler().getBackend().MayNeedRelaxation(Relaxed))
+      getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed);
+    EmitInstToData(Relaxed);
+    return;
+  }
+
+  // Otherwise emit to a separate fragment.
+  EmitInstToFragment(Inst);
+}
+
+void MCJITStreamer::Finish() {
+  // FIXME: Disable use of MCJITObjectWriter to allow sepapate patches.
+  // Writer->setFunctionInfo(FunctionInfo);
+  // getAssembler().Finish(Writer);
+}
+
+//===----------------------------------------------------------------------===//
+// Unsupported Streamer Interface Methods
+void MCJITStreamer::EmitCOFFSymbolStorageClass(int StorageClass)
+{
+  assert("Not supported by MCJIT");
+}
+
+void MCJITStreamer::EmitCOFFSymbolType(int Type)
+{
+  assert("Not supported by MCJIT");
+}
+  
+void MCJITStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol)
+{
+  assert("Not supported by MCJIT");
+}
+
+void MCJITStreamer::EndCOFFSymbolDef()
+{
+  assert("Not supported by MCJIT");
+}
+
+void MCJITStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value)
+{
+  assert("Not supported by MCJIT");
+}
+
+void MCJITStreamer::EmitFileDirective(StringRef Filename)
+{
+  assert("Not supported by MCJIT");
+}
+
+void MCJITStreamer::EmitDwarfFileDirective(unsigned FileNo,StringRef Filename)
+{
+  assert("Not supported by MCJIT");
+}
