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