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