| 1 | //===--- PPC.cpp - Implement PPC target feature support -------------------===// |
| 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 implements PPC TargetInfo objects. |
| 10 | // |
| 11 | //===----------------------------------------------------------------------===// |
| 12 | |
| 13 | #include "PPC.h" |
| 14 | #include "clang/Basic/Diagnostic.h" |
| 15 | #include "clang/Basic/MacroBuilder.h" |
| 16 | #include "clang/Basic/TargetBuiltins.h" |
| 17 | #include "llvm/TargetParser/PPCTargetParser.h" |
| 18 | #include <optional> |
| 19 | |
| 20 | using namespace clang; |
| 21 | using namespace clang::targets; |
| 22 | |
| 23 | static constexpr int NumBuiltins = |
| 24 | clang::PPC::LastTSBuiltin - Builtin::FirstTSBuiltin; |
| 25 | |
| 26 | static constexpr llvm::StringTable BuiltinStrings = |
| 27 | CLANG_BUILTIN_STR_TABLE_START |
| 28 | #define BUILTIN CLANG_BUILTIN_STR_TABLE |
| 29 | #define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE |
| 30 | #include "clang/Basic/BuiltinsPPC.def" |
| 31 | ; |
| 32 | |
| 33 | static constexpr auto BuiltinInfos = Builtin::MakeInfos<NumBuiltins>(Infos: { |
| 34 | #define BUILTIN CLANG_BUILTIN_ENTRY |
| 35 | #define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY |
| 36 | #define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY |
| 37 | #include "clang/Basic/BuiltinsPPC.def" |
| 38 | }); |
| 39 | |
| 40 | /// handleTargetFeatures - Perform initialization based on the user |
| 41 | /// configured set of features. |
| 42 | bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, |
| 43 | DiagnosticsEngine &Diags) { |
| 44 | FloatABI = HardFloat; |
| 45 | for (const auto &Feature : Features) { |
| 46 | if (Feature == "+altivec" ) { |
| 47 | HasAltivec = true; |
| 48 | } else if (Feature == "+vsx" ) { |
| 49 | HasVSX = true; |
| 50 | } else if (Feature == "+power8-vector" ) { |
| 51 | HasP8Vector = true; |
| 52 | } else if (Feature == "+crypto" ) { |
| 53 | HasP8Crypto = true; |
| 54 | } else if (Feature == "+htm" ) { |
| 55 | HasHTM = true; |
| 56 | } else if (Feature == "+float128" ) { |
| 57 | HasFloat128 = !getTriple().isOSAIX(); |
| 58 | } else if (Feature == "+power9-vector" ) { |
| 59 | HasP9Vector = true; |
| 60 | } else if (Feature == "+power10-vector" ) { |
| 61 | HasP10Vector = true; |
| 62 | } else if (Feature == "+pcrelative-memops" ) { |
| 63 | HasPCRelativeMemops = true; |
| 64 | } else if (Feature == "+spe" || Feature == "+efpu2" ) { |
| 65 | HasStrictFP = false; |
| 66 | HasSPE = true; |
| 67 | LongDoubleWidth = LongDoubleAlign = 64; |
| 68 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); |
| 69 | } else if (Feature == "+frsqrte" ) { |
| 70 | HasFrsqrte = true; |
| 71 | } else if (Feature == "+frsqrtes" ) { |
| 72 | HasFrsqrtes = true; |
| 73 | } else if (Feature == "-hard-float" ) { |
| 74 | FloatABI = SoftFloat; |
| 75 | } else if (Feature == "+mma" ) { |
| 76 | HasMMA = true; |
| 77 | } else if (Feature == "+rop-protect" ) { |
| 78 | HasROPProtect = true; |
| 79 | } else if (Feature == "+quadword-atomics" ) { |
| 80 | HasQuadwordAtomics = true; |
| 81 | } else if (Feature == "+longcall" ) { |
| 82 | UseLongCalls = true; |
| 83 | } |
| 84 | // TODO: Finish this list and add an assert that we've handled them |
| 85 | // all. |
| 86 | } |
| 87 | |
| 88 | return true; |
| 89 | } |
| 90 | |
| 91 | static void defineXLCompatMacros(MacroBuilder &Builder) { |
| 92 | Builder.defineMacro(Name: "__builtin_national2packed" , |
| 93 | Value: "__builtin_ppc_national2packed" ); |
| 94 | Builder.defineMacro(Name: "__builtin_packed2national" , |
| 95 | Value: "__builtin_ppc_packed2national" ); |
| 96 | Builder.defineMacro(Name: "__builtin_packed2zoned" , Value: "__builtin_ppc_packed2zoned" ); |
| 97 | Builder.defineMacro(Name: "__builtin_zoned2packed" , Value: "__builtin_ppc_zoned2packed" ); |
| 98 | Builder.defineMacro(Name: "__cdtbcd" , Value: "__builtin_ppc_cdtbcd" ); |
| 99 | Builder.defineMacro(Name: "__cbcdtd" , Value: "__builtin_ppc_cbcdtd" ); |
| 100 | Builder.defineMacro(Name: "__addg6s" , Value: "__builtin_ppc_addg6s" ); |
| 101 | Builder.defineMacro(Name: "__popcntb" , Value: "__builtin_ppc_popcntb" ); |
| 102 | Builder.defineMacro(Name: "__poppar4" , Value: "__builtin_ppc_poppar4" ); |
| 103 | Builder.defineMacro(Name: "__poppar8" , Value: "__builtin_ppc_poppar8" ); |
| 104 | Builder.defineMacro(Name: "__eieio" , Value: "__builtin_ppc_eieio" ); |
| 105 | Builder.defineMacro(Name: "__iospace_eieio" , Value: "__builtin_ppc_iospace_eieio" ); |
| 106 | Builder.defineMacro(Name: "__isync" , Value: "__builtin_ppc_isync" ); |
| 107 | Builder.defineMacro(Name: "__lwsync" , Value: "__builtin_ppc_lwsync" ); |
| 108 | Builder.defineMacro(Name: "__iospace_lwsync" , Value: "__builtin_ppc_iospace_lwsync" ); |
| 109 | Builder.defineMacro(Name: "__sync" , Value: "__builtin_ppc_sync" ); |
| 110 | Builder.defineMacro(Name: "__iospace_sync" , Value: "__builtin_ppc_iospace_sync" ); |
| 111 | Builder.defineMacro(Name: "__dcbfl" , Value: "__builtin_ppc_dcbfl" ); |
| 112 | Builder.defineMacro(Name: "__dcbflp" , Value: "__builtin_ppc_dcbflp" ); |
| 113 | Builder.defineMacro(Name: "__dcbst" , Value: "__builtin_ppc_dcbst" ); |
| 114 | Builder.defineMacro(Name: "__dcbt" , Value: "__builtin_ppc_dcbt" ); |
| 115 | Builder.defineMacro(Name: "__dcbtst" , Value: "__builtin_ppc_dcbtst" ); |
| 116 | Builder.defineMacro(Name: "__dcbz" , Value: "__builtin_ppc_dcbz" ); |
| 117 | Builder.defineMacro(Name: "__icbt" , Value: "__builtin_ppc_icbt" ); |
| 118 | Builder.defineMacro(Name: "__compare_and_swap" , Value: "__builtin_ppc_compare_and_swap" ); |
| 119 | Builder.defineMacro(Name: "__compare_and_swaplp" , |
| 120 | Value: "__builtin_ppc_compare_and_swaplp" ); |
| 121 | Builder.defineMacro(Name: "__fetch_and_add" , Value: "__builtin_ppc_fetch_and_add" ); |
| 122 | Builder.defineMacro(Name: "__fetch_and_addlp" , Value: "__builtin_ppc_fetch_and_addlp" ); |
| 123 | Builder.defineMacro(Name: "__fetch_and_and" , Value: "__builtin_ppc_fetch_and_and" ); |
| 124 | Builder.defineMacro(Name: "__fetch_and_andlp" , Value: "__builtin_ppc_fetch_and_andlp" ); |
| 125 | Builder.defineMacro(Name: "__fetch_and_or" , Value: "__builtin_ppc_fetch_and_or" ); |
| 126 | Builder.defineMacro(Name: "__fetch_and_orlp" , Value: "__builtin_ppc_fetch_and_orlp" ); |
| 127 | Builder.defineMacro(Name: "__fetch_and_swap" , Value: "__builtin_ppc_fetch_and_swap" ); |
| 128 | Builder.defineMacro(Name: "__fetch_and_swaplp" , Value: "__builtin_ppc_fetch_and_swaplp" ); |
| 129 | Builder.defineMacro(Name: "__ldarx" , Value: "__builtin_ppc_ldarx" ); |
| 130 | Builder.defineMacro(Name: "__lwarx" , Value: "__builtin_ppc_lwarx" ); |
| 131 | Builder.defineMacro(Name: "__lharx" , Value: "__builtin_ppc_lharx" ); |
| 132 | Builder.defineMacro(Name: "__lbarx" , Value: "__builtin_ppc_lbarx" ); |
| 133 | Builder.defineMacro(Name: "__stfiw" , Value: "__builtin_ppc_stfiw" ); |
| 134 | Builder.defineMacro(Name: "__stdcx" , Value: "__builtin_ppc_stdcx" ); |
| 135 | Builder.defineMacro(Name: "__stwcx" , Value: "__builtin_ppc_stwcx" ); |
| 136 | Builder.defineMacro(Name: "__sthcx" , Value: "__builtin_ppc_sthcx" ); |
| 137 | Builder.defineMacro(Name: "__stbcx" , Value: "__builtin_ppc_stbcx" ); |
| 138 | Builder.defineMacro(Name: "__tdw" , Value: "__builtin_ppc_tdw" ); |
| 139 | Builder.defineMacro(Name: "__tw" , Value: "__builtin_ppc_tw" ); |
| 140 | Builder.defineMacro(Name: "__trap" , Value: "__builtin_ppc_trap" ); |
| 141 | Builder.defineMacro(Name: "__trapd" , Value: "__builtin_ppc_trapd" ); |
| 142 | Builder.defineMacro(Name: "__fcfid" , Value: "__builtin_ppc_fcfid" ); |
| 143 | Builder.defineMacro(Name: "__fcfud" , Value: "__builtin_ppc_fcfud" ); |
| 144 | Builder.defineMacro(Name: "__fctid" , Value: "__builtin_ppc_fctid" ); |
| 145 | Builder.defineMacro(Name: "__fctidz" , Value: "__builtin_ppc_fctidz" ); |
| 146 | Builder.defineMacro(Name: "__fctiw" , Value: "__builtin_ppc_fctiw" ); |
| 147 | Builder.defineMacro(Name: "__fctiwz" , Value: "__builtin_ppc_fctiwz" ); |
| 148 | Builder.defineMacro(Name: "__fctudz" , Value: "__builtin_ppc_fctudz" ); |
| 149 | Builder.defineMacro(Name: "__fctuwz" , Value: "__builtin_ppc_fctuwz" ); |
| 150 | Builder.defineMacro(Name: "__cmpeqb" , Value: "__builtin_ppc_cmpeqb" ); |
| 151 | Builder.defineMacro(Name: "__cmprb" , Value: "__builtin_ppc_cmprb" ); |
| 152 | Builder.defineMacro(Name: "__setb" , Value: "__builtin_ppc_setb" ); |
| 153 | Builder.defineMacro(Name: "__cmpb" , Value: "__builtin_ppc_cmpb" ); |
| 154 | Builder.defineMacro(Name: "__mulhd" , Value: "__builtin_ppc_mulhd" ); |
| 155 | Builder.defineMacro(Name: "__mulhdu" , Value: "__builtin_ppc_mulhdu" ); |
| 156 | Builder.defineMacro(Name: "__mulhw" , Value: "__builtin_ppc_mulhw" ); |
| 157 | Builder.defineMacro(Name: "__mulhwu" , Value: "__builtin_ppc_mulhwu" ); |
| 158 | Builder.defineMacro(Name: "__maddhd" , Value: "__builtin_ppc_maddhd" ); |
| 159 | Builder.defineMacro(Name: "__maddhdu" , Value: "__builtin_ppc_maddhdu" ); |
| 160 | Builder.defineMacro(Name: "__maddld" , Value: "__builtin_ppc_maddld" ); |
| 161 | Builder.defineMacro(Name: "__rlwnm" , Value: "__builtin_ppc_rlwnm" ); |
| 162 | Builder.defineMacro(Name: "__rlwimi" , Value: "__builtin_ppc_rlwimi" ); |
| 163 | Builder.defineMacro(Name: "__rldimi" , Value: "__builtin_ppc_rldimi" ); |
| 164 | Builder.defineMacro(Name: "__load2r" , Value: "__builtin_ppc_load2r" ); |
| 165 | Builder.defineMacro(Name: "__load4r" , Value: "__builtin_ppc_load4r" ); |
| 166 | Builder.defineMacro(Name: "__load8r" , Value: "__builtin_ppc_load8r" ); |
| 167 | Builder.defineMacro(Name: "__store2r" , Value: "__builtin_ppc_store2r" ); |
| 168 | Builder.defineMacro(Name: "__store4r" , Value: "__builtin_ppc_store4r" ); |
| 169 | Builder.defineMacro(Name: "__store8r" , Value: "__builtin_ppc_store8r" ); |
| 170 | Builder.defineMacro(Name: "__extract_exp" , Value: "__builtin_ppc_extract_exp" ); |
| 171 | Builder.defineMacro(Name: "__extract_sig" , Value: "__builtin_ppc_extract_sig" ); |
| 172 | Builder.defineMacro(Name: "__mtfsb0" , Value: "__builtin_ppc_mtfsb0" ); |
| 173 | Builder.defineMacro(Name: "__mtfsb1" , Value: "__builtin_ppc_mtfsb1" ); |
| 174 | Builder.defineMacro(Name: "__mtfsf" , Value: "__builtin_ppc_mtfsf" ); |
| 175 | Builder.defineMacro(Name: "__mtfsfi" , Value: "__builtin_ppc_mtfsfi" ); |
| 176 | Builder.defineMacro(Name: "__insert_exp" , Value: "__builtin_ppc_insert_exp" ); |
| 177 | Builder.defineMacro(Name: "__fmsub" , Value: "__builtin_ppc_fmsub" ); |
| 178 | Builder.defineMacro(Name: "__fmsubs" , Value: "__builtin_ppc_fmsubs" ); |
| 179 | Builder.defineMacro(Name: "__fnmadd" , Value: "__builtin_ppc_fnmadd" ); |
| 180 | Builder.defineMacro(Name: "__fnmadds" , Value: "__builtin_ppc_fnmadds" ); |
| 181 | Builder.defineMacro(Name: "__fnmsub" , Value: "__builtin_ppc_fnmsub" ); |
| 182 | Builder.defineMacro(Name: "__fnmsubs" , Value: "__builtin_ppc_fnmsubs" ); |
| 183 | Builder.defineMacro(Name: "__fre" , Value: "__builtin_ppc_fre" ); |
| 184 | Builder.defineMacro(Name: "__fres" , Value: "__builtin_ppc_fres" ); |
| 185 | Builder.defineMacro(Name: "__swdiv_nochk" , Value: "__builtin_ppc_swdiv_nochk" ); |
| 186 | Builder.defineMacro(Name: "__swdivs_nochk" , Value: "__builtin_ppc_swdivs_nochk" ); |
| 187 | Builder.defineMacro(Name: "__alloca" , Value: "__builtin_alloca" ); |
| 188 | Builder.defineMacro(Name: "__vcipher" , Value: "__builtin_altivec_crypto_vcipher" ); |
| 189 | Builder.defineMacro(Name: "__vcipherlast" , Value: "__builtin_altivec_crypto_vcipherlast" ); |
| 190 | Builder.defineMacro(Name: "__vncipher" , Value: "__builtin_altivec_crypto_vncipher" ); |
| 191 | Builder.defineMacro(Name: "__vncipherlast" , |
| 192 | Value: "__builtin_altivec_crypto_vncipherlast" ); |
| 193 | Builder.defineMacro(Name: "__vpermxor" , Value: "__builtin_altivec_crypto_vpermxor" ); |
| 194 | Builder.defineMacro(Name: "__vpmsumb" , Value: "__builtin_altivec_crypto_vpmsumb" ); |
| 195 | Builder.defineMacro(Name: "__vpmsumd" , Value: "__builtin_altivec_crypto_vpmsumd" ); |
| 196 | Builder.defineMacro(Name: "__vpmsumh" , Value: "__builtin_altivec_crypto_vpmsumh" ); |
| 197 | Builder.defineMacro(Name: "__vpmsumw" , Value: "__builtin_altivec_crypto_vpmsumw" ); |
| 198 | Builder.defineMacro(Name: "__divde" , Value: "__builtin_divde" ); |
| 199 | Builder.defineMacro(Name: "__divwe" , Value: "__builtin_divwe" ); |
| 200 | Builder.defineMacro(Name: "__divdeu" , Value: "__builtin_divdeu" ); |
| 201 | Builder.defineMacro(Name: "__divweu" , Value: "__builtin_divweu" ); |
| 202 | Builder.defineMacro(Name: "__alignx" , Value: "__builtin_ppc_alignx" ); |
| 203 | Builder.defineMacro(Name: "__bcopy" , Value: "bcopy" ); |
| 204 | Builder.defineMacro(Name: "__bpermd" , Value: "__builtin_bpermd" ); |
| 205 | Builder.defineMacro(Name: "__cntlz4" , Value: "__builtin_clz" ); |
| 206 | Builder.defineMacro(Name: "__cntlz8" , Value: "__builtin_clzll" ); |
| 207 | Builder.defineMacro(Name: "__cmplx" , Value: "__builtin_complex" ); |
| 208 | Builder.defineMacro(Name: "__cmplxf" , Value: "__builtin_complex" ); |
| 209 | Builder.defineMacro(Name: "__cnttz4" , Value: "__builtin_ctz" ); |
| 210 | Builder.defineMacro(Name: "__cnttz8" , Value: "__builtin_ctzll" ); |
| 211 | Builder.defineMacro(Name: "__darn" , Value: "__builtin_darn" ); |
| 212 | Builder.defineMacro(Name: "__darn_32" , Value: "__builtin_darn_32" ); |
| 213 | Builder.defineMacro(Name: "__darn_raw" , Value: "__builtin_darn_raw" ); |
| 214 | Builder.defineMacro(Name: "__dcbf" , Value: "__builtin_dcbf" ); |
| 215 | Builder.defineMacro(Name: "__fence" , Value: "__builtin_ppc_fence" ); |
| 216 | Builder.defineMacro(Name: "__fmadd" , Value: "__builtin_fma" ); |
| 217 | Builder.defineMacro(Name: "__fmadds" , Value: "__builtin_fmaf" ); |
| 218 | Builder.defineMacro(Name: "__abs" , Value: "__builtin_abs" ); |
| 219 | Builder.defineMacro(Name: "__labs" , Value: "__builtin_labs" ); |
| 220 | Builder.defineMacro(Name: "__llabs" , Value: "__builtin_llabs" ); |
| 221 | Builder.defineMacro(Name: "__popcnt4" , Value: "__builtin_popcount" ); |
| 222 | Builder.defineMacro(Name: "__popcnt8" , Value: "__builtin_popcountll" ); |
| 223 | Builder.defineMacro(Name: "__readflm" , Value: "__builtin_readflm" ); |
| 224 | Builder.defineMacro(Name: "__rotatel4" , Value: "__builtin_rotateleft32" ); |
| 225 | Builder.defineMacro(Name: "__rotatel8" , Value: "__builtin_rotateleft64" ); |
| 226 | Builder.defineMacro(Name: "__rdlam" , Value: "__builtin_ppc_rdlam" ); |
| 227 | Builder.defineMacro(Name: "__setflm" , Value: "__builtin_setflm" ); |
| 228 | Builder.defineMacro(Name: "__setrnd" , Value: "__builtin_setrnd" ); |
| 229 | Builder.defineMacro(Name: "__dcbtstt" , Value: "__builtin_ppc_dcbtstt" ); |
| 230 | Builder.defineMacro(Name: "__dcbtt" , Value: "__builtin_ppc_dcbtt" ); |
| 231 | Builder.defineMacro(Name: "__mftbu" , Value: "__builtin_ppc_mftbu" ); |
| 232 | Builder.defineMacro(Name: "__mfmsr" , Value: "__builtin_ppc_mfmsr" ); |
| 233 | Builder.defineMacro(Name: "__mtmsr" , Value: "__builtin_ppc_mtmsr" ); |
| 234 | Builder.defineMacro(Name: "__mfspr" , Value: "__builtin_ppc_mfspr" ); |
| 235 | Builder.defineMacro(Name: "__mtspr" , Value: "__builtin_ppc_mtspr" ); |
| 236 | Builder.defineMacro(Name: "__fric" , Value: "__builtin_ppc_fric" ); |
| 237 | Builder.defineMacro(Name: "__frim" , Value: "__builtin_ppc_frim" ); |
| 238 | Builder.defineMacro(Name: "__frims" , Value: "__builtin_ppc_frims" ); |
| 239 | Builder.defineMacro(Name: "__frin" , Value: "__builtin_ppc_frin" ); |
| 240 | Builder.defineMacro(Name: "__frins" , Value: "__builtin_ppc_frins" ); |
| 241 | Builder.defineMacro(Name: "__frip" , Value: "__builtin_ppc_frip" ); |
| 242 | Builder.defineMacro(Name: "__frips" , Value: "__builtin_ppc_frips" ); |
| 243 | Builder.defineMacro(Name: "__friz" , Value: "__builtin_ppc_friz" ); |
| 244 | Builder.defineMacro(Name: "__frizs" , Value: "__builtin_ppc_frizs" ); |
| 245 | Builder.defineMacro(Name: "__fsel" , Value: "__builtin_ppc_fsel" ); |
| 246 | Builder.defineMacro(Name: "__fsels" , Value: "__builtin_ppc_fsels" ); |
| 247 | Builder.defineMacro(Name: "__frsqrte" , Value: "__builtin_ppc_frsqrte" ); |
| 248 | Builder.defineMacro(Name: "__frsqrtes" , Value: "__builtin_ppc_frsqrtes" ); |
| 249 | Builder.defineMacro(Name: "__fsqrt" , Value: "__builtin_ppc_fsqrt" ); |
| 250 | Builder.defineMacro(Name: "__fsqrts" , Value: "__builtin_ppc_fsqrts" ); |
| 251 | Builder.defineMacro(Name: "__addex" , Value: "__builtin_ppc_addex" ); |
| 252 | Builder.defineMacro(Name: "__cmplxl" , Value: "__builtin_complex" ); |
| 253 | Builder.defineMacro(Name: "__compare_exp_uo" , Value: "__builtin_ppc_compare_exp_uo" ); |
| 254 | Builder.defineMacro(Name: "__compare_exp_lt" , Value: "__builtin_ppc_compare_exp_lt" ); |
| 255 | Builder.defineMacro(Name: "__compare_exp_gt" , Value: "__builtin_ppc_compare_exp_gt" ); |
| 256 | Builder.defineMacro(Name: "__compare_exp_eq" , Value: "__builtin_ppc_compare_exp_eq" ); |
| 257 | Builder.defineMacro(Name: "__test_data_class" , Value: "__builtin_ppc_test_data_class" ); |
| 258 | Builder.defineMacro(Name: "__swdiv" , Value: "__builtin_ppc_swdiv" ); |
| 259 | Builder.defineMacro(Name: "__swdivs" , Value: "__builtin_ppc_swdivs" ); |
| 260 | Builder.defineMacro(Name: "__fnabs" , Value: "__builtin_ppc_fnabs" ); |
| 261 | Builder.defineMacro(Name: "__fnabss" , Value: "__builtin_ppc_fnabss" ); |
| 262 | Builder.defineMacro(Name: "__builtin_maxfe" , Value: "__builtin_ppc_maxfe" ); |
| 263 | Builder.defineMacro(Name: "__builtin_maxfl" , Value: "__builtin_ppc_maxfl" ); |
| 264 | Builder.defineMacro(Name: "__builtin_maxfs" , Value: "__builtin_ppc_maxfs" ); |
| 265 | Builder.defineMacro(Name: "__builtin_minfe" , Value: "__builtin_ppc_minfe" ); |
| 266 | Builder.defineMacro(Name: "__builtin_minfl" , Value: "__builtin_ppc_minfl" ); |
| 267 | Builder.defineMacro(Name: "__builtin_minfs" , Value: "__builtin_ppc_minfs" ); |
| 268 | Builder.defineMacro(Name: "__builtin_mffs" , Value: "__builtin_ppc_mffs" ); |
| 269 | Builder.defineMacro(Name: "__builtin_mffsl" , Value: "__builtin_ppc_mffsl" ); |
| 270 | Builder.defineMacro(Name: "__builtin_mtfsf" , Value: "__builtin_ppc_mtfsf" ); |
| 271 | Builder.defineMacro(Name: "__builtin_set_fpscr_rn" , Value: "__builtin_ppc_set_fpscr_rn" ); |
| 272 | } |
| 273 | |
| 274 | /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific |
| 275 | /// #defines that are not tied to a specific subtarget. |
| 276 | void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, |
| 277 | MacroBuilder &Builder) const { |
| 278 | |
| 279 | // We define the XLC compatibility macros only on AIX and Linux since XLC |
| 280 | // was never available on any other platforms. |
| 281 | if (getTriple().isOSAIX() || getTriple().isOSLinux()) |
| 282 | defineXLCompatMacros(Builder); |
| 283 | |
| 284 | // Target identification. |
| 285 | Builder.defineMacro(Name: "__ppc__" ); |
| 286 | Builder.defineMacro(Name: "__PPC__" ); |
| 287 | Builder.defineMacro(Name: "_ARCH_PPC" ); |
| 288 | Builder.defineMacro(Name: "__powerpc__" ); |
| 289 | Builder.defineMacro(Name: "__POWERPC__" ); |
| 290 | if (PointerWidth == 64) { |
| 291 | Builder.defineMacro(Name: "_ARCH_PPC64" ); |
| 292 | Builder.defineMacro(Name: "__powerpc64__" ); |
| 293 | Builder.defineMacro(Name: "__PPC64__" ); |
| 294 | } else if (getTriple().isOSAIX()) { |
| 295 | // The XL compilers on AIX define _ARCH_PPC64 for both 32 and 64-bit modes. |
| 296 | Builder.defineMacro(Name: "_ARCH_PPC64" ); |
| 297 | } |
| 298 | if (getTriple().isOSAIX()) { |
| 299 | Builder.defineMacro(Name: "__THW_PPC__" ); |
| 300 | // Define __PPC and __powerpc for AIX XL C/C++ compatibility |
| 301 | Builder.defineMacro(Name: "__PPC" ); |
| 302 | Builder.defineMacro(Name: "__powerpc" ); |
| 303 | } |
| 304 | |
| 305 | // Target properties. |
| 306 | if (getTriple().getArch() == llvm::Triple::ppc64le || |
| 307 | getTriple().getArch() == llvm::Triple::ppcle) { |
| 308 | Builder.defineMacro(Name: "_LITTLE_ENDIAN" ); |
| 309 | } else { |
| 310 | if (!getTriple().isOSNetBSD() && |
| 311 | !getTriple().isOSOpenBSD()) |
| 312 | Builder.defineMacro(Name: "_BIG_ENDIAN" ); |
| 313 | } |
| 314 | |
| 315 | // ABI options. |
| 316 | if (ABI == "elfv1" ) |
| 317 | Builder.defineMacro(Name: "_CALL_ELF" , Value: "1" ); |
| 318 | if (ABI == "elfv2" ) |
| 319 | Builder.defineMacro(Name: "_CALL_ELF" , Value: "2" ); |
| 320 | |
| 321 | // This typically is only for a new enough linker (bfd >= 2.16.2 or gold), but |
| 322 | // our support post-dates this and it should work on all 64-bit ppc linux |
| 323 | // platforms. It is guaranteed to work on all elfv2 platforms. |
| 324 | if (getTriple().getOS() == llvm::Triple::Linux && PointerWidth == 64) |
| 325 | Builder.defineMacro(Name: "_CALL_LINUX" , Value: "1" ); |
| 326 | |
| 327 | // Subtarget options. |
| 328 | if (!getTriple().isOSAIX()){ |
| 329 | Builder.defineMacro(Name: "__NATURAL_ALIGNMENT__" ); |
| 330 | } |
| 331 | Builder.defineMacro(Name: "__REGISTER_PREFIX__" , Value: "" ); |
| 332 | |
| 333 | // FIXME: Should be controlled by command line option. |
| 334 | if (LongDoubleWidth == 128) { |
| 335 | Builder.defineMacro(Name: "__LONG_DOUBLE_128__" ); |
| 336 | Builder.defineMacro(Name: "__LONGDOUBLE128" ); |
| 337 | if (Opts.PPCIEEELongDouble) |
| 338 | Builder.defineMacro(Name: "__LONG_DOUBLE_IEEE128__" ); |
| 339 | else |
| 340 | Builder.defineMacro(Name: "__LONG_DOUBLE_IBM128__" ); |
| 341 | } |
| 342 | |
| 343 | if (getTriple().isOSAIX() && Opts.LongDoubleSize == 64) { |
| 344 | assert(LongDoubleWidth == 64); |
| 345 | Builder.defineMacro(Name: "__LONGDOUBLE64" ); |
| 346 | } |
| 347 | |
| 348 | // Define this for elfv2 (64-bit only). |
| 349 | if (ABI == "elfv2" ) |
| 350 | Builder.defineMacro(Name: "__STRUCT_PARM_ALIGN__" , Value: "16" ); |
| 351 | |
| 352 | if (ArchDefs & ArchDefineName) |
| 353 | Builder.defineMacro(Name: Twine("_ARCH_" , StringRef(CPU).upper())); |
| 354 | if (ArchDefs & ArchDefinePpcgr) |
| 355 | Builder.defineMacro(Name: "_ARCH_PPCGR" ); |
| 356 | if (ArchDefs & ArchDefinePpcsq) |
| 357 | Builder.defineMacro(Name: "_ARCH_PPCSQ" ); |
| 358 | if (ArchDefs & ArchDefine440) |
| 359 | Builder.defineMacro(Name: "_ARCH_440" ); |
| 360 | if (ArchDefs & ArchDefine603) |
| 361 | Builder.defineMacro(Name: "_ARCH_603" ); |
| 362 | if (ArchDefs & ArchDefine604) |
| 363 | Builder.defineMacro(Name: "_ARCH_604" ); |
| 364 | if (ArchDefs & ArchDefinePwr4) |
| 365 | Builder.defineMacro(Name: "_ARCH_PWR4" ); |
| 366 | if (ArchDefs & ArchDefinePwr5) |
| 367 | Builder.defineMacro(Name: "_ARCH_PWR5" ); |
| 368 | if (ArchDefs & ArchDefinePwr5x) |
| 369 | Builder.defineMacro(Name: "_ARCH_PWR5X" ); |
| 370 | if (ArchDefs & ArchDefinePwr6) |
| 371 | Builder.defineMacro(Name: "_ARCH_PWR6" ); |
| 372 | if (ArchDefs & ArchDefinePwr6x) |
| 373 | Builder.defineMacro(Name: "_ARCH_PWR6X" ); |
| 374 | if (ArchDefs & ArchDefinePwr7) |
| 375 | Builder.defineMacro(Name: "_ARCH_PWR7" ); |
| 376 | if (ArchDefs & ArchDefinePwr8) |
| 377 | Builder.defineMacro(Name: "_ARCH_PWR8" ); |
| 378 | if (ArchDefs & ArchDefinePwr9) |
| 379 | Builder.defineMacro(Name: "_ARCH_PWR9" ); |
| 380 | if (ArchDefs & ArchDefinePwr10) |
| 381 | Builder.defineMacro(Name: "_ARCH_PWR10" ); |
| 382 | if (ArchDefs & ArchDefinePwr11) |
| 383 | Builder.defineMacro(Name: "_ARCH_PWR11" ); |
| 384 | if (ArchDefs & ArchDefineA2) |
| 385 | Builder.defineMacro(Name: "_ARCH_A2" ); |
| 386 | if (ArchDefs & ArchDefineE500) |
| 387 | Builder.defineMacro(Name: "__NO_LWSYNC__" ); |
| 388 | if (ArchDefs & ArchDefineFuture) |
| 389 | Builder.defineMacro(Name: "_ARCH_PWR_FUTURE" ); |
| 390 | |
| 391 | if (HasAltivec) { |
| 392 | Builder.defineMacro(Name: "__VEC__" , Value: "10206" ); |
| 393 | Builder.defineMacro(Name: "__ALTIVEC__" ); |
| 394 | } |
| 395 | if (HasSPE) |
| 396 | Builder.defineMacro(Name: "__SPE__" ); |
| 397 | if (HasSPE || FloatABI == SoftFloat) |
| 398 | Builder.defineMacro(Name: "__NO_FPRS__" ); |
| 399 | if (FloatABI == SoftFloat) { |
| 400 | Builder.defineMacro(Name: "_SOFT_FLOAT" ); |
| 401 | Builder.defineMacro(Name: "_SOFT_DOUBLE" ); |
| 402 | } else { |
| 403 | if (HasFrsqrte) |
| 404 | Builder.defineMacro(Name: "__RSQRTE__" ); |
| 405 | if (HasFrsqrtes) |
| 406 | Builder.defineMacro(Name: "__RSQRTEF__" ); |
| 407 | } |
| 408 | if (HasVSX) |
| 409 | Builder.defineMacro(Name: "__VSX__" ); |
| 410 | if (HasP8Vector) |
| 411 | Builder.defineMacro(Name: "__POWER8_VECTOR__" ); |
| 412 | if (HasP8Crypto) |
| 413 | Builder.defineMacro(Name: "__CRYPTO__" ); |
| 414 | if (HasHTM) |
| 415 | Builder.defineMacro(Name: "__HTM__" ); |
| 416 | if (HasFloat128) |
| 417 | Builder.defineMacro(Name: "__FLOAT128__" ); |
| 418 | if (HasP9Vector) |
| 419 | Builder.defineMacro(Name: "__POWER9_VECTOR__" ); |
| 420 | if (HasMMA) |
| 421 | Builder.defineMacro(Name: "__MMA__" ); |
| 422 | if (HasROPProtect) |
| 423 | Builder.defineMacro(Name: "__ROP_PROTECT__" ); |
| 424 | if (HasP10Vector) |
| 425 | Builder.defineMacro(Name: "__POWER10_VECTOR__" ); |
| 426 | if (HasPCRelativeMemops) |
| 427 | Builder.defineMacro(Name: "__PCREL__" ); |
| 428 | |
| 429 | Builder.defineMacro(Name: "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1" ); |
| 430 | Builder.defineMacro(Name: "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2" ); |
| 431 | Builder.defineMacro(Name: "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4" ); |
| 432 | if (PointerWidth == 64) |
| 433 | Builder.defineMacro(Name: "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8" ); |
| 434 | |
| 435 | // We have support for the bswap intrinsics so we can define this. |
| 436 | Builder.defineMacro(Name: "__HAVE_BSWAP__" , Value: "1" ); |
| 437 | |
| 438 | // FIXME: The following are not yet generated here by Clang, but are |
| 439 | // generated by GCC: |
| 440 | // |
| 441 | // __RECIP_PRECISION__ |
| 442 | // __APPLE_ALTIVEC__ |
| 443 | // __RECIP__ |
| 444 | // __RECIPF__ |
| 445 | // __NO_LWSYNC__ |
| 446 | // __CMODEL_MEDIUM__ |
| 447 | // __CMODEL_LARGE__ |
| 448 | // _CALL_SYSV |
| 449 | // _CALL_DARWIN |
| 450 | } |
| 451 | |
| 452 | // Handle explicit options being passed to the compiler here: |
| 453 | // - if we've explicitly turned off vsx and turned on any of: |
| 454 | // - power8-vector |
| 455 | // - direct-move |
| 456 | // - float128 |
| 457 | // - power9-vector |
| 458 | // - paired-vector-memops |
| 459 | // - mma |
| 460 | // - power10-vector |
| 461 | // - if we've explicitly turned on vsx and turned off altivec. |
| 462 | // - if we've explicitly turned off hard-float and turned on altivec. |
| 463 | // then go ahead and error since the customer has expressed an incompatible |
| 464 | // set of options. |
| 465 | static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags, |
| 466 | const std::vector<std::string> &FeaturesVec) { |
| 467 | auto FindVSXSubfeature = [&](StringRef Feature, StringRef SubOption, |
| 468 | StringRef Option) { |
| 469 | if (llvm::is_contained(Range: FeaturesVec, Element: Feature)) { |
| 470 | Diags.Report(DiagID: diag::err_opt_not_valid_with_opt) << SubOption << Option; |
| 471 | return true; |
| 472 | } |
| 473 | return false; |
| 474 | }; |
| 475 | |
| 476 | // Cannot allow soft-float with VSX, Altivec, or any |
| 477 | // VSX subfeatures. |
| 478 | bool Found = false; |
| 479 | if (llvm::is_contained(Range: FeaturesVec, Element: "-hard-float" )) { |
| 480 | Found |= FindVSXSubfeature("+vsx" , "-mvsx" , "-msoft-float" ); |
| 481 | Found |= FindVSXSubfeature("+altivec" , "-maltivec" , "-msoft-float" ); |
| 482 | Found |= |
| 483 | FindVSXSubfeature("+power8-vector" , "-mpower8-vector" , "-msoft-float" ); |
| 484 | Found |= FindVSXSubfeature("+direct-move" , "-mdirect-move" , "-msoft-float" ); |
| 485 | Found |= FindVSXSubfeature("+float128" , "-mfloat128" , "-msoft-float" ); |
| 486 | Found |= |
| 487 | FindVSXSubfeature("+power9-vector" , "-mpower9-vector" , "-msoft-float" ); |
| 488 | Found |= FindVSXSubfeature("+paired-vector-memops" , |
| 489 | "-mpaired-vector-memops" , "-msoft-float" ); |
| 490 | Found |= FindVSXSubfeature("+mma" , "-mmma" , "-msoft-float" ); |
| 491 | Found |= FindVSXSubfeature("+crypto" , "-mcrypto" , "-msoft-float" ); |
| 492 | Found |= FindVSXSubfeature("+power10-vector" , "-mpower10-vector" , |
| 493 | "-msoft-float" ); |
| 494 | } |
| 495 | if (Found) |
| 496 | return false; |
| 497 | |
| 498 | // Cannot allow VSX with no Altivec. |
| 499 | if (llvm::is_contained(Range: FeaturesVec, Element: "+vsx" ) && |
| 500 | llvm::is_contained(Range: FeaturesVec, Element: "-altivec" )) { |
| 501 | Diags.Report(DiagID: diag::err_opt_not_valid_with_opt) << "-mvsx" |
| 502 | << "-mno-altivec" ; |
| 503 | return false; |
| 504 | } |
| 505 | |
| 506 | // vsx was not explicitly turned off. |
| 507 | if (!llvm::is_contained(Range: FeaturesVec, Element: "-vsx" )) |
| 508 | return true; |
| 509 | |
| 510 | Found = FindVSXSubfeature("+power8-vector" , "-mpower8-vector" , "-mno-vsx" ); |
| 511 | Found |= FindVSXSubfeature("+direct-move" , "-mdirect-move" , "-mno-vsx" ); |
| 512 | Found |= FindVSXSubfeature("+float128" , "-mfloat128" , "-mno-vsx" ); |
| 513 | Found |= FindVSXSubfeature("+power9-vector" , "-mpower9-vector" , "-mno-vsx" ); |
| 514 | Found |= FindVSXSubfeature("+paired-vector-memops" , "-mpaired-vector-memops" , |
| 515 | "-mno-vsx" ); |
| 516 | Found |= FindVSXSubfeature("+mma" , "-mmma" , "-mno-vsx" ); |
| 517 | Found |= FindVSXSubfeature("+power10-vector" , "-mpower10-vector" , "-mno-vsx" ); |
| 518 | |
| 519 | // Return false if any vsx subfeatures was found. |
| 520 | return !Found; |
| 521 | } |
| 522 | |
| 523 | bool PPCTargetInfo::initFeatureMap( |
| 524 | llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, |
| 525 | const std::vector<std::string> &FeaturesVec) const { |
| 526 | |
| 527 | const llvm::Triple &TheTriple = getTriple(); |
| 528 | |
| 529 | std::optional<llvm::StringMap<bool>> FeaturesOpt = |
| 530 | llvm::PPC::getPPCDefaultTargetFeatures(T: TheTriple, |
| 531 | CPUName: llvm::PPC::normalizeCPUName(CPUName: CPU)); |
| 532 | if (FeaturesOpt) |
| 533 | Features = FeaturesOpt.value(); |
| 534 | |
| 535 | if (!ppcUserFeaturesCheck(Diags, FeaturesVec)) |
| 536 | return false; |
| 537 | |
| 538 | if (!(ArchDefs & ArchDefinePwr7) && (ArchDefs & ArchDefinePpcgr) && |
| 539 | llvm::is_contained(Range: FeaturesVec, Element: "+float128" )) { |
| 540 | // We have __float128 on PPC but not pre-VSX targets. |
| 541 | Diags.Report(DiagID: diag::err_opt_not_valid_with_opt) << "-mfloat128" << CPU; |
| 542 | return false; |
| 543 | } |
| 544 | |
| 545 | if (!(ArchDefs & ArchDefinePwr10)) { |
| 546 | if (llvm::is_contained(Range: FeaturesVec, Element: "+mma" )) { |
| 547 | // MMA operations are not available pre-Power10. |
| 548 | Diags.Report(DiagID: diag::err_opt_not_valid_with_opt) << "-mmma" << CPU; |
| 549 | return false; |
| 550 | } |
| 551 | if (llvm::is_contained(Range: FeaturesVec, Element: "+pcrel" )) { |
| 552 | // PC-Relative instructions are not available pre-Power10, |
| 553 | // and these instructions also require prefixed instructions support. |
| 554 | Diags.Report(DiagID: diag::err_opt_not_valid_without_opt) |
| 555 | << "-mpcrel" |
| 556 | << "-mcpu=pwr10 -mprefixed" ; |
| 557 | return false; |
| 558 | } |
| 559 | if (llvm::is_contained(Range: FeaturesVec, Element: "+prefixed" )) { |
| 560 | // Prefixed instructions are not available pre-Power10. |
| 561 | Diags.Report(DiagID: diag::err_opt_not_valid_without_opt) << "-mprefixed" |
| 562 | << "-mcpu=pwr10" ; |
| 563 | return false; |
| 564 | } |
| 565 | if (llvm::is_contained(Range: FeaturesVec, Element: "+paired-vector-memops" )) { |
| 566 | // Paired vector memops are not available pre-Power10. |
| 567 | Diags.Report(DiagID: diag::err_opt_not_valid_without_opt) |
| 568 | << "-mpaired-vector-memops" |
| 569 | << "-mcpu=pwr10" ; |
| 570 | return false; |
| 571 | } |
| 572 | } |
| 573 | |
| 574 | if (llvm::is_contained(Range: FeaturesVec, Element: "+rop-protect" )) { |
| 575 | if (PointerWidth == 32) { |
| 576 | Diags.Report(DiagID: diag::err_opt_not_valid_on_target) << "-mrop-protect" ; |
| 577 | return false; |
| 578 | } |
| 579 | |
| 580 | if (!(ArchDefs & ArchDefinePwr8)) { |
| 581 | // We can turn on ROP Protect on Power 8 and above. |
| 582 | Diags.Report(DiagID: diag::err_opt_not_valid_with_opt) << "-mrop-protect" << CPU; |
| 583 | return false; |
| 584 | } |
| 585 | } |
| 586 | |
| 587 | if (!(ArchDefs & ArchDefinePwr8) && |
| 588 | llvm::is_contained(Range: FeaturesVec, Element: "+privileged" )) { |
| 589 | Diags.Report(DiagID: diag::err_opt_not_valid_with_opt) << "-mprivileged" << CPU; |
| 590 | return false; |
| 591 | } |
| 592 | return TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec: FeaturesVec); |
| 593 | } |
| 594 | |
| 595 | bool PPCTargetInfo::hasFeature(StringRef Feature) const { |
| 596 | return llvm::StringSwitch<bool>(Feature) |
| 597 | .Case(S: "powerpc" , Value: true) |
| 598 | .Case(S: "altivec" , Value: HasAltivec) |
| 599 | .Case(S: "vsx" , Value: HasVSX) |
| 600 | .Case(S: "power8-vector" , Value: HasP8Vector) |
| 601 | .Case(S: "crypto" , Value: HasP8Crypto) |
| 602 | .Case(S: "htm" , Value: HasHTM) |
| 603 | .Case(S: "float128" , Value: HasFloat128) |
| 604 | .Case(S: "power9-vector" , Value: HasP9Vector) |
| 605 | .Case(S: "power10-vector" , Value: HasP10Vector) |
| 606 | .Case(S: "pcrelative-memops" , Value: HasPCRelativeMemops) |
| 607 | .Case(S: "spe" , Value: HasSPE) |
| 608 | .Case(S: "mma" , Value: HasMMA) |
| 609 | .Case(S: "rop-protect" , Value: HasROPProtect) |
| 610 | .Case(S: "quadword-atomics" , Value: HasQuadwordAtomics) |
| 611 | .Case(S: "longcall" , Value: UseLongCalls) |
| 612 | .Default(Value: false); |
| 613 | } |
| 614 | |
| 615 | void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, |
| 616 | StringRef Name, bool Enabled) const { |
| 617 | if (Enabled) { |
| 618 | if (Name == "efpu2" ) |
| 619 | Features["spe" ] = true; |
| 620 | // If we're enabling any of the vsx based features then enable vsx and |
| 621 | // altivec. We'll diagnose any problems later. |
| 622 | bool FeatureHasVSX = llvm::StringSwitch<bool>(Name) |
| 623 | .Case(S: "vsx" , Value: true) |
| 624 | .Case(S: "direct-move" , Value: true) |
| 625 | .Case(S: "power8-vector" , Value: true) |
| 626 | .Case(S: "power9-vector" , Value: true) |
| 627 | .Case(S: "paired-vector-memops" , Value: true) |
| 628 | .Case(S: "power10-vector" , Value: true) |
| 629 | .Case(S: "float128" , Value: true) |
| 630 | .Case(S: "mma" , Value: true) |
| 631 | .Default(Value: false); |
| 632 | if (FeatureHasVSX) |
| 633 | Features["vsx" ] = Features["altivec" ] = true; |
| 634 | if (Name == "power9-vector" ) |
| 635 | Features["power8-vector" ] = true; |
| 636 | else if (Name == "power10-vector" ) |
| 637 | Features["power8-vector" ] = Features["power9-vector" ] = true; |
| 638 | if (Name == "pcrel" ) |
| 639 | Features["pcrelative-memops" ] = true; |
| 640 | else if (Name == "prefixed" ) |
| 641 | Features["prefix-instrs" ] = true; |
| 642 | else |
| 643 | Features[Name] = true; |
| 644 | } else { |
| 645 | if (Name == "spe" ) |
| 646 | Features["efpu2" ] = false; |
| 647 | // If we're disabling altivec, hard-float, or vsx go ahead and disable all |
| 648 | // of the vsx features. |
| 649 | if ((Name == "altivec" ) || (Name == "vsx" ) || (Name == "hard-float" )) { |
| 650 | if (Name != "vsx" ) |
| 651 | Features["altivec" ] = Features["crypto" ] = false; |
| 652 | Features["vsx" ] = Features["direct-move" ] = Features["power8-vector" ] = |
| 653 | Features["float128" ] = Features["power9-vector" ] = |
| 654 | Features["paired-vector-memops" ] = Features["mma" ] = |
| 655 | Features["power10-vector" ] = false; |
| 656 | } |
| 657 | if (Name == "power8-vector" ) |
| 658 | Features["power9-vector" ] = Features["paired-vector-memops" ] = |
| 659 | Features["mma" ] = Features["power10-vector" ] = false; |
| 660 | else if (Name == "power9-vector" ) |
| 661 | Features["paired-vector-memops" ] = Features["mma" ] = |
| 662 | Features["power10-vector" ] = false; |
| 663 | if (Name == "pcrel" ) |
| 664 | Features["pcrelative-memops" ] = false; |
| 665 | else if (Name == "prefixed" ) |
| 666 | Features["prefix-instrs" ] = false; |
| 667 | else |
| 668 | Features[Name] = false; |
| 669 | } |
| 670 | } |
| 671 | |
| 672 | // Make sure that registers are added in the correct array index which should be |
| 673 | // the DWARF number for PPC registers. |
| 674 | const char *const PPCTargetInfo::GCCRegNames[] = { |
| 675 | "r0" , "r1" , "r2" , "r3" , "r4" , "r5" , "r6" , "r7" , "r8" , |
| 676 | "r9" , "r10" , "r11" , "r12" , "r13" , "r14" , "r15" , "r16" , "r17" , |
| 677 | "r18" , "r19" , "r20" , "r21" , "r22" , "r23" , "r24" , "r25" , "r26" , |
| 678 | "r27" , "r28" , "r29" , "r30" , "r31" , "f0" , "f1" , "f2" , "f3" , |
| 679 | "f4" , "f5" , "f6" , "f7" , "f8" , "f9" , "f10" , "f11" , "f12" , |
| 680 | "f13" , "f14" , "f15" , "f16" , "f17" , "f18" , "f19" , "f20" , "f21" , |
| 681 | "f22" , "f23" , "f24" , "f25" , "f26" , "f27" , "f28" , "f29" , "f30" , |
| 682 | "f31" , "mq" , "lr" , "ctr" , "ap" , "cr0" , "cr1" , "cr2" , "cr3" , |
| 683 | "cr4" , "cr5" , "cr6" , "cr7" , "xer" , "v0" , "v1" , "v2" , "v3" , |
| 684 | "v4" , "v5" , "v6" , "v7" , "v8" , "v9" , "v10" , "v11" , "v12" , |
| 685 | "v13" , "v14" , "v15" , "v16" , "v17" , "v18" , "v19" , "v20" , "v21" , |
| 686 | "v22" , "v23" , "v24" , "v25" , "v26" , "v27" , "v28" , "v29" , "v30" , |
| 687 | "v31" , "vrsave" , "vscr" , "spe_acc" , "spefscr" , "sfp" |
| 688 | }; |
| 689 | |
| 690 | ArrayRef<const char *> PPCTargetInfo::getGCCRegNames() const { |
| 691 | return llvm::ArrayRef(GCCRegNames); |
| 692 | } |
| 693 | |
| 694 | const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = { |
| 695 | // While some of these aliases do map to different registers |
| 696 | // they still share the same register name. |
| 697 | {.Aliases: {"0" }, .Register: "r0" }, {.Aliases: {"1" , "sp" }, .Register: "r1" }, {.Aliases: {"2" }, .Register: "r2" }, |
| 698 | {.Aliases: {"3" }, .Register: "r3" }, {.Aliases: {"4" }, .Register: "r4" }, {.Aliases: {"5" }, .Register: "r5" }, |
| 699 | {.Aliases: {"6" }, .Register: "r6" }, {.Aliases: {"7" }, .Register: "r7" }, {.Aliases: {"8" }, .Register: "r8" }, |
| 700 | {.Aliases: {"9" }, .Register: "r9" }, {.Aliases: {"10" }, .Register: "r10" }, {.Aliases: {"11" }, .Register: "r11" }, |
| 701 | {.Aliases: {"12" }, .Register: "r12" }, {.Aliases: {"13" }, .Register: "r13" }, {.Aliases: {"14" }, .Register: "r14" }, |
| 702 | {.Aliases: {"15" }, .Register: "r15" }, {.Aliases: {"16" }, .Register: "r16" }, {.Aliases: {"17" }, .Register: "r17" }, |
| 703 | {.Aliases: {"18" }, .Register: "r18" }, {.Aliases: {"19" }, .Register: "r19" }, {.Aliases: {"20" }, .Register: "r20" }, |
| 704 | {.Aliases: {"21" }, .Register: "r21" }, {.Aliases: {"22" }, .Register: "r22" }, {.Aliases: {"23" }, .Register: "r23" }, |
| 705 | {.Aliases: {"24" }, .Register: "r24" }, {.Aliases: {"25" }, .Register: "r25" }, {.Aliases: {"26" }, .Register: "r26" }, |
| 706 | {.Aliases: {"27" }, .Register: "r27" }, {.Aliases: {"28" }, .Register: "r28" }, {.Aliases: {"29" }, .Register: "r29" }, |
| 707 | {.Aliases: {"30" }, .Register: "r30" }, {.Aliases: {"31" }, .Register: "r31" }, {.Aliases: {"fr0" }, .Register: "f0" }, |
| 708 | {.Aliases: {"fr1" }, .Register: "f1" }, {.Aliases: {"fr2" }, .Register: "f2" }, {.Aliases: {"fr3" }, .Register: "f3" }, |
| 709 | {.Aliases: {"fr4" }, .Register: "f4" }, {.Aliases: {"fr5" }, .Register: "f5" }, {.Aliases: {"fr6" }, .Register: "f6" }, |
| 710 | {.Aliases: {"fr7" }, .Register: "f7" }, {.Aliases: {"fr8" }, .Register: "f8" }, {.Aliases: {"fr9" }, .Register: "f9" }, |
| 711 | {.Aliases: {"fr10" }, .Register: "f10" }, {.Aliases: {"fr11" }, .Register: "f11" }, {.Aliases: {"fr12" }, .Register: "f12" }, |
| 712 | {.Aliases: {"fr13" }, .Register: "f13" }, {.Aliases: {"fr14" }, .Register: "f14" }, {.Aliases: {"fr15" }, .Register: "f15" }, |
| 713 | {.Aliases: {"fr16" }, .Register: "f16" }, {.Aliases: {"fr17" }, .Register: "f17" }, {.Aliases: {"fr18" }, .Register: "f18" }, |
| 714 | {.Aliases: {"fr19" }, .Register: "f19" }, {.Aliases: {"fr20" }, .Register: "f20" }, {.Aliases: {"fr21" }, .Register: "f21" }, |
| 715 | {.Aliases: {"fr22" }, .Register: "f22" }, {.Aliases: {"fr23" }, .Register: "f23" }, {.Aliases: {"fr24" }, .Register: "f24" }, |
| 716 | {.Aliases: {"fr25" }, .Register: "f25" }, {.Aliases: {"fr26" }, .Register: "f26" }, {.Aliases: {"fr27" }, .Register: "f27" }, |
| 717 | {.Aliases: {"fr28" }, .Register: "f28" }, {.Aliases: {"fr29" }, .Register: "f29" }, {.Aliases: {"fr30" }, .Register: "f30" }, |
| 718 | {.Aliases: {"fr31" }, .Register: "f31" }, {.Aliases: {"cc" }, .Register: "cr0" }, |
| 719 | }; |
| 720 | |
| 721 | ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const { |
| 722 | return llvm::ArrayRef(GCCRegAliases); |
| 723 | } |
| 724 | |
| 725 | // PPC ELFABIv2 DWARF Definition "Table 2.26. Mappings of Common Registers". |
| 726 | // vs0 ~ vs31 is mapping to 32 - 63, |
| 727 | // vs32 ~ vs63 is mapping to 77 - 108. |
| 728 | // And this mapping applies to all OSes which run on powerpc. |
| 729 | const TargetInfo::AddlRegName GCCAddlRegNames[] = { |
| 730 | // Table of additional register names to use in user input. |
| 731 | {.Names: {"vs0" }, .RegNum: 32}, {.Names: {"vs1" }, .RegNum: 33}, {.Names: {"vs2" }, .RegNum: 34}, {.Names: {"vs3" }, .RegNum: 35}, |
| 732 | {.Names: {"vs4" }, .RegNum: 36}, {.Names: {"vs5" }, .RegNum: 37}, {.Names: {"vs6" }, .RegNum: 38}, {.Names: {"vs7" }, .RegNum: 39}, |
| 733 | {.Names: {"vs8" }, .RegNum: 40}, {.Names: {"vs9" }, .RegNum: 41}, {.Names: {"vs10" }, .RegNum: 42}, {.Names: {"vs11" }, .RegNum: 43}, |
| 734 | {.Names: {"vs12" }, .RegNum: 44}, {.Names: {"vs13" }, .RegNum: 45}, {.Names: {"vs14" }, .RegNum: 46}, {.Names: {"vs15" }, .RegNum: 47}, |
| 735 | {.Names: {"vs16" }, .RegNum: 48}, {.Names: {"vs17" }, .RegNum: 49}, {.Names: {"vs18" }, .RegNum: 50}, {.Names: {"vs19" }, .RegNum: 51}, |
| 736 | {.Names: {"vs20" }, .RegNum: 52}, {.Names: {"vs21" }, .RegNum: 53}, {.Names: {"vs22" }, .RegNum: 54}, {.Names: {"vs23" }, .RegNum: 55}, |
| 737 | {.Names: {"vs24" }, .RegNum: 56}, {.Names: {"vs25" }, .RegNum: 57}, {.Names: {"vs26" }, .RegNum: 58}, {.Names: {"vs27" }, .RegNum: 59}, |
| 738 | {.Names: {"vs28" }, .RegNum: 60}, {.Names: {"vs29" }, .RegNum: 61}, {.Names: {"vs30" }, .RegNum: 62}, {.Names: {"vs31" }, .RegNum: 63}, |
| 739 | {.Names: {"vs32" }, .RegNum: 77}, {.Names: {"vs33" }, .RegNum: 78}, {.Names: {"vs34" }, .RegNum: 79}, {.Names: {"vs35" }, .RegNum: 80}, |
| 740 | {.Names: {"vs36" }, .RegNum: 81}, {.Names: {"vs37" }, .RegNum: 82}, {.Names: {"vs38" }, .RegNum: 83}, {.Names: {"vs39" }, .RegNum: 84}, |
| 741 | {.Names: {"vs40" }, .RegNum: 85}, {.Names: {"vs41" }, .RegNum: 86}, {.Names: {"vs42" }, .RegNum: 87}, {.Names: {"vs43" }, .RegNum: 88}, |
| 742 | {.Names: {"vs44" }, .RegNum: 89}, {.Names: {"vs45" }, .RegNum: 90}, {.Names: {"vs46" }, .RegNum: 91}, {.Names: {"vs47" }, .RegNum: 92}, |
| 743 | {.Names: {"vs48" }, .RegNum: 93}, {.Names: {"vs49" }, .RegNum: 94}, {.Names: {"vs50" }, .RegNum: 95}, {.Names: {"vs51" }, .RegNum: 96}, |
| 744 | {.Names: {"vs52" }, .RegNum: 97}, {.Names: {"vs53" }, .RegNum: 98}, {.Names: {"vs54" }, .RegNum: 99}, {.Names: {"vs55" }, .RegNum: 100}, |
| 745 | {.Names: {"vs56" }, .RegNum: 101}, {.Names: {"vs57" }, .RegNum: 102}, {.Names: {"vs58" }, .RegNum: 103}, {.Names: {"vs59" }, .RegNum: 104}, |
| 746 | {.Names: {"vs60" }, .RegNum: 105}, {.Names: {"vs61" }, .RegNum: 106}, {.Names: {"vs62" }, .RegNum: 107}, {.Names: {"vs63" }, .RegNum: 108}, |
| 747 | }; |
| 748 | |
| 749 | ArrayRef<TargetInfo::AddlRegName> PPCTargetInfo::getGCCAddlRegNames() const { |
| 750 | return llvm::ArrayRef(GCCAddlRegNames); |
| 751 | } |
| 752 | |
| 753 | bool PPCTargetInfo::isValidCPUName(StringRef Name) const { |
| 754 | return llvm::PPC::isValidCPU(CPU: Name); |
| 755 | } |
| 756 | |
| 757 | void PPCTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { |
| 758 | llvm::PPC::fillValidCPUList(Values); |
| 759 | } |
| 760 | |
| 761 | void PPCTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { |
| 762 | if (HasAltivec) |
| 763 | Opts.AltiVec = 1; |
| 764 | TargetInfo::adjust(Diags, Opts); |
| 765 | if (LongDoubleFormat != &llvm::APFloat::IEEEdouble()) |
| 766 | LongDoubleFormat = Opts.PPCIEEELongDouble |
| 767 | ? &llvm::APFloat::IEEEquad() |
| 768 | : &llvm::APFloat::PPCDoubleDouble(); |
| 769 | Opts.IEEE128 = 1; |
| 770 | if (getTriple().isOSAIX() && Opts.EnableAIXQuadwordAtomicsABI && |
| 771 | HasQuadwordAtomics) |
| 772 | MaxAtomicInlineWidth = 128; |
| 773 | } |
| 774 | |
| 775 | llvm::SmallVector<Builtin::InfosShard> |
| 776 | PPCTargetInfo::getTargetBuiltins() const { |
| 777 | return {{.Strings: &BuiltinStrings, .Infos: BuiltinInfos}}; |
| 778 | } |
| 779 | |
| 780 | bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { |
| 781 | llvm::Triple Triple = getTriple(); |
| 782 | if (Triple.isOSAIX()) { |
| 783 | #define PPC_AIX_FEATURE(NAME, DESC, SUPPORT_METHOD, INDEX, MASK, COMP_OP, \ |
| 784 | VALUE) \ |
| 785 | .Case(NAME, true) |
| 786 | return llvm::StringSwitch<bool>(FeatureStr) |
| 787 | #include "llvm/TargetParser/PPCTargetParser.def" |
| 788 | .Default(Value: false); |
| 789 | } |
| 790 | |
| 791 | assert(Triple.isOSLinux() && |
| 792 | "__builtin_cpu_supports() is only supported for AIX and Linux." ); |
| 793 | |
| 794 | #define PPC_LNX_FEATURE(NAME, DESC, ENUMNAME, ENUMVAL, HWCAPN) .Case(NAME, true) |
| 795 | return llvm::StringSwitch<bool>(FeatureStr) |
| 796 | #include "llvm/TargetParser/PPCTargetParser.def" |
| 797 | .Default(Value: false); |
| 798 | } |
| 799 | |
| 800 | bool PPCTargetInfo::validateCpuIs(StringRef CPUName) const { |
| 801 | llvm::Triple Triple = getTriple(); |
| 802 | assert((Triple.isOSAIX() || Triple.isOSLinux()) && |
| 803 | "__builtin_cpu_is() is only supported for AIX and Linux." ); |
| 804 | |
| 805 | #define PPC_CPU(NAME, Linux_SUPPORT_METHOD, LinuxID, AIX_SUPPORT_METHOD, \ |
| 806 | AIXID) \ |
| 807 | .Case(NAME, {Linux_SUPPORT_METHOD, AIX_SUPPORT_METHOD}) |
| 808 | |
| 809 | std::pair<unsigned, unsigned> SuppportMethod = |
| 810 | llvm::StringSwitch<std::pair<unsigned, unsigned>>(CPUName) |
| 811 | #include "llvm/TargetParser/PPCTargetParser.def" |
| 812 | .Default(Value: {BUILTIN_PPC_UNSUPPORTED, BUILTIN_PPC_UNSUPPORTED}); |
| 813 | return Triple.isOSLinux() |
| 814 | ? (SuppportMethod.first != BUILTIN_PPC_UNSUPPORTED) |
| 815 | : (SuppportMethod.second != BUILTIN_PPC_UNSUPPORTED); |
| 816 | } |
| 817 | |