MCStreamer.cpp revision 2d39a0e52df9ce050bd4e2de3a2ecca8fd9a87c3
1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===//
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//                     The LLVM Compiler Infrastructure
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This file is distributed under the University of Illinois Open Source
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// License. See LICENSE.TXT for details.
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//===----------------------------------------------------------------------===//
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "llvm/MC/MCAsmInfo.h"
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "llvm/MC/MCContext.h"
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "llvm/MC/MCStreamer.h"
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "llvm/MC/MCExpr.h"
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "llvm/MC/MCObjectWriter.h"
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "llvm/MC/MCSymbol.h"
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "llvm/Support/ErrorHandling.h"
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "llvm/Support/raw_ostream.h"
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "llvm/Support/LEB128.h"
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "llvm/ADT/SmallString.h"
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "llvm/ADT/Twine.h"
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include <cstdlib>
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovusing namespace llvm;
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMCStreamer::MCStreamer(MCContext &Ctx)
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  : Context(Ctx), EmitEHFrame(true), EmitDebugFrame(false),
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CurrentW64UnwindInfo(0), LastSymbol(0) {
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const MCSection *section = NULL;
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  SectionStack.push_back(std::make_pair(section, section));
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMCStreamer::~MCStreamer() {
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  for (unsigned i = 0; i < getNumW64UnwindInfos(); ++i)
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    delete W64UnwindInfos[i];
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst MCExpr *MCStreamer::BuildSymbolDiff(MCContext &Context,
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                          const MCSymbol *A,
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                          const MCSymbol *B) {
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const MCExpr *ARef =
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MCSymbolRefExpr::Create(A, Variant, Context);
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const MCExpr *BRef =
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MCSymbolRefExpr::Create(B, Variant, Context);
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const MCExpr *AddrDelta =
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MCBinaryExpr::Create(MCBinaryExpr::Sub, ARef, BRef, Context);
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  return AddrDelta;
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst MCExpr *MCStreamer::ForceExpAbs(const MCExpr* Expr) {
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (Context.getAsmInfo().hasAggressiveSymbolFolding() ||
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      isa<MCSymbolRefExpr>(Expr))
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return Expr;
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCSymbol *ABS = Context.CreateTempSymbol();
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitAssignment(ABS, Expr);
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  return MCSymbolRefExpr::Create(ABS, Context);
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovraw_ostream &MCStreamer::GetCommentOS() {
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // By default, discard comments.
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  return nulls();
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitDwarfSetLineAddr(int64_t LineDelta,
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      const MCSymbol *Label, int PointerSize) {
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // emit the sequence to set the address
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitIntValue(dwarf::DW_LNS_extended_op, 1);
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitULEB128IntValue(PointerSize + 1);
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitIntValue(dwarf::DW_LNE_set_address, 1);
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitSymbolValue(Label, PointerSize);
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // emit the sequence for the LineDelta (from 1) and a zero address delta.
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCDwarfLineAddr::Emit(this, LineDelta, 0);
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/// EmitIntValue - Special case of EmitValue that avoids the client having to
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/// pass in a MCExpr for constant integers.
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitIntValue(uint64_t Value, unsigned Size,
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              unsigned AddrSpace) {
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  assert(Size <= 8 && "Invalid size");
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) &&
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         "Invalid size");
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  char buf[8];
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const bool isLittleEndian = Context.getAsmInfo().isLittleEndian();
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  for (unsigned i = 0; i != Size; ++i) {
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned index = isLittleEndian ? i : (Size - i - 1);
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    buf[i] = uint8_t(Value >> (index * 8));
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitBytes(StringRef(buf, Size), AddrSpace);
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/// client having to pass in a MCExpr for constant integers.
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace,
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                     unsigned Padding) {
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  SmallString<128> Tmp;
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  raw_svector_ostream OSE(Tmp);
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  encodeULEB128(Value, OSE, Padding);
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitBytes(OSE.str(), AddrSpace);
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/// client having to pass in a MCExpr for constant integers.
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace) {
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  SmallString<128> Tmp;
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  raw_svector_ostream OSE(Tmp);
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  encodeSLEB128(Value, OSE);
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitBytes(OSE.str(), AddrSpace);
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitAbsValue(const MCExpr *Value, unsigned Size,
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              unsigned AddrSpace) {
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const MCExpr *ABS = ForceExpAbs(Value);
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitValue(ABS, Size, AddrSpace);
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitValue(const MCExpr *Value, unsigned Size,
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                           unsigned AddrSpace) {
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitValueImpl(Value, Size, AddrSpace);
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                  unsigned AddrSpace) {
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitValueImpl(MCSymbolRefExpr::Create(Sym, getContext()), Size,
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                AddrSpace);
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitGPRel64Value(const MCExpr *Value) {
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  report_fatal_error("unsupported directive in streamer");
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitGPRel32Value(const MCExpr *Value) {
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  report_fatal_error("unsupported directive in streamer");
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/// EmitFill - Emit NumBytes bytes worth of the value specified by
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/// FillValue.  This implements directives such as '.space'.
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                          unsigned AddrSpace) {
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  const MCExpr *E = MCConstantExpr::Create(FillValue, getContext());
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  for (uint64_t i = 0, e = NumBytes; i != e; ++i)
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EmitValue(E, 1, AddrSpace);
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovbool MCStreamer::EmitDwarfFileDirective(unsigned FileNo,
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        StringRef Directory,
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        StringRef Filename) {
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  return getContext().GetDwarfFile(Directory, Filename, FileNo) == 0;
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                       unsigned Column, unsigned Flags,
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                       unsigned Isa,
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                       unsigned Discriminator,
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                       StringRef FileName) {
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa,
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                  Discriminator);
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMCDwarfFrameInfo *MCStreamer::getCurrentFrameInfo() {
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (FrameInfos.empty())
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return NULL;
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  return &FrameInfos.back();
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EnsureValidFrame() {
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (!CurFrame || CurFrame->End)
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    report_fatal_error("No open frame");
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                     MCSymbol *EHSymbol) {
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitLabel(MCSymbol *Symbol) {
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  assert(getCurrentSection() && "Cannot emit before setting section!");
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  Symbol->setSection(*getCurrentSection());
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  LastSymbol = Symbol;
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding) {
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidFrame();
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->CompactUnwindEncoding = CompactUnwindEncoding;
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCFISections(bool EH, bool Debug) {
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  assert(EH || Debug);
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitEHFrame = EH;
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitDebugFrame = Debug;
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCFIStartProc() {
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (CurFrame && !CurFrame->End)
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    report_fatal_error("Starting a frame before finishing the previous one!");
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCDwarfFrameInfo Frame;
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitCFIStartProcImpl(Frame);
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FrameInfos.push_back(Frame);
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::RecordProcStart(MCDwarfFrameInfo &Frame) {
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  Frame.Function = LastSymbol;
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // If the function is externally visible, we need to create a local
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // symbol to avoid relocations.
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  StringRef Prefix = getContext().getAsmInfo().getPrivateGlobalPrefix();
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (LastSymbol && LastSymbol->getName().startswith(Prefix)) {
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Frame.Begin = LastSymbol;
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  } else {
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Frame.Begin = getContext().CreateTempSymbol();
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EmitLabel(Frame.Begin);
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCFIEndProc() {
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidFrame();
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitCFIEndProcImpl(*CurFrame);
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::RecordProcEnd(MCDwarfFrameInfo &Frame) {
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  Frame.End = getContext().CreateTempSymbol();
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(Frame.End);
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidFrame();
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCSymbol *Label = getContext().CreateTempSymbol();
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(Label);
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MachineLocation Dest(MachineLocation::VirtualFP);
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MachineLocation Source(Register, -Offset);
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCCFIInstruction Instruction(Label, Dest, Source);
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->Instructions.push_back(Instruction);
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidFrame();
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCSymbol *Label = getContext().CreateTempSymbol();
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(Label);
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MachineLocation Dest(MachineLocation::VirtualFP);
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MachineLocation Source(MachineLocation::VirtualFP, -Offset);
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCCFIInstruction Instruction(Label, Dest, Source);
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->Instructions.push_back(Instruction);
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidFrame();
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCSymbol *Label = getContext().CreateTempSymbol();
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(Label);
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MachineLocation Dest(MachineLocation::VirtualFP);
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MachineLocation Source(MachineLocation::VirtualFP, Adjustment);
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCCFIInstruction Instruction(MCCFIInstruction::RelMove, Label, Dest, Source);
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->Instructions.push_back(Instruction);
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCFIDefCfaRegister(int64_t Register) {
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidFrame();
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCSymbol *Label = getContext().CreateTempSymbol();
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(Label);
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MachineLocation Dest(Register);
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MachineLocation Source(MachineLocation::VirtualFP);
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCCFIInstruction Instruction(Label, Dest, Source);
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->Instructions.push_back(Instruction);
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidFrame();
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCSymbol *Label = getContext().CreateTempSymbol();
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(Label);
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MachineLocation Dest(Register, Offset);
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MachineLocation Source(Register, Offset);
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCCFIInstruction Instruction(Label, Dest, Source);
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->Instructions.push_back(Instruction);
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidFrame();
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCSymbol *Label = getContext().CreateTempSymbol();
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(Label);
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MachineLocation Dest(Register, Offset);
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MachineLocation Source(Register, Offset);
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCCFIInstruction Instruction(MCCFIInstruction::RelMove, Label, Dest, Source);
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->Instructions.push_back(Instruction);
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCFIPersonality(const MCSymbol *Sym,
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    unsigned Encoding) {
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidFrame();
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->Personality = Sym;
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->PersonalityEncoding = Encoding;
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidFrame();
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->Lsda = Sym;
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->LsdaEncoding = Encoding;
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCFIRememberState() {
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidFrame();
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCSymbol *Label = getContext().CreateTempSymbol();
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(Label);
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCCFIInstruction Instruction(MCCFIInstruction::RememberState, Label);
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->Instructions.push_back(Instruction);
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCFIRestoreState() {
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // FIXME: Error if there is no matching cfi_remember_state.
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidFrame();
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCSymbol *Label = getContext().CreateTempSymbol();
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(Label);
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCCFIInstruction Instruction(MCCFIInstruction::RestoreState, Label);
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->Instructions.push_back(Instruction);
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCFISameValue(int64_t Register) {
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidFrame();
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCSymbol *Label = getContext().CreateTempSymbol();
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(Label);
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCCFIInstruction Instruction(MCCFIInstruction::SameValue, Label, Register);
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->Instructions.push_back(Instruction);
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCFIRestore(int64_t Register) {
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidFrame();
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCSymbol *Label = getContext().CreateTempSymbol();
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(Label);
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCCFIInstruction Instruction(MCCFIInstruction::Restore, Label, Register);
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->Instructions.push_back(Instruction);
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCFIEscape(StringRef Values) {
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidFrame();
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCSymbol *Label = getContext().CreateTempSymbol();
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(Label);
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCCFIInstruction Instruction(MCCFIInstruction::Escape, Label, Values);
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->Instructions.push_back(Instruction);
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCFISignalFrame() {
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidFrame();
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->IsSignalFrame = true;
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame) {
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  W64UnwindInfos.push_back(Frame);
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurrentW64UnwindInfo = W64UnwindInfos.back();
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EnsureValidW64UnwindInfo() {
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (!CurFrame || CurFrame->End)
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    report_fatal_error("No open Win64 EH frame function!");
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (CurFrame && !CurFrame->End)
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    report_fatal_error("Starting a function before ending the previous one!");
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHUnwindInfo *Frame = new MCWin64EHUnwindInfo;
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  Frame->Begin = getContext().CreateTempSymbol();
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  Frame->Function = Symbol;
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(Frame->Begin);
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  setCurrentW64UnwindInfo(Frame);
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitWin64EHEndProc() {
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidW64UnwindInfo();
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (CurFrame->ChainedParent)
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    report_fatal_error("Not all chained regions terminated!");
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->End = getContext().CreateTempSymbol();
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(CurFrame->End);
399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitWin64EHStartChained() {
402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidW64UnwindInfo();
403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHUnwindInfo *Frame = new MCWin64EHUnwindInfo;
404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  Frame->Begin = getContext().CreateTempSymbol();
406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  Frame->Function = CurFrame->Function;
407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  Frame->ChainedParent = CurFrame;
408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(Frame->Begin);
409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  setCurrentW64UnwindInfo(Frame);
410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitWin64EHEndChained() {
413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidW64UnwindInfo();
414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (!CurFrame->ChainedParent)
416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    report_fatal_error("End of a chained region outside a chained region!");
417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->End = getContext().CreateTempSymbol();
418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(CurFrame->End);
419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurrentW64UnwindInfo = CurFrame->ChainedParent;
420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    bool Except) {
424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidW64UnwindInfo();
425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (CurFrame->ChainedParent)
427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    report_fatal_error("Chained unwind areas can't have handlers!");
428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->ExceptionHandler = Sym;
429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (!Except && !Unwind)
430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    report_fatal_error("Don't know what kind of handler this is!");
431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (Unwind)
432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CurFrame->HandlesUnwind = true;
433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (Except)
434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CurFrame->HandlesExceptions = true;
435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitWin64EHHandlerData() {
438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidW64UnwindInfo();
439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (CurFrame->ChainedParent)
441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    report_fatal_error("Chained unwind areas can't have handlers!");
442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitWin64EHPushReg(unsigned Register) {
445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidW64UnwindInfo();
446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCSymbol *Label = getContext().CreateTempSymbol();
448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHInstruction Inst(Win64EH::UOP_PushNonVol, Label, Register);
449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(Label);
450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->Instructions.push_back(Inst);
451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidW64UnwindInfo();
455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (CurFrame->LastFrameInst >= 0)
457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    report_fatal_error("Frame register and offset already specified!");
458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (Offset & 0x0F)
459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    report_fatal_error("Misaligned frame pointer offset!");
460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHInstruction Inst(Win64EH::UOP_SetFPReg, NULL, Register, Offset);
461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->LastFrameInst = CurFrame->Instructions.size();
462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->Instructions.push_back(Inst);
463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitWin64EHAllocStack(unsigned Size) {
466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidW64UnwindInfo();
467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (Size & 7)
468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    report_fatal_error("Misaligned stack allocation!");
469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCSymbol *Label = getContext().CreateTempSymbol();
471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHInstruction Inst(Label, Size);
472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(Label);
473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->Instructions.push_back(Inst);
474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) {
477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidW64UnwindInfo();
478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (Offset & 7)
479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    report_fatal_error("Misaligned saved register offset!");
480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCSymbol *Label = getContext().CreateTempSymbol();
482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHInstruction Inst(
483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     Offset > 512*1024-8 ? Win64EH::UOP_SaveNonVolBig : Win64EH::UOP_SaveNonVol,
484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            Label, Register, Offset);
485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(Label);
486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->Instructions.push_back(Inst);
487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) {
490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidW64UnwindInfo();
491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (Offset & 0x0F)
492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    report_fatal_error("Misaligned saved vector register offset!");
493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCSymbol *Label = getContext().CreateTempSymbol();
495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHInstruction Inst(
496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Offset > 512*1024-16 ? Win64EH::UOP_SaveXMM128Big : Win64EH::UOP_SaveXMM128,
497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            Label, Register, Offset);
498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(Label);
499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->Instructions.push_back(Inst);
500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitWin64EHPushFrame(bool Code) {
503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidW64UnwindInfo();
504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (CurFrame->Instructions.size() > 0)
506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    report_fatal_error("If present, PushMachFrame must be the first UOP");
507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCSymbol *Label = getContext().CreateTempSymbol();
508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHInstruction Inst(Win64EH::UOP_PushMachFrame, Label, Code);
509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(Label);
510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->Instructions.push_back(Inst);
511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitWin64EHEndProlog() {
514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EnsureValidW64UnwindInfo();
515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  CurFrame->PrologEnd = getContext().CreateTempSymbol();
517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitLabel(CurFrame->PrologEnd);
518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  llvm_unreachable("This file format doesn't support this directive");
522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitFnStart() {
525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  errs() << "Not implemented yet\n";
526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  abort();
527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitFnEnd() {
530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  errs() << "Not implemented yet\n";
531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  abort();
532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitCantUnwind() {
535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  errs() << "Not implemented yet\n";
536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  abort();
537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitHandlerData() {
540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  errs() << "Not implemented yet\n";
541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  abort();
542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitPersonality(const MCSymbol *Personality) {
545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  errs() << "Not implemented yet\n";
546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  abort();
547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  errs() << "Not implemented yet\n";
551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  abort();
552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitPad(int64_t Offset) {
555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  errs() << "Not implemented yet\n";
556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  abort();
557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool) {
560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  errs() << "Not implemented yet\n";
561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  abort();
562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/// EmitRawText - If this file is backed by an assembly streamer, this dumps
565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/// the specified string in the output .s file.  This capability is
566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/// indicated by the hasRawTextSupport() predicate.
567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitRawText(StringRef String) {
568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  errs() << "EmitRawText called on an MCStreamer that doesn't support it, "
569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  " something must not be fully mc'ized\n";
570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  abort();
571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitRawText(const Twine &T) {
574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  SmallString<128> Str;
575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  T.toVector(Str);
576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EmitRawText(Str.str());
577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitFrames(bool usingCFI) {
580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (!getNumFrameInfos())
581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return;
582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (EmitEHFrame)
584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MCDwarfFrameEmitter::Emit(*this, usingCFI, true);
585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (EmitDebugFrame)
587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    MCDwarfFrameEmitter::Emit(*this, usingCFI, false);
588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::EmitW64Tables() {
591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (!getNumW64UnwindInfos())
592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return;
593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  MCWin64EHUnwindEmitter::Emit(*this);
595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid MCStreamer::Finish() {
598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  if (!FrameInfos.empty() && !FrameInfos.back().End)
599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    report_fatal_error("Unfinished frame!");
600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FinishImpl();
602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov