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