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 | |
13 | using namespace llvm; |
14 | |
15 | static 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 | |
71 | static 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 | |
103 | void 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 | } |