xref: /llvm-project/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.cpp (revision 020fa86897c0d39d6a806221e330abf901be3cdd)
1 //=====- NVPTXTargetStreamer.cpp - NVPTXTargetStreamer class ------------=====//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the NVPTXTargetStreamer class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "NVPTXTargetStreamer.h"
14 #include "NVPTXUtilities.h"
15 #include "llvm/MC/MCAsmInfo.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCObjectFileInfo.h"
19 #include "llvm/MC/MCSymbol.h"
20 #include "llvm/Support/Casting.h"
21 
22 using namespace llvm;
23 
24 //
25 // NVPTXTargetStreamer Implemenation
26 //
27 NVPTXTargetStreamer::NVPTXTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
28 NVPTXTargetStreamer::~NVPTXTargetStreamer() = default;
29 
30 NVPTXAsmTargetStreamer::NVPTXAsmTargetStreamer(MCStreamer &S)
31     : NVPTXTargetStreamer(S) {}
32 NVPTXAsmTargetStreamer::~NVPTXAsmTargetStreamer() = default;
33 
34 void NVPTXTargetStreamer::outputDwarfFileDirectives() {
35   for (const std::string &S : DwarfFiles)
36     getStreamer().emitRawText(S);
37   DwarfFiles.clear();
38 }
39 
40 void NVPTXTargetStreamer::closeLastSection() {
41   if (HasSections)
42     getStreamer().emitRawText("\t}");
43 }
44 
45 void NVPTXTargetStreamer::emitDwarfFileDirective(StringRef Directive) {
46   DwarfFiles.emplace_back(Directive);
47 }
48 
49 static bool isDwarfSection(const MCObjectFileInfo *FI,
50                            const MCSection *Section) {
51   // FIXME: the checks for the DWARF sections are very fragile and should be
52   // fixed up in a followup patch.
53   if (!Section || Section->isText())
54     return false;
55   return Section == FI->getDwarfAbbrevSection() ||
56          Section == FI->getDwarfInfoSection() ||
57          Section == FI->getDwarfMacinfoSection() ||
58          Section == FI->getDwarfFrameSection() ||
59          Section == FI->getDwarfAddrSection() ||
60          Section == FI->getDwarfRangesSection() ||
61          Section == FI->getDwarfARangesSection() ||
62          Section == FI->getDwarfLocSection() ||
63          Section == FI->getDwarfStrSection() ||
64          Section == FI->getDwarfLineSection() ||
65          Section == FI->getDwarfStrOffSection() ||
66          Section == FI->getDwarfLineStrSection() ||
67          Section == FI->getDwarfPubNamesSection() ||
68          Section == FI->getDwarfPubTypesSection() ||
69          Section == FI->getDwarfSwiftASTSection() ||
70          Section == FI->getDwarfTypesDWOSection() ||
71          Section == FI->getDwarfAbbrevDWOSection() ||
72          Section == FI->getDwarfAccelObjCSection() ||
73          Section == FI->getDwarfAccelNamesSection() ||
74          Section == FI->getDwarfAccelTypesSection() ||
75          Section == FI->getDwarfAccelNamespaceSection() ||
76          Section == FI->getDwarfLocDWOSection() ||
77          Section == FI->getDwarfStrDWOSection() ||
78          Section == FI->getDwarfCUIndexSection() ||
79          Section == FI->getDwarfInfoDWOSection() ||
80          Section == FI->getDwarfLineDWOSection() ||
81          Section == FI->getDwarfTUIndexSection() ||
82          Section == FI->getDwarfStrOffDWOSection() ||
83          Section == FI->getDwarfDebugNamesSection() ||
84          Section == FI->getDwarfDebugInlineSection() ||
85          Section == FI->getDwarfGnuPubNamesSection() ||
86          Section == FI->getDwarfGnuPubTypesSection();
87 }
88 
89 void NVPTXTargetStreamer::changeSection(const MCSection *CurSection,
90                                         MCSection *Section, uint32_t SubSection,
91                                         raw_ostream &OS) {
92   assert(!SubSection && "SubSection is not null!");
93   const MCObjectFileInfo *FI = getStreamer().getContext().getObjectFileInfo();
94   // Emit closing brace for DWARF sections only.
95   if (isDwarfSection(FI, CurSection))
96     OS << "\t}\n";
97   if (isDwarfSection(FI, Section)) {
98     // Emit DWARF .file directives in the outermost scope.
99     outputDwarfFileDirectives();
100     OS << "\t.section";
101     Section->printSwitchToSection(*getStreamer().getContext().getAsmInfo(),
102                                   getStreamer().getContext().getTargetTriple(),
103                                   OS, SubSection);
104     // DWARF sections are enclosed into braces - emit the open one.
105     OS << "\t{\n";
106     HasSections = true;
107   }
108 }
109 
110 void NVPTXTargetStreamer::emitRawBytes(StringRef Data) {
111   MCTargetStreamer::emitRawBytes(Data);
112   // TODO: enable this once the bug in the ptxas with the packed bytes is
113   // resolved. Currently, (it is confirmed by NVidia) it causes a crash in
114   // ptxas.
115 #if 0
116   const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
117   const char *Directive = MAI->getData8bitsDirective();
118   unsigned NumElements = Data.size();
119   const unsigned MaxLen = 40;
120   unsigned NumChunks = 1 + ((NumElements - 1) / MaxLen);
121   // Split the very long directives into several parts if the limit is
122   // specified.
123   for (unsigned I = 0; I < NumChunks; ++I) {
124     SmallString<128> Str;
125     raw_svector_ostream OS(Str);
126 
127     const char *Label = Directive;
128     for (auto It = std::next(Data.bytes_begin(), I * MaxLen),
129               End = (I == NumChunks - 1)
130                         ? Data.bytes_end()
131                         : std::next(Data.bytes_begin(), (I + 1) * MaxLen);
132          It != End; ++It) {
133       OS << Label << (unsigned)*It;
134       if (Label == Directive)
135         Label = ",";
136     }
137     Streamer.emitRawText(OS.str());
138   }
139 #endif
140 }
141 
142 void NVPTXTargetStreamer::emitValue(const MCExpr *Value) {
143   if (Value->getKind() == MCExpr::SymbolRef) {
144     const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*Value);
145     StringRef SymName = SRE.getSymbol().getName();
146     if (!SymName.starts_with(".debug")) {
147       Streamer.emitRawText(NVPTX::getValidPTXIdentifier(SymName));
148       return;
149     }
150     // Fall through to the normal printing.
151   }
152   // Otherwise, print the Value normally.
153   MCTargetStreamer::emitValue(Value);
154 }
155