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