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