Erich Keane | ebba592 | 2017-07-21 22:37:03 +0000 | [diff] [blame] | 1 | //===--- PPC.cpp - Implement PPC target feature support -------------------===// |
| 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 implements PPC TargetInfo objects. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #include "PPC.h" |
| 15 | #include "clang/Basic/Diagnostic.h" |
| 16 | #include "clang/Basic/MacroBuilder.h" |
| 17 | #include "clang/Basic/TargetBuiltins.h" |
| 18 | #include "llvm/ADT/StringSwitch.h" |
| 19 | |
| 20 | using namespace clang; |
| 21 | using namespace clang::targets; |
| 22 | |
| 23 | const Builtin::Info PPCTargetInfo::BuiltinInfo[] = { |
| 24 | #define BUILTIN(ID, TYPE, ATTRS) \ |
| 25 | {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, |
| 26 | #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ |
| 27 | {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, |
| 28 | #include "clang/Basic/BuiltinsPPC.def" |
| 29 | }; |
| 30 | |
| 31 | /// handleTargetFeatures - Perform initialization based on the user |
| 32 | /// configured set of features. |
| 33 | bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, |
| 34 | DiagnosticsEngine &Diags) { |
| 35 | for (const auto &Feature : Features) { |
| 36 | if (Feature == "+altivec") { |
| 37 | HasAltivec = true; |
| 38 | } else if (Feature == "+vsx") { |
| 39 | HasVSX = true; |
| 40 | } else if (Feature == "+bpermd") { |
| 41 | HasBPERMD = true; |
| 42 | } else if (Feature == "+extdiv") { |
| 43 | HasExtDiv = true; |
| 44 | } else if (Feature == "+power8-vector") { |
| 45 | HasP8Vector = true; |
| 46 | } else if (Feature == "+crypto") { |
| 47 | HasP8Crypto = true; |
| 48 | } else if (Feature == "+direct-move") { |
| 49 | HasDirectMove = true; |
| 50 | } else if (Feature == "+qpx") { |
| 51 | HasQPX = true; |
| 52 | } else if (Feature == "+htm") { |
| 53 | HasHTM = true; |
| 54 | } else if (Feature == "+float128") { |
| 55 | HasFloat128 = true; |
| 56 | } else if (Feature == "+power9-vector") { |
| 57 | HasP9Vector = true; |
| 58 | } |
| 59 | // TODO: Finish this list and add an assert that we've handled them |
| 60 | // all. |
| 61 | } |
| 62 | |
| 63 | return true; |
| 64 | } |
| 65 | |
| 66 | /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific |
| 67 | /// #defines that are not tied to a specific subtarget. |
| 68 | void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, |
| 69 | MacroBuilder &Builder) const { |
| 70 | // Target identification. |
| 71 | Builder.defineMacro("__ppc__"); |
| 72 | Builder.defineMacro("__PPC__"); |
| 73 | Builder.defineMacro("_ARCH_PPC"); |
| 74 | Builder.defineMacro("__powerpc__"); |
| 75 | Builder.defineMacro("__POWERPC__"); |
| 76 | if (PointerWidth == 64) { |
| 77 | Builder.defineMacro("_ARCH_PPC64"); |
| 78 | Builder.defineMacro("__powerpc64__"); |
| 79 | Builder.defineMacro("__ppc64__"); |
| 80 | Builder.defineMacro("__PPC64__"); |
| 81 | } |
| 82 | |
| 83 | // Target properties. |
| 84 | if (getTriple().getArch() == llvm::Triple::ppc64le) { |
| 85 | Builder.defineMacro("_LITTLE_ENDIAN"); |
| 86 | } else { |
| 87 | if (getTriple().getOS() != llvm::Triple::NetBSD && |
| 88 | getTriple().getOS() != llvm::Triple::OpenBSD) |
| 89 | Builder.defineMacro("_BIG_ENDIAN"); |
| 90 | } |
| 91 | |
| 92 | // ABI options. |
| 93 | if (ABI == "elfv1" || ABI == "elfv1-qpx") |
| 94 | Builder.defineMacro("_CALL_ELF", "1"); |
| 95 | if (ABI == "elfv2") |
| 96 | Builder.defineMacro("_CALL_ELF", "2"); |
| 97 | |
| 98 | // This typically is only for a new enough linker (bfd >= 2.16.2 or gold), but |
Alexander Kornienko | 2a8c18d | 2018-04-06 15:14:32 +0000 | [diff] [blame^] | 99 | // our support post-dates this and it should work on all 64-bit ppc linux |
Erich Keane | ebba592 | 2017-07-21 22:37:03 +0000 | [diff] [blame] | 100 | // platforms. It is guaranteed to work on all elfv2 platforms. |
| 101 | if (getTriple().getOS() == llvm::Triple::Linux && PointerWidth == 64) |
| 102 | Builder.defineMacro("_CALL_LINUX", "1"); |
| 103 | |
| 104 | // Subtarget options. |
| 105 | Builder.defineMacro("__NATURAL_ALIGNMENT__"); |
| 106 | Builder.defineMacro("__REGISTER_PREFIX__", ""); |
| 107 | |
| 108 | // FIXME: Should be controlled by command line option. |
| 109 | if (LongDoubleWidth == 128) { |
| 110 | Builder.defineMacro("__LONG_DOUBLE_128__"); |
| 111 | Builder.defineMacro("__LONGDOUBLE128"); |
| 112 | } |
| 113 | |
| 114 | // Define this for elfv2 (64-bit only) or 64-bit darwin. |
| 115 | if (ABI == "elfv2" || |
| 116 | (getTriple().getOS() == llvm::Triple::Darwin && PointerWidth == 64)) |
| 117 | Builder.defineMacro("__STRUCT_PARM_ALIGN__", "16"); |
| 118 | |
| 119 | // CPU identification. |
| 120 | ArchDefineTypes defs = |
| 121 | (ArchDefineTypes)llvm::StringSwitch<int>(CPU) |
| 122 | .Case("440", ArchDefineName) |
| 123 | .Case("450", ArchDefineName | ArchDefine440) |
| 124 | .Case("601", ArchDefineName) |
| 125 | .Case("602", ArchDefineName | ArchDefinePpcgr) |
| 126 | .Case("603", ArchDefineName | ArchDefinePpcgr) |
| 127 | .Case("603e", ArchDefineName | ArchDefine603 | ArchDefinePpcgr) |
| 128 | .Case("603ev", ArchDefineName | ArchDefine603 | ArchDefinePpcgr) |
| 129 | .Case("604", ArchDefineName | ArchDefinePpcgr) |
| 130 | .Case("604e", ArchDefineName | ArchDefine604 | ArchDefinePpcgr) |
| 131 | .Case("620", ArchDefineName | ArchDefinePpcgr) |
| 132 | .Case("630", ArchDefineName | ArchDefinePpcgr) |
| 133 | .Case("7400", ArchDefineName | ArchDefinePpcgr) |
| 134 | .Case("7450", ArchDefineName | ArchDefinePpcgr) |
| 135 | .Case("750", ArchDefineName | ArchDefinePpcgr) |
| 136 | .Case("970", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr | |
| 137 | ArchDefinePpcsq) |
| 138 | .Case("a2", ArchDefineA2) |
| 139 | .Case("a2q", ArchDefineName | ArchDefineA2 | ArchDefineA2q) |
| 140 | .Case("pwr3", ArchDefinePpcgr) |
| 141 | .Case("pwr4", ArchDefineName | ArchDefinePpcgr | ArchDefinePpcsq) |
| 142 | .Case("pwr5", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr | |
| 143 | ArchDefinePpcsq) |
| 144 | .Case("pwr5x", ArchDefineName | ArchDefinePwr5 | ArchDefinePwr4 | |
| 145 | ArchDefinePpcgr | ArchDefinePpcsq) |
| 146 | .Case("pwr6", ArchDefineName | ArchDefinePwr5x | ArchDefinePwr5 | |
| 147 | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) |
| 148 | .Case("pwr6x", ArchDefineName | ArchDefinePwr6 | ArchDefinePwr5x | |
| 149 | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | |
| 150 | ArchDefinePpcsq) |
| 151 | .Case("pwr7", ArchDefineName | ArchDefinePwr6x | ArchDefinePwr6 | |
| 152 | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | |
| 153 | ArchDefinePpcgr | ArchDefinePpcsq) |
| 154 | .Case("pwr8", ArchDefineName | ArchDefinePwr7 | ArchDefinePwr6x | |
| 155 | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 | |
| 156 | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) |
| 157 | .Case("pwr9", ArchDefineName | ArchDefinePwr8 | ArchDefinePwr7 | |
| 158 | ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x | |
| 159 | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | |
| 160 | ArchDefinePpcsq) |
| 161 | .Case("power3", ArchDefinePpcgr) |
| 162 | .Case("power4", ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) |
| 163 | .Case("power5", ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | |
| 164 | ArchDefinePpcsq) |
| 165 | .Case("power5x", ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | |
| 166 | ArchDefinePpcgr | ArchDefinePpcsq) |
| 167 | .Case("power6", ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 | |
| 168 | ArchDefinePwr4 | ArchDefinePpcgr | |
| 169 | ArchDefinePpcsq) |
| 170 | .Case("power6x", ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x | |
| 171 | ArchDefinePwr5 | ArchDefinePwr4 | |
| 172 | ArchDefinePpcgr | ArchDefinePpcsq) |
| 173 | .Case("power7", ArchDefinePwr7 | ArchDefinePwr6x | ArchDefinePwr6 | |
| 174 | ArchDefinePwr5x | ArchDefinePwr5 | |
| 175 | ArchDefinePwr4 | ArchDefinePpcgr | |
| 176 | ArchDefinePpcsq) |
| 177 | .Case("power8", ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6x | |
| 178 | ArchDefinePwr6 | ArchDefinePwr5x | |
| 179 | ArchDefinePwr5 | ArchDefinePwr4 | |
| 180 | ArchDefinePpcgr | ArchDefinePpcsq) |
| 181 | .Case("power9", ArchDefinePwr9 | ArchDefinePwr8 | ArchDefinePwr7 | |
| 182 | ArchDefinePwr6x | ArchDefinePwr6 | |
| 183 | ArchDefinePwr5x | ArchDefinePwr5 | |
| 184 | ArchDefinePwr4 | ArchDefinePpcgr | |
| 185 | ArchDefinePpcsq) |
| 186 | // powerpc64le automatically defaults to at least power8. |
| 187 | .Case("ppc64le", ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6x | |
| 188 | ArchDefinePwr6 | ArchDefinePwr5x | |
| 189 | ArchDefinePwr5 | ArchDefinePwr4 | |
| 190 | ArchDefinePpcgr | ArchDefinePpcsq) |
| 191 | .Default(ArchDefineNone); |
| 192 | |
| 193 | if (defs & ArchDefineName) |
| 194 | Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper())); |
| 195 | if (defs & ArchDefinePpcgr) |
| 196 | Builder.defineMacro("_ARCH_PPCGR"); |
| 197 | if (defs & ArchDefinePpcsq) |
| 198 | Builder.defineMacro("_ARCH_PPCSQ"); |
| 199 | if (defs & ArchDefine440) |
| 200 | Builder.defineMacro("_ARCH_440"); |
| 201 | if (defs & ArchDefine603) |
| 202 | Builder.defineMacro("_ARCH_603"); |
| 203 | if (defs & ArchDefine604) |
| 204 | Builder.defineMacro("_ARCH_604"); |
| 205 | if (defs & ArchDefinePwr4) |
| 206 | Builder.defineMacro("_ARCH_PWR4"); |
| 207 | if (defs & ArchDefinePwr5) |
| 208 | Builder.defineMacro("_ARCH_PWR5"); |
| 209 | if (defs & ArchDefinePwr5x) |
| 210 | Builder.defineMacro("_ARCH_PWR5X"); |
| 211 | if (defs & ArchDefinePwr6) |
| 212 | Builder.defineMacro("_ARCH_PWR6"); |
| 213 | if (defs & ArchDefinePwr6x) |
| 214 | Builder.defineMacro("_ARCH_PWR6X"); |
| 215 | if (defs & ArchDefinePwr7) |
| 216 | Builder.defineMacro("_ARCH_PWR7"); |
| 217 | if (defs & ArchDefinePwr8) |
| 218 | Builder.defineMacro("_ARCH_PWR8"); |
| 219 | if (defs & ArchDefinePwr9) |
| 220 | Builder.defineMacro("_ARCH_PWR9"); |
| 221 | if (defs & ArchDefineA2) |
| 222 | Builder.defineMacro("_ARCH_A2"); |
| 223 | if (defs & ArchDefineA2q) { |
| 224 | Builder.defineMacro("_ARCH_A2Q"); |
| 225 | Builder.defineMacro("_ARCH_QP"); |
| 226 | } |
| 227 | |
| 228 | if (getTriple().getVendor() == llvm::Triple::BGQ) { |
| 229 | Builder.defineMacro("__bg__"); |
| 230 | Builder.defineMacro("__THW_BLUEGENE__"); |
| 231 | Builder.defineMacro("__bgq__"); |
| 232 | Builder.defineMacro("__TOS_BGQ__"); |
| 233 | } |
| 234 | |
| 235 | if (HasAltivec) { |
| 236 | Builder.defineMacro("__VEC__", "10206"); |
| 237 | Builder.defineMacro("__ALTIVEC__"); |
| 238 | } |
| 239 | if (HasVSX) |
| 240 | Builder.defineMacro("__VSX__"); |
| 241 | if (HasP8Vector) |
| 242 | Builder.defineMacro("__POWER8_VECTOR__"); |
| 243 | if (HasP8Crypto) |
| 244 | Builder.defineMacro("__CRYPTO__"); |
| 245 | if (HasHTM) |
| 246 | Builder.defineMacro("__HTM__"); |
| 247 | if (HasFloat128) |
| 248 | Builder.defineMacro("__FLOAT128__"); |
| 249 | if (HasP9Vector) |
| 250 | Builder.defineMacro("__POWER9_VECTOR__"); |
| 251 | |
| 252 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); |
| 253 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); |
| 254 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); |
| 255 | if (PointerWidth == 64) |
| 256 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); |
| 257 | |
| 258 | // We have support for the bswap intrinsics so we can define this. |
| 259 | Builder.defineMacro("__HAVE_BSWAP__", "1"); |
| 260 | |
| 261 | // FIXME: The following are not yet generated here by Clang, but are |
| 262 | // generated by GCC: |
| 263 | // |
| 264 | // _SOFT_FLOAT_ |
| 265 | // __RECIP_PRECISION__ |
| 266 | // __APPLE_ALTIVEC__ |
| 267 | // __RECIP__ |
| 268 | // __RECIPF__ |
| 269 | // __RSQRTE__ |
| 270 | // __RSQRTEF__ |
| 271 | // _SOFT_DOUBLE_ |
| 272 | // __NO_LWSYNC__ |
| 273 | // __CMODEL_MEDIUM__ |
| 274 | // __CMODEL_LARGE__ |
| 275 | // _CALL_SYSV |
| 276 | // _CALL_DARWIN |
| 277 | // __NO_FPRS__ |
| 278 | } |
| 279 | |
| 280 | // Handle explicit options being passed to the compiler here: if we've |
| 281 | // explicitly turned off vsx and turned on any of: |
| 282 | // - power8-vector |
| 283 | // - direct-move |
| 284 | // - float128 |
| 285 | // - power9-vector |
| 286 | // then go ahead and error since the customer has expressed an incompatible |
| 287 | // set of options. |
| 288 | static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags, |
| 289 | const std::vector<std::string> &FeaturesVec) { |
| 290 | |
| 291 | if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "-vsx") != |
| 292 | FeaturesVec.end()) { |
| 293 | if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+power8-vector") != |
| 294 | FeaturesVec.end()) { |
| 295 | Diags.Report(diag::err_opt_not_valid_with_opt) << "-mpower8-vector" |
| 296 | << "-mno-vsx"; |
| 297 | return false; |
| 298 | } |
| 299 | |
| 300 | if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+direct-move") != |
| 301 | FeaturesVec.end()) { |
| 302 | Diags.Report(diag::err_opt_not_valid_with_opt) << "-mdirect-move" |
| 303 | << "-mno-vsx"; |
| 304 | return false; |
| 305 | } |
| 306 | |
| 307 | if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+float128") != |
| 308 | FeaturesVec.end()) { |
| 309 | Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" |
| 310 | << "-mno-vsx"; |
| 311 | return false; |
| 312 | } |
| 313 | |
| 314 | if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+power9-vector") != |
| 315 | FeaturesVec.end()) { |
| 316 | Diags.Report(diag::err_opt_not_valid_with_opt) << "-mpower9-vector" |
| 317 | << "-mno-vsx"; |
| 318 | return false; |
| 319 | } |
| 320 | } |
| 321 | |
| 322 | return true; |
| 323 | } |
| 324 | |
| 325 | bool PPCTargetInfo::initFeatureMap( |
| 326 | llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, |
| 327 | const std::vector<std::string> &FeaturesVec) const { |
| 328 | Features["altivec"] = llvm::StringSwitch<bool>(CPU) |
| 329 | .Case("7400", true) |
| 330 | .Case("g4", true) |
| 331 | .Case("7450", true) |
| 332 | .Case("g4+", true) |
| 333 | .Case("970", true) |
| 334 | .Case("g5", true) |
| 335 | .Case("pwr6", true) |
| 336 | .Case("pwr7", true) |
| 337 | .Case("pwr8", true) |
| 338 | .Case("pwr9", true) |
| 339 | .Case("ppc64", true) |
| 340 | .Case("ppc64le", true) |
| 341 | .Default(false); |
| 342 | |
| 343 | Features["qpx"] = (CPU == "a2q"); |
| 344 | Features["power9-vector"] = (CPU == "pwr9"); |
| 345 | Features["crypto"] = llvm::StringSwitch<bool>(CPU) |
| 346 | .Case("ppc64le", true) |
| 347 | .Case("pwr9", true) |
| 348 | .Case("pwr8", true) |
| 349 | .Default(false); |
| 350 | Features["power8-vector"] = llvm::StringSwitch<bool>(CPU) |
| 351 | .Case("ppc64le", true) |
| 352 | .Case("pwr9", true) |
| 353 | .Case("pwr8", true) |
| 354 | .Default(false); |
| 355 | Features["bpermd"] = llvm::StringSwitch<bool>(CPU) |
| 356 | .Case("ppc64le", true) |
| 357 | .Case("pwr9", true) |
| 358 | .Case("pwr8", true) |
| 359 | .Case("pwr7", true) |
| 360 | .Default(false); |
| 361 | Features["extdiv"] = llvm::StringSwitch<bool>(CPU) |
| 362 | .Case("ppc64le", true) |
| 363 | .Case("pwr9", true) |
| 364 | .Case("pwr8", true) |
| 365 | .Case("pwr7", true) |
| 366 | .Default(false); |
| 367 | Features["direct-move"] = llvm::StringSwitch<bool>(CPU) |
| 368 | .Case("ppc64le", true) |
| 369 | .Case("pwr9", true) |
| 370 | .Case("pwr8", true) |
| 371 | .Default(false); |
| 372 | Features["vsx"] = llvm::StringSwitch<bool>(CPU) |
| 373 | .Case("ppc64le", true) |
| 374 | .Case("pwr9", true) |
| 375 | .Case("pwr8", true) |
| 376 | .Case("pwr7", true) |
| 377 | .Default(false); |
| 378 | Features["htm"] = llvm::StringSwitch<bool>(CPU) |
| 379 | .Case("ppc64le", true) |
| 380 | .Case("pwr9", true) |
| 381 | .Case("pwr8", true) |
| 382 | .Default(false); |
| 383 | |
| 384 | if (!ppcUserFeaturesCheck(Diags, FeaturesVec)) |
| 385 | return false; |
| 386 | |
| 387 | return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); |
| 388 | } |
| 389 | |
| 390 | bool PPCTargetInfo::hasFeature(StringRef Feature) const { |
| 391 | return llvm::StringSwitch<bool>(Feature) |
| 392 | .Case("powerpc", true) |
| 393 | .Case("altivec", HasAltivec) |
| 394 | .Case("vsx", HasVSX) |
| 395 | .Case("power8-vector", HasP8Vector) |
| 396 | .Case("crypto", HasP8Crypto) |
| 397 | .Case("direct-move", HasDirectMove) |
| 398 | .Case("qpx", HasQPX) |
| 399 | .Case("htm", HasHTM) |
| 400 | .Case("bpermd", HasBPERMD) |
| 401 | .Case("extdiv", HasExtDiv) |
| 402 | .Case("float128", HasFloat128) |
| 403 | .Case("power9-vector", HasP9Vector) |
| 404 | .Default(false); |
| 405 | } |
| 406 | |
| 407 | void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, |
| 408 | StringRef Name, bool Enabled) const { |
| 409 | if (Enabled) { |
| 410 | // If we're enabling any of the vsx based features then enable vsx and |
| 411 | // altivec. We'll diagnose any problems later. |
| 412 | bool FeatureHasVSX = llvm::StringSwitch<bool>(Name) |
| 413 | .Case("vsx", true) |
| 414 | .Case("direct-move", true) |
| 415 | .Case("power8-vector", true) |
| 416 | .Case("power9-vector", true) |
| 417 | .Case("float128", true) |
| 418 | .Default(false); |
| 419 | if (FeatureHasVSX) |
| 420 | Features["vsx"] = Features["altivec"] = true; |
| 421 | if (Name == "power9-vector") |
| 422 | Features["power8-vector"] = true; |
| 423 | Features[Name] = true; |
| 424 | } else { |
| 425 | // If we're disabling altivec or vsx go ahead and disable all of the vsx |
| 426 | // features. |
| 427 | if ((Name == "altivec") || (Name == "vsx")) |
| 428 | Features["vsx"] = Features["direct-move"] = Features["power8-vector"] = |
| 429 | Features["float128"] = Features["power9-vector"] = false; |
| 430 | if (Name == "power8-vector") |
| 431 | Features["power9-vector"] = false; |
| 432 | Features[Name] = false; |
| 433 | } |
| 434 | } |
| 435 | |
| 436 | const char *const PPCTargetInfo::GCCRegNames[] = { |
| 437 | "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", |
| 438 | "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", |
| 439 | "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", |
| 440 | "r27", "r28", "r29", "r30", "r31", "f0", "f1", "f2", "f3", |
| 441 | "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", |
| 442 | "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", |
| 443 | "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", |
| 444 | "f31", "mq", "lr", "ctr", "ap", "cr0", "cr1", "cr2", "cr3", |
| 445 | "cr4", "cr5", "cr6", "cr7", "xer", "v0", "v1", "v2", "v3", |
| 446 | "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", |
| 447 | "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", |
| 448 | "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", |
| 449 | "v31", "vrsave", "vscr", "spe_acc", "spefscr", "sfp" |
| 450 | }; |
| 451 | |
| 452 | ArrayRef<const char *> PPCTargetInfo::getGCCRegNames() const { |
| 453 | return llvm::makeArrayRef(GCCRegNames); |
| 454 | } |
| 455 | |
| 456 | const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = { |
| 457 | // While some of these aliases do map to different registers |
| 458 | // they still share the same register name. |
| 459 | {{"0"}, "r0"}, {{"1"}, "r1"}, {{"2"}, "r2"}, {{"3"}, "r3"}, |
| 460 | {{"4"}, "r4"}, {{"5"}, "r5"}, {{"6"}, "r6"}, {{"7"}, "r7"}, |
| 461 | {{"8"}, "r8"}, {{"9"}, "r9"}, {{"10"}, "r10"}, {{"11"}, "r11"}, |
| 462 | {{"12"}, "r12"}, {{"13"}, "r13"}, {{"14"}, "r14"}, {{"15"}, "r15"}, |
| 463 | {{"16"}, "r16"}, {{"17"}, "r17"}, {{"18"}, "r18"}, {{"19"}, "r19"}, |
| 464 | {{"20"}, "r20"}, {{"21"}, "r21"}, {{"22"}, "r22"}, {{"23"}, "r23"}, |
| 465 | {{"24"}, "r24"}, {{"25"}, "r25"}, {{"26"}, "r26"}, {{"27"}, "r27"}, |
| 466 | {{"28"}, "r28"}, {{"29"}, "r29"}, {{"30"}, "r30"}, {{"31"}, "r31"}, |
| 467 | {{"fr0"}, "f0"}, {{"fr1"}, "f1"}, {{"fr2"}, "f2"}, {{"fr3"}, "f3"}, |
| 468 | {{"fr4"}, "f4"}, {{"fr5"}, "f5"}, {{"fr6"}, "f6"}, {{"fr7"}, "f7"}, |
| 469 | {{"fr8"}, "f8"}, {{"fr9"}, "f9"}, {{"fr10"}, "f10"}, {{"fr11"}, "f11"}, |
| 470 | {{"fr12"}, "f12"}, {{"fr13"}, "f13"}, {{"fr14"}, "f14"}, {{"fr15"}, "f15"}, |
| 471 | {{"fr16"}, "f16"}, {{"fr17"}, "f17"}, {{"fr18"}, "f18"}, {{"fr19"}, "f19"}, |
| 472 | {{"fr20"}, "f20"}, {{"fr21"}, "f21"}, {{"fr22"}, "f22"}, {{"fr23"}, "f23"}, |
| 473 | {{"fr24"}, "f24"}, {{"fr25"}, "f25"}, {{"fr26"}, "f26"}, {{"fr27"}, "f27"}, |
| 474 | {{"fr28"}, "f28"}, {{"fr29"}, "f29"}, {{"fr30"}, "f30"}, {{"fr31"}, "f31"}, |
| 475 | {{"cc"}, "cr0"}, |
| 476 | }; |
| 477 | |
| 478 | ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const { |
| 479 | return llvm::makeArrayRef(GCCRegAliases); |
| 480 | } |
| 481 | |
Erich Keane | e44bdb3 | 2018-02-08 23:16:55 +0000 | [diff] [blame] | 482 | static constexpr llvm::StringLiteral ValidCPUNames[] = { |
| 483 | {"generic"}, {"440"}, {"450"}, {"601"}, {"602"}, |
| 484 | {"603"}, {"603e"}, {"603ev"}, {"604"}, {"604e"}, |
| 485 | {"620"}, {"630"}, {"g3"}, {"7400"}, {"g4"}, |
| 486 | {"7450"}, {"g4+"}, {"750"}, {"970"}, {"g5"}, |
| 487 | {"a2"}, {"a2q"}, {"e500mc"}, {"e5500"}, {"power3"}, |
| 488 | {"pwr3"}, {"power4"}, {"pwr4"}, {"power5"}, {"pwr5"}, |
| 489 | {"power5x"}, {"pwr5x"}, {"power6"}, {"pwr6"}, {"power6x"}, |
| 490 | {"pwr6x"}, {"power7"}, {"pwr7"}, {"power8"}, {"pwr8"}, |
| 491 | {"power9"}, {"pwr9"}, {"powerpc"}, {"ppc"}, {"powerpc64"}, |
| 492 | {"ppc64"}, {"powerpc64le"}, {"ppc64le"}, |
| 493 | }; |
| 494 | |
Erich Keane | ebba592 | 2017-07-21 22:37:03 +0000 | [diff] [blame] | 495 | bool PPCTargetInfo::isValidCPUName(StringRef Name) const { |
Erich Keane | fa69c71 | 2018-02-09 00:13:49 +0000 | [diff] [blame] | 496 | return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames); |
Erich Keane | e44bdb3 | 2018-02-08 23:16:55 +0000 | [diff] [blame] | 497 | } |
| 498 | |
| 499 | void PPCTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { |
| 500 | Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames)); |
Erich Keane | ebba592 | 2017-07-21 22:37:03 +0000 | [diff] [blame] | 501 | } |
| 502 | |
| 503 | void PPCTargetInfo::adjust(LangOptions &Opts) { |
| 504 | if (HasAltivec) |
| 505 | Opts.AltiVec = 1; |
| 506 | TargetInfo::adjust(Opts); |
| 507 | } |
| 508 | |
| 509 | ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const { |
| 510 | return llvm::makeArrayRef(BuiltinInfo, clang::PPC::LastTSBuiltin - |
| 511 | Builtin::FirstTSBuiltin); |
| 512 | } |