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 // 23 NVPTXTargetStreamer::NVPTXTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} 24 25 NVPTXTargetStreamer::~NVPTXTargetStreamer() = default; 26 27 void NVPTXTargetStreamer::outputDwarfFileDirectives() { 28 for (const std::string &S : DwarfFiles) 29 getStreamer().emitRawText(S); 30 DwarfFiles.clear(); 31 } 32 33 void NVPTXTargetStreamer::closeLastSection() { 34 if (HasSections) 35 getStreamer().emitRawText("\t}"); 36 } 37 38 void NVPTXTargetStreamer::emitDwarfFileDirective(StringRef Directive) { 39 DwarfFiles.emplace_back(Directive); 40 } 41 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 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 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