/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Basic/Targets/PPC.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- PPC.h - Declare PPC target feature support -------------*- C++ -*-===// |
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 | | // This file declares PPC TargetInfo objects. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_PPC_H |
14 | | #define LLVM_CLANG_LIB_BASIC_TARGETS_PPC_H |
15 | | |
16 | | #include "OSTargets.h" |
17 | | #include "clang/Basic/TargetInfo.h" |
18 | | #include "clang/Basic/TargetOptions.h" |
19 | | #include "llvm/ADT/Triple.h" |
20 | | #include "llvm/ADT/StringSwitch.h" |
21 | | #include "llvm/Support/Compiler.h" |
22 | | |
23 | | namespace clang { |
24 | | namespace targets { |
25 | | |
26 | | // PPC abstract base class |
27 | | class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { |
28 | | |
29 | | /// Flags for architecture specific defines. |
30 | | typedef enum { |
31 | | ArchDefineNone = 0, |
32 | | ArchDefineName = 1 << 0, // <name> is substituted for arch name. |
33 | | ArchDefinePpcgr = 1 << 1, |
34 | | ArchDefinePpcsq = 1 << 2, |
35 | | ArchDefine440 = 1 << 3, |
36 | | ArchDefine603 = 1 << 4, |
37 | | ArchDefine604 = 1 << 5, |
38 | | ArchDefinePwr4 = 1 << 6, |
39 | | ArchDefinePwr5 = 1 << 7, |
40 | | ArchDefinePwr5x = 1 << 8, |
41 | | ArchDefinePwr6 = 1 << 9, |
42 | | ArchDefinePwr6x = 1 << 10, |
43 | | ArchDefinePwr7 = 1 << 11, |
44 | | ArchDefinePwr8 = 1 << 12, |
45 | | ArchDefinePwr9 = 1 << 13, |
46 | | ArchDefinePwr10 = 1 << 14, |
47 | | ArchDefineFuture = 1 << 15, |
48 | | ArchDefineA2 = 1 << 16, |
49 | | ArchDefineE500 = 1 << 18 |
50 | | } ArchDefineTypes; |
51 | | |
52 | | ArchDefineTypes ArchDefs = ArchDefineNone; |
53 | | static const Builtin::Info BuiltinInfo[]; |
54 | | static const char *const GCCRegNames[]; |
55 | | static const TargetInfo::GCCRegAlias GCCRegAliases[]; |
56 | | std::string CPU; |
57 | | enum PPCFloatABI { HardFloat, SoftFloat } FloatABI; |
58 | | |
59 | | // Target cpu features. |
60 | | bool HasAltivec = false; |
61 | | bool HasMMA = false; |
62 | | bool HasROPProtect = false; |
63 | | bool HasPrivileged = false; |
64 | | bool HasVSX = false; |
65 | | bool UseCRBits = false; |
66 | | bool HasP8Vector = false; |
67 | | bool HasP8Crypto = false; |
68 | | bool HasDirectMove = false; |
69 | | bool HasHTM = false; |
70 | | bool HasBPERMD = false; |
71 | | bool HasExtDiv = false; |
72 | | bool HasP9Vector = false; |
73 | | bool HasSPE = false; |
74 | | bool PairedVectorMemops = false; |
75 | | bool HasP10Vector = false; |
76 | | bool HasPCRelativeMemops = false; |
77 | | bool HasPrefixInstrs = false; |
78 | | bool IsISA2_06 = false; |
79 | | bool IsISA2_07 = false; |
80 | | bool IsISA3_0 = false; |
81 | | bool IsISA3_1 = false; |
82 | | bool HasQuadwordAtomics = false; |
83 | | |
84 | | protected: |
85 | | std::string ABI; |
86 | | |
87 | | public: |
88 | | PPCTargetInfo(const llvm::Triple &Triple, const TargetOptions &) |
89 | 4.18k | : TargetInfo(Triple) { |
90 | 4.18k | SuitableAlign = 128; |
91 | 4.18k | SimdDefaultAlign = 128; |
92 | 4.18k | LongDoubleWidth = LongDoubleAlign = 128; |
93 | 4.18k | LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble(); |
94 | 4.18k | HasStrictFP = true; |
95 | 4.18k | HasIbm128 = true; |
96 | 4.18k | } |
97 | | |
98 | | // Set the language option for altivec based on our value. |
99 | | void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override; |
100 | | |
101 | | // Note: GCC recognizes the following additional cpus: |
102 | | // 401, 403, 405, 405fp, 440fp, 464, 464fp, 476, 476fp, 505, 740, 801, |
103 | | // 821, 823, 8540, e300c2, e300c3, e500mc64, e6500, 860, cell, titan, rs64. |
104 | | bool isValidCPUName(StringRef Name) const override; |
105 | | void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; |
106 | | |
107 | 279 | bool setCPU(const std::string &Name) override { |
108 | 279 | bool CPUKnown = isValidCPUName(Name); |
109 | 279 | if (CPUKnown) { |
110 | 278 | CPU = Name; |
111 | | |
112 | | // CPU identification. |
113 | 278 | ArchDefs = |
114 | 278 | (ArchDefineTypes)llvm::StringSwitch<int>(CPU) |
115 | 278 | .Case("440", ArchDefineName) |
116 | 278 | .Case("450", ArchDefineName | ArchDefine440) |
117 | 278 | .Case("601", ArchDefineName) |
118 | 278 | .Case("602", ArchDefineName | ArchDefinePpcgr) |
119 | 278 | .Case("603", ArchDefineName | ArchDefinePpcgr) |
120 | 278 | .Case("603e", ArchDefineName | ArchDefine603 | ArchDefinePpcgr) |
121 | 278 | .Case("603ev", ArchDefineName | ArchDefine603 | ArchDefinePpcgr) |
122 | 278 | .Case("604", ArchDefineName | ArchDefinePpcgr) |
123 | 278 | .Case("604e", ArchDefineName | ArchDefine604 | ArchDefinePpcgr) |
124 | 278 | .Case("620", ArchDefineName | ArchDefinePpcgr) |
125 | 278 | .Case("630", ArchDefineName | ArchDefinePpcgr) |
126 | 278 | .Case("7400", ArchDefineName | ArchDefinePpcgr) |
127 | 278 | .Case("7450", ArchDefineName | ArchDefinePpcgr) |
128 | 278 | .Case("750", ArchDefineName | ArchDefinePpcgr) |
129 | 278 | .Case("970", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr | |
130 | 278 | ArchDefinePpcsq) |
131 | 278 | .Case("a2", ArchDefineA2) |
132 | 278 | .Cases("power3", "pwr3", ArchDefinePpcgr) |
133 | 278 | .Cases("power4", "pwr4", |
134 | 278 | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) |
135 | 278 | .Cases("power5", "pwr5", |
136 | 278 | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | |
137 | 278 | ArchDefinePpcsq) |
138 | 278 | .Cases("power5x", "pwr5x", |
139 | 278 | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | |
140 | 278 | ArchDefinePpcgr | ArchDefinePpcsq) |
141 | 278 | .Cases("power6", "pwr6", |
142 | 278 | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 | |
143 | 278 | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) |
144 | 278 | .Cases("power6x", "pwr6x", |
145 | 278 | ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x | |
146 | 278 | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | |
147 | 278 | ArchDefinePpcsq) |
148 | 278 | .Cases("power7", "pwr7", |
149 | 278 | ArchDefinePwr7 | ArchDefinePwr6 | ArchDefinePwr5x | |
150 | 278 | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | |
151 | 278 | ArchDefinePpcsq) |
152 | | // powerpc64le automatically defaults to at least power8. |
153 | 278 | .Cases("power8", "pwr8", "ppc64le", |
154 | 278 | ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6 | |
155 | 278 | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | |
156 | 278 | ArchDefinePpcgr | ArchDefinePpcsq) |
157 | 278 | .Cases("power9", "pwr9", |
158 | 278 | ArchDefinePwr9 | ArchDefinePwr8 | ArchDefinePwr7 | |
159 | 278 | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 | |
160 | 278 | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) |
161 | 278 | .Cases("power10", "pwr10", |
162 | 278 | ArchDefinePwr10 | ArchDefinePwr9 | ArchDefinePwr8 | |
163 | 278 | ArchDefinePwr7 | ArchDefinePwr6 | ArchDefinePwr5x | |
164 | 278 | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | |
165 | 278 | ArchDefinePpcsq) |
166 | 278 | .Case("future", |
167 | 278 | ArchDefineFuture | ArchDefinePwr10 | ArchDefinePwr9 | |
168 | 278 | ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6 | |
169 | 278 | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | |
170 | 278 | ArchDefinePpcgr | ArchDefinePpcsq) |
171 | 278 | .Cases("8548", "e500", ArchDefineE500) |
172 | 278 | .Default(ArchDefineNone); |
173 | 278 | } |
174 | 279 | return CPUKnown; |
175 | 279 | } |
176 | | |
177 | 7.61k | StringRef getABI() const override { return ABI; } |
178 | | |
179 | | ArrayRef<Builtin::Info> getTargetBuiltins() const override; |
180 | | |
181 | 0 | bool isCLZForZeroUndef() const override { return false; } |
182 | | |
183 | | void getTargetDefines(const LangOptions &Opts, |
184 | | MacroBuilder &Builder) const override; |
185 | | |
186 | | bool |
187 | | initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, |
188 | | StringRef CPU, |
189 | | const std::vector<std::string> &FeaturesVec) const override; |
190 | | |
191 | | void addP10SpecificFeatures(llvm::StringMap<bool> &Features) const; |
192 | | void addFutureSpecificFeatures(llvm::StringMap<bool> &Features) const; |
193 | | |
194 | | bool handleTargetFeatures(std::vector<std::string> &Features, |
195 | | DiagnosticsEngine &Diags) override; |
196 | | |
197 | | bool hasFeature(StringRef Feature) const override; |
198 | | |
199 | | void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name, |
200 | | bool Enabled) const override; |
201 | | |
202 | | ArrayRef<const char *> getGCCRegNames() const override; |
203 | | |
204 | | ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override; |
205 | | |
206 | | ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override; |
207 | | |
208 | | bool validateAsmConstraint(const char *&Name, |
209 | 37 | TargetInfo::ConstraintInfo &Info) const override { |
210 | 37 | switch (*Name) { |
211 | 0 | default: |
212 | 0 | return false; |
213 | 0 | case 'O': // Zero |
214 | 0 | break; |
215 | 1 | case 'f': // Floating point register |
216 | | // Don't use floating point registers on soft float ABI. |
217 | 1 | if (FloatABI == SoftFloat) |
218 | 1 | return false; |
219 | 1 | LLVM_FALLTHROUGH0 ;0 |
220 | 0 | case 'b': // Base register |
221 | 0 | Info.setAllowsRegister(); |
222 | 0 | break; |
223 | | // FIXME: The following are added to allow parsing. |
224 | | // I just took a guess at what the actions should be. |
225 | | // Also, is more specific checking needed? I.e. specific registers? |
226 | 1 | case 'd': // Floating point register (containing 64-bit value) |
227 | 2 | case 'v': // Altivec vector register |
228 | | // Don't use floating point and altivec vector registers |
229 | | // on soft float ABI |
230 | 2 | if (FloatABI == SoftFloat) |
231 | 2 | return false; |
232 | 0 | Info.setAllowsRegister(); |
233 | 0 | break; |
234 | 30 | case 'w': |
235 | 30 | switch (Name[1]) { |
236 | 0 | case 'd': // VSX vector register to hold vector double data |
237 | 0 | case 'f': // VSX vector register to hold vector float data |
238 | 6 | case 's': // VSX vector register to hold scalar double data |
239 | 12 | case 'w': // VSX vector register to hold scalar double data |
240 | 12 | case 'a': // Any VSX register |
241 | 30 | case 'c': // An individual CR bit |
242 | 30 | case 'i': // FP or VSX register to hold 64-bit integers data |
243 | 30 | break; |
244 | 0 | default: |
245 | 0 | return false; |
246 | 30 | } |
247 | 30 | Info.setAllowsRegister(); |
248 | 30 | Name++; // Skip over 'w'. |
249 | 30 | break; |
250 | 0 | case 'h': // `MQ', `CTR', or `LINK' register |
251 | 0 | case 'q': // `MQ' register |
252 | 0 | case 'c': // `CTR' register |
253 | 0 | case 'l': // `LINK' register |
254 | 0 | case 'x': // `CR' register (condition register) number 0 |
255 | 0 | case 'y': // `CR' register (condition register) |
256 | 0 | case 'z': // `XER[CA]' carry bit (part of the XER register) |
257 | 0 | Info.setAllowsRegister(); |
258 | 0 | break; |
259 | 0 | case 'I': // Signed 16-bit constant |
260 | 0 | case 'J': // Unsigned 16-bit constant shifted left 16 bits |
261 | | // (use `L' instead for SImode constants) |
262 | 0 | case 'K': // Unsigned 16-bit constant |
263 | 0 | case 'L': // Signed 16-bit constant shifted left 16 bits |
264 | 0 | case 'M': // Constant larger than 31 |
265 | 0 | case 'N': // Exact power of 2 |
266 | 0 | case 'P': // Constant whose negation is a signed 16-bit constant |
267 | 0 | case 'G': // Floating point constant that can be loaded into a |
268 | | // register with one instruction per word |
269 | 0 | case 'H': // Integer/Floating point constant that can be loaded |
270 | | // into a register using three instructions |
271 | 0 | break; |
272 | 0 | case 'm': // Memory operand. Note that on PowerPC targets, m can |
273 | | // include addresses that update the base register. It |
274 | | // is therefore only safe to use `m' in an asm statement |
275 | | // if that asm statement accesses the operand exactly once. |
276 | | // The asm statement must also use `%U<opno>' as a |
277 | | // placeholder for the "update" flag in the corresponding |
278 | | // load or store instruction. For example: |
279 | | // asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val)); |
280 | | // is correct but: |
281 | | // asm ("st %1,%0" : "=m" (mem) : "r" (val)); |
282 | | // is not. Use es rather than m if you don't want the base |
283 | | // register to be updated. |
284 | 0 | case 'e': |
285 | 0 | if (Name[1] != 's') |
286 | 0 | return false; |
287 | | // es: A "stable" memory operand; that is, one which does not |
288 | | // include any automodification of the base register. Unlike |
289 | | // `m', this constraint can be used in asm statements that |
290 | | // might access the operand several times, or that might not |
291 | | // access it at all. |
292 | 0 | Info.setAllowsMemory(); |
293 | 0 | Name++; // Skip over 'e'. |
294 | 0 | break; |
295 | 0 | case 'Q': // Memory operand that is an offset from a register (it is |
296 | | // usually better to use `m' or `es' in asm statements) |
297 | 0 | Info.setAllowsRegister(); |
298 | 0 | LLVM_FALLTHROUGH; |
299 | 4 | case 'Z': // Memory operand that is an indexed or indirect from a |
300 | | // register (it is usually better to use `m' or `es' in |
301 | | // asm statements) |
302 | 4 | Info.setAllowsMemory(); |
303 | 4 | break; |
304 | 0 | case 'R': // AIX TOC entry |
305 | 0 | case 'a': // Address operand that is an indexed or indirect from a |
306 | | // register (`p' is preferable for asm statements) |
307 | 0 | case 'S': // Constant suitable as a 64-bit mask operand |
308 | 0 | case 'T': // Constant suitable as a 32-bit mask operand |
309 | 0 | case 'U': // System V Release 4 small data area reference |
310 | 0 | case 't': // AND masks that can be performed by two rldic{l, r} |
311 | | // instructions |
312 | 0 | case 'W': // Vector constant that does not require memory |
313 | 0 | case 'j': // Vector constant that is all zeros. |
314 | 0 | break; |
315 | | // End FIXME. |
316 | 37 | } |
317 | 34 | return true; |
318 | 37 | } |
319 | | |
320 | 263 | std::string convertConstraint(const char *&Constraint) const override { |
321 | 263 | std::string R; |
322 | 263 | switch (*Constraint) { |
323 | 0 | case 'e': |
324 | 15 | case 'w': |
325 | | // Two-character constraint; add "^" hint for later parsing. |
326 | 15 | R = std::string("^") + std::string(Constraint, 2); |
327 | 15 | Constraint++; |
328 | 15 | break; |
329 | 248 | default: |
330 | 248 | return TargetInfo::convertConstraint(Constraint); |
331 | 263 | } |
332 | 15 | return R; |
333 | 263 | } |
334 | | |
335 | 88 | const char *getClobbers() const override { return ""; } |
336 | 0 | int getEHDataRegisterNumber(unsigned RegNo) const override { |
337 | 0 | if (RegNo == 0) |
338 | 0 | return 3; |
339 | 0 | if (RegNo == 1) |
340 | 0 | return 4; |
341 | 0 | return -1; |
342 | 0 | } |
343 | | |
344 | 4 | bool hasSjLjLowering() const override { return true; } |
345 | | |
346 | 211 | const char *getLongDoubleMangling() const override { |
347 | 211 | if (LongDoubleWidth == 64) |
348 | 54 | return "e"; |
349 | 157 | return LongDoubleFormat == &llvm::APFloat::PPCDoubleDouble() |
350 | 157 | ? "g"151 |
351 | 157 | : "u9__ieee128"6 ; |
352 | 211 | } |
353 | 92 | const char *getFloat128Mangling() const override { return "u9__ieee128"; } |
354 | 52 | const char *getIbm128Mangling() const override { return "g"; } |
355 | | |
356 | 23 | bool hasBitIntType() const override { return true; } |
357 | | |
358 | 0 | bool isSPRegName(StringRef RegName) const override { |
359 | 0 | return RegName.equals("r1") || RegName.equals("x1"); |
360 | 0 | } |
361 | | }; |
362 | | |
363 | | class LLVM_LIBRARY_VISIBILITY PPC32TargetInfo : public PPCTargetInfo { |
364 | | public: |
365 | | PPC32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
366 | 246 | : PPCTargetInfo(Triple, Opts) { |
367 | 246 | if (Triple.isOSAIX()) |
368 | 146 | resetDataLayout("E-m:a-p:32:32-i64:64-n32"); |
369 | 100 | else if (Triple.getArch() == llvm::Triple::ppcle) |
370 | 2 | resetDataLayout("e-m:e-p:32:32-i64:64-n32"); |
371 | 98 | else |
372 | 98 | resetDataLayout("E-m:e-p:32:32-i64:64-n32"); |
373 | | |
374 | 246 | switch (getTriple().getOS()) { |
375 | 27 | case llvm::Triple::Linux: |
376 | 29 | case llvm::Triple::FreeBSD: |
377 | 31 | case llvm::Triple::NetBSD: |
378 | 31 | SizeType = UnsignedInt; |
379 | 31 | PtrDiffType = SignedInt; |
380 | 31 | IntPtrType = SignedInt; |
381 | 31 | break; |
382 | 146 | case llvm::Triple::AIX: |
383 | 146 | SizeType = UnsignedLong; |
384 | 146 | PtrDiffType = SignedLong; |
385 | 146 | IntPtrType = SignedLong; |
386 | 146 | LongDoubleWidth = 64; |
387 | 146 | LongDoubleAlign = DoubleAlign = 32; |
388 | 146 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); |
389 | 146 | break; |
390 | 69 | default: |
391 | 69 | break; |
392 | 246 | } |
393 | | |
394 | 246 | if (Triple.isOSFreeBSD() || Triple.isOSNetBSD()244 || Triple.isOSOpenBSD()242 || |
395 | 246 | Triple.isMusl()238 ) { |
396 | 8 | LongDoubleWidth = LongDoubleAlign = 64; |
397 | 8 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); |
398 | 8 | } |
399 | | |
400 | | // PPC32 supports atomics up to 4 bytes. |
401 | 246 | MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; |
402 | 246 | } clang::targets::PPC32TargetInfo::PPC32TargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 366 | 187 | : PPCTargetInfo(Triple, Opts) { | 367 | 187 | if (Triple.isOSAIX()) | 368 | 146 | resetDataLayout("E-m:a-p:32:32-i64:64-n32"); | 369 | 41 | else if (Triple.getArch() == llvm::Triple::ppcle) | 370 | 0 | resetDataLayout("e-m:e-p:32:32-i64:64-n32"); | 371 | 41 | else | 372 | 41 | resetDataLayout("E-m:e-p:32:32-i64:64-n32"); | 373 | | | 374 | 187 | switch (getTriple().getOS()) { | 375 | 27 | case llvm::Triple::Linux: | 376 | 29 | case llvm::Triple::FreeBSD: | 377 | 31 | case llvm::Triple::NetBSD: | 378 | 31 | SizeType = UnsignedInt; | 379 | 31 | PtrDiffType = SignedInt; | 380 | 31 | IntPtrType = SignedInt; | 381 | 31 | break; | 382 | 146 | case llvm::Triple::AIX: | 383 | 146 | SizeType = UnsignedLong; | 384 | 146 | PtrDiffType = SignedLong; | 385 | 146 | IntPtrType = SignedLong; | 386 | 146 | LongDoubleWidth = 64; | 387 | 146 | LongDoubleAlign = DoubleAlign = 32; | 388 | 146 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); | 389 | 146 | break; | 390 | 10 | default: | 391 | 10 | break; | 392 | 187 | } | 393 | | | 394 | 187 | if (Triple.isOSFreeBSD() || Triple.isOSNetBSD()185 || Triple.isOSOpenBSD()183 || | 395 | 187 | Triple.isMusl()179 ) { | 396 | 8 | LongDoubleWidth = LongDoubleAlign = 64; | 397 | 8 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); | 398 | 8 | } | 399 | | | 400 | | // PPC32 supports atomics up to 4 bytes. | 401 | 187 | MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; | 402 | 187 | } |
clang::targets::PPC32TargetInfo::PPC32TargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 366 | 59 | : PPCTargetInfo(Triple, Opts) { | 367 | 59 | if (Triple.isOSAIX()) | 368 | 0 | resetDataLayout("E-m:a-p:32:32-i64:64-n32"); | 369 | 59 | else if (Triple.getArch() == llvm::Triple::ppcle) | 370 | 2 | resetDataLayout("e-m:e-p:32:32-i64:64-n32"); | 371 | 57 | else | 372 | 57 | resetDataLayout("E-m:e-p:32:32-i64:64-n32"); | 373 | | | 374 | 59 | switch (getTriple().getOS()) { | 375 | 0 | case llvm::Triple::Linux: | 376 | 0 | case llvm::Triple::FreeBSD: | 377 | 0 | case llvm::Triple::NetBSD: | 378 | 0 | SizeType = UnsignedInt; | 379 | 0 | PtrDiffType = SignedInt; | 380 | 0 | IntPtrType = SignedInt; | 381 | 0 | break; | 382 | 0 | case llvm::Triple::AIX: | 383 | 0 | SizeType = UnsignedLong; | 384 | 0 | PtrDiffType = SignedLong; | 385 | 0 | IntPtrType = SignedLong; | 386 | 0 | LongDoubleWidth = 64; | 387 | 0 | LongDoubleAlign = DoubleAlign = 32; | 388 | 0 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); | 389 | 0 | break; | 390 | 59 | default: | 391 | 59 | break; | 392 | 59 | } | 393 | | | 394 | 59 | if (Triple.isOSFreeBSD() || Triple.isOSNetBSD() || Triple.isOSOpenBSD() || | 395 | 59 | Triple.isMusl()) { | 396 | 0 | LongDoubleWidth = LongDoubleAlign = 64; | 397 | 0 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); | 398 | 0 | } | 399 | | | 400 | | // PPC32 supports atomics up to 4 bytes. | 401 | 59 | MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; | 402 | 59 | } |
|
403 | | |
404 | 82 | BuiltinVaListKind getBuiltinVaListKind() const override { |
405 | | // This is the ELF definition, and is overridden by the Darwin sub-target |
406 | 82 | return TargetInfo::PowerABIBuiltinVaList; |
407 | 82 | } |
408 | | }; |
409 | | |
410 | | // Note: ABI differences may eventually require us to have a separate |
411 | | // TargetInfo for little endian. |
412 | | class LLVM_LIBRARY_VISIBILITY PPC64TargetInfo : public PPCTargetInfo { |
413 | | public: |
414 | | PPC64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
415 | 3.94k | : PPCTargetInfo(Triple, Opts) { |
416 | 3.94k | LongWidth = LongAlign = PointerWidth = PointerAlign = 64; |
417 | 3.94k | IntMaxType = SignedLong; |
418 | 3.94k | Int64Type = SignedLong; |
419 | 3.94k | std::string DataLayout; |
420 | | |
421 | 3.94k | if (Triple.isOSAIX()) { |
422 | | // TODO: Set appropriate ABI for AIX platform. |
423 | 106 | DataLayout = "E-m:a-i64:64-n32:64"; |
424 | 106 | LongDoubleWidth = 64; |
425 | 106 | LongDoubleAlign = DoubleAlign = 32; |
426 | 106 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); |
427 | 3.83k | } else if ((Triple.getArch() == llvm::Triple::ppc64le)) { |
428 | 3.66k | DataLayout = "e-m:e-i64:64-n32:64"; |
429 | 3.66k | ABI = "elfv2"; |
430 | 3.66k | } else { |
431 | 170 | DataLayout = "E-m:e-i64:64-n32:64"; |
432 | 170 | ABI = "elfv1"; |
433 | 170 | } |
434 | | |
435 | 3.94k | if (Triple.isOSFreeBSD() || Triple.isOSOpenBSD()3.93k || Triple.isMusl()3.93k ) { |
436 | 15 | LongDoubleWidth = LongDoubleAlign = 64; |
437 | 15 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); |
438 | 15 | } |
439 | | |
440 | 3.94k | if (Triple.isOSAIX() || Triple.isOSLinux()3.83k ) |
441 | 409 | DataLayout += "-S128-v256:256:256-v512:512:512"; |
442 | 3.94k | resetDataLayout(DataLayout); |
443 | | |
444 | | // Newer PPC64 instruction sets support atomics up to 16 bytes. |
445 | 3.94k | MaxAtomicPromoteWidth = 128; |
446 | | // Baseline PPC64 supports inlining atomics up to 8 bytes. |
447 | 3.94k | MaxAtomicInlineWidth = 64; |
448 | 3.94k | } clang::targets::PPC64TargetInfo::PPC64TargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 415 | 427 | : PPCTargetInfo(Triple, Opts) { | 416 | 427 | LongWidth = LongAlign = PointerWidth = PointerAlign = 64; | 417 | 427 | IntMaxType = SignedLong; | 418 | 427 | Int64Type = SignedLong; | 419 | 427 | std::string DataLayout; | 420 | | | 421 | 427 | if (Triple.isOSAIX()) { | 422 | | // TODO: Set appropriate ABI for AIX platform. | 423 | 106 | DataLayout = "E-m:a-i64:64-n32:64"; | 424 | 106 | LongDoubleWidth = 64; | 425 | 106 | LongDoubleAlign = DoubleAlign = 32; | 426 | 106 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); | 427 | 321 | } else if ((Triple.getArch() == llvm::Triple::ppc64le)) { | 428 | 223 | DataLayout = "e-m:e-i64:64-n32:64"; | 429 | 223 | ABI = "elfv2"; | 430 | 223 | } else { | 431 | 98 | DataLayout = "E-m:e-i64:64-n32:64"; | 432 | 98 | ABI = "elfv1"; | 433 | 98 | } | 434 | | | 435 | 427 | if (Triple.isOSFreeBSD() || Triple.isOSOpenBSD()419 || Triple.isMusl()416 ) { | 436 | 15 | LongDoubleWidth = LongDoubleAlign = 64; | 437 | 15 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); | 438 | 15 | } | 439 | | | 440 | 427 | if (Triple.isOSAIX() || Triple.isOSLinux()321 ) | 441 | 409 | DataLayout += "-S128-v256:256:256-v512:512:512"; | 442 | 427 | resetDataLayout(DataLayout); | 443 | | | 444 | | // Newer PPC64 instruction sets support atomics up to 16 bytes. | 445 | 427 | MaxAtomicPromoteWidth = 128; | 446 | | // Baseline PPC64 supports inlining atomics up to 8 bytes. | 447 | 427 | MaxAtomicInlineWidth = 64; | 448 | 427 | } |
clang::targets::PPC64TargetInfo::PPC64TargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 415 | 3.51k | : PPCTargetInfo(Triple, Opts) { | 416 | 3.51k | LongWidth = LongAlign = PointerWidth = PointerAlign = 64; | 417 | 3.51k | IntMaxType = SignedLong; | 418 | 3.51k | Int64Type = SignedLong; | 419 | 3.51k | std::string DataLayout; | 420 | | | 421 | 3.51k | if (Triple.isOSAIX()) { | 422 | | // TODO: Set appropriate ABI for AIX platform. | 423 | 0 | DataLayout = "E-m:a-i64:64-n32:64"; | 424 | 0 | LongDoubleWidth = 64; | 425 | 0 | LongDoubleAlign = DoubleAlign = 32; | 426 | 0 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); | 427 | 3.51k | } else if ((Triple.getArch() == llvm::Triple::ppc64le)) { | 428 | 3.44k | DataLayout = "e-m:e-i64:64-n32:64"; | 429 | 3.44k | ABI = "elfv2"; | 430 | 3.44k | } else { | 431 | 72 | DataLayout = "E-m:e-i64:64-n32:64"; | 432 | 72 | ABI = "elfv1"; | 433 | 72 | } | 434 | | | 435 | 3.51k | if (Triple.isOSFreeBSD() || Triple.isOSOpenBSD() || Triple.isMusl()) { | 436 | 0 | LongDoubleWidth = LongDoubleAlign = 64; | 437 | 0 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); | 438 | 0 | } | 439 | | | 440 | 3.51k | if (Triple.isOSAIX() || Triple.isOSLinux()) | 441 | 0 | DataLayout += "-S128-v256:256:256-v512:512:512"; | 442 | 3.51k | resetDataLayout(DataLayout); | 443 | | | 444 | | // Newer PPC64 instruction sets support atomics up to 16 bytes. | 445 | 3.51k | MaxAtomicPromoteWidth = 128; | 446 | | // Baseline PPC64 supports inlining atomics up to 8 bytes. | 447 | 3.51k | MaxAtomicInlineWidth = 64; | 448 | 3.51k | } |
|
449 | | |
450 | 3.88k | void setMaxAtomicWidth() override { |
451 | | // For power8 and up, backend is able to inline 16-byte atomic lock free |
452 | | // code. |
453 | | // TODO: We should allow AIX to inline quadword atomics in the future. |
454 | 3.88k | if (!getTriple().isOSAIX() && hasFeature("quadword-atomics")3.77k ) |
455 | 91 | MaxAtomicInlineWidth = 128; |
456 | 3.88k | } |
457 | | |
458 | 3.75k | BuiltinVaListKind getBuiltinVaListKind() const override { |
459 | 3.75k | return TargetInfo::CharPtrBuiltinVaList; |
460 | 3.75k | } |
461 | | |
462 | | // PPC64 Linux-specific ABI options. |
463 | 105 | bool setABI(const std::string &Name) override { |
464 | 105 | if (Name == "elfv1" || Name == "elfv2"69 ) { |
465 | 105 | ABI = Name; |
466 | 105 | return true; |
467 | 105 | } |
468 | 0 | return false; |
469 | 105 | } |
470 | | |
471 | 120 | CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { |
472 | 120 | switch (CC) { |
473 | 0 | case CC_Swift: |
474 | 0 | return CCCR_OK; |
475 | 120 | case CC_SwiftAsync: |
476 | 120 | return CCCR_Error; |
477 | 0 | default: |
478 | 0 | return CCCR_Warning; |
479 | 120 | } |
480 | 120 | } |
481 | | }; |
482 | | |
483 | | class LLVM_LIBRARY_VISIBILITY DarwinPPC32TargetInfo |
484 | | : public DarwinTargetInfo<PPC32TargetInfo> { |
485 | | public: |
486 | | DarwinPPC32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
487 | 6 | : DarwinTargetInfo<PPC32TargetInfo>(Triple, Opts) { |
488 | 6 | HasAlignMac68kSupport = true; |
489 | 6 | BoolWidth = BoolAlign = 32; // XXX support -mone-byte-bool? |
490 | 6 | PtrDiffType = SignedInt; // for http://llvm.org/bugs/show_bug.cgi?id=15726 |
491 | 6 | LongLongAlign = 32; |
492 | 6 | resetDataLayout("E-m:o-p:32:32-f64:32:64-n32", "_"); |
493 | 6 | } clang::targets::DarwinPPC32TargetInfo::DarwinPPC32TargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 487 | 6 | : DarwinTargetInfo<PPC32TargetInfo>(Triple, Opts) { | 488 | 6 | HasAlignMac68kSupport = true; | 489 | 6 | BoolWidth = BoolAlign = 32; // XXX support -mone-byte-bool? | 490 | 6 | PtrDiffType = SignedInt; // for http://llvm.org/bugs/show_bug.cgi?id=15726 | 491 | 6 | LongLongAlign = 32; | 492 | 6 | resetDataLayout("E-m:o-p:32:32-f64:32:64-n32", "_"); | 493 | 6 | } |
Unexecuted instantiation: clang::targets::DarwinPPC32TargetInfo::DarwinPPC32TargetInfo(llvm::Triple const&, clang::TargetOptions const&) |
494 | | |
495 | 5 | BuiltinVaListKind getBuiltinVaListKind() const override { |
496 | 5 | return TargetInfo::CharPtrBuiltinVaList; |
497 | 5 | } |
498 | | }; |
499 | | |
500 | | class LLVM_LIBRARY_VISIBILITY DarwinPPC64TargetInfo |
501 | | : public DarwinTargetInfo<PPC64TargetInfo> { |
502 | | public: |
503 | | DarwinPPC64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
504 | 1 | : DarwinTargetInfo<PPC64TargetInfo>(Triple, Opts) { |
505 | 1 | HasAlignMac68kSupport = true; |
506 | 1 | resetDataLayout("E-m:o-i64:64-n32:64", "_"); |
507 | 1 | } clang::targets::DarwinPPC64TargetInfo::DarwinPPC64TargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 504 | 1 | : DarwinTargetInfo<PPC64TargetInfo>(Triple, Opts) { | 505 | 1 | HasAlignMac68kSupport = true; | 506 | 1 | resetDataLayout("E-m:o-i64:64-n32:64", "_"); | 507 | 1 | } |
Unexecuted instantiation: clang::targets::DarwinPPC64TargetInfo::DarwinPPC64TargetInfo(llvm::Triple const&, clang::TargetOptions const&) |
508 | | }; |
509 | | |
510 | | class LLVM_LIBRARY_VISIBILITY AIXPPC32TargetInfo : |
511 | | public AIXTargetInfo<PPC32TargetInfo> { |
512 | | public: |
513 | | using AIXTargetInfo::AIXTargetInfo; |
514 | 122 | BuiltinVaListKind getBuiltinVaListKind() const override { |
515 | 122 | return TargetInfo::CharPtrBuiltinVaList; |
516 | 122 | } |
517 | | }; |
518 | | |
519 | | class LLVM_LIBRARY_VISIBILITY AIXPPC64TargetInfo : |
520 | | public AIXTargetInfo<PPC64TargetInfo> { |
521 | | public: |
522 | | using AIXTargetInfo::AIXTargetInfo; |
523 | | }; |
524 | | |
525 | | } // namespace targets |
526 | | } // namespace clang |
527 | | #endif // LLVM_CLANG_LIB_BASIC_TARGETS_PPC_H |