1 //===--- PPC.h - Declare PPC target feature support -------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file declares PPC TargetInfo objects. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_PPC_H 15 #define LLVM_CLANG_LIB_BASIC_TARGETS_PPC_H 16 17 #include "OSTargets.h" 18 #include "clang/Basic/TargetInfo.h" 19 #include "clang/Basic/TargetOptions.h" 20 #include "llvm/ADT/Triple.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 static const Builtin::Info BuiltinInfo[]; 29 static const char *const GCCRegNames[]; 30 static const TargetInfo::GCCRegAlias GCCRegAliases[]; 31 std::string CPU; 32 33 // Target cpu features. 34 bool HasAltivec; 35 bool HasVSX; 36 bool HasP8Vector; 37 bool HasP8Crypto; 38 bool HasDirectMove; 39 bool HasQPX; 40 bool HasHTM; 41 bool HasBPERMD; 42 bool HasExtDiv; 43 bool HasP9Vector; 44 45 protected: 46 std::string ABI; 47 48 public: 49 PPCTargetInfo(const llvm::Triple &Triple, const TargetOptions &) 50 : TargetInfo(Triple), HasAltivec(false), HasVSX(false), 51 HasP8Vector(false), HasP8Crypto(false), HasDirectMove(false), 52 HasQPX(false), HasHTM(false), HasBPERMD(false), HasExtDiv(false), 53 HasP9Vector(false) { 54 SuitableAlign = 128; 55 SimdDefaultAlign = 128; 56 LongDoubleWidth = LongDoubleAlign = 128; 57 LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble(); 58 } 59 60 /// \brief Flags for architecture specific defines. 61 typedef enum { 62 ArchDefineNone = 0, 63 ArchDefineName = 1 << 0, // <name> is substituted for arch name. 64 ArchDefinePpcgr = 1 << 1, 65 ArchDefinePpcsq = 1 << 2, 66 ArchDefine440 = 1 << 3, 67 ArchDefine603 = 1 << 4, 68 ArchDefine604 = 1 << 5, 69 ArchDefinePwr4 = 1 << 6, 70 ArchDefinePwr5 = 1 << 7, 71 ArchDefinePwr5x = 1 << 8, 72 ArchDefinePwr6 = 1 << 9, 73 ArchDefinePwr6x = 1 << 10, 74 ArchDefinePwr7 = 1 << 11, 75 ArchDefinePwr8 = 1 << 12, 76 ArchDefinePwr9 = 1 << 13, 77 ArchDefineA2 = 1 << 14, 78 ArchDefineA2q = 1 << 15 79 } ArchDefineTypes; 80 81 // Set the language option for altivec based on our value. 82 void adjust(LangOptions &Opts) override; 83 84 // Note: GCC recognizes the following additional cpus: 85 // 401, 403, 405, 405fp, 440fp, 464, 464fp, 476, 476fp, 505, 740, 801, 86 // 821, 823, 8540, 8548, e300c2, e300c3, e500mc64, e6500, 860, cell, 87 // titan, rs64. 88 bool isValidCPUName(StringRef Name) const override; 89 90 bool setCPU(const std::string &Name) override { 91 bool CPUKnown = isValidCPUName(Name); 92 if (CPUKnown) 93 CPU = Name; 94 return CPUKnown; 95 } 96 97 StringRef getABI() const override { return ABI; } 98 99 ArrayRef<Builtin::Info> getTargetBuiltins() const override; 100 101 bool isCLZForZeroUndef() const override { return false; } 102 103 void getTargetDefines(const LangOptions &Opts, 104 MacroBuilder &Builder) const override; 105 106 bool 107 initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 108 StringRef CPU, 109 const std::vector<std::string> &FeaturesVec) const override; 110 111 bool handleTargetFeatures(std::vector<std::string> &Features, 112 DiagnosticsEngine &Diags) override; 113 114 bool hasFeature(StringRef Feature) const override; 115 116 void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name, 117 bool Enabled) const override; 118 119 ArrayRef<const char *> getGCCRegNames() const override; 120 121 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override; 122 123 bool validateAsmConstraint(const char *&Name, 124 TargetInfo::ConstraintInfo &Info) const override { 125 switch (*Name) { 126 default: 127 return false; 128 case 'O': // Zero 129 break; 130 case 'b': // Base register 131 case 'f': // Floating point register 132 Info.setAllowsRegister(); 133 break; 134 // FIXME: The following are added to allow parsing. 135 // I just took a guess at what the actions should be. 136 // Also, is more specific checking needed? I.e. specific registers? 137 case 'd': // Floating point register (containing 64-bit value) 138 case 'v': // Altivec vector register 139 Info.setAllowsRegister(); 140 break; 141 case 'w': 142 switch (Name[1]) { 143 case 'd': // VSX vector register to hold vector double data 144 case 'f': // VSX vector register to hold vector float data 145 case 's': // VSX vector register to hold scalar float data 146 case 'a': // Any VSX register 147 case 'c': // An individual CR bit 148 break; 149 default: 150 return false; 151 } 152 Info.setAllowsRegister(); 153 Name++; // Skip over 'w'. 154 break; 155 case 'h': // `MQ', `CTR', or `LINK' register 156 case 'q': // `MQ' register 157 case 'c': // `CTR' register 158 case 'l': // `LINK' register 159 case 'x': // `CR' register (condition register) number 0 160 case 'y': // `CR' register (condition register) 161 case 'z': // `XER[CA]' carry bit (part of the XER register) 162 Info.setAllowsRegister(); 163 break; 164 case 'I': // Signed 16-bit constant 165 case 'J': // Unsigned 16-bit constant shifted left 16 bits 166 // (use `L' instead for SImode constants) 167 case 'K': // Unsigned 16-bit constant 168 case 'L': // Signed 16-bit constant shifted left 16 bits 169 case 'M': // Constant larger than 31 170 case 'N': // Exact power of 2 171 case 'P': // Constant whose negation is a signed 16-bit constant 172 case 'G': // Floating point constant that can be loaded into a 173 // register with one instruction per word 174 case 'H': // Integer/Floating point constant that can be loaded 175 // into a register using three instructions 176 break; 177 case 'm': // Memory operand. Note that on PowerPC targets, m can 178 // include addresses that update the base register. It 179 // is therefore only safe to use `m' in an asm statement 180 // if that asm statement accesses the operand exactly once. 181 // The asm statement must also use `%U<opno>' as a 182 // placeholder for the "update" flag in the corresponding 183 // load or store instruction. For example: 184 // asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val)); 185 // is correct but: 186 // asm ("st %1,%0" : "=m" (mem) : "r" (val)); 187 // is not. Use es rather than m if you don't want the base 188 // register to be updated. 189 case 'e': 190 if (Name[1] != 's') 191 return false; 192 // es: A "stable" memory operand; that is, one which does not 193 // include any automodification of the base register. Unlike 194 // `m', this constraint can be used in asm statements that 195 // might access the operand several times, or that might not 196 // access it at all. 197 Info.setAllowsMemory(); 198 Name++; // Skip over 'e'. 199 break; 200 case 'Q': // Memory operand that is an offset from a register (it is 201 // usually better to use `m' or `es' in asm statements) 202 case 'Z': // Memory operand that is an indexed or indirect from a 203 // register (it is usually better to use `m' or `es' in 204 // asm statements) 205 Info.setAllowsMemory(); 206 Info.setAllowsRegister(); 207 break; 208 case 'R': // AIX TOC entry 209 case 'a': // Address operand that is an indexed or indirect from a 210 // register (`p' is preferable for asm statements) 211 case 'S': // Constant suitable as a 64-bit mask operand 212 case 'T': // Constant suitable as a 32-bit mask operand 213 case 'U': // System V Release 4 small data area reference 214 case 't': // AND masks that can be performed by two rldic{l, r} 215 // instructions 216 case 'W': // Vector constant that does not require memory 217 case 'j': // Vector constant that is all zeros. 218 break; 219 // End FIXME. 220 } 221 return true; 222 } 223 224 std::string convertConstraint(const char *&Constraint) const override { 225 std::string R; 226 switch (*Constraint) { 227 case 'e': 228 case 'w': 229 // Two-character constraint; add "^" hint for later parsing. 230 R = std::string("^") + std::string(Constraint, 2); 231 Constraint++; 232 break; 233 default: 234 return TargetInfo::convertConstraint(Constraint); 235 } 236 return R; 237 } 238 239 const char *getClobbers() const override { return ""; } 240 int getEHDataRegisterNumber(unsigned RegNo) const override { 241 if (RegNo == 0) 242 return 3; 243 if (RegNo == 1) 244 return 4; 245 return -1; 246 } 247 248 bool hasSjLjLowering() const override { return true; } 249 250 bool useFloat128ManglingForLongDouble() const override { 251 return LongDoubleWidth == 128 && 252 LongDoubleFormat == &llvm::APFloat::PPCDoubleDouble() && 253 getTriple().isOSBinFormatELF(); 254 } 255 }; 256 257 class LLVM_LIBRARY_VISIBILITY PPC32TargetInfo : public PPCTargetInfo { 258 public: 259 PPC32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 260 : PPCTargetInfo(Triple, Opts) { 261 resetDataLayout("E-m:e-p:32:32-i64:64-n32"); 262 263 switch (getTriple().getOS()) { 264 case llvm::Triple::Linux: 265 case llvm::Triple::FreeBSD: 266 case llvm::Triple::NetBSD: 267 SizeType = UnsignedInt; 268 PtrDiffType = SignedInt; 269 IntPtrType = SignedInt; 270 break; 271 default: 272 break; 273 } 274 275 if (getTriple().getOS() == llvm::Triple::FreeBSD) { 276 LongDoubleWidth = LongDoubleAlign = 64; 277 LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 278 } 279 280 // PPC32 supports atomics up to 4 bytes. 281 MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; 282 } 283 284 BuiltinVaListKind getBuiltinVaListKind() const override { 285 // This is the ELF definition, and is overridden by the Darwin sub-target 286 return TargetInfo::PowerABIBuiltinVaList; 287 } 288 }; 289 290 // Note: ABI differences may eventually require us to have a separate 291 // TargetInfo for little endian. 292 class LLVM_LIBRARY_VISIBILITY PPC64TargetInfo : public PPCTargetInfo { 293 public: 294 PPC64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 295 : PPCTargetInfo(Triple, Opts) { 296 LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 297 IntMaxType = SignedLong; 298 Int64Type = SignedLong; 299 300 if ((Triple.getArch() == llvm::Triple::ppc64le)) { 301 resetDataLayout("e-m:e-i64:64-n32:64"); 302 ABI = "elfv2"; 303 } else { 304 resetDataLayout("E-m:e-i64:64-n32:64"); 305 ABI = "elfv1"; 306 } 307 308 switch (getTriple().getOS()) { 309 case llvm::Triple::FreeBSD: 310 LongDoubleWidth = LongDoubleAlign = 64; 311 LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 312 break; 313 case llvm::Triple::NetBSD: 314 IntMaxType = SignedLongLong; 315 Int64Type = SignedLongLong; 316 break; 317 default: 318 break; 319 } 320 321 // PPC64 supports atomics up to 8 bytes. 322 MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; 323 } 324 325 BuiltinVaListKind getBuiltinVaListKind() const override { 326 return TargetInfo::CharPtrBuiltinVaList; 327 } 328 329 // PPC64 Linux-specific ABI options. 330 bool setABI(const std::string &Name) override { 331 if (Name == "elfv1" || Name == "elfv1-qpx" || Name == "elfv2") { 332 ABI = Name; 333 return true; 334 } 335 return false; 336 } 337 }; 338 339 class LLVM_LIBRARY_VISIBILITY DarwinPPC32TargetInfo 340 : public DarwinTargetInfo<PPC32TargetInfo> { 341 public: 342 DarwinPPC32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 343 : DarwinTargetInfo<PPC32TargetInfo>(Triple, Opts) { 344 HasAlignMac68kSupport = true; 345 BoolWidth = BoolAlign = 32; // XXX support -mone-byte-bool? 346 PtrDiffType = SignedInt; // for http://llvm.org/bugs/show_bug.cgi?id=15726 347 LongLongAlign = 32; 348 resetDataLayout("E-m:o-p:32:32-f64:32:64-n32"); 349 } 350 351 BuiltinVaListKind getBuiltinVaListKind() const override { 352 return TargetInfo::CharPtrBuiltinVaList; 353 } 354 }; 355 356 class LLVM_LIBRARY_VISIBILITY DarwinPPC64TargetInfo 357 : public DarwinTargetInfo<PPC64TargetInfo> { 358 public: 359 DarwinPPC64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 360 : DarwinTargetInfo<PPC64TargetInfo>(Triple, Opts) { 361 HasAlignMac68kSupport = true; 362 resetDataLayout("E-m:o-i64:64-n32:64"); 363 } 364 }; 365 366 } // namespace targets 367 } // namespace clang 368 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_PPC_H 369