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