152 lines · cpp
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-exception6//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 22using namespace llvm;23 24//25// NVPTXTargetStreamer Implemenation26//27NVPTXTargetStreamer::NVPTXTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}28NVPTXTargetStreamer::~NVPTXTargetStreamer() = default;29 30NVPTXAsmTargetStreamer::NVPTXAsmTargetStreamer(MCStreamer &S)31 : NVPTXTargetStreamer(S) {}32NVPTXAsmTargetStreamer::~NVPTXAsmTargetStreamer() = default;33 34void NVPTXTargetStreamer::outputDwarfFileDirectives() {35 for (const std::string &S : DwarfFiles)36 getStreamer().emitRawText(S);37 DwarfFiles.clear();38}39 40void NVPTXTargetStreamer::closeLastSection() {41 if (HasSections)42 getStreamer().emitRawText("\t}");43}44 45void NVPTXTargetStreamer::emitDwarfFileDirective(StringRef Directive) {46 DwarfFiles.emplace_back(Directive);47}48 49static bool isDwarfSection(const MCObjectFileInfo *FI,50 const MCSection *Section) {51 // FIXME: the checks for the DWARF sections are very fragile and should be52 // 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 89void 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\t" << Section->getName() << '\n';101 // DWARF sections are enclosed into braces - emit the open one.102 OS << "\t{\n";103 HasSections = true;104 }105}106 107void NVPTXTargetStreamer::emitRawBytes(StringRef Data) {108 MCTargetStreamer::emitRawBytes(Data);109 // TODO: enable this once the bug in the ptxas with the packed bytes is110 // resolved. Currently, (it is confirmed by NVidia) it causes a crash in111 // ptxas.112#if 0113 const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();114 const char *Directive = MAI->getData8bitsDirective();115 unsigned NumElements = Data.size();116 const unsigned MaxLen = 40;117 unsigned NumChunks = 1 + ((NumElements - 1) / MaxLen);118 // Split the very long directives into several parts if the limit is119 // specified.120 for (unsigned I = 0; I < NumChunks; ++I) {121 SmallString<128> Str;122 raw_svector_ostream OS(Str);123 124 const char *Label = Directive;125 for (auto It = std::next(Data.bytes_begin(), I * MaxLen),126 End = (I == NumChunks - 1)127 ? Data.bytes_end()128 : std::next(Data.bytes_begin(), (I + 1) * MaxLen);129 It != End; ++It) {130 OS << Label << (unsigned)*It;131 if (Label == Directive)132 Label = ",";133 }134 Streamer.emitRawText(OS.str());135 }136#endif137}138 139void NVPTXTargetStreamer::emitValue(const MCExpr *Value) {140 if (Value->getKind() == MCExpr::SymbolRef) {141 const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*Value);142 StringRef SymName = SRE.getSymbol().getName();143 if (!SymName.starts_with(".debug")) {144 Streamer.emitRawText(NVPTX::getValidPTXIdentifier(SymName));145 return;146 }147 // Fall through to the normal printing.148 }149 // Otherwise, print the Value normally.150 MCTargetStreamer::emitValue(Value);151}152