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.data()); 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 FI->getTargetTriple(), OS, SubSection); 98 // DWARF sections are enclosed into braces - emit the open one. 99 OS << "\t{\n"; 100 HasSections = true; 101 } 102 } 103 104 void NVPTXTargetStreamer::emitRawBytes(StringRef Data) { 105 MCTargetStreamer::emitRawBytes(Data); 106 // TODO: enable this once the bug in the ptxas with the packed bytes is 107 // resolved. Currently, (it is confirmed by NVidia) it causes a crash in 108 // ptxas. 109 #if 0 110 const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo(); 111 const char *Directive = MAI->getData8bitsDirective(); 112 unsigned NumElements = Data.size(); 113 const unsigned MaxLen = 40; 114 unsigned NumChunks = 1 + ((NumElements - 1) / MaxLen); 115 // Split the very long directives into several parts if the limit is 116 // specified. 117 for (unsigned I = 0; I < NumChunks; ++I) { 118 SmallString<128> Str; 119 raw_svector_ostream OS(Str); 120 121 const char *Label = Directive; 122 for (auto It = std::next(Data.bytes_begin(), I * MaxLen), 123 End = (I == NumChunks - 1) 124 ? Data.bytes_end() 125 : std::next(Data.bytes_begin(), (I + 1) * MaxLen); 126 It != End; ++It) { 127 OS << Label << (unsigned)*It; 128 if (Label == Directive) 129 Label = ","; 130 } 131 Streamer.EmitRawText(OS.str()); 132 } 133 #endif 134 } 135 136