blob: 8163e5bbd632becc93943865b1badd6a7ff56a5d [file] [log] [blame]
//===- MCSectionGOFF.cpp - GOFF Code Section Representation ---------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCSectionGOFF.h"
#include "llvm/BinaryFormat/GOFF.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
static void emitCATTR(raw_ostream &OS, StringRef Name, GOFF::ESDRmode Rmode,
GOFF::ESDAlignment Alignment,
GOFF::ESDLoadingBehavior LoadBehavior,
GOFF::ESDExecutable Executable, bool IsReadOnly,
uint32_t SortKey, uint8_t FillByteValue,
StringRef PartName) {
OS << Name << " CATTR ";
OS << "ALIGN(" << static_cast<unsigned>(Alignment) << "),"
<< "FILL(" << static_cast<unsigned>(FillByteValue) << ")";
switch (LoadBehavior) {
case GOFF::ESD_LB_Deferred:
OS << ",DEFLOAD";
break;
case GOFF::ESD_LB_NoLoad:
OS << ",NOLOAD";
break;
default:
break;
}
switch (Executable) {
case GOFF::ESD_EXE_CODE:
OS << ",EXECUTABLE";
break;
case GOFF::ESD_EXE_DATA:
OS << ",NOTEXECUTABLE";
break;
default:
break;
}
if (IsReadOnly)
OS << ",READONLY";
if (Rmode != GOFF::ESD_RMODE_None) {
OS << ',';
OS << "RMODE(";
switch (Rmode) {
case GOFF::ESD_RMODE_24:
OS << "24";
break;
case GOFF::ESD_RMODE_31:
OS << "31";
break;
case GOFF::ESD_RMODE_64:
OS << "64";
break;
case GOFF::ESD_RMODE_None:
break;
}
OS << ')';
}
if (SortKey)
OS << ",PRIORITY(" << SortKey << ")";
if (!PartName.empty())
OS << ",PART(" << PartName << ")";
OS << '\n';
}
static void emitXATTR(raw_ostream &OS, StringRef Name,
GOFF::ESDLinkageType Linkage,
GOFF::ESDExecutable Executable,
GOFF::ESDBindingScope BindingScope) {
OS << Name << " XATTR ";
OS << "LINKAGE(" << (Linkage == GOFF::ESD_LT_OS ? "OS" : "XPLINK") << "),";
if (Executable != GOFF::ESD_EXE_Unspecified)
OS << "REFERENCE(" << (Executable == GOFF::ESD_EXE_CODE ? "CODE" : "DATA")
<< "),";
if (BindingScope != GOFF::ESD_BSC_Unspecified) {
OS << "SCOPE(";
switch (BindingScope) {
case GOFF::ESD_BSC_Section:
OS << "SECTION";
break;
case GOFF::ESD_BSC_Module:
OS << "MODULE";
break;
case GOFF::ESD_BSC_Library:
OS << "LIBRARY";
break;
case GOFF::ESD_BSC_ImportExport:
OS << "EXPORT";
break;
default:
break;
}
OS << ')';
}
OS << '\n';
}
void MCSectionGOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
raw_ostream &OS,
uint32_t Subsection) const {
switch (SymbolType) {
case GOFF::ESD_ST_SectionDefinition: {
OS << Name << " CSECT\n";
Emitted = true;
break;
}
case GOFF::ESD_ST_ElementDefinition: {
getParent()->printSwitchToSection(MAI, T, OS, Subsection);
if (!Emitted) {
emitCATTR(OS, Name, EDAttributes.Rmode, EDAttributes.Alignment,
EDAttributes.LoadBehavior, GOFF::ESD_EXE_Unspecified,
EDAttributes.IsReadOnly, 0, EDAttributes.FillByteValue,
StringRef());
Emitted = true;
} else
OS << Name << " CATTR\n";
break;
}
case GOFF::ESD_ST_PartReference: {
MCSectionGOFF *ED = getParent();
ED->getParent()->printSwitchToSection(MAI, T, OS, Subsection);
if (!Emitted) {
emitCATTR(OS, ED->getName(), ED->getEDAttributes().Rmode,
ED->EDAttributes.Alignment, ED->EDAttributes.LoadBehavior,
PRAttributes.Executable, ED->EDAttributes.IsReadOnly,
PRAttributes.SortKey, ED->EDAttributes.FillByteValue, Name);
emitXATTR(OS, Name, PRAttributes.Linkage, PRAttributes.Executable,
PRAttributes.BindingScope);
ED->Emitted = true;
Emitted = true;
} else
OS << ED->getName() << " CATTR PART(" << Name << ")\n";
break;
}
default:
llvm_unreachable("Wrong section type");
}
}