//=====- 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
}

