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