1274955Ssvnmir//===-- X86WinCOFFStreamer.cpp - X86 Target WinCOFF Streamer ----*- C++ -*-===//
2274955Ssvnmir//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6274955Ssvnmir//
7274955Ssvnmir//===----------------------------------------------------------------------===//
8274955Ssvnmir
9274955Ssvnmir#include "X86MCTargetDesc.h"
10327952Sdim#include "X86TargetStreamer.h"
11327952Sdim#include "llvm/MC/MCAsmBackend.h"
12327952Sdim#include "llvm/MC/MCCodeEmitter.h"
13341825Sdim#include "llvm/MC/MCObjectWriter.h"
14280031Sdim#include "llvm/MC/MCWin64EH.h"
15274955Ssvnmir#include "llvm/MC/MCWinCOFFStreamer.h"
16274955Ssvnmir
17274955Ssvnmirusing namespace llvm;
18274955Ssvnmir
19274955Ssvnmirnamespace {
20274955Ssvnmirclass X86WinCOFFStreamer : public MCWinCOFFStreamer {
21280031Sdim  Win64EH::UnwindEmitter EHStreamer;
22274955Ssvnmirpublic:
23327952Sdim  X86WinCOFFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> AB,
24341825Sdim                     std::unique_ptr<MCCodeEmitter> CE,
25341825Sdim                     std::unique_ptr<MCObjectWriter> OW)
26341825Sdim      : MCWinCOFFStreamer(C, std::move(AB), std::move(CE), std::move(OW)) {}
27274955Ssvnmir
28327952Sdim  void EmitWinEHHandlerData(SMLoc Loc) override;
29280031Sdim  void EmitWindowsUnwindTables() override;
30327952Sdim  void EmitCVFPOData(const MCSymbol *ProcSym, SMLoc Loc) override;
31274955Ssvnmir  void FinishImpl() override;
32274955Ssvnmir};
33274955Ssvnmir
34327952Sdimvoid X86WinCOFFStreamer::EmitWinEHHandlerData(SMLoc Loc) {
35327952Sdim  MCStreamer::EmitWinEHHandlerData(Loc);
36274955Ssvnmir
37274955Ssvnmir  // We have to emit the unwind info now, because this directive
38360784Sdim  // actually switches to the .xdata section.
39360784Sdim  if (WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo())
40360784Sdim    EHStreamer.EmitUnwindInfo(*this, CurFrame);
41274955Ssvnmir}
42274955Ssvnmir
43280031Sdimvoid X86WinCOFFStreamer::EmitWindowsUnwindTables() {
44280031Sdim  if (!getNumWinFrameInfos())
45280031Sdim    return;
46280031Sdim  EHStreamer.Emit(*this);
47280031Sdim}
48280031Sdim
49327952Sdimvoid X86WinCOFFStreamer::EmitCVFPOData(const MCSymbol *ProcSym, SMLoc Loc) {
50327952Sdim  X86TargetStreamer *XTS =
51327952Sdim      static_cast<X86TargetStreamer *>(getTargetStreamer());
52327952Sdim  XTS->emitFPOData(ProcSym, Loc);
53327952Sdim}
54327952Sdim
55274955Ssvnmirvoid X86WinCOFFStreamer::FinishImpl() {
56274955Ssvnmir  EmitFrames(nullptr);
57274955Ssvnmir  EmitWindowsUnwindTables();
58274955Ssvnmir
59274955Ssvnmir  MCWinCOFFStreamer::FinishImpl();
60274955Ssvnmir}
61274955Ssvnmir}
62274955Ssvnmir
63327952SdimMCStreamer *llvm::createX86WinCOFFStreamer(MCContext &C,
64327952Sdim                                           std::unique_ptr<MCAsmBackend> &&AB,
65341825Sdim                                           std::unique_ptr<MCObjectWriter> &&OW,
66327952Sdim                                           std::unique_ptr<MCCodeEmitter> &&CE,
67327952Sdim                                           bool RelaxAll,
68296417Sdim                                           bool IncrementalLinkerCompatible) {
69327952Sdim  X86WinCOFFStreamer *S =
70341825Sdim      new X86WinCOFFStreamer(C, std::move(AB), std::move(CE), std::move(OW));
71274955Ssvnmir  S->getAssembler().setRelaxAll(RelaxAll);
72296417Sdim  S->getAssembler().setIncrementalLinkerCompatible(IncrementalLinkerCompatible);
73274955Ssvnmir  return S;
74274955Ssvnmir}
75274955Ssvnmir
76