MCObjectStreamer.cpp revision 4172a8abbabea2359d91bb07101166565127d798
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 108dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar#include "llvm/MC/MCObjectStreamer.h" 11df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne#include "llvm/ADT/STLExtras.h" 12f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCAsmBackend.h" 13f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCAsmInfo.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" 19f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCObjectWriter.h" 20ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola#include "llvm/MC/MCSymbol.h" 21b02f1e9a6bc332ebd77571fdffcdc44d77e76b31Serge Pavlov#include "llvm/MC/MCSection.h" 22f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/Support/ErrorHandling.h" 238dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarusing namespace llvm; 248dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar 255da3665cc501ed8928e63678254357214ec0b9ebChandler CarruthMCObjectStreamer::MCObjectStreamer(StreamerKind Kind, MCContext &Context, 265da3665cc501ed8928e63678254357214ec0b9ebChandler Carruth MCAsmBackend &TAB, raw_ostream &OS, 275da3665cc501ed8928e63678254357214ec0b9ebChandler Carruth MCCodeEmitter *Emitter_) 285da3665cc501ed8928e63678254357214ec0b9ebChandler Carruth : MCStreamer(Kind, Context), 295da3665cc501ed8928e63678254357214ec0b9ebChandler Carruth Assembler(new MCAssembler(Context, TAB, *Emitter_, 305da3665cc501ed8928e63678254357214ec0b9ebChandler Carruth *TAB.createObjectWriter(OS), OS)), 315da3665cc501ed8928e63678254357214ec0b9ebChandler Carruth CurSectionData(0) {} 328dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar 335da3665cc501ed8928e63678254357214ec0b9ebChandler CarruthMCObjectStreamer::MCObjectStreamer(StreamerKind Kind, MCContext &Context, 345da3665cc501ed8928e63678254357214ec0b9ebChandler Carruth MCAsmBackend &TAB, raw_ostream &OS, 355da3665cc501ed8928e63678254357214ec0b9ebChandler Carruth MCCodeEmitter *Emitter_, 3601dff9646173fea0c38df4471f41272557ca831aJan Sjödin MCAssembler *_Assembler) 375da3665cc501ed8928e63678254357214ec0b9ebChandler Carruth : MCStreamer(Kind, Context), Assembler(_Assembler), CurSectionData(0) {} 3801dff9646173fea0c38df4471f41272557ca831aJan Sjödin 398dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel DunbarMCObjectStreamer::~MCObjectStreamer() { 401abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer delete &Assembler->getBackend(); 411abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer delete &Assembler->getEmitter(); 42feb7ba3d9abfa1eb89f6da93c51649baaa931ab8Daniel Dunbar delete &Assembler->getWriter(); 438dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar delete Assembler; 448dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar} 4583b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar 465399d2502acaf96fe8420e61913e77f0b23650ffPedro Artigasvoid MCObjectStreamer::reset() { 4799cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas if (Assembler) 4899cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas Assembler->reset(); 49b9d1005e96681b5c8cc1ed959fa129de62933020Pedro Artigas CurSectionData = 0; 50df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne CurInsertionPoint = MCSectionData::iterator(); 515399d2502acaf96fe8420e61913e77f0b23650ffPedro Artigas MCStreamer::reset(); 525399d2502acaf96fe8420e61913e77f0b23650ffPedro Artigas} 535399d2502acaf96fe8420e61913e77f0b23650ffPedro Artigas 548067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. SpencerMCFragment *MCObjectStreamer::getCurrentFragment() const { 558067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer assert(getCurrentSectionData() && "No current section!"); 568067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 57df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne if (CurInsertionPoint != getCurrentSectionData()->getFragmentList().begin()) 58df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne return prior(CurInsertionPoint); 598067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 608067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer return 0; 618067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer} 628067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 638067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. SpencerMCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const { 648067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 6567144e37ba5cd35ee917daac631e03963b05a674Derek Schuff // When bundling is enabled, we don't want to add data to a fragment that 6667144e37ba5cd35ee917daac631e03963b05a674Derek Schuff // already has instructions (see MCELFStreamer::EmitInstToData for details) 67df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne if (!F || (Assembler->isBundlingEnabled() && F->hasInstructions())) { 68df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne F = new MCDataFragment(); 69df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne insert(F); 70df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne } 718067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer return F; 728067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer} 738067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 748067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencerconst MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) { 758067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer switch (Value->getKind()) { 767597212abced110723f2fee985a7d60557c092ecEvan Cheng case MCExpr::Target: 777597212abced110723f2fee985a7d60557c092ecEvan Cheng cast<MCTargetExpr>(Value)->AddValueSymbols(Assembler); 787597212abced110723f2fee985a7d60557c092ecEvan Cheng break; 797597212abced110723f2fee985a7d60557c092ecEvan Cheng 808067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer case MCExpr::Constant: 818067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer break; 828067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 838067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer case MCExpr::Binary: { 848067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); 858067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer AddValueSymbols(BE->getLHS()); 868067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer AddValueSymbols(BE->getRHS()); 878067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer break; 888067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer } 898067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 908067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer case MCExpr::SymbolRef: 918067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol()); 928067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer break; 938067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 948067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer case MCExpr::Unary: 958067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr()); 968067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer break; 978067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer } 988067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 998067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer return Value; 1008067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer} 1018067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 102a3863ea2dacafc925a8272ebf9884fc64bef686cRafael Espindolavoid MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) { 1036f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola MCDataFragment *DF = getOrCreateDataFragment(); 1046f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola 10541b646c127300c6e3b83f1a0bfc49c812110ebf4Cameron Zwarich MCLineEntry::Make(this, getCurrentSection().first); 10641b646c127300c6e3b83f1a0bfc49c812110ebf4Cameron Zwarich 1076f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola // Avoid fixups when possible. 1086f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola int64_t AbsValue; 109d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue, getAssembler())) { 110a3863ea2dacafc925a8272ebf9884fc64bef686cRafael Espindola EmitIntValue(AbsValue, Size); 1112df042cb32ecb8d2e1d499dfa27d5074c8b40e13Rafael Espindola return; 1126f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola } 11364d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky DF->getFixups().push_back( 11464d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky MCFixup::Create(DF->getContents().size(), Value, 11564d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky MCFixup::getKindForSize(Size, false))); 1162df042cb32ecb8d2e1d499dfa27d5074c8b40e13Rafael Espindola DF->getContents().resize(DF->getContents().size() + Size, 0); 1176f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola} 1186f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola 119547be2699c547b79a7735858a64921d8ccf180f7Rafael Espindolavoid MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { 120547be2699c547b79a7735858a64921d8ccf180f7Rafael Espindola RecordProcStart(Frame); 121547be2699c547b79a7735858a64921d8ccf180f7Rafael Espindola} 122547be2699c547b79a7735858a64921d8ccf180f7Rafael Espindola 1231fe9737eb49ecb80fbb547f0e16e10a726cd53cfRafael Espindolavoid MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { 1241fe9737eb49ecb80fbb547f0e16e10a726cd53cfRafael Espindola RecordProcEnd(Frame); 1251fe9737eb49ecb80fbb547f0e16e10a726cd53cfRafael Espindola} 1261fe9737eb49ecb80fbb547f0e16e10a726cd53cfRafael Espindola 127ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindolavoid MCObjectStreamer::EmitLabel(MCSymbol *Symbol) { 128ed708f9c1facb9928ef2f79503e7030c8f25b00dRafael Espindola MCStreamer::EmitLabel(Symbol); 129ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola 130ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 131ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola 132ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola // FIXME: This is wasteful, we don't necessarily need to create a data 133ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola // fragment. Instead, we should mark the symbol as pointing into the data 134ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola // fragment if it exists, otherwise we should just queue the label and set its 135ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola // fragment pointer when we emit the next fragment. 136ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola MCDataFragment *F = getOrCreateDataFragment(); 137ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola assert(!SD.getFragment() && "Unexpected fragment on symbol data!"); 138ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola SD.setFragment(F); 139ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola SD.setOffset(F->getContents().size()); 140ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola} 141ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola 1422c3a4641a7785da78839caf574277df9cd93b52cReed Kotlervoid MCObjectStreamer::EmitDebugLabel(MCSymbol *Symbol) { 1432c3a4641a7785da78839caf574277df9cd93b52cReed Kotler EmitLabel(Symbol); 1442c3a4641a7785da78839caf574277df9cd93b52cReed Kotler} 1452c3a4641a7785da78839caf574277df9cd93b52cReed Kotler 146e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindolavoid MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) { 147660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola int64_t IntValue; 148d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) { 149e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindola EmitULEB128IntValue(IntValue); 150660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola return; 151660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola } 152a6f2678f08299f053feb58337fc4322131d99bf4Rafael Espindola Value = ForceExpAbs(Value); 153df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne insert(new MCLEBFragment(*Value, false)); 1543ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola} 1553ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola 156e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindolavoid MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) { 157660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola int64_t IntValue; 158d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) { 159e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindola EmitSLEB128IntValue(IntValue); 160660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola return; 161660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola } 162a6f2678f08299f053feb58337fc4322131d99bf4Rafael Espindola Value = ForceExpAbs(Value); 163df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne insert(new MCLEBFragment(*Value, true)); 1643ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola} 1653ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola 166484291c27319668ad99cb87def000254357736fbRafael Espindolavoid MCObjectStreamer::EmitWeakReference(MCSymbol *Alias, 167484291c27319668ad99cb87def000254357736fbRafael Espindola const MCSymbol *Symbol) { 168484291c27319668ad99cb87def000254357736fbRafael Espindola report_fatal_error("This file format doesn't support weak aliases."); 169484291c27319668ad99cb87def000254357736fbRafael Espindola} 170484291c27319668ad99cb87def000254357736fbRafael Espindola 171df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbournevoid MCObjectStreamer::ChangeSection(const MCSection *Section, 172df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne const MCExpr *Subsection) { 17383b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar assert(Section && "Cannot switch to a null section!"); 17483b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar 17583b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar CurSectionData = &getAssembler().getOrCreateSectionData(*Section); 176df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne 177df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne int64_t IntSubsection = 0; 178df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne if (Subsection && 179df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne !Subsection->EvaluateAsAbsolute(IntSubsection, getAssembler())) 180df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne report_fatal_error("Cannot evaluate subsection number"); 181df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne if (IntSubsection < 0 || IntSubsection > 8192) 182df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne report_fatal_error("Subsection number out of range"); 183df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne CurInsertionPoint = 184df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne CurSectionData->getSubsectionInsertionPoint(unsigned(IntSubsection)); 18583b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar} 18683b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar 187ef76b273f96d99a4a260f3dcadde8fbb96256cf3Eli Benderskyvoid MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 188ef76b273f96d99a4a260f3dcadde8fbb96256cf3Eli Bendersky getAssembler().getOrCreateSymbolData(*Symbol); 189ef76b273f96d99a4a260f3dcadde8fbb96256cf3Eli Bendersky Symbol->setVariableValue(AddValueSymbols(Value)); 190ef76b273f96d99a4a260f3dcadde8fbb96256cf3Eli Bendersky} 191ef76b273f96d99a4a260f3dcadde8fbb96256cf3Eli Bendersky 192f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindolavoid MCObjectStreamer::EmitInstruction(const MCInst &Inst) { 193f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola // Scan for values. 194f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola for (unsigned i = Inst.getNumOperands(); i--; ) 195f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola if (Inst.getOperand(i).isExpr()) 196f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola AddValueSymbols(Inst.getOperand(i).getExpr()); 197f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola 1984766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky MCSectionData *SD = getCurrentSectionData(); 1994766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky SD->setHasInstructions(true); 200f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola 201f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola // Now that a machine instruction has been assembled into this section, make 202f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola // a line entry for any .loc directive that has been seen. 203df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne MCLineEntry::Make(this, getCurrentSection().first); 204f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola 205f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola // If this instruction doesn't need relaxation, just emit it as data. 2064766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky MCAssembler &Assembler = getAssembler(); 2074766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky if (!Assembler.getBackend().mayNeedRelaxation(Inst)) { 208f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola EmitInstToData(Inst); 209f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola return; 210f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola } 211f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola 2124766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky // Otherwise, relax and emit it as data if either: 2134766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky // - The RelaxAll flag was passed 2144766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky // - Bundling is enabled and this instruction is inside a bundle-locked 2154766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky // group. We want to emit all such instructions into the same data 2164766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky // fragment. 2174766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky if (Assembler.getRelaxAll() || 2184766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky (Assembler.isBundlingEnabled() && SD->isBundleLocked())) { 219f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola MCInst Relaxed; 220ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbach getAssembler().getBackend().relaxInstruction(Inst, Relaxed); 221ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbach while (getAssembler().getBackend().mayNeedRelaxation(Relaxed)) 222ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbach getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed); 223f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola EmitInstToData(Relaxed); 224f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola return; 225f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola } 226f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola 227f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola // Otherwise emit to a separate fragment. 228f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola EmitInstToFragment(Inst); 229f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola} 230f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola 231dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindolavoid MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) { 2324766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky // Always create a new, separate fragment here, because its size can change 2334766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky // during relaxation. 234df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne MCRelaxableFragment *IF = new MCRelaxableFragment(Inst); 235df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne insert(IF); 236dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola 23750ebe53353f6870e913f7715d6d4fc5a1f5bedd6Eli Friedman SmallString<128> Code; 23850ebe53353f6870e913f7715d6d4fc5a1f5bedd6Eli Friedman raw_svector_ostream VecOS(Code); 239dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups()); 24050ebe53353f6870e913f7715d6d4fc5a1f5bedd6Eli Friedman VecOS.flush(); 24164d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky IF->getContents().append(Code.begin(), Code.end()); 242dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola} 243dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola 244f78708593407286de34506e699da25a56b65a20dMatt Beaumont-Gay#ifndef NDEBUG 2454172a8abbabea2359d91bb07101166565127d798Craig Topperstatic const char *const BundlingNotImplementedMsg = 2464766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky "Aligned bundling is not implemented for this object format"; 247f78708593407286de34506e699da25a56b65a20dMatt Beaumont-Gay#endif 2484766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky 2494766ef41b31e4f97bce1179c3b0398303bf65356Eli Benderskyvoid MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) { 2504766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky llvm_unreachable(BundlingNotImplementedMsg); 2514766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky} 2524766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky 2536c1d4972cf1cd6b6072e31c05f97abb1ed7a8497Eli Benderskyvoid MCObjectStreamer::EmitBundleLock(bool AlignToEnd) { 2544766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky llvm_unreachable(BundlingNotImplementedMsg); 2554766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky} 2564766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky 2574766ef41b31e4f97bce1179c3b0398303bf65356Eli Benderskyvoid MCObjectStreamer::EmitBundleUnlock() { 2584766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky llvm_unreachable(BundlingNotImplementedMsg); 2594766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky} 2604766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky 2614df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigandvoid MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, 2624df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand unsigned Column, unsigned Flags, 2634df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand unsigned Isa, 2644df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand unsigned Discriminator, 2654df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand StringRef FileName) { 2664df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand // In case we see two .loc directives in a row, make sure the 2674df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand // first one gets a line entry. 2684df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand MCLineEntry::Make(this, getCurrentSection().first); 2694df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand 2704df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags, 2714df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand Isa, Discriminator, FileName); 2724df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand} 2734df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand 27432a006e606742b1c5401e49607e33717bb5441f0Rafael Espindolavoid MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, 27532a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola const MCSymbol *LastLabel, 276672b93a3324cc1da6d374eed4c75c050a9cad7beEvan Cheng const MCSymbol *Label, 277672b93a3324cc1da6d374eed4c75c050a9cad7beEvan Cheng unsigned PointerSize) { 27832a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola if (!LastLabel) { 27932a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola EmitDwarfSetLineAddr(LineDelta, Label, PointerSize); 28032a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola return; 28132a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola } 282245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); 28332a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola int64_t Res; 284d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) { 28532a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola MCDwarfLineAddr::Emit(this, LineDelta, Res); 28632a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola return; 28732a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola } 288a6f2678f08299f053feb58337fc4322131d99bf4Rafael Espindola AddrDelta = ForceExpAbs(AddrDelta); 289df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta)); 29032a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola} 29132a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola 292245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindolavoid MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, 293245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola const MCSymbol *Label) { 294245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); 295245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola int64_t Res; 296245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) { 297245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res); 298245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola return; 299245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola } 300a6f2678f08299f053feb58337fc4322131d99bf4Rafael Espindola AddrDelta = ForceExpAbs(AddrDelta); 301df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne insert(new MCDwarfCallFrameFragment(*AddrDelta)); 302245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola} 303245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola 304a3863ea2dacafc925a8272ebf9884fc64bef686cRafael Espindolavoid MCObjectStreamer::EmitBytes(StringRef Data) { 305e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); 306e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer} 307e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer 308e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramervoid MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment, 309e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer int64_t Value, 310e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer unsigned ValueSize, 311e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer unsigned MaxBytesToEmit) { 312e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer if (MaxBytesToEmit == 0) 313e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer MaxBytesToEmit = ByteAlignment; 314df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit)); 315e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer 316e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer // Update the maximum alignment on the current section if necessary. 317e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer if (ByteAlignment > getCurrentSectionData()->getAlignment()) 318e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer getCurrentSectionData()->setAlignment(ByteAlignment); 319e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer} 320e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer 321e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramervoid MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment, 322e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer unsigned MaxBytesToEmit) { 323e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit); 324e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true); 325e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer} 326e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer 327ebd4c05c3cbd61215366d4d16f1c1a2e57e7156dJim Grosbachbool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, 328660a4d9e0a15ad25db10d25a1a8caeafc0ebad5eJim Grosbach unsigned char Value) { 329f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola int64_t Res; 330f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola if (Offset->EvaluateAsAbsolute(Res, getAssembler())) { 331df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne insert(new MCOrgFragment(*Offset, Value)); 332ebd4c05c3cbd61215366d4d16f1c1a2e57e7156dJim Grosbach return false; 333f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola } 334f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola 335f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola MCSymbol *CurrentPos = getContext().CreateTempSymbol(); 336f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola EmitLabel(CurrentPos); 337f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 338f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola const MCExpr *Ref = 339f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola MCSymbolRefExpr::Create(CurrentPos, Variant, getContext()); 340f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola const MCExpr *Delta = 341f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext()); 342f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola 343f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola if (!Delta->EvaluateAsAbsolute(Res, getAssembler())) 344ebd4c05c3cbd61215366d4d16f1c1a2e57e7156dJim Grosbach return true; 345ca1dd05c3c12e857614ae6837f90894396225dd6Eric Christopher EmitFill(Res, Value); 346ebd4c05c3cbd61215366d4d16f1c1a2e57e7156dJim Grosbach return false; 347e23930543c0de0adcfec00cd18e9243ad812a167Rafael Espindola} 348e23930543c0de0adcfec00cd18e9243ad812a167Rafael Espindola 34984bfc2f090639f933df06cc675c4385511516befAkira Hatanaka// Associate GPRel32 fixup with data and resize data area 35084bfc2f090639f933df06cc675c4385511516befAkira Hatanakavoid MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { 35184bfc2f090639f933df06cc675c4385511516befAkira Hatanaka MCDataFragment *DF = getOrCreateDataFragment(); 35284bfc2f090639f933df06cc675c4385511516befAkira Hatanaka 35364d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(), 35464d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky Value, FK_GPRel_4)); 35584bfc2f090639f933df06cc675c4385511516befAkira Hatanaka DF->getContents().resize(DF->getContents().size() + 4, 0); 35684bfc2f090639f933df06cc675c4385511516befAkira Hatanaka} 35784bfc2f090639f933df06cc675c4385511516befAkira Hatanaka 358101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Carter// Associate GPRel32 fixup with data and resize data area 359101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Cartervoid MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) { 360101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Carter MCDataFragment *DF = getOrCreateDataFragment(); 361101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Carter 36264d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(), 36364d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky Value, FK_GPRel_4)); 364101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Carter DF->getContents().resize(DF->getContents().size() + 8, 0); 365101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Carter} 366101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Carter 367a3863ea2dacafc925a8272ebf9884fc64bef686cRafael Espindolavoid MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) { 368f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramer // FIXME: A MCFillFragment would be more memory efficient but MCExpr has 369f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramer // problems evaluating expressions across multiple fragments. 370f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramer getOrCreateDataFragment()->getContents().append(NumBytes, FillValue); 371f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramer} 372f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramer 373a3863ea2dacafc925a8272ebf9884fc64bef686cRafael Espindolavoid MCObjectStreamer::EmitZeros(uint64_t NumBytes) { 374b02f1e9a6bc332ebd77571fdffcdc44d77e76b31Serge Pavlov unsigned ItemSize = getCurrentSection().first->isVirtualSection() ? 0 : 1; 375b02f1e9a6bc332ebd77571fdffcdc44d77e76b31Serge Pavlov insert(new MCFillFragment(0, ItemSize, NumBytes)); 376b02f1e9a6bc332ebd77571fdffcdc44d77e76b31Serge Pavlov} 377b02f1e9a6bc332ebd77571fdffcdc44d77e76b31Serge Pavlov 37899b4237c1647156f0e1d3d7e03efdab23ed79778Rafael Espindolavoid MCObjectStreamer::FinishImpl() { 37989b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola // Dump out the dwarf file & directory tables and line tables. 380e6ec02e8afe1bec8f9de5c907a50a6efdee261a0Rafael Espindola const MCSymbol *LineSectionSymbol = NULL; 38189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola if (getContext().hasDwarfFiles()) 382489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola LineSectionSymbol = MCDwarfFileTable::Emit(this); 38389b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 38494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // If we are generating dwarf for assembly source files dump out the sections. 38594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby if (getContext().getGenDwarfForAssembly()) 386489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola MCGenDwarfInfo::Emit(this, LineSectionSymbol); 38794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 38883b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar getAssembler().Finish(); 38983b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar} 390