10b57cec5SDimitry Andric //=====- NVPTXTargetStreamer.cpp - NVPTXTargetStreamer class ------------=====// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the NVPTXTargetStreamer class. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "NVPTXTargetStreamer.h" 140b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 150b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 160b57cec5SDimitry Andric #include "llvm/MC/MCObjectFileInfo.h" 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric using namespace llvm; 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric // 210b57cec5SDimitry Andric // NVPTXTargetStreamer Implemenation 220b57cec5SDimitry Andric // 230b57cec5SDimitry Andric NVPTXTargetStreamer::NVPTXTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} 240b57cec5SDimitry Andric NVPTXTargetStreamer::~NVPTXTargetStreamer() = default; 250b57cec5SDimitry Andric 26bdd1243dSDimitry Andric NVPTXAsmTargetStreamer::NVPTXAsmTargetStreamer(MCStreamer &S) 27bdd1243dSDimitry Andric : NVPTXTargetStreamer(S) {} 28bdd1243dSDimitry Andric NVPTXAsmTargetStreamer::~NVPTXAsmTargetStreamer() = default; 29bdd1243dSDimitry Andric 300b57cec5SDimitry Andric void NVPTXTargetStreamer::outputDwarfFileDirectives() { 310b57cec5SDimitry Andric for (const std::string &S : DwarfFiles) 32349cc55cSDimitry Andric getStreamer().emitRawText(S); 330b57cec5SDimitry Andric DwarfFiles.clear(); 340b57cec5SDimitry Andric } 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric void NVPTXTargetStreamer::closeLastSection() { 370b57cec5SDimitry Andric if (HasSections) 385ffd83dbSDimitry Andric getStreamer().emitRawText("\t}"); 390b57cec5SDimitry Andric } 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric void NVPTXTargetStreamer::emitDwarfFileDirective(StringRef Directive) { 420b57cec5SDimitry Andric DwarfFiles.emplace_back(Directive); 430b57cec5SDimitry Andric } 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric static bool isDwarfSection(const MCObjectFileInfo *FI, 460b57cec5SDimitry Andric const MCSection *Section) { 470b57cec5SDimitry Andric // FIXME: the checks for the DWARF sections are very fragile and should be 480b57cec5SDimitry Andric // fixed up in a followup patch. 49*0fca6ea1SDimitry Andric if (!Section || Section->isText()) 500b57cec5SDimitry Andric return false; 510b57cec5SDimitry Andric return Section == FI->getDwarfAbbrevSection() || 520b57cec5SDimitry Andric Section == FI->getDwarfInfoSection() || 530b57cec5SDimitry Andric Section == FI->getDwarfMacinfoSection() || 540b57cec5SDimitry Andric Section == FI->getDwarfFrameSection() || 550b57cec5SDimitry Andric Section == FI->getDwarfAddrSection() || 560b57cec5SDimitry Andric Section == FI->getDwarfRangesSection() || 570b57cec5SDimitry Andric Section == FI->getDwarfARangesSection() || 580b57cec5SDimitry Andric Section == FI->getDwarfLocSection() || 590b57cec5SDimitry Andric Section == FI->getDwarfStrSection() || 600b57cec5SDimitry Andric Section == FI->getDwarfLineSection() || 610b57cec5SDimitry Andric Section == FI->getDwarfStrOffSection() || 620b57cec5SDimitry Andric Section == FI->getDwarfLineStrSection() || 630b57cec5SDimitry Andric Section == FI->getDwarfPubNamesSection() || 640b57cec5SDimitry Andric Section == FI->getDwarfPubTypesSection() || 650b57cec5SDimitry Andric Section == FI->getDwarfSwiftASTSection() || 660b57cec5SDimitry Andric Section == FI->getDwarfTypesDWOSection() || 670b57cec5SDimitry Andric Section == FI->getDwarfAbbrevDWOSection() || 680b57cec5SDimitry Andric Section == FI->getDwarfAccelObjCSection() || 690b57cec5SDimitry Andric Section == FI->getDwarfAccelNamesSection() || 700b57cec5SDimitry Andric Section == FI->getDwarfAccelTypesSection() || 710b57cec5SDimitry Andric Section == FI->getDwarfAccelNamespaceSection() || 720b57cec5SDimitry Andric Section == FI->getDwarfLocDWOSection() || 730b57cec5SDimitry Andric Section == FI->getDwarfStrDWOSection() || 740b57cec5SDimitry Andric Section == FI->getDwarfCUIndexSection() || 750b57cec5SDimitry Andric Section == FI->getDwarfInfoDWOSection() || 760b57cec5SDimitry Andric Section == FI->getDwarfLineDWOSection() || 770b57cec5SDimitry Andric Section == FI->getDwarfTUIndexSection() || 780b57cec5SDimitry Andric Section == FI->getDwarfStrOffDWOSection() || 790b57cec5SDimitry Andric Section == FI->getDwarfDebugNamesSection() || 800b57cec5SDimitry Andric Section == FI->getDwarfDebugInlineSection() || 810b57cec5SDimitry Andric Section == FI->getDwarfGnuPubNamesSection() || 820b57cec5SDimitry Andric Section == FI->getDwarfGnuPubTypesSection(); 830b57cec5SDimitry Andric } 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric void NVPTXTargetStreamer::changeSection(const MCSection *CurSection, 86*0fca6ea1SDimitry Andric MCSection *Section, uint32_t SubSection, 870b57cec5SDimitry Andric raw_ostream &OS) { 880b57cec5SDimitry Andric assert(!SubSection && "SubSection is not null!"); 890b57cec5SDimitry Andric const MCObjectFileInfo *FI = getStreamer().getContext().getObjectFileInfo(); 900b57cec5SDimitry Andric // Emit closing brace for DWARF sections only. 910b57cec5SDimitry Andric if (isDwarfSection(FI, CurSection)) 920b57cec5SDimitry Andric OS << "\t}\n"; 930b57cec5SDimitry Andric if (isDwarfSection(FI, Section)) { 940b57cec5SDimitry Andric // Emit DWARF .file directives in the outermost scope. 950b57cec5SDimitry Andric outputDwarfFileDirectives(); 960b57cec5SDimitry Andric OS << "\t.section"; 9781ad6265SDimitry Andric Section->printSwitchToSection(*getStreamer().getContext().getAsmInfo(), 98fe6060f1SDimitry Andric getStreamer().getContext().getTargetTriple(), 99fe6060f1SDimitry Andric OS, SubSection); 1000b57cec5SDimitry Andric // DWARF sections are enclosed into braces - emit the open one. 1010b57cec5SDimitry Andric OS << "\t{\n"; 1020b57cec5SDimitry Andric HasSections = true; 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric } 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric void NVPTXTargetStreamer::emitRawBytes(StringRef Data) { 1070b57cec5SDimitry Andric MCTargetStreamer::emitRawBytes(Data); 1080b57cec5SDimitry Andric // TODO: enable this once the bug in the ptxas with the packed bytes is 1090b57cec5SDimitry Andric // resolved. Currently, (it is confirmed by NVidia) it causes a crash in 1100b57cec5SDimitry Andric // ptxas. 1110b57cec5SDimitry Andric #if 0 1120b57cec5SDimitry Andric const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo(); 1130b57cec5SDimitry Andric const char *Directive = MAI->getData8bitsDirective(); 1140b57cec5SDimitry Andric unsigned NumElements = Data.size(); 1150b57cec5SDimitry Andric const unsigned MaxLen = 40; 1160b57cec5SDimitry Andric unsigned NumChunks = 1 + ((NumElements - 1) / MaxLen); 1170b57cec5SDimitry Andric // Split the very long directives into several parts if the limit is 1180b57cec5SDimitry Andric // specified. 1190b57cec5SDimitry Andric for (unsigned I = 0; I < NumChunks; ++I) { 1200b57cec5SDimitry Andric SmallString<128> Str; 1210b57cec5SDimitry Andric raw_svector_ostream OS(Str); 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric const char *Label = Directive; 1240b57cec5SDimitry Andric for (auto It = std::next(Data.bytes_begin(), I * MaxLen), 1250b57cec5SDimitry Andric End = (I == NumChunks - 1) 1260b57cec5SDimitry Andric ? Data.bytes_end() 1270b57cec5SDimitry Andric : std::next(Data.bytes_begin(), (I + 1) * MaxLen); 1280b57cec5SDimitry Andric It != End; ++It) { 1290b57cec5SDimitry Andric OS << Label << (unsigned)*It; 1300b57cec5SDimitry Andric if (Label == Directive) 1310b57cec5SDimitry Andric Label = ","; 1320b57cec5SDimitry Andric } 1335ffd83dbSDimitry Andric Streamer.emitRawText(OS.str()); 1340b57cec5SDimitry Andric } 1350b57cec5SDimitry Andric #endif 1360b57cec5SDimitry Andric } 1370b57cec5SDimitry Andric 138