//=====- NVPTXTargetStreamer.cpp - NVPTXTargetStreamer class ------------=====//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the NVPTXTargetStreamer class.
//
//===----------------------------------------------------------------------===//
#include "NVPTXTargetStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCObjectFileInfo.h"
using namespace llvm;
//
// NVPTXTargetStreamer Implemenation
//
NVPTXTargetStreamer::NVPTXTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
NVPTXTargetStreamer::~NVPTXTargetStreamer() = default;
void NVPTXTargetStreamer::outputDwarfFileDirectives() {
for (const std::string &S : DwarfFiles)
getStreamer().emitRawText(S.data());
DwarfFiles.clear();
}
void NVPTXTargetStreamer::closeLastSection() {
if (HasSections)
getStreamer().emitRawText("\t}");
}
void NVPTXTargetStreamer::emitDwarfFileDirective(StringRef Directive) {
DwarfFiles.emplace_back(Directive);
}
static bool isDwarfSection(const MCObjectFileInfo *FI,
const MCSection *Section) {
// FIXME: the checks for the DWARF sections are very fragile and should be
// fixed up in a followup patch.
if (!Section || Section->getKind().isText() ||
Section->getKind().isWriteable())
return false;
return Section == FI->getDwarfAbbrevSection() ||
Section == FI->getDwarfInfoSection() ||
Section == FI->getDwarfMacinfoSection() ||
Section == FI->getDwarfFrameSection() ||
Section == FI->getDwarfAddrSection() ||
Section == FI->getDwarfRangesSection() ||
Section == FI->getDwarfARangesSection() ||
Section == FI->getDwarfLocSection() ||
Section == FI->getDwarfStrSection() ||
Section == FI->getDwarfLineSection() ||
Section == FI->getDwarfStrOffSection() ||
Section == FI->getDwarfLineStrSection() ||
Section == FI->getDwarfPubNamesSection() ||
Section == FI->getDwarfPubTypesSection() ||
Section == FI->getDwarfSwiftASTSection() ||
Section == FI->getDwarfTypesDWOSection() ||
Section == FI->getDwarfAbbrevDWOSection() ||
Section == FI->getDwarfAccelObjCSection() ||
Section == FI->getDwarfAccelNamesSection() ||
Section == FI->getDwarfAccelTypesSection() ||
Section == FI->getDwarfAccelNamespaceSection() ||
Section == FI->getDwarfLocDWOSection() ||
Section == FI->getDwarfStrDWOSection() ||
Section == FI->getDwarfCUIndexSection() ||
Section == FI->getDwarfInfoDWOSection() ||
Section == FI->getDwarfLineDWOSection() ||
Section == FI->getDwarfTUIndexSection() ||
Section == FI->getDwarfStrOffDWOSection() ||
Section == FI->getDwarfDebugNamesSection() ||
Section == FI->getDwarfDebugInlineSection() ||
Section == FI->getDwarfGnuPubNamesSection() ||
Section == FI->getDwarfGnuPubTypesSection();
}
void NVPTXTargetStreamer::changeSection(const MCSection *CurSection,
MCSection *Section,
const MCExpr *SubSection,
raw_ostream &OS) {
assert(!SubSection && "SubSection is not null!");
const MCObjectFileInfo *FI = getStreamer().getContext().getObjectFileInfo();
// Emit closing brace for DWARF sections only.
if (isDwarfSection(FI, CurSection))
OS << "\t}\n";
if (isDwarfSection(FI, Section)) {
// Emit DWARF .file directives in the outermost scope.
outputDwarfFileDirectives();
OS << "\t.section";
Section->PrintSwitchToSection(*getStreamer().getContext().getAsmInfo(),
FI->getTargetTriple(), OS, SubSection);
// DWARF sections are enclosed into braces - emit the open one.
OS << "\t{\n";
HasSections = true;
}
}
void NVPTXTargetStreamer::emitRawBytes(StringRef Data) {
MCTargetStreamer::emitRawBytes(Data);
// TODO: enable this once the bug in the ptxas with the packed bytes is
// resolved. Currently, (it is confirmed by NVidia) it causes a crash in
// ptxas.
#if 0
const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
const char *Directive = MAI->getData8bitsDirective();
unsigned NumElements = Data.size();
const unsigned MaxLen = 40;
unsigned NumChunks = 1 + ((NumElements - 1) / MaxLen);
// Split the very long directives into several parts if the limit is
// specified.
for (unsigned I = 0; I < NumChunks; ++I) {
SmallString<128> Str;
raw_svector_ostream OS(Str);
const char *Label = Directive;
for (auto It = std::next(Data.bytes_begin(), I * MaxLen),
End = (I == NumChunks - 1)
? Data.bytes_end()
: std::next(Data.bytes_begin(), (I + 1) * MaxLen);
It != End; ++It) {
OS << Label << (unsigned)*It;
if (Label == Directive)
Label = ",";
}
Streamer.emitRawText(OS.str());
}
#endif
}