1195098Sed//===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===//
2195098Sed//
3195098Sed//                     The LLVM Compiler Infrastructure
4195098Sed//
5195098Sed// This file is distributed under the University of Illinois Open Source
6195098Sed// License. See LICENSE.TXT for details.
7195098Sed//
8195098Sed//===----------------------------------------------------------------------===//
9195098Sed
10249423Sdim#include "llvm/MC/MCStreamer.h"
11249423Sdim#include "llvm/ADT/SmallString.h"
12249423Sdim#include "llvm/ADT/Twine.h"
13263508Sdim#include "llvm/MC/MCAsmBackend.h"
14218893Sdim#include "llvm/MC/MCAsmInfo.h"
15218893Sdim#include "llvm/MC/MCContext.h"
16202878Srdivacky#include "llvm/MC/MCExpr.h"
17218893Sdim#include "llvm/MC/MCObjectWriter.h"
18221345Sdim#include "llvm/MC/MCSymbol.h"
19218893Sdim#include "llvm/Support/ErrorHandling.h"
20249423Sdim#include "llvm/Support/LEB128.h"
21202878Srdivacky#include "llvm/Support/raw_ostream.h"
22206274Srdivacky#include <cstdlib>
23195098Sedusing namespace llvm;
24195098Sed
25263508Sdim// Pin the vtables to this file.
26263508SdimMCTargetStreamer::~MCTargetStreamer() {}
27263508Sdimvoid ARMTargetStreamer::anchor() {}
28263508Sdim
29263508SdimMCStreamer::MCStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer)
30263508Sdim    : Context(Ctx), TargetStreamer(TargetStreamer), EmitEHFrame(true),
31263508Sdim      EmitDebugFrame(false), CurrentW64UnwindInfo(0), LastSymbol(0),
32263508Sdim      AutoInitSections(false) {
33251662Sdim  SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
34263508Sdim  if (TargetStreamer)
35263508Sdim    TargetStreamer->setStreamer(this);
36195098Sed}
37195098Sed
38195098SedMCStreamer::~MCStreamer() {
39223017Sdim  for (unsigned i = 0; i < getNumW64UnwindInfos(); ++i)
40223017Sdim    delete W64UnwindInfos[i];
41195098Sed}
42202878Srdivacky
43249423Sdimvoid MCStreamer::reset() {
44249423Sdim  for (unsigned i = 0; i < getNumW64UnwindInfos(); ++i)
45249423Sdim    delete W64UnwindInfos[i];
46251662Sdim  W64UnwindInfos.clear();
47249423Sdim  EmitEHFrame = true;
48249423Sdim  EmitDebugFrame = false;
49249423Sdim  CurrentW64UnwindInfo = 0;
50249423Sdim  LastSymbol = 0;
51249423Sdim  SectionStack.clear();
52251662Sdim  SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
53249423Sdim}
54249423Sdim
55221345Sdimconst MCExpr *MCStreamer::BuildSymbolDiff(MCContext &Context,
56221345Sdim                                          const MCSymbol *A,
57221345Sdim                                          const MCSymbol *B) {
58221345Sdim  MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
59221345Sdim  const MCExpr *ARef =
60221345Sdim    MCSymbolRefExpr::Create(A, Variant, Context);
61221345Sdim  const MCExpr *BRef =
62221345Sdim    MCSymbolRefExpr::Create(B, Variant, Context);
63221345Sdim  const MCExpr *AddrDelta =
64221345Sdim    MCBinaryExpr::Create(MCBinaryExpr::Sub, ARef, BRef, Context);
65221345Sdim  return AddrDelta;
66221345Sdim}
67221345Sdim
68223017Sdimconst MCExpr *MCStreamer::ForceExpAbs(const MCExpr* Expr) {
69263508Sdim  if (Context.getAsmInfo()->hasAggressiveSymbolFolding() ||
70223017Sdim      isa<MCSymbolRefExpr>(Expr))
71223017Sdim    return Expr;
72221345Sdim
73223017Sdim  MCSymbol *ABS = Context.CreateTempSymbol();
74223017Sdim  EmitAssignment(ABS, Expr);
75223017Sdim  return MCSymbolRefExpr::Create(ABS, Context);
76221345Sdim}
77221345Sdim
78202878Srdivackyraw_ostream &MCStreamer::GetCommentOS() {
79202878Srdivacky  // By default, discard comments.
80202878Srdivacky  return nulls();
81202878Srdivacky}
82202878Srdivacky
83263508Sdimvoid MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) {
84263508Sdim  for (std::vector<MCDwarfFrameInfo>::iterator I = FrameInfos.begin(),
85263508Sdim         E = FrameInfos.end(); I != E; ++I)
86263508Sdim    I->CompactUnwindEncoding =
87263508Sdim      (MAB ? MAB->generateCompactUnwindEncoding(I->Instructions) : 0);
88263508Sdim}
89263508Sdim
90218893Sdimvoid MCStreamer::EmitDwarfSetLineAddr(int64_t LineDelta,
91218893Sdim                                      const MCSymbol *Label, int PointerSize) {
92218893Sdim  // emit the sequence to set the address
93218893Sdim  EmitIntValue(dwarf::DW_LNS_extended_op, 1);
94218893Sdim  EmitULEB128IntValue(PointerSize + 1);
95218893Sdim  EmitIntValue(dwarf::DW_LNE_set_address, 1);
96218893Sdim  EmitSymbolValue(Label, PointerSize);
97202878Srdivacky
98218893Sdim  // emit the sequence for the LineDelta (from 1) and a zero address delta.
99218893Sdim  MCDwarfLineAddr::Emit(this, LineDelta, 0);
100218893Sdim}
101218893Sdim
102202878Srdivacky/// EmitIntValue - Special case of EmitValue that avoids the client having to
103202878Srdivacky/// pass in a MCExpr for constant integers.
104263508Sdimvoid MCStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
105218893Sdim  assert(Size <= 8 && "Invalid size");
106218893Sdim  assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) &&
107218893Sdim         "Invalid size");
108218893Sdim  char buf[8];
109263508Sdim  const bool isLittleEndian = Context.getAsmInfo()->isLittleEndian();
110223017Sdim  for (unsigned i = 0; i != Size; ++i) {
111223017Sdim    unsigned index = isLittleEndian ? i : (Size - i - 1);
112223017Sdim    buf[i] = uint8_t(Value >> (index * 8));
113223017Sdim  }
114263508Sdim  EmitBytes(StringRef(buf, Size));
115202878Srdivacky}
116202878Srdivacky
117218893Sdim/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
118218893Sdim/// client having to pass in a MCExpr for constant integers.
119263508Sdimvoid MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned Padding) {
120234353Sdim  SmallString<128> Tmp;
121218893Sdim  raw_svector_ostream OSE(Tmp);
122239462Sdim  encodeULEB128(Value, OSE, Padding);
123263508Sdim  EmitBytes(OSE.str());
124218893Sdim}
125218893Sdim
126218893Sdim/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
127218893Sdim/// client having to pass in a MCExpr for constant integers.
128263508Sdimvoid MCStreamer::EmitSLEB128IntValue(int64_t Value) {
129234353Sdim  SmallString<128> Tmp;
130218893Sdim  raw_svector_ostream OSE(Tmp);
131239462Sdim  encodeSLEB128(Value, OSE);
132263508Sdim  EmitBytes(OSE.str());
133218893Sdim}
134218893Sdim
135263508Sdimvoid MCStreamer::EmitAbsValue(const MCExpr *Value, unsigned Size) {
136223017Sdim  const MCExpr *ABS = ForceExpAbs(Value);
137263508Sdim  EmitValue(ABS, Size);
138218893Sdim}
139218893Sdim
140218893Sdim
141263508Sdimvoid MCStreamer::EmitValue(const MCExpr *Value, unsigned Size) {
142263508Sdim  EmitValueImpl(Value, Size);
143218893Sdim}
144218893Sdim
145263508Sdimvoid MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size) {
146263508Sdim  EmitValueImpl(MCSymbolRefExpr::Create(Sym, getContext()), Size);
147218893Sdim}
148218893Sdim
149234353Sdimvoid MCStreamer::EmitGPRel64Value(const MCExpr *Value) {
150234353Sdim  report_fatal_error("unsupported directive in streamer");
151234353Sdim}
152234353Sdim
153218893Sdimvoid MCStreamer::EmitGPRel32Value(const MCExpr *Value) {
154218893Sdim  report_fatal_error("unsupported directive in streamer");
155218893Sdim}
156218893Sdim
157202878Srdivacky/// EmitFill - Emit NumBytes bytes worth of the value specified by
158202878Srdivacky/// FillValue.  This implements directives such as '.space'.
159263508Sdimvoid MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) {
160202878Srdivacky  const MCExpr *E = MCConstantExpr::Create(FillValue, getContext());
161202878Srdivacky  for (uint64_t i = 0, e = NumBytes; i != e; ++i)
162263508Sdim    EmitValue(E, 1);
163202878Srdivacky}
164206274Srdivacky
165263508Sdim/// The implementation in this class just redirects to EmitFill.
166263508Sdimvoid MCStreamer::EmitZeros(uint64_t NumBytes) {
167263508Sdim  EmitFill(NumBytes, 0);
168263508Sdim}
169263508Sdim
170218893Sdimbool MCStreamer::EmitDwarfFileDirective(unsigned FileNo,
171234353Sdim                                        StringRef Directory,
172249423Sdim                                        StringRef Filename, unsigned CUID) {
173249423Sdim  return getContext().GetDwarfFile(Directory, Filename, FileNo, CUID) == 0;
174218893Sdim}
175218893Sdim
176218893Sdimvoid MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
177218893Sdim                                       unsigned Column, unsigned Flags,
178218893Sdim                                       unsigned Isa,
179221345Sdim                                       unsigned Discriminator,
180221345Sdim                                       StringRef FileName) {
181218893Sdim  getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa,
182218893Sdim                                  Discriminator);
183218893Sdim}
184218893Sdim
185218893SdimMCDwarfFrameInfo *MCStreamer::getCurrentFrameInfo() {
186218893Sdim  if (FrameInfos.empty())
187249423Sdim    return 0;
188218893Sdim  return &FrameInfos.back();
189218893Sdim}
190218893Sdim
191218893Sdimvoid MCStreamer::EnsureValidFrame() {
192218893Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
193218893Sdim  if (!CurFrame || CurFrame->End)
194218893Sdim    report_fatal_error("No open frame");
195218893Sdim}
196218893Sdim
197221345Sdimvoid MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
198221345Sdim                                     MCSymbol *EHSymbol) {
199221345Sdim}
200221345Sdim
201263508Sdimvoid MCStreamer::AssignSection(MCSymbol *Symbol, const MCSection *Section) {
202263508Sdim  if (Section)
203263508Sdim    Symbol->setSection(*Section);
204263508Sdim  else
205263508Sdim    Symbol->setUndefined();
206263508Sdim
207263508Sdim  // As we emit symbols into a section, track the order so that they can
208263508Sdim  // be sorted upon later. Zero is reserved to mean 'unemitted'.
209263508Sdim  SymbolOrdering[Symbol] = 1 + SymbolOrdering.size();
210263508Sdim}
211263508Sdim
212221345Sdimvoid MCStreamer::EmitLabel(MCSymbol *Symbol) {
213221345Sdim  assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
214251662Sdim  assert(getCurrentSection().first && "Cannot emit before setting section!");
215263508Sdim  AssignSection(Symbol, getCurrentSection().first);
216226633Sdim  LastSymbol = Symbol;
217226633Sdim}
218221345Sdim
219249423Sdimvoid MCStreamer::EmitDebugLabel(MCSymbol *Symbol) {
220249423Sdim  assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
221251662Sdim  assert(getCurrentSection().first && "Cannot emit before setting section!");
222263508Sdim  AssignSection(Symbol, getCurrentSection().first);
223249423Sdim  LastSymbol = Symbol;
224249423Sdim}
225249423Sdim
226226633Sdimvoid MCStreamer::EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding) {
227226633Sdim  EnsureValidFrame();
228226633Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
229226633Sdim  CurFrame->CompactUnwindEncoding = CompactUnwindEncoding;
230226633Sdim}
231226633Sdim
232223017Sdimvoid MCStreamer::EmitCFISections(bool EH, bool Debug) {
233223017Sdim  assert(EH || Debug);
234223017Sdim  EmitEHFrame = EH;
235223017Sdim  EmitDebugFrame = Debug;
236223017Sdim}
237223017Sdim
238221345Sdimvoid MCStreamer::EmitCFIStartProc() {
239218893Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
240221345Sdim  if (CurFrame && !CurFrame->End)
241218893Sdim    report_fatal_error("Starting a frame before finishing the previous one!");
242226633Sdim
243218893Sdim  MCDwarfFrameInfo Frame;
244234353Sdim  EmitCFIStartProcImpl(Frame);
245234353Sdim
246234353Sdim  FrameInfos.push_back(Frame);
247234353Sdim}
248234353Sdim
249234353Sdimvoid MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
250234353Sdim}
251234353Sdim
252234353Sdimvoid MCStreamer::RecordProcStart(MCDwarfFrameInfo &Frame) {
253226633Sdim  Frame.Function = LastSymbol;
254226633Sdim  // If the function is externally visible, we need to create a local
255226633Sdim  // symbol to avoid relocations.
256263508Sdim  StringRef Prefix = getContext().getAsmInfo()->getPrivateGlobalPrefix();
257226633Sdim  if (LastSymbol && LastSymbol->getName().startswith(Prefix)) {
258226633Sdim    Frame.Begin = LastSymbol;
259226633Sdim  } else {
260226633Sdim    Frame.Begin = getContext().CreateTempSymbol();
261226633Sdim    EmitLabel(Frame.Begin);
262226633Sdim  }
263218893Sdim}
264218893Sdim
265221345Sdimvoid MCStreamer::EmitCFIEndProc() {
266218893Sdim  EnsureValidFrame();
267218893Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
268234353Sdim  EmitCFIEndProcImpl(*CurFrame);
269218893Sdim}
270218893Sdim
271234353Sdimvoid MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
272234353Sdim}
273234353Sdim
274234353Sdimvoid MCStreamer::RecordProcEnd(MCDwarfFrameInfo &Frame) {
275234353Sdim  Frame.End = getContext().CreateTempSymbol();
276234353Sdim  EmitLabel(Frame.End);
277234353Sdim}
278234353Sdim
279249423SdimMCSymbol *MCStreamer::EmitCFICommon() {
280218893Sdim  EnsureValidFrame();
281218893Sdim  MCSymbol *Label = getContext().CreateTempSymbol();
282218893Sdim  EmitLabel(Label);
283249423Sdim  return Label;
284249423Sdim}
285249423Sdim
286249423Sdimvoid MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
287249423Sdim  MCSymbol *Label = EmitCFICommon();
288249423Sdim  MCCFIInstruction Instruction =
289249423Sdim    MCCFIInstruction::createDefCfa(Label, Register, Offset);
290249423Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
291218893Sdim  CurFrame->Instructions.push_back(Instruction);
292218893Sdim}
293218893Sdim
294221345Sdimvoid MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
295249423Sdim  MCSymbol *Label = EmitCFICommon();
296249423Sdim  MCCFIInstruction Instruction =
297249423Sdim    MCCFIInstruction::createDefCfaOffset(Label, Offset);
298218893Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
299218893Sdim  CurFrame->Instructions.push_back(Instruction);
300218893Sdim}
301218893Sdim
302221345Sdimvoid MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
303249423Sdim  MCSymbol *Label = EmitCFICommon();
304249423Sdim  MCCFIInstruction Instruction =
305249423Sdim    MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment);
306218893Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
307221345Sdim  CurFrame->Instructions.push_back(Instruction);
308221345Sdim}
309221345Sdim
310221345Sdimvoid MCStreamer::EmitCFIDefCfaRegister(int64_t Register) {
311249423Sdim  MCSymbol *Label = EmitCFICommon();
312249423Sdim  MCCFIInstruction Instruction =
313249423Sdim    MCCFIInstruction::createDefCfaRegister(Label, Register);
314221345Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
315218893Sdim  CurFrame->Instructions.push_back(Instruction);
316218893Sdim}
317218893Sdim
318221345Sdimvoid MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
319249423Sdim  MCSymbol *Label = EmitCFICommon();
320249423Sdim  MCCFIInstruction Instruction =
321249423Sdim    MCCFIInstruction::createOffset(Label, Register, Offset);
322218893Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
323218893Sdim  CurFrame->Instructions.push_back(Instruction);
324218893Sdim}
325218893Sdim
326221345Sdimvoid MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
327249423Sdim  MCSymbol *Label = EmitCFICommon();
328249423Sdim  MCCFIInstruction Instruction =
329249423Sdim    MCCFIInstruction::createRelOffset(Label, Register, Offset);
330221345Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
331221345Sdim  CurFrame->Instructions.push_back(Instruction);
332221345Sdim}
333221345Sdim
334221345Sdimvoid MCStreamer::EmitCFIPersonality(const MCSymbol *Sym,
335218893Sdim                                    unsigned Encoding) {
336218893Sdim  EnsureValidFrame();
337218893Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
338218893Sdim  CurFrame->Personality = Sym;
339218893Sdim  CurFrame->PersonalityEncoding = Encoding;
340218893Sdim}
341218893Sdim
342221345Sdimvoid MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
343218893Sdim  EnsureValidFrame();
344218893Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
345218893Sdim  CurFrame->Lsda = Sym;
346218893Sdim  CurFrame->LsdaEncoding = Encoding;
347218893Sdim}
348218893Sdim
349221345Sdimvoid MCStreamer::EmitCFIRememberState() {
350249423Sdim  MCSymbol *Label = EmitCFICommon();
351249423Sdim  MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
352218893Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
353218893Sdim  CurFrame->Instructions.push_back(Instruction);
354218893Sdim}
355218893Sdim
356221345Sdimvoid MCStreamer::EmitCFIRestoreState() {
357218893Sdim  // FIXME: Error if there is no matching cfi_remember_state.
358249423Sdim  MCSymbol *Label = EmitCFICommon();
359249423Sdim  MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
360218893Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
361218893Sdim  CurFrame->Instructions.push_back(Instruction);
362218893Sdim}
363218893Sdim
364221345Sdimvoid MCStreamer::EmitCFISameValue(int64_t Register) {
365249423Sdim  MCSymbol *Label = EmitCFICommon();
366249423Sdim  MCCFIInstruction Instruction =
367249423Sdim    MCCFIInstruction::createSameValue(Label, Register);
368221345Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
369221345Sdim  CurFrame->Instructions.push_back(Instruction);
370221345Sdim}
371221345Sdim
372234353Sdimvoid MCStreamer::EmitCFIRestore(int64_t Register) {
373249423Sdim  MCSymbol *Label = EmitCFICommon();
374249423Sdim  MCCFIInstruction Instruction =
375249423Sdim    MCCFIInstruction::createRestore(Label, Register);
376234353Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
377234353Sdim  CurFrame->Instructions.push_back(Instruction);
378234353Sdim}
379234353Sdim
380234353Sdimvoid MCStreamer::EmitCFIEscape(StringRef Values) {
381249423Sdim  MCSymbol *Label = EmitCFICommon();
382249423Sdim  MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
383234353Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
384234353Sdim  CurFrame->Instructions.push_back(Instruction);
385234353Sdim}
386234353Sdim
387234353Sdimvoid MCStreamer::EmitCFISignalFrame() {
388234353Sdim  EnsureValidFrame();
389234353Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
390234353Sdim  CurFrame->IsSignalFrame = true;
391234353Sdim}
392234353Sdim
393249423Sdimvoid MCStreamer::EmitCFIUndefined(int64_t Register) {
394249423Sdim  MCSymbol *Label = EmitCFICommon();
395249423Sdim  MCCFIInstruction Instruction =
396249423Sdim    MCCFIInstruction::createUndefined(Label, Register);
397249423Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
398249423Sdim  CurFrame->Instructions.push_back(Instruction);
399249423Sdim}
400249423Sdim
401249423Sdimvoid MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
402249423Sdim  MCSymbol *Label = EmitCFICommon();
403249423Sdim  MCCFIInstruction Instruction =
404249423Sdim    MCCFIInstruction::createRegister(Label, Register1, Register2);
405249423Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
406249423Sdim  CurFrame->Instructions.push_back(Instruction);
407249423Sdim}
408249423Sdim
409263508Sdimvoid MCStreamer::EmitCFIWindowSave() {
410263508Sdim  MCSymbol *Label = EmitCFICommon();
411263508Sdim  MCCFIInstruction Instruction =
412263508Sdim    MCCFIInstruction::createWindowSave(Label);
413263508Sdim  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
414263508Sdim  CurFrame->Instructions.push_back(Instruction);
415263508Sdim}
416263508Sdim
417223017Sdimvoid MCStreamer::setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame) {
418223017Sdim  W64UnwindInfos.push_back(Frame);
419223017Sdim  CurrentW64UnwindInfo = W64UnwindInfos.back();
420223017Sdim}
421223017Sdim
422223017Sdimvoid MCStreamer::EnsureValidW64UnwindInfo() {
423223017Sdim  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
424223017Sdim  if (!CurFrame || CurFrame->End)
425223017Sdim    report_fatal_error("No open Win64 EH frame function!");
426223017Sdim}
427223017Sdim
428223017Sdimvoid MCStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
429223017Sdim  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
430223017Sdim  if (CurFrame && !CurFrame->End)
431223017Sdim    report_fatal_error("Starting a function before ending the previous one!");
432223017Sdim  MCWin64EHUnwindInfo *Frame = new MCWin64EHUnwindInfo;
433223017Sdim  Frame->Begin = getContext().CreateTempSymbol();
434223017Sdim  Frame->Function = Symbol;
435223017Sdim  EmitLabel(Frame->Begin);
436223017Sdim  setCurrentW64UnwindInfo(Frame);
437223017Sdim}
438223017Sdim
439223017Sdimvoid MCStreamer::EmitWin64EHEndProc() {
440223017Sdim  EnsureValidW64UnwindInfo();
441223017Sdim  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
442223017Sdim  if (CurFrame->ChainedParent)
443223017Sdim    report_fatal_error("Not all chained regions terminated!");
444223017Sdim  CurFrame->End = getContext().CreateTempSymbol();
445223017Sdim  EmitLabel(CurFrame->End);
446223017Sdim}
447223017Sdim
448223017Sdimvoid MCStreamer::EmitWin64EHStartChained() {
449223017Sdim  EnsureValidW64UnwindInfo();
450223017Sdim  MCWin64EHUnwindInfo *Frame = new MCWin64EHUnwindInfo;
451223017Sdim  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
452223017Sdim  Frame->Begin = getContext().CreateTempSymbol();
453223017Sdim  Frame->Function = CurFrame->Function;
454223017Sdim  Frame->ChainedParent = CurFrame;
455223017Sdim  EmitLabel(Frame->Begin);
456223017Sdim  setCurrentW64UnwindInfo(Frame);
457223017Sdim}
458223017Sdim
459223017Sdimvoid MCStreamer::EmitWin64EHEndChained() {
460223017Sdim  EnsureValidW64UnwindInfo();
461223017Sdim  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
462223017Sdim  if (!CurFrame->ChainedParent)
463223017Sdim    report_fatal_error("End of a chained region outside a chained region!");
464223017Sdim  CurFrame->End = getContext().CreateTempSymbol();
465223017Sdim  EmitLabel(CurFrame->End);
466223017Sdim  CurrentW64UnwindInfo = CurFrame->ChainedParent;
467223017Sdim}
468223017Sdim
469223017Sdimvoid MCStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
470223017Sdim                                    bool Except) {
471223017Sdim  EnsureValidW64UnwindInfo();
472223017Sdim  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
473223017Sdim  if (CurFrame->ChainedParent)
474223017Sdim    report_fatal_error("Chained unwind areas can't have handlers!");
475223017Sdim  CurFrame->ExceptionHandler = Sym;
476223017Sdim  if (!Except && !Unwind)
477223017Sdim    report_fatal_error("Don't know what kind of handler this is!");
478223017Sdim  if (Unwind)
479223017Sdim    CurFrame->HandlesUnwind = true;
480223017Sdim  if (Except)
481223017Sdim    CurFrame->HandlesExceptions = true;
482223017Sdim}
483223017Sdim
484223017Sdimvoid MCStreamer::EmitWin64EHHandlerData() {
485223017Sdim  EnsureValidW64UnwindInfo();
486223017Sdim  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
487223017Sdim  if (CurFrame->ChainedParent)
488223017Sdim    report_fatal_error("Chained unwind areas can't have handlers!");
489223017Sdim}
490223017Sdim
491223017Sdimvoid MCStreamer::EmitWin64EHPushReg(unsigned Register) {
492223017Sdim  EnsureValidW64UnwindInfo();
493223017Sdim  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
494223017Sdim  MCSymbol *Label = getContext().CreateTempSymbol();
495223017Sdim  MCWin64EHInstruction Inst(Win64EH::UOP_PushNonVol, Label, Register);
496223017Sdim  EmitLabel(Label);
497223017Sdim  CurFrame->Instructions.push_back(Inst);
498223017Sdim}
499223017Sdim
500223017Sdimvoid MCStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
501223017Sdim  EnsureValidW64UnwindInfo();
502223017Sdim  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
503223017Sdim  if (CurFrame->LastFrameInst >= 0)
504223017Sdim    report_fatal_error("Frame register and offset already specified!");
505223017Sdim  if (Offset & 0x0F)
506223017Sdim    report_fatal_error("Misaligned frame pointer offset!");
507263508Sdim  MCSymbol *Label = getContext().CreateTempSymbol();
508263508Sdim  MCWin64EHInstruction Inst(Win64EH::UOP_SetFPReg, Label, Register, Offset);
509263508Sdim  EmitLabel(Label);
510223017Sdim  CurFrame->LastFrameInst = CurFrame->Instructions.size();
511223017Sdim  CurFrame->Instructions.push_back(Inst);
512223017Sdim}
513223017Sdim
514223017Sdimvoid MCStreamer::EmitWin64EHAllocStack(unsigned Size) {
515223017Sdim  EnsureValidW64UnwindInfo();
516223017Sdim  if (Size & 7)
517223017Sdim    report_fatal_error("Misaligned stack allocation!");
518223017Sdim  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
519223017Sdim  MCSymbol *Label = getContext().CreateTempSymbol();
520223017Sdim  MCWin64EHInstruction Inst(Label, Size);
521223017Sdim  EmitLabel(Label);
522223017Sdim  CurFrame->Instructions.push_back(Inst);
523223017Sdim}
524223017Sdim
525223017Sdimvoid MCStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) {
526223017Sdim  EnsureValidW64UnwindInfo();
527223017Sdim  if (Offset & 7)
528223017Sdim    report_fatal_error("Misaligned saved register offset!");
529223017Sdim  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
530223017Sdim  MCSymbol *Label = getContext().CreateTempSymbol();
531223017Sdim  MCWin64EHInstruction Inst(
532223017Sdim     Offset > 512*1024-8 ? Win64EH::UOP_SaveNonVolBig : Win64EH::UOP_SaveNonVol,
533223017Sdim                            Label, Register, Offset);
534223017Sdim  EmitLabel(Label);
535223017Sdim  CurFrame->Instructions.push_back(Inst);
536223017Sdim}
537223017Sdim
538223017Sdimvoid MCStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) {
539223017Sdim  EnsureValidW64UnwindInfo();
540223017Sdim  if (Offset & 0x0F)
541223017Sdim    report_fatal_error("Misaligned saved vector register offset!");
542223017Sdim  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
543223017Sdim  MCSymbol *Label = getContext().CreateTempSymbol();
544223017Sdim  MCWin64EHInstruction Inst(
545223017Sdim    Offset > 512*1024-16 ? Win64EH::UOP_SaveXMM128Big : Win64EH::UOP_SaveXMM128,
546223017Sdim                            Label, Register, Offset);
547223017Sdim  EmitLabel(Label);
548223017Sdim  CurFrame->Instructions.push_back(Inst);
549223017Sdim}
550223017Sdim
551223017Sdimvoid MCStreamer::EmitWin64EHPushFrame(bool Code) {
552223017Sdim  EnsureValidW64UnwindInfo();
553223017Sdim  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
554223017Sdim  if (CurFrame->Instructions.size() > 0)
555223017Sdim    report_fatal_error("If present, PushMachFrame must be the first UOP");
556223017Sdim  MCSymbol *Label = getContext().CreateTempSymbol();
557223017Sdim  MCWin64EHInstruction Inst(Win64EH::UOP_PushMachFrame, Label, Code);
558223017Sdim  EmitLabel(Label);
559223017Sdim  CurFrame->Instructions.push_back(Inst);
560223017Sdim}
561223017Sdim
562223017Sdimvoid MCStreamer::EmitWin64EHEndProlog() {
563223017Sdim  EnsureValidW64UnwindInfo();
564223017Sdim  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
565223017Sdim  CurFrame->PrologEnd = getContext().CreateTempSymbol();
566223017Sdim  EmitLabel(CurFrame->PrologEnd);
567223017Sdim}
568223017Sdim
569234353Sdimvoid MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
570234353Sdim  llvm_unreachable("This file format doesn't support this directive");
571234353Sdim}
572234353Sdim
573208599Srdivacky/// EmitRawText - If this file is backed by an assembly streamer, this dumps
574206274Srdivacky/// the specified string in the output .s file.  This capability is
575206274Srdivacky/// indicated by the hasRawTextSupport() predicate.
576263508Sdimvoid MCStreamer::EmitRawTextImpl(StringRef String) {
577206274Srdivacky  errs() << "EmitRawText called on an MCStreamer that doesn't support it, "
578206274Srdivacky  " something must not be fully mc'ized\n";
579206274Srdivacky  abort();
580206274Srdivacky}
581206274Srdivacky
582206274Srdivackyvoid MCStreamer::EmitRawText(const Twine &T) {
583206274Srdivacky  SmallString<128> Str;
584263508Sdim  EmitRawTextImpl(T.toStringRef(Str));
585206274Srdivacky}
586223017Sdim
587263508Sdimvoid MCStreamer::EmitFrames(MCAsmBackend *MAB, bool usingCFI) {
588223017Sdim  if (!getNumFrameInfos())
589223017Sdim    return;
590223017Sdim
591223017Sdim  if (EmitEHFrame)
592263508Sdim    MCDwarfFrameEmitter::Emit(*this, MAB, usingCFI, true);
593223017Sdim
594223017Sdim  if (EmitDebugFrame)
595263508Sdim    MCDwarfFrameEmitter::Emit(*this, MAB, usingCFI, false);
596223017Sdim}
597223017Sdim
598223017Sdimvoid MCStreamer::EmitW64Tables() {
599223017Sdim  if (!getNumW64UnwindInfos())
600223017Sdim    return;
601223017Sdim
602223017Sdim  MCWin64EHUnwindEmitter::Emit(*this);
603223017Sdim}
604234353Sdim
605234353Sdimvoid MCStreamer::Finish() {
606234353Sdim  if (!FrameInfos.empty() && !FrameInfos.back().End)
607234353Sdim    report_fatal_error("Unfinished frame!");
608234353Sdim
609234353Sdim  FinishImpl();
610234353Sdim}
611249423Sdim
612249423SdimMCSymbolData &MCStreamer::getOrCreateSymbolData(MCSymbol *Symbol) {
613249423Sdim  report_fatal_error("Not supported!");
614249423Sdim  return *(static_cast<MCSymbolData*>(0));
615249423Sdim}
616