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