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 "llvm/MC/MCAsmInfo.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCObjectFileInfo.h"
17 
18 using namespace llvm;
19 
20 //
21 // NVPTXTargetStreamer Implemenation
22 //
NVPTXTargetStreamer(MCStreamer & S)23 NVPTXTargetStreamer::NVPTXTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
24 
25 NVPTXTargetStreamer::~NVPTXTargetStreamer() = default;
26 
outputDwarfFileDirectives()27 void NVPTXTargetStreamer::outputDwarfFileDirectives() {
28   for (const std::string &S : DwarfFiles)
29     getStreamer().emitRawText(S.data());
30   DwarfFiles.clear();
31 }
32 
closeLastSection()33 void NVPTXTargetStreamer::closeLastSection() {
34   if (HasSections)
35     getStreamer().emitRawText("\t}");
36 }
37 
emitDwarfFileDirective(StringRef Directive)38 void NVPTXTargetStreamer::emitDwarfFileDirective(StringRef Directive) {
39   DwarfFiles.emplace_back(Directive);
40 }
41 
isDwarfSection(const MCObjectFileInfo * FI,const MCSection * Section)42 static bool isDwarfSection(const MCObjectFileInfo *FI,
43                            const MCSection *Section) {
44   // FIXME: the checks for the DWARF sections are very fragile and should be
45   // fixed up in a followup patch.
46   if (!Section || Section->getKind().isText() ||
47       Section->getKind().isWriteable())
48     return false;
49   return Section == FI->getDwarfAbbrevSection() ||
50          Section == FI->getDwarfInfoSection() ||
51          Section == FI->getDwarfMacinfoSection() ||
52          Section == FI->getDwarfFrameSection() ||
53          Section == FI->getDwarfAddrSection() ||
54          Section == FI->getDwarfRangesSection() ||
55          Section == FI->getDwarfARangesSection() ||
56          Section == FI->getDwarfLocSection() ||
57          Section == FI->getDwarfStrSection() ||
58          Section == FI->getDwarfLineSection() ||
59          Section == FI->getDwarfStrOffSection() ||
60          Section == FI->getDwarfLineStrSection() ||
61          Section == FI->getDwarfPubNamesSection() ||
62          Section == FI->getDwarfPubTypesSection() ||
63          Section == FI->getDwarfSwiftASTSection() ||
64          Section == FI->getDwarfTypesDWOSection() ||
65          Section == FI->getDwarfAbbrevDWOSection() ||
66          Section == FI->getDwarfAccelObjCSection() ||
67          Section == FI->getDwarfAccelNamesSection() ||
68          Section == FI->getDwarfAccelTypesSection() ||
69          Section == FI->getDwarfAccelNamespaceSection() ||
70          Section == FI->getDwarfLocDWOSection() ||
71          Section == FI->getDwarfStrDWOSection() ||
72          Section == FI->getDwarfCUIndexSection() ||
73          Section == FI->getDwarfInfoDWOSection() ||
74          Section == FI->getDwarfLineDWOSection() ||
75          Section == FI->getDwarfTUIndexSection() ||
76          Section == FI->getDwarfStrOffDWOSection() ||
77          Section == FI->getDwarfDebugNamesSection() ||
78          Section == FI->getDwarfDebugInlineSection() ||
79          Section == FI->getDwarfGnuPubNamesSection() ||
80          Section == FI->getDwarfGnuPubTypesSection();
81 }
82 
changeSection(const MCSection * CurSection,MCSection * Section,const MCExpr * SubSection,raw_ostream & OS)83 void NVPTXTargetStreamer::changeSection(const MCSection *CurSection,
84                                         MCSection *Section,
85                                         const MCExpr *SubSection,
86                                         raw_ostream &OS) {
87   assert(!SubSection && "SubSection is not null!");
88   const MCObjectFileInfo *FI = getStreamer().getContext().getObjectFileInfo();
89   // Emit closing brace for DWARF sections only.
90   if (isDwarfSection(FI, CurSection))
91     OS << "\t}\n";
92   if (isDwarfSection(FI, Section)) {
93     // Emit DWARF .file directives in the outermost scope.
94     outputDwarfFileDirectives();
95     OS << "\t.section";
96     Section->PrintSwitchToSection(*getStreamer().getContext().getAsmInfo(),
97                                   getStreamer().getContext().getTargetTriple(),
98                                   OS, SubSection);
99     // DWARF sections are enclosed into braces - emit the open one.
100     OS << "\t{\n";
101     HasSections = true;
102   }
103 }
104 
emitRawBytes(StringRef Data)105 void NVPTXTargetStreamer::emitRawBytes(StringRef Data) {
106   MCTargetStreamer::emitRawBytes(Data);
107   // TODO: enable this once the bug in the ptxas with the packed bytes is
108   // resolved. Currently, (it is confirmed by NVidia) it causes a crash in
109   // ptxas.
110 #if 0
111   const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
112   const char *Directive = MAI->getData8bitsDirective();
113   unsigned NumElements = Data.size();
114   const unsigned MaxLen = 40;
115   unsigned NumChunks = 1 + ((NumElements - 1) / MaxLen);
116   // Split the very long directives into several parts if the limit is
117   // specified.
118   for (unsigned I = 0; I < NumChunks; ++I) {
119     SmallString<128> Str;
120     raw_svector_ostream OS(Str);
121 
122     const char *Label = Directive;
123     for (auto It = std::next(Data.bytes_begin(), I * MaxLen),
124               End = (I == NumChunks - 1)
125                         ? Data.bytes_end()
126                         : std::next(Data.bytes_begin(), (I + 1) * MaxLen);
127          It != End; ++It) {
128       OS << Label << (unsigned)*It;
129       if (Label == Directive)
130         Label = ",";
131     }
132     Streamer.emitRawText(OS.str());
133   }
134 #endif
135 }
136 
137