1//===- MCAsmInfoGOFF.cpp - MCGOFFAsmInfo properties -----------------------===//
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-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file defines certain target specific asm properties for GOFF (z/OS)
11/// based targets.
12///
13//===----------------------------------------------------------------------===//
14
15#include "llvm/MC/MCAsmInfoGOFF.h"
16#include "llvm/BinaryFormat/GOFF.h"
17#include "llvm/MC/MCSectionGOFF.h"
18#include "llvm/Support/raw_ostream.h"
19
20using namespace llvm;
21
22MCAsmInfoGOFF::MCAsmInfoGOFF() {
23 Data64bitsDirective = "\t.quad\t";
24 WeakRefDirective = "WXTRN";
25 PrivateGlobalPrefix = "L#";
26 PrivateLabelPrefix = "L#";
27 ZeroDirective = "\t.space\t";
28}
29
30static void emitCATTR(raw_ostream &OS, StringRef Name, GOFF::ESDRmode Rmode,
31 GOFF::ESDAlignment Alignment,
32 GOFF::ESDLoadingBehavior LoadBehavior,
33 GOFF::ESDExecutable Executable, bool IsReadOnly,
34 uint32_t SortKey, uint8_t FillByteValue,
35 StringRef PartName) {
36 OS << Name << " CATTR ";
37 OS << "ALIGN(" << static_cast<unsigned>(Alignment) << "),"
38 << "FILL(" << static_cast<unsigned>(FillByteValue) << ")";
39 switch (LoadBehavior) {
40 case GOFF::ESD_LB_Deferred:
41 OS << ",DEFLOAD";
42 break;
43 case GOFF::ESD_LB_NoLoad:
44 OS << ",NOLOAD";
45 break;
46 default:
47 break;
48 }
49 switch (Executable) {
50 case GOFF::ESD_EXE_CODE:
51 OS << ",EXECUTABLE";
52 break;
53 case GOFF::ESD_EXE_DATA:
54 OS << ",NOTEXECUTABLE";
55 break;
56 default:
57 break;
58 }
59 if (IsReadOnly)
60 OS << ",READONLY";
61 if (Rmode != GOFF::ESD_RMODE_None) {
62 OS << ',';
63 OS << "RMODE(";
64 switch (Rmode) {
65 case GOFF::ESD_RMODE_None:
66 llvm_unreachable("");
67 case GOFF::ESD_RMODE_24:
68 OS << "24";
69 break;
70 case GOFF::ESD_RMODE_31:
71 OS << "31";
72 break;
73 case GOFF::ESD_RMODE_64:
74 OS << "64";
75 break;
76 }
77 OS << ')';
78 }
79 if (SortKey)
80 OS << ",PRIORITY(" << SortKey << ")";
81 if (!PartName.empty())
82 OS << ",PART(" << PartName << ")";
83 OS << '\n';
84}
85
86static void emitXATTR(raw_ostream &OS, StringRef Name,
87 GOFF::ESDLinkageType Linkage,
88 GOFF::ESDExecutable Executable,
89 GOFF::ESDBindingScope BindingScope) {
90 OS << Name << " XATTR ";
91 OS << "LINKAGE(" << (Linkage == GOFF::ESD_LT_OS ? "OS" : "XPLINK") << "),";
92 if (Executable != GOFF::ESD_EXE_Unspecified)
93 OS << "REFERENCE(" << (Executable == GOFF::ESD_EXE_CODE ? "CODE" : "DATA")
94 << "),";
95 if (BindingScope != GOFF::ESD_BSC_Unspecified) {
96 OS << "SCOPE(";
97 switch (BindingScope) {
98 case GOFF::ESD_BSC_Section:
99 OS << "SECTION";
100 break;
101 case GOFF::ESD_BSC_Module:
102 OS << "MODULE";
103 break;
104 case GOFF::ESD_BSC_Library:
105 OS << "LIBRARY";
106 break;
107 case GOFF::ESD_BSC_ImportExport:
108 OS << "EXPORT";
109 break;
110 default:
111 break;
112 }
113 OS << ')';
114 }
115 OS << '\n';
116}
117
118void MCAsmInfoGOFF::printSwitchToSection(const MCSection &Section,
119 uint32_t Subsection, const Triple &T,
120 raw_ostream &OS) const {
121 auto &Sec =
122 const_cast<MCSectionGOFF &>(static_cast<const MCSectionGOFF &>(Section));
123 switch (Sec.SymbolType) {
124 case GOFF::ESD_ST_SectionDefinition: {
125 OS << Sec.getName() << " CSECT\n";
126 Sec.Emitted = true;
127 break;
128 }
129 case GOFF::ESD_ST_ElementDefinition: {
130 printSwitchToSection(Section: *Sec.getParent(), Subsection, T, OS);
131 if (!Sec.Emitted) {
132 emitCATTR(OS, Name: Sec.getName(), Rmode: Sec.EDAttributes.Rmode,
133 Alignment: Sec.EDAttributes.Alignment, LoadBehavior: Sec.EDAttributes.LoadBehavior,
134 Executable: GOFF::ESD_EXE_Unspecified, IsReadOnly: Sec.EDAttributes.IsReadOnly, SortKey: 0,
135 FillByteValue: Sec.EDAttributes.FillByteValue, PartName: StringRef());
136 Sec.Emitted = true;
137 } else
138 OS << Sec.getName() << " CATTR\n";
139 break;
140 }
141 case GOFF::ESD_ST_PartReference: {
142 MCSectionGOFF *ED = Sec.getParent();
143 printSwitchToSection(Section: *ED->getParent(), Subsection, T, OS);
144 if (!Sec.Emitted) {
145 emitCATTR(OS, Name: ED->getName(), Rmode: ED->getEDAttributes().Rmode,
146 Alignment: ED->EDAttributes.Alignment, LoadBehavior: ED->EDAttributes.LoadBehavior,
147 Executable: Sec.PRAttributes.Executable, IsReadOnly: ED->EDAttributes.IsReadOnly,
148 SortKey: Sec.PRAttributes.SortKey, FillByteValue: ED->EDAttributes.FillByteValue,
149 PartName: Sec.getName());
150 emitXATTR(OS, Name: Sec.getName(), Linkage: Sec.PRAttributes.Linkage,
151 Executable: Sec.PRAttributes.Executable, BindingScope: Sec.PRAttributes.BindingScope);
152 ED->Emitted = true;
153 Sec.Emitted = true;
154 } else
155 OS << ED->getName() << " CATTR PART(" << Sec.getName() << ")\n";
156 break;
157 }
158 default:
159 llvm_unreachable("Wrong section type");
160 }
161}
162