MCObjectStreamer.cpp revision ed708f9c1facb9928ef2f79503e7030c8f25b00d
18dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===//
28dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//
38dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//                     The LLVM Compiler Infrastructure
48dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//
58dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar// This file is distributed under the University of Illinois Open Source
68dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar// License. See LICENSE.TXT for details.
78dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//
88dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//===----------------------------------------------------------------------===//
98dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar
10835439a397407e421263bd476e5b18bf787ffb6aRafael Espindola#include "llvm/MC/MCAsmInfo.h"
118dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar#include "llvm/MC/MCObjectStreamer.h"
128dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar
138067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer#include "llvm/Support/ErrorHandling.h"
148dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar#include "llvm/MC/MCAssembler.h"
151abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer#include "llvm/MC/MCCodeEmitter.h"
1689b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola#include "llvm/MC/MCContext.h"
17f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola#include "llvm/MC/MCDwarf.h"
188067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer#include "llvm/MC/MCExpr.h"
19ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola#include "llvm/MC/MCSymbol.h"
201abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer#include "llvm/Target/TargetAsmBackend.h"
2189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola#include "llvm/Target/TargetAsmInfo.h"
228dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarusing namespace llvm;
238dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar
248dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel DunbarMCObjectStreamer::MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB,
25feb7ba3d9abfa1eb89f6da93c51649baaa931ab8Daniel Dunbar                                   raw_ostream &OS, MCCodeEmitter *Emitter_)
26feb7ba3d9abfa1eb89f6da93c51649baaa931ab8Daniel Dunbar  : MCStreamer(Context),
27feb7ba3d9abfa1eb89f6da93c51649baaa931ab8Daniel Dunbar    Assembler(new MCAssembler(Context, TAB,
28feb7ba3d9abfa1eb89f6da93c51649baaa931ab8Daniel Dunbar                              *Emitter_, *TAB.createObjectWriter(OS),
29feb7ba3d9abfa1eb89f6da93c51649baaa931ab8Daniel Dunbar                              OS)),
3083b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar    CurSectionData(0)
318dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar{
328dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar}
338dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar
3401dff9646173fea0c38df4471f41272557ca831aJan SjödinMCObjectStreamer::MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB,
3501dff9646173fea0c38df4471f41272557ca831aJan Sjödin                                   raw_ostream &OS, MCCodeEmitter *Emitter_,
3601dff9646173fea0c38df4471f41272557ca831aJan Sjödin                                   MCAssembler *_Assembler)
3701dff9646173fea0c38df4471f41272557ca831aJan Sjödin  : MCStreamer(Context), Assembler(_Assembler), CurSectionData(0)
3801dff9646173fea0c38df4471f41272557ca831aJan Sjödin{
3901dff9646173fea0c38df4471f41272557ca831aJan Sjödin}
4001dff9646173fea0c38df4471f41272557ca831aJan Sjödin
418dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel DunbarMCObjectStreamer::~MCObjectStreamer() {
421abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer  delete &Assembler->getBackend();
431abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer  delete &Assembler->getEmitter();
44feb7ba3d9abfa1eb89f6da93c51649baaa931ab8Daniel Dunbar  delete &Assembler->getWriter();
458dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar  delete Assembler;
468dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar}
4783b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar
488067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. SpencerMCFragment *MCObjectStreamer::getCurrentFragment() const {
498067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  assert(getCurrentSectionData() && "No current section!");
508067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer
518067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  if (!getCurrentSectionData()->empty())
528067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer    return &getCurrentSectionData()->getFragmentList().back();
538067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer
548067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  return 0;
558067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer}
568067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer
578067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. SpencerMCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const {
588067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
598067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  if (!F)
608067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer    F = new MCDataFragment(getCurrentSectionData());
618067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  return F;
628067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer}
638067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer
648067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencerconst MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) {
658067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  switch (Value->getKind()) {
667597212abced110723f2fee985a7d60557c092ecEvan Cheng  case MCExpr::Target:
677597212abced110723f2fee985a7d60557c092ecEvan Cheng    cast<MCTargetExpr>(Value)->AddValueSymbols(Assembler);
687597212abced110723f2fee985a7d60557c092ecEvan Cheng    break;
697597212abced110723f2fee985a7d60557c092ecEvan Cheng
708067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  case MCExpr::Constant:
718067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer    break;
728067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer
738067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  case MCExpr::Binary: {
748067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer    const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
758067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer    AddValueSymbols(BE->getLHS());
768067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer    AddValueSymbols(BE->getRHS());
778067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer    break;
788067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  }
798067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer
808067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  case MCExpr::SymbolRef:
818067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer    Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol());
828067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer    break;
838067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer
848067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  case MCExpr::Unary:
858067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer    AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr());
868067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer    break;
878067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  }
888067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer
898067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  return Value;
908067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer}
918067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer
9289b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindolavoid MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
9389b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola                                     bool isPCRel, unsigned AddrSpace) {
946f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola  assert(AddrSpace == 0 && "Address space must be 0!");
956f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola  MCDataFragment *DF = getOrCreateDataFragment();
966f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola
976f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola  // Avoid fixups when possible.
986f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola  int64_t AbsValue;
99d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola  if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue, getAssembler())) {
1002df042cb32ecb8d2e1d499dfa27d5074c8b40e13Rafael Espindola    EmitIntValue(AbsValue, Size, AddrSpace);
1012df042cb32ecb8d2e1d499dfa27d5074c8b40e13Rafael Espindola    return;
1026f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola  }
1032df042cb32ecb8d2e1d499dfa27d5074c8b40e13Rafael Espindola  DF->addFixup(MCFixup::Create(DF->getContents().size(),
104835439a397407e421263bd476e5b18bf787ffb6aRafael Espindola                               Value,
10589b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola                               MCFixup::getKindForSize(Size, isPCRel)));
1062df042cb32ecb8d2e1d499dfa27d5074c8b40e13Rafael Espindola  DF->getContents().resize(DF->getContents().size() + Size, 0);
1076f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola}
1086f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola
109ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindolavoid MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
110ed708f9c1facb9928ef2f79503e7030c8f25b00dRafael Espindola  MCStreamer::EmitLabel(Symbol);
111ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola
112ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
113ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola
114ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  // FIXME: This is wasteful, we don't necessarily need to create a data
115ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  // fragment. Instead, we should mark the symbol as pointing into the data
116ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  // fragment if it exists, otherwise we should just queue the label and set its
117ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  // fragment pointer when we emit the next fragment.
118ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  MCDataFragment *F = getOrCreateDataFragment();
119ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
120ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  SD.setFragment(F);
121ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  SD.setOffset(F->getContents().size());
122ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola}
123ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola
124d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindolastatic const MCExpr *ForceExpAbs(MCObjectStreamer *Streamer,
125d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola                                  MCContext &Context, const MCExpr* Expr) {
126d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola if (Context.getAsmInfo().hasAggressiveSymbolFolding())
127d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola   return Expr;
128d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola
129d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola MCSymbol *ABS = Context.CreateTempSymbol();
130d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola Streamer->EmitAssignment(ABS, Expr);
131d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola return MCSymbolRefExpr::Create(ABS, Context);
132d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola}
133d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola
134e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindolavoid MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
135660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola  int64_t IntValue;
136d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola  if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
137e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindola    EmitULEB128IntValue(IntValue);
138660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola    return;
139660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola  }
140d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola  Value = ForceExpAbs(this, getContext(), Value);
1413ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola  new MCLEBFragment(*Value, false, getCurrentSectionData());
1423ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola}
1433ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola
144e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindolavoid MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
145660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola  int64_t IntValue;
146d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola  if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
147e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindola    EmitSLEB128IntValue(IntValue);
148660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola    return;
149660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola  }
150d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola  Value = ForceExpAbs(this, getContext(), Value);
1513ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola  new MCLEBFragment(*Value, true, getCurrentSectionData());
1523ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola}
1533ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola
154484291c27319668ad99cb87def000254357736fbRafael Espindolavoid MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
155484291c27319668ad99cb87def000254357736fbRafael Espindola                                         const MCSymbol *Symbol) {
156484291c27319668ad99cb87def000254357736fbRafael Espindola  report_fatal_error("This file format doesn't support weak aliases.");
157484291c27319668ad99cb87def000254357736fbRafael Espindola}
158484291c27319668ad99cb87def000254357736fbRafael Espindola
1597768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindolavoid MCObjectStreamer::ChangeSection(const MCSection *Section) {
16083b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar  assert(Section && "Cannot switch to a null section!");
16183b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar
16283b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar  CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
16383b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar}
16483b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar
165f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindolavoid MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
166f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  // Scan for values.
167f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  for (unsigned i = Inst.getNumOperands(); i--; )
168f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola    if (Inst.getOperand(i).isExpr())
169f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola      AddValueSymbols(Inst.getOperand(i).getExpr());
170f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola
171f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  getCurrentSectionData()->setHasInstructions(true);
172f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola
173f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  // Now that a machine instruction has been assembled into this section, make
174f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  // a line entry for any .loc directive that has been seen.
175f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  MCLineEntry::Make(this, getCurrentSection());
176f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola
177f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  // If this instruction doesn't need relaxation, just emit it as data.
178f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) {
179f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola    EmitInstToData(Inst);
180f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola    return;
181f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  }
182f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola
183f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  // Otherwise, if we are relaxing everything, relax the instruction as much as
184f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  // possible and emit it as data.
185f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  if (getAssembler().getRelaxAll()) {
186f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola    MCInst Relaxed;
187f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola    getAssembler().getBackend().RelaxInstruction(Inst, Relaxed);
188f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola    while (getAssembler().getBackend().MayNeedRelaxation(Relaxed))
189f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola      getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed);
190f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola    EmitInstToData(Relaxed);
191f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola    return;
192f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  }
193f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola
194f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  // Otherwise emit to a separate fragment.
195f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  EmitInstToFragment(Inst);
196f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola}
197f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola
198dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindolavoid MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
199dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola  MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
200dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola
20150ebe53353f6870e913f7715d6d4fc5a1f5bedd6Eli Friedman  SmallString<128> Code;
20250ebe53353f6870e913f7715d6d4fc5a1f5bedd6Eli Friedman  raw_svector_ostream VecOS(Code);
203dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups());
20450ebe53353f6870e913f7715d6d4fc5a1f5bedd6Eli Friedman  VecOS.flush();
20550ebe53353f6870e913f7715d6d4fc5a1f5bedd6Eli Friedman  IF->getCode().append(Code.begin(), Code.end());
206dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola}
207dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola
208245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindolastatic const MCExpr *BuildSymbolDiff(MCContext &Context,
209245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola                                     const MCSymbol *A, const MCSymbol *B) {
210245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola  MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
211245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola  const MCExpr *ARef =
212245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola    MCSymbolRefExpr::Create(A, Variant, Context);
213245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola  const MCExpr *BRef =
214245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola    MCSymbolRefExpr::Create(B, Variant, Context);
215245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola  const MCExpr *AddrDelta =
216245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola    MCBinaryExpr::Create(MCBinaryExpr::Sub, ARef, BRef, Context);
217245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola  return AddrDelta;
218245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola}
219245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola
22032a006e606742b1c5401e49607e33717bb5441f0Rafael Espindolavoid MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
22132a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola                                                const MCSymbol *LastLabel,
22232a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola                                                const MCSymbol *Label) {
22332a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola  if (!LastLabel) {
22489b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola    int PointerSize = getContext().getTargetAsmInfo().getPointerSize();
22532a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola    EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
22632a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola    return;
22732a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola  }
228245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola  const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
22932a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola  int64_t Res;
230d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola  if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
23132a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola    MCDwarfLineAddr::Emit(this, LineDelta, Res);
23232a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola    return;
23332a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola  }
234245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola  AddrDelta = ForceExpAbs(this, getContext(), AddrDelta);
23532a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola  new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, getCurrentSectionData());
23632a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola}
23732a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola
238245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindolavoid MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
239245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola                                                 const MCSymbol *Label) {
240245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola  const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
241245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola  int64_t Res;
242245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola  if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
243245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola    MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
244245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola    return;
245245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola  }
246245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola  AddrDelta = ForceExpAbs(this, getContext(), AddrDelta);
247245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola  new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData());
248245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola}
249245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola
250e23930543c0de0adcfec00cd18e9243ad812a167Rafael Espindolavoid MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
251e23930543c0de0adcfec00cd18e9243ad812a167Rafael Espindola                                        unsigned char Value) {
252f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola  int64_t Res;
253f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola  if (Offset->EvaluateAsAbsolute(Res, getAssembler())) {
254f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola    new MCOrgFragment(*Offset, Value, getCurrentSectionData());
255f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola    return;
256f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola  }
257f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola
258f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola  MCSymbol *CurrentPos = getContext().CreateTempSymbol();
259f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola  EmitLabel(CurrentPos);
260f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola  MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
261f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola  const MCExpr *Ref =
262f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola    MCSymbolRefExpr::Create(CurrentPos, Variant, getContext());
263f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola  const MCExpr *Delta =
264f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola    MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext());
265f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola
266f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola  if (!Delta->EvaluateAsAbsolute(Res, getAssembler()))
267f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola    report_fatal_error("expected assembly-time absolute expression");
268f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola  EmitFill(Res, Value, 0);
269e23930543c0de0adcfec00cd18e9243ad812a167Rafael Espindola}
270e23930543c0de0adcfec00cd18e9243ad812a167Rafael Espindola
27183b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbarvoid MCObjectStreamer::Finish() {
27289b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola  // Dump out the dwarf file & directory tables and line tables.
27389b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola  if (getContext().hasDwarfFiles())
27489b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola    MCDwarfFileTable::Emit(this);
27589b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola
27683b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar  getAssembler().Finish();
27783b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar}
278