|  | //===- MCAsmInfoGOFF.cpp - MCGOFFAsmInfo properties -----------------------===// | 
|  | // | 
|  | // 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 | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | /// | 
|  | /// \file | 
|  | /// This file defines certain target specific asm properties for GOFF (z/OS) | 
|  | /// based targets. | 
|  | /// | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "llvm/MC/MCAsmInfoGOFF.h" | 
|  | #include "llvm/BinaryFormat/GOFF.h" | 
|  | #include "llvm/MC/MCSectionGOFF.h" | 
|  | #include "llvm/Support/raw_ostream.h" | 
|  |  | 
|  | using namespace llvm; | 
|  |  | 
|  | MCAsmInfoGOFF::MCAsmInfoGOFF() { | 
|  | Data64bitsDirective = "\t.quad\t"; | 
|  | HasDotTypeDotSizeDirective = false; | 
|  | PrivateGlobalPrefix = "L#"; | 
|  | PrivateLabelPrefix = "L#"; | 
|  | ZeroDirective = "\t.space\t"; | 
|  | } | 
|  |  | 
|  | 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_None: | 
|  | llvm_unreachable(""); | 
|  | case GOFF::ESD_RMODE_24: | 
|  | OS << "24"; | 
|  | break; | 
|  | case GOFF::ESD_RMODE_31: | 
|  | OS << "31"; | 
|  | break; | 
|  | case GOFF::ESD_RMODE_64: | 
|  | OS << "64"; | 
|  | 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 MCAsmInfoGOFF::printSwitchToSection(const MCSection &Section, | 
|  | uint32_t Subsection, const Triple &T, | 
|  | raw_ostream &OS) const { | 
|  | auto &Sec = | 
|  | const_cast<MCSectionGOFF &>(static_cast<const MCSectionGOFF &>(Section)); | 
|  | switch (Sec.SymbolType) { | 
|  | case GOFF::ESD_ST_SectionDefinition: { | 
|  | OS << Sec.getName() << " CSECT\n"; | 
|  | Sec.Emitted = true; | 
|  | break; | 
|  | } | 
|  | case GOFF::ESD_ST_ElementDefinition: { | 
|  | printSwitchToSection(*Sec.getParent(), Subsection, T, OS); | 
|  | if (!Sec.Emitted) { | 
|  | emitCATTR(OS, Sec.getName(), Sec.EDAttributes.Rmode, | 
|  | Sec.EDAttributes.Alignment, Sec.EDAttributes.LoadBehavior, | 
|  | GOFF::ESD_EXE_Unspecified, Sec.EDAttributes.IsReadOnly, 0, | 
|  | Sec.EDAttributes.FillByteValue, StringRef()); | 
|  | Sec.Emitted = true; | 
|  | } else | 
|  | OS << Sec.getName() << " CATTR\n"; | 
|  | break; | 
|  | } | 
|  | case GOFF::ESD_ST_PartReference: { | 
|  | MCSectionGOFF *ED = Sec.getParent(); | 
|  | printSwitchToSection(*ED->getParent(), Subsection, T, OS); | 
|  | if (!Sec.Emitted) { | 
|  | emitCATTR(OS, ED->getName(), ED->getEDAttributes().Rmode, | 
|  | ED->EDAttributes.Alignment, ED->EDAttributes.LoadBehavior, | 
|  | Sec.PRAttributes.Executable, ED->EDAttributes.IsReadOnly, | 
|  | Sec.PRAttributes.SortKey, ED->EDAttributes.FillByteValue, | 
|  | Sec.getName()); | 
|  | emitXATTR(OS, Sec.getName(), Sec.PRAttributes.Linkage, | 
|  | Sec.PRAttributes.Executable, Sec.PRAttributes.BindingScope); | 
|  | ED->Emitted = true; | 
|  | Sec.Emitted = true; | 
|  | } else | 
|  | OS << ED->getName() << " CATTR PART(" << Sec.getName() << ")\n"; | 
|  | break; | 
|  | } | 
|  | default: | 
|  | llvm_unreachable("Wrong section type"); | 
|  | } | 
|  | } |