1 //===-- llvm/BinaryFormat/XCOFF.cpp - The XCOFF file format -----*- C++/-*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/BinaryFormat/XCOFF.h"
10 #include "llvm/ADT/SmallString.h"
11 #include "llvm/ADT/StringRef.h"
12 #include "llvm/ADT/StringSwitch.h"
13 #include "llvm/Support/Errc.h"
14 #include "llvm/Support/Error.h"
15 #include "llvm/TargetParser/PPCTargetParser.h"
20 case XCOFF::XMC_##A: \
22 StringRef
XCOFF::getMappingClassString(XCOFF::StorageMappingClass SMC
) {
48 // TODO: need to add a test case for "Unknown" and other SMC.
52 #define RELOC_CASE(A) \
55 StringRef
XCOFF::getRelocationTypeString(XCOFF::RelocationType Type
) {
85 #define LANG_CASE(A) \
86 case XCOFF::TracebackTable::A: \
89 StringRef
XCOFF::getNameForTracebackTableLanguageId(
90 XCOFF::TracebackTable::LanguageID LangId
) {
105 LANG_CASE(ObjectiveC
)
112 XCOFF::CFileCpuId
XCOFF::getCpuID(StringRef CPUName
) {
113 StringRef CPU
= PPC::normalizeCPUName(CPUName
);
114 return StringSwitch
<XCOFF::CFileCpuId
>(CPU
)
115 .Cases("generic", "COM", XCOFF::TCPU_COM
)
116 .Case("601", XCOFF::TCPU_601
)
117 .Cases("602", "603", "603e", "603ev", XCOFF::TCPU_603
)
118 .Cases("604", "604e", XCOFF::TCPU_604
)
119 .Case("620", XCOFF::TCPU_620
)
120 .Case("970", XCOFF::TCPU_970
)
121 .Cases("a2", "g3", "g4", "g5", "e500", XCOFF::TCPU_COM
)
122 .Cases("pwr3", "pwr4", XCOFF::TCPU_COM
)
123 .Cases("pwr5", "PWR5", XCOFF::TCPU_PWR5
)
124 .Cases("pwr5x", "PWR5X", XCOFF::TCPU_PWR5X
)
125 .Cases("pwr6", "PWR6", XCOFF::TCPU_PWR6
)
126 .Cases("pwr6x", "PWR6E", XCOFF::TCPU_PWR6E
)
127 .Cases("pwr7", "PWR7", XCOFF::TCPU_PWR7
)
128 .Cases("pwr8", "PWR8", XCOFF::TCPU_PWR8
)
129 .Cases("pwr9", "PWR9", XCOFF::TCPU_PWR9
)
130 .Cases("pwr10", "PWR10", XCOFF::TCPU_PWR10
)
131 .Cases("ppc", "PPC", "ppc32", "ppc64", XCOFF::TCPU_COM
)
132 .Case("ppc64le", XCOFF::TCPU_PWR8
)
133 .Case("future", XCOFF::TCPU_PWR10
)
134 .Cases("any", "ANY", XCOFF::TCPU_ANY
)
135 .Default(XCOFF::TCPU_INVALID
);
138 #define TCPU_CASE(A) \
139 case XCOFF::TCPU_##A: \
141 StringRef
XCOFF::getTCPUString(XCOFF::CFileCpuId TCPU
) {
169 Expected
<SmallString
<32>> XCOFF::parseParmsType(uint32_t Value
,
170 unsigned FixedParmsNum
,
171 unsigned FloatingParmsNum
) {
172 SmallString
<32> ParmsType
;
174 unsigned ParsedFixedNum
= 0;
175 unsigned ParsedFloatingNum
= 0;
176 unsigned ParsedNum
= 0;
177 unsigned ParmsNum
= FixedParmsNum
+ FloatingParmsNum
;
179 // In the function PPCFunctionInfo::getParmsType(), when there are no vector
180 // parameters, the 31st bit of ParmsType is always zero even if it indicates a
181 // floating point parameter. The parameter type information is lost. There
182 // are only 8 GPRs used for parameters passing, the floating parameters
183 // also occupy GPRs if there are available, so the 31st bit can never be a
184 // fixed parameter. At the same time, we also do not know whether the zero of
185 // the 31st bit indicates a float or double parameter type here. Therefore, we
186 // ignore the 31st bit.
187 while (Bits
< 31 && ParsedNum
< ParmsNum
) {
190 if ((Value
& TracebackTable::ParmTypeIsFloatingBit
) == 0) {
191 // Fixed parameter type.
197 if ((Value
& TracebackTable::ParmTypeFloatingIsDoubleBit
) == 0)
198 // Float parameter type.
201 // Double parameter type.
209 // We have more parameters than the 32 Bits could encode.
210 if (ParsedNum
< ParmsNum
)
211 ParmsType
+= ", ...";
213 if (Value
!= 0u || ParsedFixedNum
> FixedParmsNum
||
214 ParsedFloatingNum
> FloatingParmsNum
)
215 return createStringError(errc::invalid_argument
,
216 "ParmsType encodes can not map to ParmsNum "
217 "parameters in parseParmsType.");
221 SmallString
<32> XCOFF::getExtendedTBTableFlagString(uint8_t Flag
) {
224 if (Flag
& ExtendedTBTableFlag::TB_OS1
)
226 if (Flag
& ExtendedTBTableFlag::TB_RESERVED
)
227 Res
+= "TB_RESERVED ";
228 if (Flag
& ExtendedTBTableFlag::TB_SSP_CANARY
)
229 Res
+= "TB_SSP_CANARY ";
230 if (Flag
& ExtendedTBTableFlag::TB_OS2
)
232 if (Flag
& ExtendedTBTableFlag::TB_EH_INFO
)
233 Res
+= "TB_EH_INFO ";
234 if (Flag
& ExtendedTBTableFlag::TB_LONGTBTABLE2
)
235 Res
+= "TB_LONGTBTABLE2 ";
237 // Two of the bits that haven't got used in the mask.
241 // Pop the last space.
246 Expected
<SmallString
<32>>
247 XCOFF::parseParmsTypeWithVecInfo(uint32_t Value
, unsigned FixedParmsNum
,
248 unsigned FloatingParmsNum
,
249 unsigned VectorParmsNum
) {
250 SmallString
<32> ParmsType
;
252 unsigned ParsedFixedNum
= 0;
253 unsigned ParsedFloatingNum
= 0;
254 unsigned ParsedVectorNum
= 0;
255 unsigned ParsedNum
= 0;
256 unsigned ParmsNum
= FixedParmsNum
+ FloatingParmsNum
+ VectorParmsNum
;
258 for (int Bits
= 0; Bits
< 32 && ParsedNum
< ParmsNum
; Bits
+= 2) {
262 switch (Value
& TracebackTable::ParmTypeMask
) {
263 case TracebackTable::ParmTypeIsFixedBits
:
267 case TracebackTable::ParmTypeIsVectorBits
:
271 case TracebackTable::ParmTypeIsFloatingBits
:
275 case TracebackTable::ParmTypeIsDoubleBits
:
280 assert(false && "Unrecognized bits in ParmsType.");
285 // We have more parameters than the 32 Bits could encode.
286 if (ParsedNum
< ParmsNum
)
287 ParmsType
+= ", ...";
289 if (Value
!= 0u || ParsedFixedNum
> FixedParmsNum
||
290 ParsedFloatingNum
> FloatingParmsNum
|| ParsedVectorNum
> VectorParmsNum
)
291 return createStringError(
292 errc::invalid_argument
,
293 "ParmsType encodes can not map to ParmsNum parameters "
294 "in parseParmsTypeWithVecInfo.");
299 Expected
<SmallString
<32>> XCOFF::parseVectorParmsType(uint32_t Value
,
301 SmallString
<32> ParmsType
;
302 unsigned ParsedNum
= 0;
303 for (int Bits
= 0; ParsedNum
< ParmsNum
&& Bits
< 32; Bits
+= 2) {
306 switch (Value
& TracebackTable::ParmTypeMask
) {
307 case TracebackTable::ParmTypeIsVectorCharBit
:
311 case TracebackTable::ParmTypeIsVectorShortBit
:
315 case TracebackTable::ParmTypeIsVectorIntBit
:
319 case TracebackTable::ParmTypeIsVectorFloatBit
:
327 // We have more parameters than the 32 Bits could encode.
328 if (ParsedNum
< ParmsNum
)
329 ParmsType
+= ", ...";
332 return createStringError(errc::invalid_argument
,
333 "ParmsType encodes more than ParmsNum parameters "
334 "in parseVectorParmsType.");