MCStreamer.cpp revision 6d86492f5ed0f9853ddd3b24e1aa037e305e1784
1032091d7f62774443c282915964189ea3d8930dePatrick Jenkins//===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===// 2032091d7f62774443c282915964189ea3d8930dePatrick Jenkins// 3032091d7f62774443c282915964189ea3d8930dePatrick Jenkins// The LLVM Compiler Infrastructure 4032091d7f62774443c282915964189ea3d8930dePatrick Jenkins// 521c62da287237d39d0d95004881ea4baae3be6daChris Lattner// This file is distributed under the University of Illinois Open Source 621c62da287237d39d0d95004881ea4baae3be6daChris Lattner// License. See LICENSE.TXT for details. 7032091d7f62774443c282915964189ea3d8930dePatrick Jenkins// 8032091d7f62774443c282915964189ea3d8930dePatrick Jenkins//===----------------------------------------------------------------------===// 9032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 10032091d7f62774443c282915964189ea3d8930dePatrick Jenkins#include "llvm/MC/MCContext.h" 11032091d7f62774443c282915964189ea3d8930dePatrick Jenkins#include "llvm/MC/MCStreamer.h" 12032091d7f62774443c282915964189ea3d8930dePatrick Jenkins#include "llvm/MC/MCExpr.h" 13032091d7f62774443c282915964189ea3d8930dePatrick Jenkins#include "llvm/MC/MCObjectWriter.h" 14032091d7f62774443c282915964189ea3d8930dePatrick Jenkins#include "llvm/Support/ErrorHandling.h" 15032091d7f62774443c282915964189ea3d8930dePatrick Jenkins#include "llvm/Support/raw_ostream.h" 167f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner#include "llvm/ADT/SmallString.h" 17032091d7f62774443c282915964189ea3d8930dePatrick Jenkins#include "llvm/ADT/Twine.h" 18032091d7f62774443c282915964189ea3d8930dePatrick Jenkins#include <cstdlib> 197f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattnerusing namespace llvm; 20032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 21032091d7f62774443c282915964189ea3d8930dePatrick JenkinsMCStreamer::MCStreamer(MCContext &Ctx) : Context(Ctx), CurSection(0), 227f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner PrevSection(0) { 23032091d7f62774443c282915964189ea3d8930dePatrick Jenkins} 24032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 25032091d7f62774443c282915964189ea3d8930dePatrick JenkinsMCStreamer::~MCStreamer() { 26032091d7f62774443c282915964189ea3d8930dePatrick Jenkins} 27032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 28032091d7f62774443c282915964189ea3d8930dePatrick Jenkinsraw_ostream &MCStreamer::GetCommentOS() { 29032091d7f62774443c282915964189ea3d8930dePatrick Jenkins // By default, discard comments. 30032091d7f62774443c282915964189ea3d8930dePatrick Jenkins return nulls(); 31032091d7f62774443c282915964189ea3d8930dePatrick Jenkins} 327f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner 331d1ef14248a24cb7239e0bc9298d84004a8044e6Nick Lewyckyvoid MCStreamer::EmitDwarfSetLineAddr(int64_t LineDelta, 34032091d7f62774443c282915964189ea3d8930dePatrick Jenkins const MCSymbol *Label, int PointerSize) { 35032091d7f62774443c282915964189ea3d8930dePatrick Jenkins // emit the sequence to set the address 36032091d7f62774443c282915964189ea3d8930dePatrick Jenkins EmitIntValue(dwarf::DW_LNS_extended_op, 1); 37032091d7f62774443c282915964189ea3d8930dePatrick Jenkins EmitULEB128IntValue(PointerSize + 1); 387f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner EmitIntValue(dwarf::DW_LNE_set_address, 1); 39032091d7f62774443c282915964189ea3d8930dePatrick Jenkins EmitSymbolValue(Label, PointerSize); 40032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 417f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner // emit the sequence for the LineDelta (from 1) and a zero address delta. 427f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner MCDwarfLineAddr::Emit(this, LineDelta, 0); 437f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner} 44032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 45032091d7f62774443c282915964189ea3d8930dePatrick Jenkins/// EmitIntValue - Special case of EmitValue that avoids the client having to 46032091d7f62774443c282915964189ea3d8930dePatrick Jenkins/// pass in a MCExpr for constant integers. 471d1ef14248a24cb7239e0bc9298d84004a8044e6Nick Lewyckyvoid MCStreamer::EmitIntValue(uint64_t Value, unsigned Size, 487f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner unsigned AddrSpace) { 497f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner assert(Size <= 8); 50032091d7f62774443c282915964189ea3d8930dePatrick Jenkins char buf[8]; 51032091d7f62774443c282915964189ea3d8930dePatrick Jenkins // FIXME: Endianness assumption. 52032091d7f62774443c282915964189ea3d8930dePatrick Jenkins for (unsigned i = 0; i != Size; ++i) 531d1ef14248a24cb7239e0bc9298d84004a8044e6Nick Lewycky buf[i] = uint8_t(Value >> (i * 8)); 54032091d7f62774443c282915964189ea3d8930dePatrick Jenkins EmitBytes(StringRef(buf, Size), AddrSpace); 55032091d7f62774443c282915964189ea3d8930dePatrick Jenkins} 56032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 57032091d7f62774443c282915964189ea3d8930dePatrick Jenkins/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the 58032091d7f62774443c282915964189ea3d8930dePatrick Jenkins/// client having to pass in a MCExpr for constant integers. 591d1ef14248a24cb7239e0bc9298d84004a8044e6Nick Lewyckyvoid MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace) { 601d1ef14248a24cb7239e0bc9298d84004a8044e6Nick Lewycky SmallString<32> Tmp; 61032091d7f62774443c282915964189ea3d8930dePatrick Jenkins raw_svector_ostream OSE(Tmp); 627f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner MCObjectWriter::EncodeULEB128(Value, OSE); 63032091d7f62774443c282915964189ea3d8930dePatrick Jenkins EmitBytes(OSE.str(), AddrSpace); 641d1ef14248a24cb7239e0bc9298d84004a8044e6Nick Lewycky} 65032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 66032091d7f62774443c282915964189ea3d8930dePatrick Jenkins/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the 67032091d7f62774443c282915964189ea3d8930dePatrick Jenkins/// client having to pass in a MCExpr for constant integers. 68032091d7f62774443c282915964189ea3d8930dePatrick Jenkinsvoid MCStreamer::EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace) { 697f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner SmallString<32> Tmp; 707f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner raw_svector_ostream OSE(Tmp); 71032091d7f62774443c282915964189ea3d8930dePatrick Jenkins MCObjectWriter::EncodeSLEB128(Value, OSE); 721d1ef14248a24cb7239e0bc9298d84004a8044e6Nick Lewycky EmitBytes(OSE.str(), AddrSpace); 73032091d7f62774443c282915964189ea3d8930dePatrick Jenkins} 74032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 75032091d7f62774443c282915964189ea3d8930dePatrick Jenkinsvoid MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size, 76032091d7f62774443c282915964189ea3d8930dePatrick Jenkins unsigned AddrSpace) { 77032091d7f62774443c282915964189ea3d8930dePatrick Jenkins EmitValue(MCSymbolRefExpr::Create(Sym, getContext()), Size, AddrSpace); 78032091d7f62774443c282915964189ea3d8930dePatrick Jenkins} 79032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 80032091d7f62774443c282915964189ea3d8930dePatrick Jenkinsvoid MCStreamer::EmitGPRel32Value(const MCExpr *Value) { 81032091d7f62774443c282915964189ea3d8930dePatrick Jenkins report_fatal_error("unsupported directive in streamer"); 82032091d7f62774443c282915964189ea3d8930dePatrick Jenkins} 83032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 84032091d7f62774443c282915964189ea3d8930dePatrick Jenkins/// EmitFill - Emit NumBytes bytes worth of the value specified by 851d1ef14248a24cb7239e0bc9298d84004a8044e6Nick Lewycky/// FillValue. This implements directives such as '.space'. 86032091d7f62774443c282915964189ea3d8930dePatrick Jenkinsvoid MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue, 87032091d7f62774443c282915964189ea3d8930dePatrick Jenkins unsigned AddrSpace) { 88032091d7f62774443c282915964189ea3d8930dePatrick Jenkins const MCExpr *E = MCConstantExpr::Create(FillValue, getContext()); 89032091d7f62774443c282915964189ea3d8930dePatrick Jenkins for (uint64_t i = 0, e = NumBytes; i != e; ++i) 90032091d7f62774443c282915964189ea3d8930dePatrick Jenkins EmitValue(E, 1, AddrSpace); 91032091d7f62774443c282915964189ea3d8930dePatrick Jenkins} 92032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 93032091d7f62774443c282915964189ea3d8930dePatrick Jenkinsbool MCStreamer::EmitDwarfFileDirective(unsigned FileNo, 94032091d7f62774443c282915964189ea3d8930dePatrick Jenkins StringRef Filename) { 95032091d7f62774443c282915964189ea3d8930dePatrick Jenkins return getContext().GetDwarfFile(Filename, FileNo) == 0; 967f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner} 97032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 98032091d7f62774443c282915964189ea3d8930dePatrick Jenkinsvoid MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, 99032091d7f62774443c282915964189ea3d8930dePatrick Jenkins unsigned Column, unsigned Flags, 100032091d7f62774443c282915964189ea3d8930dePatrick Jenkins unsigned Isa, 101032091d7f62774443c282915964189ea3d8930dePatrick Jenkins unsigned Discriminator) { 102032091d7f62774443c282915964189ea3d8930dePatrick Jenkins getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa, 103032091d7f62774443c282915964189ea3d8930dePatrick Jenkins Discriminator); 104032091d7f62774443c282915964189ea3d8930dePatrick Jenkins} 105032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 106032091d7f62774443c282915964189ea3d8930dePatrick Jenkinsbool MCStreamer::EmitCFIStartProc() { 107032091d7f62774443c282915964189ea3d8930dePatrick Jenkins return false; 108032091d7f62774443c282915964189ea3d8930dePatrick Jenkins} 109032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 110032091d7f62774443c282915964189ea3d8930dePatrick Jenkinsbool MCStreamer::EmitCFIEndProc() { 1117f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner return false; 112032091d7f62774443c282915964189ea3d8930dePatrick Jenkins} 113 114bool MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) { 115 return false; 116} 117 118bool MCStreamer::EmitCFIDefCfaRegister(int64_t Register) { 119 return false; 120} 121 122bool MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { 123 return false; 124} 125 126bool MCStreamer::EmitCFIPersonality(const MCSymbol *Sym) { 127 return false; 128} 129 130bool MCStreamer::EmitCFILsda(const MCSymbol *Sym) { 131 return false; 132} 133 134/// EmitRawText - If this file is backed by an assembly streamer, this dumps 135/// the specified string in the output .s file. This capability is 136/// indicated by the hasRawTextSupport() predicate. 137void MCStreamer::EmitRawText(StringRef String) { 138 errs() << "EmitRawText called on an MCStreamer that doesn't support it, " 139 " something must not be fully mc'ized\n"; 140 abort(); 141} 142 143void MCStreamer::EmitRawText(const Twine &T) { 144 SmallString<128> Str; 145 T.toVector(Str); 146 EmitRawText(Str.str()); 147} 148