xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFStreamer.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- X86WinCOFFStreamer.cpp - X86 Target WinCOFF Streamer ----*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "X86MCTargetDesc.h"
100b57cec5SDimitry Andric #include "X86TargetStreamer.h"
110b57cec5SDimitry Andric #include "llvm/MC/MCAsmBackend.h"
1281ad6265SDimitry Andric #include "llvm/MC/MCAssembler.h"
130b57cec5SDimitry Andric #include "llvm/MC/MCCodeEmitter.h"
140b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h"
150b57cec5SDimitry Andric #include "llvm/MC/MCWin64EH.h"
160b57cec5SDimitry Andric #include "llvm/MC/MCWinCOFFStreamer.h"
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric using namespace llvm;
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric namespace {
210b57cec5SDimitry Andric class X86WinCOFFStreamer : public MCWinCOFFStreamer {
220b57cec5SDimitry Andric   Win64EH::UnwindEmitter EHStreamer;
230b57cec5SDimitry Andric public:
240b57cec5SDimitry Andric   X86WinCOFFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> AB,
250b57cec5SDimitry Andric                      std::unique_ptr<MCCodeEmitter> CE,
260b57cec5SDimitry Andric                      std::unique_ptr<MCObjectWriter> OW)
270b57cec5SDimitry Andric       : MCWinCOFFStreamer(C, std::move(AB), std::move(CE), std::move(OW)) {}
280b57cec5SDimitry Andric 
29*0fca6ea1SDimitry Andric   void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
3081ad6265SDimitry Andric   void emitWinEHHandlerData(SMLoc Loc) override;
3181ad6265SDimitry Andric   void emitWindowsUnwindTables(WinEH::FrameInfo *Frame) override;
3281ad6265SDimitry Andric   void emitWindowsUnwindTables() override;
3381ad6265SDimitry Andric   void emitCVFPOData(const MCSymbol *ProcSym, SMLoc Loc) override;
345ffd83dbSDimitry Andric   void finishImpl() override;
350b57cec5SDimitry Andric };
360b57cec5SDimitry Andric 
37*0fca6ea1SDimitry Andric void X86WinCOFFStreamer::emitInstruction(const MCInst &Inst,
38*0fca6ea1SDimitry Andric                                          const MCSubtargetInfo &STI) {
39*0fca6ea1SDimitry Andric   X86_MC::emitInstruction(*this, Inst, STI);
40*0fca6ea1SDimitry Andric }
41*0fca6ea1SDimitry Andric 
4281ad6265SDimitry Andric void X86WinCOFFStreamer::emitWinEHHandlerData(SMLoc Loc) {
4381ad6265SDimitry Andric   MCStreamer::emitWinEHHandlerData(Loc);
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric   // We have to emit the unwind info now, because this directive
468bcb0991SDimitry Andric   // actually switches to the .xdata section.
478bcb0991SDimitry Andric   if (WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo())
48e8d8bef9SDimitry Andric     EHStreamer.EmitUnwindInfo(*this, CurFrame, /* HandlerData = */ true);
49e8d8bef9SDimitry Andric }
50e8d8bef9SDimitry Andric 
5181ad6265SDimitry Andric void X86WinCOFFStreamer::emitWindowsUnwindTables(WinEH::FrameInfo *Frame) {
52e8d8bef9SDimitry Andric   EHStreamer.EmitUnwindInfo(*this, Frame, /* HandlerData = */ false);
530b57cec5SDimitry Andric }
540b57cec5SDimitry Andric 
5581ad6265SDimitry Andric void X86WinCOFFStreamer::emitWindowsUnwindTables() {
560b57cec5SDimitry Andric   if (!getNumWinFrameInfos())
570b57cec5SDimitry Andric     return;
580b57cec5SDimitry Andric   EHStreamer.Emit(*this);
590b57cec5SDimitry Andric }
600b57cec5SDimitry Andric 
6181ad6265SDimitry Andric void X86WinCOFFStreamer::emitCVFPOData(const MCSymbol *ProcSym, SMLoc Loc) {
620b57cec5SDimitry Andric   X86TargetStreamer *XTS =
630b57cec5SDimitry Andric       static_cast<X86TargetStreamer *>(getTargetStreamer());
640b57cec5SDimitry Andric   XTS->emitFPOData(ProcSym, Loc);
650b57cec5SDimitry Andric }
660b57cec5SDimitry Andric 
675ffd83dbSDimitry Andric void X86WinCOFFStreamer::finishImpl() {
685ffd83dbSDimitry Andric   emitFrames(nullptr);
6981ad6265SDimitry Andric   emitWindowsUnwindTables();
700b57cec5SDimitry Andric 
715ffd83dbSDimitry Andric   MCWinCOFFStreamer::finishImpl();
720b57cec5SDimitry Andric }
73e8d8bef9SDimitry Andric } // namespace
740b57cec5SDimitry Andric 
75*0fca6ea1SDimitry Andric MCStreamer *
76*0fca6ea1SDimitry Andric llvm::createX86WinCOFFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> &&AB,
770b57cec5SDimitry Andric                                std::unique_ptr<MCObjectWriter> &&OW,
78*0fca6ea1SDimitry Andric                                std::unique_ptr<MCCodeEmitter> &&CE) {
79*0fca6ea1SDimitry Andric   return new X86WinCOFFStreamer(C, std::move(AB), std::move(CE), std::move(OW));
800b57cec5SDimitry Andric }
81