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