| //=====- NVPTXTargetStreamer.cpp - NVPTXTargetStreamer class ------------=====// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file implements the NVPTXTargetStreamer class. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "NVPTXTargetStreamer.h" |
| #include "llvm/MC/MCAsmInfo.h" |
| #include "llvm/MC/MCContext.h" |
| #include "llvm/MC/MCObjectFileInfo.h" |
| |
| using namespace llvm; |
| |
| // |
| // NVPTXTargetStreamer Implemenation |
| // |
| NVPTXTargetStreamer::NVPTXTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} |
| |
| NVPTXTargetStreamer::~NVPTXTargetStreamer() = default; |
| |
| void NVPTXTargetStreamer::outputDwarfFileDirectives() { |
| for (const std::string &S : DwarfFiles) |
| getStreamer().EmitRawText(S.data()); |
| DwarfFiles.clear(); |
| } |
| |
| void NVPTXTargetStreamer::closeLastSection() { |
| if (HasSections) |
| getStreamer().EmitRawText("\t}"); |
| } |
| |
| void NVPTXTargetStreamer::emitDwarfFileDirective(StringRef Directive) { |
| DwarfFiles.emplace_back(Directive); |
| } |
| |
| static bool isDwarfSection(const MCObjectFileInfo *FI, |
| const MCSection *Section) { |
| // FIXME: the checks for the DWARF sections are very fragile and should be |
| // fixed up in a followup patch. |
| if (!Section || Section->getKind().isText() || |
| Section->getKind().isWriteable()) |
| return false; |
| return Section == FI->getDwarfAbbrevSection() || |
| Section == FI->getDwarfInfoSection() || |
| Section == FI->getDwarfMacinfoSection() || |
| Section == FI->getDwarfFrameSection() || |
| Section == FI->getDwarfAddrSection() || |
| Section == FI->getDwarfRangesSection() || |
| Section == FI->getDwarfARangesSection() || |
| Section == FI->getDwarfLocSection() || |
| Section == FI->getDwarfStrSection() || |
| Section == FI->getDwarfLineSection() || |
| Section == FI->getDwarfStrOffSection() || |
| Section == FI->getDwarfLineStrSection() || |
| Section == FI->getDwarfPubNamesSection() || |
| Section == FI->getDwarfPubTypesSection() || |
| Section == FI->getDwarfSwiftASTSection() || |
| Section == FI->getDwarfTypesDWOSection() || |
| Section == FI->getDwarfAbbrevDWOSection() || |
| Section == FI->getDwarfAccelObjCSection() || |
| Section == FI->getDwarfAccelNamesSection() || |
| Section == FI->getDwarfAccelTypesSection() || |
| Section == FI->getDwarfAccelNamespaceSection() || |
| Section == FI->getDwarfLocDWOSection() || |
| Section == FI->getDwarfStrDWOSection() || |
| Section == FI->getDwarfCUIndexSection() || |
| Section == FI->getDwarfInfoDWOSection() || |
| Section == FI->getDwarfLineDWOSection() || |
| Section == FI->getDwarfTUIndexSection() || |
| Section == FI->getDwarfStrOffDWOSection() || |
| Section == FI->getDwarfDebugNamesSection() || |
| Section == FI->getDwarfDebugInlineSection() || |
| Section == FI->getDwarfGnuPubNamesSection() || |
| Section == FI->getDwarfGnuPubTypesSection(); |
| } |
| |
| void NVPTXTargetStreamer::changeSection(const MCSection *CurSection, |
| MCSection *Section, |
| const MCExpr *SubSection, |
| raw_ostream &OS) { |
| assert(!SubSection && "SubSection is not null!"); |
| const MCObjectFileInfo *FI = getStreamer().getContext().getObjectFileInfo(); |
| // Emit closing brace for DWARF sections only. |
| if (isDwarfSection(FI, CurSection)) |
| OS << "\t}\n"; |
| if (isDwarfSection(FI, Section)) { |
| // Emit DWARF .file directives in the outermost scope. |
| outputDwarfFileDirectives(); |
| OS << "\t.section"; |
| Section->PrintSwitchToSection(*getStreamer().getContext().getAsmInfo(), |
| FI->getTargetTriple(), OS, SubSection); |
| // DWARF sections are enclosed into braces - emit the open one. |
| OS << "\t{\n"; |
| HasSections = true; |
| } |
| } |
| |
| void NVPTXTargetStreamer::emitRawBytes(StringRef Data) { |
| MCTargetStreamer::emitRawBytes(Data); |
| // TODO: enable this once the bug in the ptxas with the packed bytes is |
| // resolved. Currently, (it is confirmed by NVidia) it causes a crash in |
| // ptxas. |
| #if 0 |
| const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo(); |
| const char *Directive = MAI->getData8bitsDirective(); |
| unsigned NumElements = Data.size(); |
| const unsigned MaxLen = 40; |
| unsigned NumChunks = 1 + ((NumElements - 1) / MaxLen); |
| // Split the very long directives into several parts if the limit is |
| // specified. |
| for (unsigned I = 0; I < NumChunks; ++I) { |
| SmallString<128> Str; |
| raw_svector_ostream OS(Str); |
| |
| const char *Label = Directive; |
| for (auto It = std::next(Data.bytes_begin(), I * MaxLen), |
| End = (I == NumChunks - 1) |
| ? Data.bytes_end() |
| : std::next(Data.bytes_begin(), (I + 1) * MaxLen); |
| It != End; ++It) { |
| OS << Label << (unsigned)*It; |
| if (Label == Directive) |
| Label = ","; |
| } |
| Streamer.EmitRawText(OS.str()); |
| } |
| #endif |
| } |
| |