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"
13261991Sdim#include "llvm/MC/MCAsmBackend.h"
14218893Sdim#include "llvm/MC/MCAsmInfo.h"
15218893Sdim#include "llvm/MC/MCContext.h"
16202878Srdivacky#include "llvm/MC/MCExpr.h"
17288943Sdim#include "llvm/MC/MCInst.h"
18288943Sdim#include "llvm/MC/MCInstPrinter.h"
19276479Sdim#include "llvm/MC/MCObjectFileInfo.h"
20218893Sdim#include "llvm/MC/MCObjectWriter.h"
21288943Sdim#include "llvm/MC/MCSection.h"
22221345Sdim#include "llvm/MC/MCSymbol.h"
23276479Sdim#include "llvm/MC/MCWin64EH.h"
24218893Sdim#include "llvm/Support/ErrorHandling.h"
25249423Sdim#include "llvm/Support/LEB128.h"
26202878Srdivacky#include "llvm/Support/raw_ostream.h"
27206274Srdivacky#include <cstdlib>
28195098Sedusing namespace llvm;
29195098Sed
30261991Sdim// Pin the vtables to this file.
31261991SdimMCTargetStreamer::~MCTargetStreamer() {}
32261991Sdim
33276479SdimMCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) {
34276479Sdim  S.setTargetStreamer(this);
35276479Sdim}
36276479Sdim
37276479Sdimvoid MCTargetStreamer::emitLabel(MCSymbol *Symbol) {}
38276479Sdim
39276479Sdimvoid MCTargetStreamer::finish() {}
40276479Sdim
41276479Sdimvoid MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
42276479Sdim
43276479SdimMCStreamer::MCStreamer(MCContext &Ctx)
44276479Sdim    : Context(Ctx), CurrentWinFrameInfo(nullptr) {
45251662Sdim  SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
46195098Sed}
47195098Sed
48195098SedMCStreamer::~MCStreamer() {
49276479Sdim  for (unsigned i = 0; i < getNumWinFrameInfos(); ++i)
50276479Sdim    delete WinFrameInfos[i];
51195098Sed}
52202878Srdivacky
53249423Sdimvoid MCStreamer::reset() {
54280031Sdim  DwarfFrameInfos.clear();
55276479Sdim  for (unsigned i = 0; i < getNumWinFrameInfos(); ++i)
56276479Sdim    delete WinFrameInfos[i];
57276479Sdim  WinFrameInfos.clear();
58276479Sdim  CurrentWinFrameInfo = nullptr;
59280031Sdim  SymbolOrdering.clear();
60249423Sdim  SectionStack.clear();
61251662Sdim  SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
62249423Sdim}
63249423Sdim
64202878Srdivackyraw_ostream &MCStreamer::GetCommentOS() {
65202878Srdivacky  // By default, discard comments.
66202878Srdivacky  return nulls();
67202878Srdivacky}
68202878Srdivacky
69276479Sdimvoid MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {}
70276479Sdim
71261991Sdimvoid MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) {
72276479Sdim  for (auto &FI : DwarfFrameInfos)
73276479Sdim    FI.CompactUnwindEncoding =
74276479Sdim        (MAB ? MAB->generateCompactUnwindEncoding(FI.Instructions) : 0);
75261991Sdim}
76261991Sdim
77202878Srdivacky/// EmitIntValue - Special case of EmitValue that avoids the client having to
78202878Srdivacky/// pass in a MCExpr for constant integers.
79261991Sdimvoid MCStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
80280031Sdim  assert(1 <= Size && Size <= 8 && "Invalid size");
81218893Sdim  assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) &&
82218893Sdim         "Invalid size");
83218893Sdim  char buf[8];
84261991Sdim  const bool isLittleEndian = Context.getAsmInfo()->isLittleEndian();
85223017Sdim  for (unsigned i = 0; i != Size; ++i) {
86223017Sdim    unsigned index = isLittleEndian ? i : (Size - i - 1);
87223017Sdim    buf[i] = uint8_t(Value >> (index * 8));
88223017Sdim  }
89261991Sdim  EmitBytes(StringRef(buf, Size));
90202878Srdivacky}
91202878Srdivacky
92218893Sdim/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
93218893Sdim/// client having to pass in a MCExpr for constant integers.
94261991Sdimvoid MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned Padding) {
95234353Sdim  SmallString<128> Tmp;
96218893Sdim  raw_svector_ostream OSE(Tmp);
97239462Sdim  encodeULEB128(Value, OSE, Padding);
98261991Sdim  EmitBytes(OSE.str());
99218893Sdim}
100218893Sdim
101218893Sdim/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
102218893Sdim/// client having to pass in a MCExpr for constant integers.
103261991Sdimvoid MCStreamer::EmitSLEB128IntValue(int64_t Value) {
104234353Sdim  SmallString<128> Tmp;
105218893Sdim  raw_svector_ostream OSE(Tmp);
106239462Sdim  encodeSLEB128(Value, OSE);
107261991Sdim  EmitBytes(OSE.str());
108218893Sdim}
109218893Sdim
110296417Sdimvoid MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) {
111276479Sdim  EmitValueImpl(Value, Size, Loc);
112218893Sdim}
113218893Sdim
114276479Sdimvoid MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
115276479Sdim                                 bool IsSectionRelative) {
116276479Sdim  assert((!IsSectionRelative || Size == 4) &&
117276479Sdim         "SectionRelative value requires 4-bytes");
118276479Sdim
119276479Sdim  if (!IsSectionRelative)
120288943Sdim    EmitValueImpl(MCSymbolRefExpr::create(Sym, getContext()), Size);
121276479Sdim  else
122276479Sdim    EmitCOFFSecRel32(Sym);
123218893Sdim}
124218893Sdim
125234353Sdimvoid MCStreamer::EmitGPRel64Value(const MCExpr *Value) {
126234353Sdim  report_fatal_error("unsupported directive in streamer");
127234353Sdim}
128234353Sdim
129218893Sdimvoid MCStreamer::EmitGPRel32Value(const MCExpr *Value) {
130218893Sdim  report_fatal_error("unsupported directive in streamer");
131218893Sdim}
132218893Sdim
133202878Srdivacky/// EmitFill - Emit NumBytes bytes worth of the value specified by
134202878Srdivacky/// FillValue.  This implements directives such as '.space'.
135261991Sdimvoid MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) {
136288943Sdim  const MCExpr *E = MCConstantExpr::create(FillValue, getContext());
137202878Srdivacky  for (uint64_t i = 0, e = NumBytes; i != e; ++i)
138261991Sdim    EmitValue(E, 1);
139202878Srdivacky}
140206274Srdivacky
141261991Sdim/// The implementation in this class just redirects to EmitFill.
142261991Sdimvoid MCStreamer::EmitZeros(uint64_t NumBytes) {
143261991Sdim  EmitFill(NumBytes, 0);
144261991Sdim}
145261991Sdim
146276479Sdimunsigned MCStreamer::EmitDwarfFileDirective(unsigned FileNo,
147276479Sdim                                            StringRef Directory,
148276479Sdim                                            StringRef Filename, unsigned CUID) {
149288943Sdim  return getContext().getDwarfFile(Directory, Filename, FileNo, CUID);
150218893Sdim}
151218893Sdim
152218893Sdimvoid MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
153218893Sdim                                       unsigned Column, unsigned Flags,
154218893Sdim                                       unsigned Isa,
155221345Sdim                                       unsigned Discriminator,
156221345Sdim                                       StringRef FileName) {
157218893Sdim  getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa,
158218893Sdim                                  Discriminator);
159218893Sdim}
160218893Sdim
161276479SdimMCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
162276479Sdim  MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
163276479Sdim  if (!Table.getLabel()) {
164276479Sdim    StringRef Prefix = Context.getAsmInfo()->getPrivateGlobalPrefix();
165276479Sdim    Table.setLabel(
166288943Sdim        Context.getOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID)));
167276479Sdim  }
168276479Sdim  return Table.getLabel();
169218893Sdim}
170218893Sdim
171276479SdimMCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
172276479Sdim  if (DwarfFrameInfos.empty())
173276479Sdim    return nullptr;
174276479Sdim  return &DwarfFrameInfos.back();
175276479Sdim}
176276479Sdim
177276479Sdimvoid MCStreamer::EnsureValidDwarfFrame() {
178276479Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
179218893Sdim  if (!CurFrame || CurFrame->End)
180218893Sdim    report_fatal_error("No open frame");
181218893Sdim}
182218893Sdim
183221345Sdimvoid MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
184221345Sdim                                     MCSymbol *EHSymbol) {
185221345Sdim}
186221345Sdim
187280031Sdimvoid MCStreamer::InitSections(bool NoExecStack) {
188276479Sdim  SwitchSection(getContext().getObjectFileInfo()->getTextSection());
189276479Sdim}
190276479Sdim
191296417Sdimvoid MCStreamer::AssignFragment(MCSymbol *Symbol, MCFragment *Fragment) {
192296417Sdim  assert(Fragment);
193296417Sdim  Symbol->setFragment(Fragment);
194261991Sdim
195261991Sdim  // As we emit symbols into a section, track the order so that they can
196261991Sdim  // be sorted upon later. Zero is reserved to mean 'unemitted'.
197261991Sdim  SymbolOrdering[Symbol] = 1 + SymbolOrdering.size();
198261991Sdim}
199261991Sdim
200221345Sdimvoid MCStreamer::EmitLabel(MCSymbol *Symbol) {
201221345Sdim  assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
202251662Sdim  assert(getCurrentSection().first && "Cannot emit before setting section!");
203296417Sdim  assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
204296417Sdim  Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
205221345Sdim
206276479Sdim  MCTargetStreamer *TS = getTargetStreamer();
207276479Sdim  if (TS)
208276479Sdim    TS->emitLabel(Symbol);
209249423Sdim}
210249423Sdim
211223017Sdimvoid MCStreamer::EmitCFISections(bool EH, bool Debug) {
212223017Sdim  assert(EH || Debug);
213223017Sdim}
214223017Sdim
215276479Sdimvoid MCStreamer::EmitCFIStartProc(bool IsSimple) {
216276479Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
217221345Sdim  if (CurFrame && !CurFrame->End)
218218893Sdim    report_fatal_error("Starting a frame before finishing the previous one!");
219226633Sdim
220218893Sdim  MCDwarfFrameInfo Frame;
221276479Sdim  Frame.IsSimple = IsSimple;
222234353Sdim  EmitCFIStartProcImpl(Frame);
223234353Sdim
224280031Sdim  const MCAsmInfo* MAI = Context.getAsmInfo();
225280031Sdim  if (MAI) {
226280031Sdim    for (const MCCFIInstruction& Inst : MAI->getInitialFrameState()) {
227280031Sdim      if (Inst.getOperation() == MCCFIInstruction::OpDefCfa ||
228280031Sdim          Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister) {
229280031Sdim        Frame.CurrentCfaRegister = Inst.getRegister();
230280031Sdim      }
231280031Sdim    }
232280031Sdim  }
233280031Sdim
234276479Sdim  DwarfFrameInfos.push_back(Frame);
235234353Sdim}
236234353Sdim
237234353Sdimvoid MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
238234353Sdim}
239234353Sdim
240221345Sdimvoid MCStreamer::EmitCFIEndProc() {
241276479Sdim  EnsureValidDwarfFrame();
242276479Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
243234353Sdim  EmitCFIEndProcImpl(*CurFrame);
244218893Sdim}
245218893Sdim
246234353Sdimvoid MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
247276479Sdim  // Put a dummy non-null value in Frame.End to mark that this frame has been
248276479Sdim  // closed.
249276479Sdim  Frame.End = (MCSymbol *) 1;
250234353Sdim}
251234353Sdim
252249423SdimMCSymbol *MCStreamer::EmitCFICommon() {
253276479Sdim  EnsureValidDwarfFrame();
254288943Sdim  MCSymbol *Label = getContext().createTempSymbol();
255218893Sdim  EmitLabel(Label);
256249423Sdim  return Label;
257249423Sdim}
258249423Sdim
259249423Sdimvoid MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
260249423Sdim  MCSymbol *Label = EmitCFICommon();
261249423Sdim  MCCFIInstruction Instruction =
262249423Sdim    MCCFIInstruction::createDefCfa(Label, Register, Offset);
263276479Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
264218893Sdim  CurFrame->Instructions.push_back(Instruction);
265280031Sdim  CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
266218893Sdim}
267218893Sdim
268221345Sdimvoid MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
269249423Sdim  MCSymbol *Label = EmitCFICommon();
270249423Sdim  MCCFIInstruction Instruction =
271249423Sdim    MCCFIInstruction::createDefCfaOffset(Label, Offset);
272276479Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
273218893Sdim  CurFrame->Instructions.push_back(Instruction);
274218893Sdim}
275218893Sdim
276221345Sdimvoid MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
277249423Sdim  MCSymbol *Label = EmitCFICommon();
278249423Sdim  MCCFIInstruction Instruction =
279249423Sdim    MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment);
280276479Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
281221345Sdim  CurFrame->Instructions.push_back(Instruction);
282221345Sdim}
283221345Sdim
284221345Sdimvoid MCStreamer::EmitCFIDefCfaRegister(int64_t Register) {
285249423Sdim  MCSymbol *Label = EmitCFICommon();
286249423Sdim  MCCFIInstruction Instruction =
287249423Sdim    MCCFIInstruction::createDefCfaRegister(Label, Register);
288276479Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
289218893Sdim  CurFrame->Instructions.push_back(Instruction);
290280031Sdim  CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
291218893Sdim}
292218893Sdim
293221345Sdimvoid MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
294249423Sdim  MCSymbol *Label = EmitCFICommon();
295249423Sdim  MCCFIInstruction Instruction =
296249423Sdim    MCCFIInstruction::createOffset(Label, Register, Offset);
297276479Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
298218893Sdim  CurFrame->Instructions.push_back(Instruction);
299218893Sdim}
300218893Sdim
301221345Sdimvoid MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
302249423Sdim  MCSymbol *Label = EmitCFICommon();
303249423Sdim  MCCFIInstruction Instruction =
304249423Sdim    MCCFIInstruction::createRelOffset(Label, Register, Offset);
305276479Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
306221345Sdim  CurFrame->Instructions.push_back(Instruction);
307221345Sdim}
308221345Sdim
309221345Sdimvoid MCStreamer::EmitCFIPersonality(const MCSymbol *Sym,
310218893Sdim                                    unsigned Encoding) {
311276479Sdim  EnsureValidDwarfFrame();
312276479Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
313218893Sdim  CurFrame->Personality = Sym;
314218893Sdim  CurFrame->PersonalityEncoding = Encoding;
315218893Sdim}
316218893Sdim
317221345Sdimvoid MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
318276479Sdim  EnsureValidDwarfFrame();
319276479Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
320218893Sdim  CurFrame->Lsda = Sym;
321218893Sdim  CurFrame->LsdaEncoding = Encoding;
322218893Sdim}
323218893Sdim
324221345Sdimvoid MCStreamer::EmitCFIRememberState() {
325249423Sdim  MCSymbol *Label = EmitCFICommon();
326249423Sdim  MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
327276479Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
328218893Sdim  CurFrame->Instructions.push_back(Instruction);
329218893Sdim}
330218893Sdim
331221345Sdimvoid MCStreamer::EmitCFIRestoreState() {
332218893Sdim  // FIXME: Error if there is no matching cfi_remember_state.
333249423Sdim  MCSymbol *Label = EmitCFICommon();
334249423Sdim  MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
335276479Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
336218893Sdim  CurFrame->Instructions.push_back(Instruction);
337218893Sdim}
338218893Sdim
339221345Sdimvoid MCStreamer::EmitCFISameValue(int64_t Register) {
340249423Sdim  MCSymbol *Label = EmitCFICommon();
341249423Sdim  MCCFIInstruction Instruction =
342249423Sdim    MCCFIInstruction::createSameValue(Label, Register);
343276479Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
344221345Sdim  CurFrame->Instructions.push_back(Instruction);
345221345Sdim}
346221345Sdim
347234353Sdimvoid MCStreamer::EmitCFIRestore(int64_t Register) {
348249423Sdim  MCSymbol *Label = EmitCFICommon();
349249423Sdim  MCCFIInstruction Instruction =
350249423Sdim    MCCFIInstruction::createRestore(Label, Register);
351276479Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
352234353Sdim  CurFrame->Instructions.push_back(Instruction);
353234353Sdim}
354234353Sdim
355234353Sdimvoid MCStreamer::EmitCFIEscape(StringRef Values) {
356249423Sdim  MCSymbol *Label = EmitCFICommon();
357249423Sdim  MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
358276479Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
359234353Sdim  CurFrame->Instructions.push_back(Instruction);
360234353Sdim}
361234353Sdim
362296417Sdimvoid MCStreamer::EmitCFIGnuArgsSize(int64_t Size) {
363296417Sdim  MCSymbol *Label = EmitCFICommon();
364296417Sdim  MCCFIInstruction Instruction =
365296417Sdim    MCCFIInstruction::createGnuArgsSize(Label, Size);
366296417Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
367296417Sdim  CurFrame->Instructions.push_back(Instruction);
368296417Sdim}
369296417Sdim
370234353Sdimvoid MCStreamer::EmitCFISignalFrame() {
371276479Sdim  EnsureValidDwarfFrame();
372276479Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
373234353Sdim  CurFrame->IsSignalFrame = true;
374234353Sdim}
375234353Sdim
376249423Sdimvoid MCStreamer::EmitCFIUndefined(int64_t Register) {
377249423Sdim  MCSymbol *Label = EmitCFICommon();
378249423Sdim  MCCFIInstruction Instruction =
379249423Sdim    MCCFIInstruction::createUndefined(Label, Register);
380276479Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
381249423Sdim  CurFrame->Instructions.push_back(Instruction);
382249423Sdim}
383249423Sdim
384249423Sdimvoid MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
385249423Sdim  MCSymbol *Label = EmitCFICommon();
386249423Sdim  MCCFIInstruction Instruction =
387249423Sdim    MCCFIInstruction::createRegister(Label, Register1, Register2);
388276479Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
389249423Sdim  CurFrame->Instructions.push_back(Instruction);
390249423Sdim}
391249423Sdim
392261991Sdimvoid MCStreamer::EmitCFIWindowSave() {
393261991Sdim  MCSymbol *Label = EmitCFICommon();
394261991Sdim  MCCFIInstruction Instruction =
395261991Sdim    MCCFIInstruction::createWindowSave(Label);
396276479Sdim  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
397261991Sdim  CurFrame->Instructions.push_back(Instruction);
398261991Sdim}
399261991Sdim
400276479Sdimvoid MCStreamer::EnsureValidWinFrameInfo() {
401288943Sdim  const MCAsmInfo *MAI = Context.getAsmInfo();
402288943Sdim  if (!MAI->usesWindowsCFI())
403288943Sdim    report_fatal_error(".seh_* directives are not supported on this target");
404276479Sdim  if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End)
405223017Sdim    report_fatal_error("No open Win64 EH frame function!");
406223017Sdim}
407223017Sdim
408276479Sdimvoid MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) {
409288943Sdim  const MCAsmInfo *MAI = Context.getAsmInfo();
410288943Sdim  if (!MAI->usesWindowsCFI())
411288943Sdim    report_fatal_error(".seh_* directives are not supported on this target");
412276479Sdim  if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
413223017Sdim    report_fatal_error("Starting a function before ending the previous one!");
414280031Sdim
415288943Sdim  MCSymbol *StartProc = getContext().createTempSymbol();
416280031Sdim  EmitLabel(StartProc);
417280031Sdim
418280031Sdim  WinFrameInfos.push_back(new WinEH::FrameInfo(Symbol, StartProc));
419276479Sdim  CurrentWinFrameInfo = WinFrameInfos.back();
420223017Sdim}
421223017Sdim
422276479Sdimvoid MCStreamer::EmitWinCFIEndProc() {
423276479Sdim  EnsureValidWinFrameInfo();
424276479Sdim  if (CurrentWinFrameInfo->ChainedParent)
425223017Sdim    report_fatal_error("Not all chained regions terminated!");
426280031Sdim
427288943Sdim  MCSymbol *Label = getContext().createTempSymbol();
428280031Sdim  EmitLabel(Label);
429280031Sdim  CurrentWinFrameInfo->End = Label;
430223017Sdim}
431223017Sdim
432276479Sdimvoid MCStreamer::EmitWinCFIStartChained() {
433276479Sdim  EnsureValidWinFrameInfo();
434280031Sdim
435288943Sdim  MCSymbol *StartProc = getContext().createTempSymbol();
436280031Sdim  EmitLabel(StartProc);
437280031Sdim
438280031Sdim  WinFrameInfos.push_back(new WinEH::FrameInfo(CurrentWinFrameInfo->Function,
439280031Sdim                                               StartProc, CurrentWinFrameInfo));
440276479Sdim  CurrentWinFrameInfo = WinFrameInfos.back();
441223017Sdim}
442223017Sdim
443276479Sdimvoid MCStreamer::EmitWinCFIEndChained() {
444276479Sdim  EnsureValidWinFrameInfo();
445276479Sdim  if (!CurrentWinFrameInfo->ChainedParent)
446223017Sdim    report_fatal_error("End of a chained region outside a chained region!");
447280031Sdim
448288943Sdim  MCSymbol *Label = getContext().createTempSymbol();
449280031Sdim  EmitLabel(Label);
450280031Sdim
451280031Sdim  CurrentWinFrameInfo->End = Label;
452280031Sdim  CurrentWinFrameInfo =
453280031Sdim      const_cast<WinEH::FrameInfo *>(CurrentWinFrameInfo->ChainedParent);
454223017Sdim}
455223017Sdim
456276479Sdimvoid MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind,
457276479Sdim                                  bool Except) {
458276479Sdim  EnsureValidWinFrameInfo();
459276479Sdim  if (CurrentWinFrameInfo->ChainedParent)
460223017Sdim    report_fatal_error("Chained unwind areas can't have handlers!");
461276479Sdim  CurrentWinFrameInfo->ExceptionHandler = Sym;
462223017Sdim  if (!Except && !Unwind)
463223017Sdim    report_fatal_error("Don't know what kind of handler this is!");
464223017Sdim  if (Unwind)
465276479Sdim    CurrentWinFrameInfo->HandlesUnwind = true;
466223017Sdim  if (Except)
467276479Sdim    CurrentWinFrameInfo->HandlesExceptions = true;
468223017Sdim}
469223017Sdim
470276479Sdimvoid MCStreamer::EmitWinEHHandlerData() {
471276479Sdim  EnsureValidWinFrameInfo();
472276479Sdim  if (CurrentWinFrameInfo->ChainedParent)
473223017Sdim    report_fatal_error("Chained unwind areas can't have handlers!");
474223017Sdim}
475223017Sdim
476296417Sdimvoid MCStreamer::EmitSyntaxDirective() {}
477296417Sdim
478276479Sdimvoid MCStreamer::EmitWinCFIPushReg(unsigned Register) {
479276479Sdim  EnsureValidWinFrameInfo();
480276479Sdim
481288943Sdim  MCSymbol *Label = getContext().createTempSymbol();
482223017Sdim  EmitLabel(Label);
483276479Sdim
484276479Sdim  WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(Label, Register);
485276479Sdim  CurrentWinFrameInfo->Instructions.push_back(Inst);
486223017Sdim}
487223017Sdim
488276479Sdimvoid MCStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) {
489276479Sdim  EnsureValidWinFrameInfo();
490276479Sdim  if (CurrentWinFrameInfo->LastFrameInst >= 0)
491223017Sdim    report_fatal_error("Frame register and offset already specified!");
492223017Sdim  if (Offset & 0x0F)
493223017Sdim    report_fatal_error("Misaligned frame pointer offset!");
494276479Sdim  if (Offset > 240)
495276479Sdim    report_fatal_error("Frame offset must be less than or equal to 240!");
496276479Sdim
497288943Sdim  MCSymbol *Label = getContext().createTempSymbol();
498261991Sdim  EmitLabel(Label);
499276479Sdim
500276479Sdim  WinEH::Instruction Inst =
501276479Sdim      Win64EH::Instruction::SetFPReg(Label, Register, Offset);
502276479Sdim  CurrentWinFrameInfo->LastFrameInst = CurrentWinFrameInfo->Instructions.size();
503276479Sdim  CurrentWinFrameInfo->Instructions.push_back(Inst);
504223017Sdim}
505223017Sdim
506276479Sdimvoid MCStreamer::EmitWinCFIAllocStack(unsigned Size) {
507276479Sdim  EnsureValidWinFrameInfo();
508276479Sdim  if (Size == 0)
509276479Sdim    report_fatal_error("Allocation size must be non-zero!");
510223017Sdim  if (Size & 7)
511223017Sdim    report_fatal_error("Misaligned stack allocation!");
512276479Sdim
513288943Sdim  MCSymbol *Label = getContext().createTempSymbol();
514223017Sdim  EmitLabel(Label);
515276479Sdim
516276479Sdim  WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
517276479Sdim  CurrentWinFrameInfo->Instructions.push_back(Inst);
518223017Sdim}
519223017Sdim
520276479Sdimvoid MCStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) {
521276479Sdim  EnsureValidWinFrameInfo();
522223017Sdim  if (Offset & 7)
523223017Sdim    report_fatal_error("Misaligned saved register offset!");
524276479Sdim
525288943Sdim  MCSymbol *Label = getContext().createTempSymbol();
526223017Sdim  EmitLabel(Label);
527276479Sdim
528276479Sdim  WinEH::Instruction Inst =
529276479Sdim      Win64EH::Instruction::SaveNonVol(Label, Register, Offset);
530276479Sdim  CurrentWinFrameInfo->Instructions.push_back(Inst);
531223017Sdim}
532223017Sdim
533276479Sdimvoid MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) {
534276479Sdim  EnsureValidWinFrameInfo();
535223017Sdim  if (Offset & 0x0F)
536223017Sdim    report_fatal_error("Misaligned saved vector register offset!");
537276479Sdim
538288943Sdim  MCSymbol *Label = getContext().createTempSymbol();
539223017Sdim  EmitLabel(Label);
540276479Sdim
541276479Sdim  WinEH::Instruction Inst =
542276479Sdim      Win64EH::Instruction::SaveXMM(Label, Register, Offset);
543276479Sdim  CurrentWinFrameInfo->Instructions.push_back(Inst);
544223017Sdim}
545223017Sdim
546276479Sdimvoid MCStreamer::EmitWinCFIPushFrame(bool Code) {
547276479Sdim  EnsureValidWinFrameInfo();
548276479Sdim  if (CurrentWinFrameInfo->Instructions.size() > 0)
549223017Sdim    report_fatal_error("If present, PushMachFrame must be the first UOP");
550276479Sdim
551288943Sdim  MCSymbol *Label = getContext().createTempSymbol();
552223017Sdim  EmitLabel(Label);
553276479Sdim
554276479Sdim  WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
555276479Sdim  CurrentWinFrameInfo->Instructions.push_back(Inst);
556223017Sdim}
557223017Sdim
558276479Sdimvoid MCStreamer::EmitWinCFIEndProlog() {
559276479Sdim  EnsureValidWinFrameInfo();
560280031Sdim
561288943Sdim  MCSymbol *Label = getContext().createTempSymbol();
562280031Sdim  EmitLabel(Label);
563280031Sdim
564280031Sdim  CurrentWinFrameInfo->PrologEnd = Label;
565223017Sdim}
566223017Sdim
567288943Sdimvoid MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {
568288943Sdim}
569288943Sdim
570276479Sdimvoid MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
571276479Sdim}
572276479Sdim
573234353Sdimvoid MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
574234353Sdim}
575234353Sdim
576208599Srdivacky/// EmitRawText - If this file is backed by an assembly streamer, this dumps
577206274Srdivacky/// the specified string in the output .s file.  This capability is
578206274Srdivacky/// indicated by the hasRawTextSupport() predicate.
579261991Sdimvoid MCStreamer::EmitRawTextImpl(StringRef String) {
580206274Srdivacky  errs() << "EmitRawText called on an MCStreamer that doesn't support it, "
581206274Srdivacky  " something must not be fully mc'ized\n";
582206274Srdivacky  abort();
583206274Srdivacky}
584206274Srdivacky
585206274Srdivackyvoid MCStreamer::EmitRawText(const Twine &T) {
586206274Srdivacky  SmallString<128> Str;
587261991Sdim  EmitRawTextImpl(T.toStringRef(Str));
588206274Srdivacky}
589223017Sdim
590276479Sdimvoid MCStreamer::EmitWindowsUnwindTables() {
591223017Sdim}
592234353Sdim
593234353Sdimvoid MCStreamer::Finish() {
594276479Sdim  if (!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End)
595234353Sdim    report_fatal_error("Unfinished frame!");
596234353Sdim
597276479Sdim  MCTargetStreamer *TS = getTargetStreamer();
598276479Sdim  if (TS)
599276479Sdim    TS->finish();
600276479Sdim
601234353Sdim  FinishImpl();
602234353Sdim}
603249423Sdim
604276479Sdimvoid MCStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
605276479Sdim  visitUsedExpr(*Value);
606276479Sdim  Symbol->setVariableValue(Value);
607276479Sdim
608276479Sdim  MCTargetStreamer *TS = getTargetStreamer();
609276479Sdim  if (TS)
610276479Sdim    TS->emitAssignment(Symbol, Value);
611249423Sdim}
612276479Sdim
613288943Sdimvoid MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter, raw_ostream &OS,
614288943Sdim                              const MCInst &Inst, const MCSubtargetInfo &STI) {
615288943Sdim  InstPrinter.printInst(&Inst, OS, "", STI);
616288943Sdim}
617288943Sdim
618276479Sdimvoid MCStreamer::visitUsedSymbol(const MCSymbol &Sym) {
619276479Sdim}
620276479Sdim
621276479Sdimvoid MCStreamer::visitUsedExpr(const MCExpr &Expr) {
622276479Sdim  switch (Expr.getKind()) {
623276479Sdim  case MCExpr::Target:
624276479Sdim    cast<MCTargetExpr>(Expr).visitUsedExpr(*this);
625276479Sdim    break;
626276479Sdim
627276479Sdim  case MCExpr::Constant:
628276479Sdim    break;
629276479Sdim
630276479Sdim  case MCExpr::Binary: {
631276479Sdim    const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr);
632276479Sdim    visitUsedExpr(*BE.getLHS());
633276479Sdim    visitUsedExpr(*BE.getRHS());
634276479Sdim    break;
635276479Sdim  }
636276479Sdim
637276479Sdim  case MCExpr::SymbolRef:
638276479Sdim    visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol());
639276479Sdim    break;
640276479Sdim
641276479Sdim  case MCExpr::Unary:
642276479Sdim    visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr());
643276479Sdim    break;
644276479Sdim  }
645276479Sdim}
646276479Sdim
647276479Sdimvoid MCStreamer::EmitInstruction(const MCInst &Inst,
648276479Sdim                                 const MCSubtargetInfo &STI) {
649276479Sdim  // Scan for values.
650276479Sdim  for (unsigned i = Inst.getNumOperands(); i--;)
651276479Sdim    if (Inst.getOperand(i).isExpr())
652276479Sdim      visitUsedExpr(*Inst.getOperand(i).getExpr());
653276479Sdim}
654276479Sdim
655288943Sdimvoid MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
656288943Sdim                                        unsigned Size) {
657288943Sdim  // Get the Hi-Lo expression.
658288943Sdim  const MCExpr *Diff =
659288943Sdim      MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
660288943Sdim                              MCSymbolRefExpr::create(Lo, Context), Context);
661288943Sdim
662288943Sdim  const MCAsmInfo *MAI = Context.getAsmInfo();
663288943Sdim  if (!MAI->doesSetDirectiveSuppressesReloc()) {
664288943Sdim    EmitValue(Diff, Size);
665288943Sdim    return;
666288943Sdim  }
667288943Sdim
668288943Sdim  // Otherwise, emit with .set (aka assignment).
669288943Sdim  MCSymbol *SetLabel = Context.createTempSymbol("set", true);
670288943Sdim  EmitAssignment(SetLabel, Diff);
671288943Sdim  EmitSymbolValue(SetLabel, Size);
672288943Sdim}
673288943Sdim
674276479Sdimvoid MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {}
675276479Sdimvoid MCStreamer::EmitThumbFunc(MCSymbol *Func) {}
676276479Sdimvoid MCStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
677276479Sdimvoid MCStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {}
678276479Sdimvoid MCStreamer::EndCOFFSymbolDef() {}
679276479Sdimvoid MCStreamer::EmitFileDirective(StringRef Filename) {}
680276479Sdimvoid MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {}
681276479Sdimvoid MCStreamer::EmitCOFFSymbolType(int Type) {}
682288943Sdimvoid MCStreamer::emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value) {}
683276479Sdimvoid MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
684276479Sdim                                       unsigned ByteAlignment) {}
685288943Sdimvoid MCStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
686276479Sdim                                uint64_t Size, unsigned ByteAlignment) {}
687288943Sdimvoid MCStreamer::ChangeSection(MCSection *, const MCExpr *) {}
688276479Sdimvoid MCStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
689276479Sdimvoid MCStreamer::EmitBytes(StringRef Data) {}
690296417Sdimvoid MCStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) {
691276479Sdim  visitUsedExpr(*Value);
692276479Sdim}
693276479Sdimvoid MCStreamer::EmitULEB128Value(const MCExpr *Value) {}
694276479Sdimvoid MCStreamer::EmitSLEB128Value(const MCExpr *Value) {}
695276479Sdimvoid MCStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
696276479Sdim                                      unsigned ValueSize,
697276479Sdim                                      unsigned MaxBytesToEmit) {}
698276479Sdimvoid MCStreamer::EmitCodeAlignment(unsigned ByteAlignment,
699276479Sdim                                   unsigned MaxBytesToEmit) {}
700296417Sdimvoid MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value) {}
701276479Sdimvoid MCStreamer::EmitBundleAlignMode(unsigned AlignPow2) {}
702276479Sdimvoid MCStreamer::EmitBundleLock(bool AlignToEnd) {}
703276479Sdimvoid MCStreamer::FinishImpl() {}
704276479Sdimvoid MCStreamer::EmitBundleUnlock() {}
705288943Sdim
706288943Sdimvoid MCStreamer::SwitchSection(MCSection *Section, const MCExpr *Subsection) {
707288943Sdim  assert(Section && "Cannot switch to a null section!");
708288943Sdim  MCSectionSubPair curSection = SectionStack.back().first;
709288943Sdim  SectionStack.back().second = curSection;
710288943Sdim  if (MCSectionSubPair(Section, Subsection) != curSection) {
711288943Sdim    ChangeSection(Section, Subsection);
712288943Sdim    SectionStack.back().first = MCSectionSubPair(Section, Subsection);
713288943Sdim    assert(!Section->hasEnded() && "Section already ended");
714288943Sdim    MCSymbol *Sym = Section->getBeginSymbol();
715288943Sdim    if (Sym && !Sym->isInSection())
716288943Sdim      EmitLabel(Sym);
717288943Sdim  }
718288943Sdim}
719288943Sdim
720288943SdimMCSymbol *MCStreamer::endSection(MCSection *Section) {
721288943Sdim  // TODO: keep track of the last subsection so that this symbol appears in the
722288943Sdim  // correct place.
723288943Sdim  MCSymbol *Sym = Section->getEndSymbol(Context);
724288943Sdim  if (Sym->isInSection())
725288943Sdim    return Sym;
726288943Sdim
727288943Sdim  SwitchSection(Section);
728288943Sdim  EmitLabel(Sym);
729288943Sdim  return Sym;
730288943Sdim}
731