1 1.1 mrg /* Target-specific built-in function support for the Power architecture. 2 1.1 mrg See also rs6000-c.c, rs6000-gen-builtins.c, rs6000-builtins.def, and 3 1.1 mrg rs6000-overloads.def. 4 1.1 mrg Note that "normal" builtins (generic math functions, etc.) are handled 5 1.1 mrg in rs6000.c. 6 1.1 mrg 7 1.1 mrg Copyright (C) 2002-2022 Free Software Foundation, Inc. 8 1.1 mrg 9 1.1 mrg This file is part of GCC. 10 1.1 mrg 11 1.1 mrg GCC is free software; you can redistribute it and/or modify it 12 1.1 mrg under the terms of the GNU General Public License as published 13 1.1 mrg by the Free Software Foundation; either version 3, or (at your 14 1.1 mrg option) any later version. 15 1.1 mrg 16 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT 17 1.1 mrg ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18 1.1 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 19 1.1 mrg License for more details. 20 1.1 mrg 21 1.1 mrg You should have received a copy of the GNU General Public License 22 1.1 mrg along with GCC; see the file COPYING3. If not see 23 1.1 mrg <http://www.gnu.org/licenses/>. */ 24 1.1 mrg 25 1.1 mrg #define IN_TARGET_CODE 1 26 1.1 mrg 27 1.1 mrg #include "config.h" 28 1.1 mrg #include "system.h" 29 1.1 mrg #include "coretypes.h" 30 1.1 mrg #include "target.h" 31 1.1 mrg #include "backend.h" 32 1.1 mrg #include "rtl.h" 33 1.1 mrg #include "tree.h" 34 1.1 mrg #include "memmodel.h" 35 1.1 mrg #include "gimple.h" 36 1.1 mrg #include "tm_p.h" 37 1.1 mrg #include "optabs.h" 38 1.1 mrg #include "recog.h" 39 1.1 mrg #include "diagnostic-core.h" 40 1.1 mrg #include "fold-const.h" 41 1.1 mrg #include "stor-layout.h" 42 1.1 mrg #include "calls.h" 43 1.1 mrg #include "varasm.h" 44 1.1 mrg #include "explow.h" 45 1.1 mrg #include "expr.h" 46 1.1 mrg #include "langhooks.h" 47 1.1 mrg #include "gimplify.h" 48 1.1 mrg #include "gimple-fold.h" 49 1.1 mrg #include "gimple-iterator.h" 50 1.1 mrg #include "ssa.h" 51 1.1 mrg #include "tree-ssa-propagate.h" 52 1.1 mrg #include "builtins.h" 53 1.1 mrg #include "tree-vector-builder.h" 54 1.1 mrg #if TARGET_XCOFF 55 1.1 mrg #include "xcoffout.h" /* get declarations of xcoff_*_section_name */ 56 1.1 mrg #endif 57 1.1 mrg #include "ppc-auxv.h" 58 1.1 mrg #include "rs6000-internal.h" 59 1.1 mrg 60 1.1 mrg /* Built in types. */ 61 1.1 mrg tree rs6000_builtin_types[RS6000_BTI_MAX]; 62 1.1 mrg 63 1.1 mrg /* Support targetm.vectorize.builtin_mask_for_load. */ 64 1.1 mrg tree altivec_builtin_mask_for_load; 65 1.1 mrg 66 1.1 mrg /* **** General support functions **** */ 67 1.1 mrg 68 1.1 mrg /* Raise an error message for a builtin function that is called without the 69 1.1 mrg appropriate target options being set. */ 70 1.1 mrg 71 1.1 mrg void 72 1.1 mrg rs6000_invalid_builtin (enum rs6000_gen_builtins fncode) 73 1.1 mrg { 74 1.1 mrg size_t j = (size_t) fncode; 75 1.1 mrg const char *name = rs6000_builtin_info[j].bifname; 76 1.1 mrg 77 1.1 mrg switch (rs6000_builtin_info[j].enable) 78 1.1 mrg { 79 1.1 mrg case ENB_P5: 80 1.1 mrg error ("%qs requires the %qs option", name, "-mcpu=power5"); 81 1.1 mrg break; 82 1.1 mrg case ENB_P6: 83 1.1 mrg error ("%qs requires the %qs option", name, "-mcpu=power6"); 84 1.1 mrg break; 85 1.1 mrg case ENB_P6_64: 86 1.1 mrg error ("%qs requires the %qs option and either the %qs or %qs option", 87 1.1 mrg name, "-mcpu=power6", "-m64", "-mpowerpc64"); 88 1.1 mrg break; 89 1.1 mrg case ENB_ALTIVEC: 90 1.1 mrg error ("%qs requires the %qs option", name, "-maltivec"); 91 1.1 mrg break; 92 1.1 mrg case ENB_CELL: 93 1.1 mrg error ("%qs requires the %qs option", name, "-mcpu=cell"); 94 1.1 mrg break; 95 1.1 mrg case ENB_VSX: 96 1.1 mrg error ("%qs requires the %qs option", name, "-mvsx"); 97 1.1 mrg break; 98 1.1 mrg case ENB_P7: 99 1.1 mrg error ("%qs requires the %qs option", name, "-mcpu=power7"); 100 1.1 mrg break; 101 1.1 mrg case ENB_P7_64: 102 1.1 mrg error ("%qs requires the %qs option and either the %qs or %qs option", 103 1.1 mrg name, "-mcpu=power7", "-m64", "-mpowerpc64"); 104 1.1 mrg break; 105 1.1 mrg case ENB_P8: 106 1.1 mrg error ("%qs requires the %qs option", name, "-mcpu=power8"); 107 1.1 mrg break; 108 1.1 mrg case ENB_P8V: 109 1.1 mrg error ("%qs requires the %qs and %qs options", name, "-mcpu=power8", 110 1.1 mrg "-mvsx"); 111 1.1 mrg break; 112 1.1 mrg case ENB_P9: 113 1.1 mrg error ("%qs requires the %qs option", name, "-mcpu=power9"); 114 1.1 mrg break; 115 1.1 mrg case ENB_P9_64: 116 1.1 mrg error ("%qs requires the %qs option and either the %qs or %qs option", 117 1.1 mrg name, "-mcpu=power9", "-m64", "-mpowerpc64"); 118 1.1 mrg break; 119 1.1 mrg case ENB_P9V: 120 1.1 mrg error ("%qs requires the %qs and %qs options", name, "-mcpu=power9", 121 1.1 mrg "-mvsx"); 122 1.1 mrg break; 123 1.1 mrg case ENB_IEEE128_HW: 124 1.1 mrg error ("%qs requires quad-precision floating-point arithmetic", name); 125 1.1 mrg break; 126 1.1 mrg case ENB_DFP: 127 1.1 mrg error ("%qs requires the %qs option", name, "-mhard-dfp"); 128 1.1 mrg break; 129 1.1 mrg case ENB_CRYPTO: 130 1.1 mrg error ("%qs requires the %qs option", name, "-mcrypto"); 131 1.1 mrg break; 132 1.1 mrg case ENB_HTM: 133 1.1 mrg error ("%qs requires the %qs option", name, "-mhtm"); 134 1.1 mrg break; 135 1.1 mrg case ENB_P10: 136 1.1 mrg error ("%qs requires the %qs option", name, "-mcpu=power10"); 137 1.1 mrg break; 138 1.1 mrg case ENB_P10_64: 139 1.1 mrg error ("%qs requires the %qs option and either the %qs or %qs option", 140 1.1 mrg name, "-mcpu=power10", "-m64", "-mpowerpc64"); 141 1.1 mrg break; 142 1.1 mrg case ENB_MMA: 143 1.1 mrg error ("%qs requires the %qs option", name, "-mmma"); 144 1.1 mrg break; 145 1.1 mrg default: 146 1.1 mrg case ENB_ALWAYS: 147 1.1 mrg gcc_unreachable (); 148 1.1 mrg } 149 1.1 mrg } 150 1.1 mrg 151 1.1 mrg /* Check whether a builtin function is supported in this target 152 1.1 mrg configuration. */ 153 1.1 mrg bool 154 1.1 mrg rs6000_builtin_is_supported (enum rs6000_gen_builtins fncode) 155 1.1 mrg { 156 1.1 mrg switch (rs6000_builtin_info[(size_t) fncode].enable) 157 1.1 mrg { 158 1.1 mrg case ENB_ALWAYS: 159 1.1 mrg return true; 160 1.1 mrg case ENB_P5: 161 1.1 mrg return TARGET_POPCNTB; 162 1.1 mrg case ENB_P6: 163 1.1 mrg return TARGET_CMPB; 164 1.1 mrg case ENB_P6_64: 165 1.1 mrg return TARGET_CMPB && TARGET_POWERPC64; 166 1.1 mrg case ENB_P7: 167 1.1 mrg return TARGET_POPCNTD; 168 1.1 mrg case ENB_P7_64: 169 1.1 mrg return TARGET_POPCNTD && TARGET_POWERPC64; 170 1.1 mrg case ENB_P8: 171 1.1 mrg return TARGET_POWER8; 172 1.1 mrg case ENB_P8V: 173 1.1 mrg return TARGET_P8_VECTOR; 174 1.1 mrg case ENB_P9: 175 1.1 mrg return TARGET_MODULO; 176 1.1 mrg case ENB_P9_64: 177 1.1 mrg return TARGET_MODULO && TARGET_POWERPC64; 178 1.1 mrg case ENB_P9V: 179 1.1 mrg return TARGET_P9_VECTOR; 180 1.1 mrg case ENB_P10: 181 1.1 mrg return TARGET_POWER10; 182 1.1 mrg case ENB_P10_64: 183 1.1 mrg return TARGET_POWER10 && TARGET_POWERPC64; 184 1.1 mrg case ENB_ALTIVEC: 185 1.1 mrg return TARGET_ALTIVEC; 186 1.1 mrg case ENB_VSX: 187 1.1 mrg return TARGET_VSX; 188 1.1 mrg case ENB_CELL: 189 1.1 mrg return TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL; 190 1.1 mrg case ENB_IEEE128_HW: 191 1.1 mrg return TARGET_FLOAT128_HW; 192 1.1 mrg case ENB_DFP: 193 1.1 mrg return TARGET_DFP; 194 1.1 mrg case ENB_CRYPTO: 195 1.1 mrg return TARGET_CRYPTO; 196 1.1 mrg case ENB_HTM: 197 1.1 mrg return TARGET_HTM; 198 1.1 mrg case ENB_MMA: 199 1.1 mrg return TARGET_MMA; 200 1.1 mrg default: 201 1.1 mrg gcc_unreachable (); 202 1.1 mrg } 203 1.1 mrg gcc_unreachable (); 204 1.1 mrg } 205 1.1 mrg 206 1.1 mrg /* Target hook for early folding of built-ins, shamelessly stolen 207 1.1 mrg from ia64.cc. */ 208 1.1 mrg 209 1.1 mrg tree 210 1.1 mrg rs6000_fold_builtin (tree fndecl ATTRIBUTE_UNUSED, 211 1.1 mrg int n_args ATTRIBUTE_UNUSED, 212 1.1 mrg tree *args ATTRIBUTE_UNUSED, 213 1.1 mrg bool ignore ATTRIBUTE_UNUSED) 214 1.1 mrg { 215 1.1 mrg #ifdef SUBTARGET_FOLD_BUILTIN 216 1.1 mrg return SUBTARGET_FOLD_BUILTIN (fndecl, n_args, args, ignore); 217 1.1 mrg #else 218 1.1 mrg return NULL_TREE; 219 1.1 mrg #endif 220 1.1 mrg } 221 1.1 mrg 222 1.1 mrg tree 223 1.1 mrg rs6000_builtin_decl (unsigned code, bool /* initialize_p */) 224 1.1 mrg { 225 1.1 mrg rs6000_gen_builtins fcode = (rs6000_gen_builtins) code; 226 1.1 mrg 227 1.1 mrg if (fcode >= RS6000_OVLD_MAX) 228 1.1 mrg return error_mark_node; 229 1.1 mrg 230 1.1 mrg return rs6000_builtin_decls[code]; 231 1.1 mrg } 232 1.1 mrg 233 1.1 mrg /* Implement targetm.vectorize.builtin_mask_for_load. */ 234 1.1 mrg tree 235 1.1 mrg rs6000_builtin_mask_for_load (void) 236 1.1 mrg { 237 1.1 mrg /* Don't use lvsl/vperm for P8 and similarly efficient machines. */ 238 1.1 mrg if ((TARGET_ALTIVEC && !TARGET_VSX) 239 1.1 mrg || (TARGET_VSX && !TARGET_EFFICIENT_UNALIGNED_VSX)) 240 1.1 mrg return altivec_builtin_mask_for_load; 241 1.1 mrg else 242 1.1 mrg return 0; 243 1.1 mrg } 244 1.1 mrg 245 1.1 mrg /* Implement targetm.vectorize.builtin_md_vectorized_function. */ 246 1.1 mrg 247 1.1 mrg tree 248 1.1 mrg rs6000_builtin_md_vectorized_function (tree fndecl, tree type_out, 249 1.1 mrg tree type_in) 250 1.1 mrg { 251 1.1 mrg machine_mode in_mode, out_mode; 252 1.1 mrg int in_n, out_n; 253 1.1 mrg 254 1.1 mrg if (TARGET_DEBUG_BUILTIN) 255 1.1 mrg fprintf (stderr, 256 1.1 mrg "rs6000_builtin_md_vectorized_function (%s, %s, %s)\n", 257 1.1 mrg IDENTIFIER_POINTER (DECL_NAME (fndecl)), 258 1.1 mrg GET_MODE_NAME (TYPE_MODE (type_out)), 259 1.1 mrg GET_MODE_NAME (TYPE_MODE (type_in))); 260 1.1 mrg 261 1.1 mrg /* TODO: Should this be gcc_assert? */ 262 1.1 mrg if (TREE_CODE (type_out) != VECTOR_TYPE 263 1.1 mrg || TREE_CODE (type_in) != VECTOR_TYPE) 264 1.1 mrg return NULL_TREE; 265 1.1 mrg 266 1.1 mrg out_mode = TYPE_MODE (TREE_TYPE (type_out)); 267 1.1 mrg out_n = TYPE_VECTOR_SUBPARTS (type_out); 268 1.1 mrg in_mode = TYPE_MODE (TREE_TYPE (type_in)); 269 1.1 mrg in_n = TYPE_VECTOR_SUBPARTS (type_in); 270 1.1 mrg 271 1.1 mrg enum rs6000_gen_builtins fn 272 1.1 mrg = (enum rs6000_gen_builtins) DECL_MD_FUNCTION_CODE (fndecl); 273 1.1 mrg switch (fn) 274 1.1 mrg { 275 1.1 mrg case RS6000_BIF_RSQRTF: 276 1.1 mrg if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode) 277 1.1 mrg && out_mode == SFmode && out_n == 4 278 1.1 mrg && in_mode == SFmode && in_n == 4) 279 1.1 mrg return rs6000_builtin_decls[RS6000_BIF_VRSQRTFP]; 280 1.1 mrg break; 281 1.1 mrg case RS6000_BIF_RSQRT: 282 1.1 mrg if (VECTOR_UNIT_VSX_P (V2DFmode) 283 1.1 mrg && out_mode == DFmode && out_n == 2 284 1.1 mrg && in_mode == DFmode && in_n == 2) 285 1.1 mrg return rs6000_builtin_decls[RS6000_BIF_RSQRT_2DF]; 286 1.1 mrg break; 287 1.1 mrg case RS6000_BIF_RECIPF: 288 1.1 mrg if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode) 289 1.1 mrg && out_mode == SFmode && out_n == 4 290 1.1 mrg && in_mode == SFmode && in_n == 4) 291 1.1 mrg return rs6000_builtin_decls[RS6000_BIF_VRECIPFP]; 292 1.1 mrg break; 293 1.1 mrg case RS6000_BIF_RECIP: 294 1.1 mrg if (VECTOR_UNIT_VSX_P (V2DFmode) 295 1.1 mrg && out_mode == DFmode && out_n == 2 296 1.1 mrg && in_mode == DFmode && in_n == 2) 297 1.1 mrg return rs6000_builtin_decls[RS6000_BIF_RECIP_V2DF]; 298 1.1 mrg break; 299 1.1 mrg default: 300 1.1 mrg break; 301 1.1 mrg } 302 1.1 mrg 303 1.1 mrg machine_mode in_vmode = TYPE_MODE (type_in); 304 1.1 mrg machine_mode out_vmode = TYPE_MODE (type_out); 305 1.1 mrg 306 1.1 mrg /* Power10 supported vectorized built-in functions. */ 307 1.1 mrg if (TARGET_POWER10 308 1.1 mrg && in_vmode == out_vmode 309 1.1 mrg && VECTOR_UNIT_ALTIVEC_OR_VSX_P (in_vmode)) 310 1.1 mrg { 311 1.1 mrg machine_mode exp_mode = DImode; 312 1.1 mrg machine_mode exp_vmode = V2DImode; 313 1.1 mrg enum rs6000_gen_builtins bif; 314 1.1 mrg switch (fn) 315 1.1 mrg { 316 1.1 mrg case RS6000_BIF_DIVWE: 317 1.1 mrg case RS6000_BIF_DIVWEU: 318 1.1 mrg exp_mode = SImode; 319 1.1 mrg exp_vmode = V4SImode; 320 1.1 mrg if (fn == RS6000_BIF_DIVWE) 321 1.1 mrg bif = RS6000_BIF_VDIVESW; 322 1.1 mrg else 323 1.1 mrg bif = RS6000_BIF_VDIVEUW; 324 1.1 mrg break; 325 1.1 mrg case RS6000_BIF_DIVDE: 326 1.1 mrg case RS6000_BIF_DIVDEU: 327 1.1 mrg if (fn == RS6000_BIF_DIVDE) 328 1.1 mrg bif = RS6000_BIF_VDIVESD; 329 1.1 mrg else 330 1.1 mrg bif = RS6000_BIF_VDIVEUD; 331 1.1 mrg break; 332 1.1 mrg case RS6000_BIF_CFUGED: 333 1.1 mrg bif = RS6000_BIF_VCFUGED; 334 1.1 mrg break; 335 1.1 mrg case RS6000_BIF_CNTLZDM: 336 1.1 mrg bif = RS6000_BIF_VCLZDM; 337 1.1 mrg break; 338 1.1 mrg case RS6000_BIF_CNTTZDM: 339 1.1 mrg bif = RS6000_BIF_VCTZDM; 340 1.1 mrg break; 341 1.1 mrg case RS6000_BIF_PDEPD: 342 1.1 mrg bif = RS6000_BIF_VPDEPD; 343 1.1 mrg break; 344 1.1 mrg case RS6000_BIF_PEXTD: 345 1.1 mrg bif = RS6000_BIF_VPEXTD; 346 1.1 mrg break; 347 1.1 mrg default: 348 1.1 mrg return NULL_TREE; 349 1.1 mrg } 350 1.1 mrg 351 1.1 mrg if (in_mode == exp_mode && in_vmode == exp_vmode) 352 1.1 mrg return rs6000_builtin_decls[bif]; 353 1.1 mrg } 354 1.1 mrg 355 1.1 mrg return NULL_TREE; 356 1.1 mrg } 357 1.1 mrg 358 1.1 mrg /* Returns a code for a target-specific builtin that implements 359 1.1 mrg reciprocal of the function, or NULL_TREE if not available. */ 360 1.1 mrg 361 1.1 mrg tree 362 1.1 mrg rs6000_builtin_reciprocal (tree fndecl) 363 1.1 mrg { 364 1.1 mrg switch (DECL_MD_FUNCTION_CODE (fndecl)) 365 1.1 mrg { 366 1.1 mrg case RS6000_BIF_XVSQRTDP: 367 1.1 mrg if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode)) 368 1.1 mrg return NULL_TREE; 369 1.1 mrg 370 1.1 mrg return rs6000_builtin_decls[RS6000_BIF_RSQRT_2DF]; 371 1.1 mrg 372 1.1 mrg case RS6000_BIF_XVSQRTSP: 373 1.1 mrg if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode)) 374 1.1 mrg return NULL_TREE; 375 1.1 mrg 376 1.1 mrg return rs6000_builtin_decls[RS6000_BIF_RSQRT_4SF]; 377 1.1 mrg 378 1.1 mrg default: 379 1.1 mrg return NULL_TREE; 380 1.1 mrg } 381 1.1 mrg } 382 1.1 mrg 383 1.1 mrg /* **** Initialization support **** */ 384 1.1 mrg 385 1.1 mrg /* Create a builtin vector type with a name. Taking care not to give 386 1.1 mrg the canonical type a name. */ 387 1.1 mrg 388 1.1 mrg static tree 389 1.1 mrg rs6000_vector_type (const char *name, tree elt_type, unsigned num_elts) 390 1.1 mrg { 391 1.1 mrg tree result = build_vector_type (elt_type, num_elts); 392 1.1 mrg 393 1.1 mrg /* Copy so we don't give the canonical type a name. */ 394 1.1 mrg result = build_variant_type_copy (result); 395 1.1 mrg 396 1.1 mrg add_builtin_type (name, result); 397 1.1 mrg 398 1.1 mrg return result; 399 1.1 mrg } 400 1.1 mrg 401 1.1 mrg /* Debug utility to translate a type node to a single textual token. */ 402 1.1 mrg static 403 1.1 mrg const char *rs6000_type_string (tree type_node) 404 1.1 mrg { 405 1.1 mrg if (type_node == NULL_TREE) 406 1.1 mrg return "**NULL**"; 407 1.1 mrg else if (type_node == void_type_node) 408 1.1 mrg return "void"; 409 1.1 mrg else if (type_node == long_integer_type_node) 410 1.1 mrg return "long"; 411 1.1 mrg else if (type_node == long_unsigned_type_node) 412 1.1 mrg return "ulong"; 413 1.1 mrg else if (type_node == long_long_integer_type_node) 414 1.1 mrg return "longlong"; 415 1.1 mrg else if (type_node == long_long_unsigned_type_node) 416 1.1 mrg return "ulonglong"; 417 1.1 mrg else if (type_node == bool_V2DI_type_node) 418 1.1 mrg return "vbll"; 419 1.1 mrg else if (type_node == bool_V4SI_type_node) 420 1.1 mrg return "vbi"; 421 1.1 mrg else if (type_node == bool_V8HI_type_node) 422 1.1 mrg return "vbs"; 423 1.1 mrg else if (type_node == bool_V16QI_type_node) 424 1.1 mrg return "vbc"; 425 1.1 mrg else if (type_node == bool_int_type_node) 426 1.1 mrg return "bool"; 427 1.1 mrg else if (type_node == dfloat64_type_node) 428 1.1 mrg return "_Decimal64"; 429 1.1 mrg else if (type_node == double_type_node) 430 1.1 mrg return "double"; 431 1.1 mrg else if (type_node == intDI_type_node) 432 1.1 mrg return "sll"; 433 1.1 mrg else if (type_node == intHI_type_node) 434 1.1 mrg return "ss"; 435 1.1 mrg else if (type_node == ibm128_float_type_node) 436 1.1 mrg return "__ibm128"; 437 1.1 mrg else if (type_node == ieee128_float_type_node) 438 1.1 mrg return "__ieee128"; 439 1.1 mrg else if (type_node == opaque_V4SI_type_node) 440 1.1 mrg return "opaque"; 441 1.1 mrg else if (POINTER_TYPE_P (type_node)) 442 1.1 mrg return "void*"; 443 1.1 mrg else if (type_node == intQI_type_node || type_node == char_type_node) 444 1.1 mrg return "sc"; 445 1.1 mrg else if (type_node == dfloat32_type_node) 446 1.1 mrg return "_Decimal32"; 447 1.1 mrg else if (type_node == float_type_node) 448 1.1 mrg return "float"; 449 1.1 mrg else if (type_node == intSI_type_node || type_node == integer_type_node) 450 1.1 mrg return "si"; 451 1.1 mrg else if (type_node == dfloat128_type_node) 452 1.1 mrg return "_Decimal128"; 453 1.1 mrg else if (type_node == long_double_type_node) 454 1.1 mrg return "longdouble"; 455 1.1 mrg else if (type_node == intTI_type_node) 456 1.1 mrg return "sq"; 457 1.1 mrg else if (type_node == unsigned_intDI_type_node) 458 1.1 mrg return "ull"; 459 1.1 mrg else if (type_node == unsigned_intHI_type_node) 460 1.1 mrg return "us"; 461 1.1 mrg else if (type_node == unsigned_intQI_type_node) 462 1.1 mrg return "uc"; 463 1.1 mrg else if (type_node == unsigned_intSI_type_node) 464 1.1 mrg return "ui"; 465 1.1 mrg else if (type_node == unsigned_intTI_type_node) 466 1.1 mrg return "uq"; 467 1.1 mrg else if (type_node == unsigned_V1TI_type_node) 468 1.1 mrg return "vuq"; 469 1.1 mrg else if (type_node == unsigned_V2DI_type_node) 470 1.1 mrg return "vull"; 471 1.1 mrg else if (type_node == unsigned_V4SI_type_node) 472 1.1 mrg return "vui"; 473 1.1 mrg else if (type_node == unsigned_V8HI_type_node) 474 1.1 mrg return "vus"; 475 1.1 mrg else if (type_node == unsigned_V16QI_type_node) 476 1.1 mrg return "vuc"; 477 1.1 mrg else if (type_node == V16QI_type_node) 478 1.1 mrg return "vsc"; 479 1.1 mrg else if (type_node == V1TI_type_node) 480 1.1 mrg return "vsq"; 481 1.1 mrg else if (type_node == V2DF_type_node) 482 1.1 mrg return "vd"; 483 1.1 mrg else if (type_node == V2DI_type_node) 484 1.1 mrg return "vsll"; 485 1.1 mrg else if (type_node == V4SF_type_node) 486 1.1 mrg return "vf"; 487 1.1 mrg else if (type_node == V4SI_type_node) 488 1.1 mrg return "vsi"; 489 1.1 mrg else if (type_node == V8HI_type_node) 490 1.1 mrg return "vss"; 491 1.1 mrg else if (type_node == pixel_V8HI_type_node) 492 1.1 mrg return "vp"; 493 1.1 mrg else if (type_node == pcvoid_type_node) 494 1.1 mrg return "voidc*"; 495 1.1 mrg else if (type_node == float128_type_node) 496 1.1 mrg return "_Float128"; 497 1.1 mrg else if (type_node == vector_pair_type_node) 498 1.1 mrg return "__vector_pair"; 499 1.1 mrg else if (type_node == vector_quad_type_node) 500 1.1 mrg return "__vector_quad"; 501 1.1 mrg 502 1.1 mrg return "unknown"; 503 1.1 mrg } 504 1.1 mrg 505 1.1 mrg void 506 1.1 mrg rs6000_init_builtins (void) 507 1.1 mrg { 508 1.1 mrg tree tdecl; 509 1.1 mrg tree t; 510 1.1 mrg 511 1.1 mrg if (TARGET_DEBUG_BUILTIN) 512 1.1 mrg fprintf (stderr, "rs6000_init_builtins%s%s\n", 513 1.1 mrg (TARGET_ALTIVEC) ? ", altivec" : "", 514 1.1 mrg (TARGET_VSX) ? ", vsx" : ""); 515 1.1 mrg 516 1.1 mrg V2DI_type_node = rs6000_vector_type ("__vector long long", 517 1.1 mrg long_long_integer_type_node, 2); 518 1.1 mrg ptr_V2DI_type_node 519 1.1 mrg = build_pointer_type (build_qualified_type (V2DI_type_node, 520 1.1 mrg TYPE_QUAL_CONST)); 521 1.1 mrg 522 1.1 mrg V2DF_type_node = rs6000_vector_type ("__vector double", double_type_node, 2); 523 1.1 mrg ptr_V2DF_type_node 524 1.1 mrg = build_pointer_type (build_qualified_type (V2DF_type_node, 525 1.1 mrg TYPE_QUAL_CONST)); 526 1.1 mrg 527 1.1 mrg V4SI_type_node = rs6000_vector_type ("__vector signed int", 528 1.1 mrg intSI_type_node, 4); 529 1.1 mrg ptr_V4SI_type_node 530 1.1 mrg = build_pointer_type (build_qualified_type (V4SI_type_node, 531 1.1 mrg TYPE_QUAL_CONST)); 532 1.1 mrg 533 1.1 mrg V4SF_type_node = rs6000_vector_type ("__vector float", float_type_node, 4); 534 1.1 mrg ptr_V4SF_type_node 535 1.1 mrg = build_pointer_type (build_qualified_type (V4SF_type_node, 536 1.1 mrg TYPE_QUAL_CONST)); 537 1.1 mrg 538 1.1 mrg V8HI_type_node = rs6000_vector_type ("__vector signed short", 539 1.1 mrg intHI_type_node, 8); 540 1.1 mrg ptr_V8HI_type_node 541 1.1 mrg = build_pointer_type (build_qualified_type (V8HI_type_node, 542 1.1 mrg TYPE_QUAL_CONST)); 543 1.1 mrg 544 1.1 mrg V16QI_type_node = rs6000_vector_type ("__vector signed char", 545 1.1 mrg intQI_type_node, 16); 546 1.1 mrg ptr_V16QI_type_node 547 1.1 mrg = build_pointer_type (build_qualified_type (V16QI_type_node, 548 1.1 mrg TYPE_QUAL_CONST)); 549 1.1 mrg 550 1.1 mrg unsigned_V16QI_type_node = rs6000_vector_type ("__vector unsigned char", 551 1.1 mrg unsigned_intQI_type_node, 16); 552 1.1 mrg ptr_unsigned_V16QI_type_node 553 1.1 mrg = build_pointer_type (build_qualified_type (unsigned_V16QI_type_node, 554 1.1 mrg TYPE_QUAL_CONST)); 555 1.1 mrg 556 1.1 mrg unsigned_V8HI_type_node = rs6000_vector_type ("__vector unsigned short", 557 1.1 mrg unsigned_intHI_type_node, 8); 558 1.1 mrg ptr_unsigned_V8HI_type_node 559 1.1 mrg = build_pointer_type (build_qualified_type (unsigned_V8HI_type_node, 560 1.1 mrg TYPE_QUAL_CONST)); 561 1.1 mrg 562 1.1 mrg unsigned_V4SI_type_node = rs6000_vector_type ("__vector unsigned int", 563 1.1 mrg unsigned_intSI_type_node, 4); 564 1.1 mrg ptr_unsigned_V4SI_type_node 565 1.1 mrg = build_pointer_type (build_qualified_type (unsigned_V4SI_type_node, 566 1.1 mrg TYPE_QUAL_CONST)); 567 1.1 mrg 568 1.1 mrg unsigned_V2DI_type_node 569 1.1 mrg = rs6000_vector_type ("__vector unsigned long long", 570 1.1 mrg long_long_unsigned_type_node, 2); 571 1.1 mrg 572 1.1 mrg ptr_unsigned_V2DI_type_node 573 1.1 mrg = build_pointer_type (build_qualified_type (unsigned_V2DI_type_node, 574 1.1 mrg TYPE_QUAL_CONST)); 575 1.1 mrg 576 1.1 mrg opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4); 577 1.1 mrg 578 1.1 mrg const_str_type_node 579 1.1 mrg = build_pointer_type (build_qualified_type (char_type_node, 580 1.1 mrg TYPE_QUAL_CONST)); 581 1.1 mrg 582 1.1 mrg /* We use V1TI mode as a special container to hold __int128_t items that 583 1.1 mrg must live in VSX registers. */ 584 1.1 mrg if (intTI_type_node) 585 1.1 mrg { 586 1.1 mrg V1TI_type_node = rs6000_vector_type ("__vector __int128", 587 1.1 mrg intTI_type_node, 1); 588 1.1 mrg ptr_V1TI_type_node 589 1.1 mrg = build_pointer_type (build_qualified_type (V1TI_type_node, 590 1.1 mrg TYPE_QUAL_CONST)); 591 1.1 mrg unsigned_V1TI_type_node 592 1.1 mrg = rs6000_vector_type ("__vector unsigned __int128", 593 1.1 mrg unsigned_intTI_type_node, 1); 594 1.1 mrg ptr_unsigned_V1TI_type_node 595 1.1 mrg = build_pointer_type (build_qualified_type (unsigned_V1TI_type_node, 596 1.1 mrg TYPE_QUAL_CONST)); 597 1.1 mrg } 598 1.1 mrg 599 1.1 mrg /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...' 600 1.1 mrg types, especially in C++ land. Similarly, 'vector pixel' is distinct from 601 1.1 mrg 'vector unsigned short'. */ 602 1.1 mrg 603 1.1 mrg bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node); 604 1.1 mrg bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node); 605 1.1 mrg bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node); 606 1.1 mrg bool_long_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node); 607 1.1 mrg pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node); 608 1.1 mrg 609 1.1 mrg long_integer_type_internal_node = long_integer_type_node; 610 1.1 mrg long_unsigned_type_internal_node = long_unsigned_type_node; 611 1.1 mrg long_long_integer_type_internal_node = long_long_integer_type_node; 612 1.1 mrg long_long_unsigned_type_internal_node = long_long_unsigned_type_node; 613 1.1 mrg intQI_type_internal_node = intQI_type_node; 614 1.1 mrg uintQI_type_internal_node = unsigned_intQI_type_node; 615 1.1 mrg intHI_type_internal_node = intHI_type_node; 616 1.1 mrg uintHI_type_internal_node = unsigned_intHI_type_node; 617 1.1 mrg intSI_type_internal_node = intSI_type_node; 618 1.1 mrg uintSI_type_internal_node = unsigned_intSI_type_node; 619 1.1 mrg intDI_type_internal_node = intDI_type_node; 620 1.1 mrg uintDI_type_internal_node = unsigned_intDI_type_node; 621 1.1 mrg intTI_type_internal_node = intTI_type_node; 622 1.1 mrg uintTI_type_internal_node = unsigned_intTI_type_node; 623 1.1 mrg float_type_internal_node = float_type_node; 624 1.1 mrg double_type_internal_node = double_type_node; 625 1.1 mrg long_double_type_internal_node = long_double_type_node; 626 1.1 mrg dfloat64_type_internal_node = dfloat64_type_node; 627 1.1 mrg dfloat128_type_internal_node = dfloat128_type_node; 628 1.1 mrg void_type_internal_node = void_type_node; 629 1.1 mrg 630 1.1 mrg ptr_intQI_type_node 631 1.1 mrg = build_pointer_type (build_qualified_type (intQI_type_internal_node, 632 1.1 mrg TYPE_QUAL_CONST)); 633 1.1 mrg ptr_uintQI_type_node 634 1.1 mrg = build_pointer_type (build_qualified_type (uintQI_type_internal_node, 635 1.1 mrg TYPE_QUAL_CONST)); 636 1.1 mrg ptr_intHI_type_node 637 1.1 mrg = build_pointer_type (build_qualified_type (intHI_type_internal_node, 638 1.1 mrg TYPE_QUAL_CONST)); 639 1.1 mrg ptr_uintHI_type_node 640 1.1 mrg = build_pointer_type (build_qualified_type (uintHI_type_internal_node, 641 1.1 mrg TYPE_QUAL_CONST)); 642 1.1 mrg ptr_intSI_type_node 643 1.1 mrg = build_pointer_type (build_qualified_type (intSI_type_internal_node, 644 1.1 mrg TYPE_QUAL_CONST)); 645 1.1 mrg ptr_uintSI_type_node 646 1.1 mrg = build_pointer_type (build_qualified_type (uintSI_type_internal_node, 647 1.1 mrg TYPE_QUAL_CONST)); 648 1.1 mrg ptr_intDI_type_node 649 1.1 mrg = build_pointer_type (build_qualified_type (intDI_type_internal_node, 650 1.1 mrg TYPE_QUAL_CONST)); 651 1.1 mrg ptr_uintDI_type_node 652 1.1 mrg = build_pointer_type (build_qualified_type (uintDI_type_internal_node, 653 1.1 mrg TYPE_QUAL_CONST)); 654 1.1 mrg ptr_intTI_type_node 655 1.1 mrg = build_pointer_type (build_qualified_type (intTI_type_internal_node, 656 1.1 mrg TYPE_QUAL_CONST)); 657 1.1 mrg ptr_uintTI_type_node 658 1.1 mrg = build_pointer_type (build_qualified_type (uintTI_type_internal_node, 659 1.1 mrg TYPE_QUAL_CONST)); 660 1.1 mrg 661 1.1 mrg t = build_qualified_type (long_integer_type_internal_node, TYPE_QUAL_CONST); 662 1.1 mrg ptr_long_integer_type_node = build_pointer_type (t); 663 1.1 mrg 664 1.1 mrg t = build_qualified_type (long_unsigned_type_internal_node, TYPE_QUAL_CONST); 665 1.1 mrg ptr_long_unsigned_type_node = build_pointer_type (t); 666 1.1 mrg 667 1.1 mrg ptr_float_type_node 668 1.1 mrg = build_pointer_type (build_qualified_type (float_type_internal_node, 669 1.1 mrg TYPE_QUAL_CONST)); 670 1.1 mrg ptr_double_type_node 671 1.1 mrg = build_pointer_type (build_qualified_type (double_type_internal_node, 672 1.1 mrg TYPE_QUAL_CONST)); 673 1.1 mrg ptr_long_double_type_node 674 1.1 mrg = build_pointer_type (build_qualified_type (long_double_type_internal_node, 675 1.1 mrg TYPE_QUAL_CONST)); 676 1.1 mrg if (dfloat64_type_node) 677 1.1 mrg { 678 1.1 mrg t = build_qualified_type (dfloat64_type_internal_node, TYPE_QUAL_CONST); 679 1.1 mrg ptr_dfloat64_type_node = build_pointer_type (t); 680 1.1 mrg } 681 1.1 mrg else 682 1.1 mrg ptr_dfloat64_type_node = NULL; 683 1.1 mrg 684 1.1 mrg if (dfloat128_type_node) 685 1.1 mrg { 686 1.1 mrg t = build_qualified_type (dfloat128_type_internal_node, TYPE_QUAL_CONST); 687 1.1 mrg ptr_dfloat128_type_node = build_pointer_type (t); 688 1.1 mrg } 689 1.1 mrg else 690 1.1 mrg ptr_dfloat128_type_node = NULL; 691 1.1 mrg 692 1.1 mrg t = build_qualified_type (long_long_integer_type_internal_node, 693 1.1 mrg TYPE_QUAL_CONST); 694 1.1 mrg ptr_long_long_integer_type_node = build_pointer_type (t); 695 1.1 mrg 696 1.1 mrg t = build_qualified_type (long_long_unsigned_type_internal_node, 697 1.1 mrg TYPE_QUAL_CONST); 698 1.1 mrg ptr_long_long_unsigned_type_node = build_pointer_type (t); 699 1.1 mrg 700 1.1 mrg /* 128-bit floating point support. KFmode is IEEE 128-bit floating point. 701 1.1 mrg IFmode is the IBM extended 128-bit format that is a pair of doubles. 702 1.1 mrg TFmode will be either IEEE 128-bit floating point or the IBM double-double 703 1.1 mrg format that uses a pair of doubles, depending on the switches and 704 1.1 mrg defaults. 705 1.1 mrg 706 1.1 mrg If we don't support for either 128-bit IBM double double or IEEE 128-bit 707 1.1 mrg floating point, we need make sure the type is non-zero or else self-test 708 1.1 mrg fails during bootstrap. 709 1.1 mrg 710 1.1 mrg Always create __ibm128 as a separate type, even if the current long double 711 1.1 mrg format is IBM extended double. 712 1.1 mrg 713 1.1 mrg For IEEE 128-bit floating point, always create the type __ieee128. If the 714 1.1 mrg user used -mfloat128, rs6000-c.cc will create a define from __float128 to 715 1.1 mrg __ieee128. */ 716 1.1 mrg if (TARGET_LONG_DOUBLE_128 && (!TARGET_IEEEQUAD || TARGET_FLOAT128_TYPE)) 717 1.1 mrg { 718 1.1 mrg if (!TARGET_IEEEQUAD) 719 1.1 mrg ibm128_float_type_node = long_double_type_node; 720 1.1 mrg else 721 1.1 mrg { 722 1.1 mrg ibm128_float_type_node = make_node (REAL_TYPE); 723 1.1 mrg TYPE_PRECISION (ibm128_float_type_node) = 128; 724 1.1 mrg SET_TYPE_MODE (ibm128_float_type_node, IFmode); 725 1.1 mrg layout_type (ibm128_float_type_node); 726 1.1 mrg } 727 1.1 mrg t = build_qualified_type (ibm128_float_type_node, TYPE_QUAL_CONST); 728 1.1 mrg lang_hooks.types.register_builtin_type (ibm128_float_type_node, 729 1.1 mrg "__ibm128"); 730 1.1 mrg } 731 1.1 mrg else 732 1.1 mrg ibm128_float_type_node = NULL_TREE; 733 1.1 mrg 734 1.1 mrg if (TARGET_FLOAT128_TYPE) 735 1.1 mrg { 736 1.1 mrg if (TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128) 737 1.1 mrg ieee128_float_type_node = long_double_type_node; 738 1.1 mrg else 739 1.1 mrg ieee128_float_type_node = float128_type_node; 740 1.1 mrg t = build_qualified_type (ieee128_float_type_node, TYPE_QUAL_CONST); 741 1.1 mrg lang_hooks.types.register_builtin_type (ieee128_float_type_node, 742 1.1 mrg "__ieee128"); 743 1.1 mrg } 744 1.1 mrg else 745 1.1 mrg ieee128_float_type_node = NULL_TREE; 746 1.1 mrg 747 1.1 mrg /* Vector pair and vector quad support. */ 748 1.1 mrg vector_pair_type_node = make_node (OPAQUE_TYPE); 749 1.1 mrg SET_TYPE_MODE (vector_pair_type_node, OOmode); 750 1.1 mrg TYPE_SIZE (vector_pair_type_node) = bitsize_int (GET_MODE_BITSIZE (OOmode)); 751 1.1 mrg TYPE_PRECISION (vector_pair_type_node) = GET_MODE_BITSIZE (OOmode); 752 1.1 mrg TYPE_SIZE_UNIT (vector_pair_type_node) = size_int (GET_MODE_SIZE (OOmode)); 753 1.1 mrg SET_TYPE_ALIGN (vector_pair_type_node, 256); 754 1.1 mrg TYPE_USER_ALIGN (vector_pair_type_node) = 0; 755 1.1 mrg lang_hooks.types.register_builtin_type (vector_pair_type_node, 756 1.1 mrg "__vector_pair"); 757 1.1 mrg t = build_qualified_type (vector_pair_type_node, TYPE_QUAL_CONST); 758 1.1 mrg ptr_vector_pair_type_node = build_pointer_type (t); 759 1.1 mrg 760 1.1 mrg vector_quad_type_node = make_node (OPAQUE_TYPE); 761 1.1 mrg SET_TYPE_MODE (vector_quad_type_node, XOmode); 762 1.1 mrg TYPE_SIZE (vector_quad_type_node) = bitsize_int (GET_MODE_BITSIZE (XOmode)); 763 1.1 mrg TYPE_PRECISION (vector_quad_type_node) = GET_MODE_BITSIZE (XOmode); 764 1.1 mrg TYPE_SIZE_UNIT (vector_quad_type_node) = size_int (GET_MODE_SIZE (XOmode)); 765 1.1 mrg SET_TYPE_ALIGN (vector_quad_type_node, 512); 766 1.1 mrg TYPE_USER_ALIGN (vector_quad_type_node) = 0; 767 1.1 mrg lang_hooks.types.register_builtin_type (vector_quad_type_node, 768 1.1 mrg "__vector_quad"); 769 1.1 mrg t = build_qualified_type (vector_quad_type_node, TYPE_QUAL_CONST); 770 1.1 mrg ptr_vector_quad_type_node = build_pointer_type (t); 771 1.1 mrg 772 1.1 mrg tdecl = add_builtin_type ("__bool char", bool_char_type_node); 773 1.1 mrg TYPE_NAME (bool_char_type_node) = tdecl; 774 1.1 mrg 775 1.1 mrg tdecl = add_builtin_type ("__bool short", bool_short_type_node); 776 1.1 mrg TYPE_NAME (bool_short_type_node) = tdecl; 777 1.1 mrg 778 1.1 mrg tdecl = add_builtin_type ("__bool int", bool_int_type_node); 779 1.1 mrg TYPE_NAME (bool_int_type_node) = tdecl; 780 1.1 mrg 781 1.1 mrg tdecl = add_builtin_type ("__pixel", pixel_type_node); 782 1.1 mrg TYPE_NAME (pixel_type_node) = tdecl; 783 1.1 mrg 784 1.1 mrg bool_V16QI_type_node = rs6000_vector_type ("__vector __bool char", 785 1.1 mrg bool_char_type_node, 16); 786 1.1 mrg ptr_bool_V16QI_type_node 787 1.1 mrg = build_pointer_type (build_qualified_type (bool_V16QI_type_node, 788 1.1 mrg TYPE_QUAL_CONST)); 789 1.1 mrg 790 1.1 mrg bool_V8HI_type_node = rs6000_vector_type ("__vector __bool short", 791 1.1 mrg bool_short_type_node, 8); 792 1.1 mrg ptr_bool_V8HI_type_node 793 1.1 mrg = build_pointer_type (build_qualified_type (bool_V8HI_type_node, 794 1.1 mrg TYPE_QUAL_CONST)); 795 1.1 mrg 796 1.1 mrg bool_V4SI_type_node = rs6000_vector_type ("__vector __bool int", 797 1.1 mrg bool_int_type_node, 4); 798 1.1 mrg ptr_bool_V4SI_type_node 799 1.1 mrg = build_pointer_type (build_qualified_type (bool_V4SI_type_node, 800 1.1 mrg TYPE_QUAL_CONST)); 801 1.1 mrg 802 1.1 mrg bool_V2DI_type_node = rs6000_vector_type (TARGET_POWERPC64 803 1.1 mrg ? "__vector __bool long" 804 1.1 mrg : "__vector __bool long long", 805 1.1 mrg bool_long_long_type_node, 2); 806 1.1 mrg ptr_bool_V2DI_type_node 807 1.1 mrg = build_pointer_type (build_qualified_type (bool_V2DI_type_node, 808 1.1 mrg TYPE_QUAL_CONST)); 809 1.1 mrg 810 1.1 mrg bool_V1TI_type_node = rs6000_vector_type ("__vector __bool __int128", 811 1.1 mrg intTI_type_node, 1); 812 1.1 mrg ptr_bool_V1TI_type_node 813 1.1 mrg = build_pointer_type (build_qualified_type (bool_V1TI_type_node, 814 1.1 mrg TYPE_QUAL_CONST)); 815 1.1 mrg 816 1.1 mrg pixel_V8HI_type_node = rs6000_vector_type ("__vector __pixel", 817 1.1 mrg pixel_type_node, 8); 818 1.1 mrg ptr_pixel_V8HI_type_node 819 1.1 mrg = build_pointer_type (build_qualified_type (pixel_V8HI_type_node, 820 1.1 mrg TYPE_QUAL_CONST)); 821 1.1 mrg pcvoid_type_node 822 1.1 mrg = build_pointer_type (build_qualified_type (void_type_node, 823 1.1 mrg TYPE_QUAL_CONST)); 824 1.1 mrg 825 1.1 mrg /* Execute the autogenerated initialization code for builtins. */ 826 1.1 mrg rs6000_init_generated_builtins (); 827 1.1 mrg 828 1.1 mrg if (TARGET_DEBUG_BUILTIN) 829 1.1 mrg { 830 1.1 mrg fprintf (stderr, "\nAutogenerated built-in functions:\n\n"); 831 1.1 mrg for (int i = 1; i < (int) RS6000_BIF_MAX; i++) 832 1.1 mrg { 833 1.1 mrg bif_enable e = rs6000_builtin_info[i].enable; 834 1.1 mrg if (e == ENB_P5 && !TARGET_POPCNTB) 835 1.1 mrg continue; 836 1.1 mrg if (e == ENB_P6 && !TARGET_CMPB) 837 1.1 mrg continue; 838 1.1 mrg if (e == ENB_P6_64 && !(TARGET_CMPB && TARGET_POWERPC64)) 839 1.1 mrg continue; 840 1.1 mrg if (e == ENB_ALTIVEC && !TARGET_ALTIVEC) 841 1.1 mrg continue; 842 1.1 mrg if (e == ENB_VSX && !TARGET_VSX) 843 1.1 mrg continue; 844 1.1 mrg if (e == ENB_P7 && !TARGET_POPCNTD) 845 1.1 mrg continue; 846 1.1 mrg if (e == ENB_P7_64 && !(TARGET_POPCNTD && TARGET_POWERPC64)) 847 1.1 mrg continue; 848 1.1 mrg if (e == ENB_P8 && !TARGET_DIRECT_MOVE) 849 1.1 mrg continue; 850 1.1 mrg if (e == ENB_P8V && !TARGET_P8_VECTOR) 851 1.1 mrg continue; 852 1.1 mrg if (e == ENB_P9 && !TARGET_MODULO) 853 1.1 mrg continue; 854 1.1 mrg if (e == ENB_P9_64 && !(TARGET_MODULO && TARGET_POWERPC64)) 855 1.1 mrg continue; 856 1.1 mrg if (e == ENB_P9V && !TARGET_P9_VECTOR) 857 1.1 mrg continue; 858 1.1 mrg if (e == ENB_IEEE128_HW && !TARGET_FLOAT128_HW) 859 1.1 mrg continue; 860 1.1 mrg if (e == ENB_DFP && !TARGET_DFP) 861 1.1 mrg continue; 862 1.1 mrg if (e == ENB_CRYPTO && !TARGET_CRYPTO) 863 1.1 mrg continue; 864 1.1 mrg if (e == ENB_HTM && !TARGET_HTM) 865 1.1 mrg continue; 866 1.1 mrg if (e == ENB_P10 && !TARGET_POWER10) 867 1.1 mrg continue; 868 1.1 mrg if (e == ENB_P10_64 && !(TARGET_POWER10 && TARGET_POWERPC64)) 869 1.1 mrg continue; 870 1.1 mrg if (e == ENB_MMA && !TARGET_MMA) 871 1.1 mrg continue; 872 1.1 mrg tree fntype = rs6000_builtin_info_fntype[i]; 873 1.1 mrg tree t = TREE_TYPE (fntype); 874 1.1 mrg fprintf (stderr, "%s %s (", rs6000_type_string (t), 875 1.1 mrg rs6000_builtin_info[i].bifname); 876 1.1 mrg t = TYPE_ARG_TYPES (fntype); 877 1.1 mrg while (t && TREE_VALUE (t) != void_type_node) 878 1.1 mrg { 879 1.1 mrg fprintf (stderr, "%s", 880 1.1 mrg rs6000_type_string (TREE_VALUE (t))); 881 1.1 mrg t = TREE_CHAIN (t); 882 1.1 mrg if (t && TREE_VALUE (t) != void_type_node) 883 1.1 mrg fprintf (stderr, ", "); 884 1.1 mrg } 885 1.1 mrg fprintf (stderr, "); %s [%4d]\n", 886 1.1 mrg rs6000_builtin_info[i].attr_string, (int) i); 887 1.1 mrg } 888 1.1 mrg fprintf (stderr, "\nEnd autogenerated built-in functions.\n\n\n"); 889 1.1 mrg } 890 1.1 mrg 891 1.1 mrg if (TARGET_XCOFF) 892 1.1 mrg { 893 1.1 mrg /* AIX libm provides clog as __clog. */ 894 1.1 mrg if ((tdecl = builtin_decl_explicit (BUILT_IN_CLOG)) != NULL_TREE) 895 1.1 mrg set_user_assembler_name (tdecl, "__clog"); 896 1.1 mrg 897 1.1 mrg /* When long double is 64 bit, some long double builtins of libc 898 1.1 mrg functions (like __builtin_frexpl) must call the double version 899 1.1 mrg (frexp) not the long double version (frexpl) that expects a 128 bit 900 1.1 mrg argument. */ 901 1.1 mrg if (! TARGET_LONG_DOUBLE_128) 902 1.1 mrg { 903 1.1 mrg if ((tdecl = builtin_decl_explicit (BUILT_IN_FMODL)) != NULL_TREE) 904 1.1 mrg set_user_assembler_name (tdecl, "fmod"); 905 1.1 mrg if ((tdecl = builtin_decl_explicit (BUILT_IN_FREXPL)) != NULL_TREE) 906 1.1 mrg set_user_assembler_name (tdecl, "frexp"); 907 1.1 mrg if ((tdecl = builtin_decl_explicit (BUILT_IN_LDEXPL)) != NULL_TREE) 908 1.1 mrg set_user_assembler_name (tdecl, "ldexp"); 909 1.1 mrg if ((tdecl = builtin_decl_explicit (BUILT_IN_MODFL)) != NULL_TREE) 910 1.1 mrg set_user_assembler_name (tdecl, "modf"); 911 1.1 mrg } 912 1.1 mrg } 913 1.1 mrg 914 1.1 mrg altivec_builtin_mask_for_load 915 1.1 mrg = rs6000_builtin_decls[RS6000_BIF_MASK_FOR_LOAD]; 916 1.1 mrg 917 1.1 mrg #ifdef SUBTARGET_INIT_BUILTINS 918 1.1 mrg SUBTARGET_INIT_BUILTINS; 919 1.1 mrg #endif 920 1.1 mrg 921 1.1 mrg return; 922 1.1 mrg } 923 1.1 mrg 924 1.1 mrg /* **** GIMPLE folding support **** */ 925 1.1 mrg 926 1.1 mrg /* Helper function to handle the gimple folding of a vector compare 927 1.1 mrg operation. This sets up true/false vectors, and uses the 928 1.1 mrg VEC_COND_EXPR operation. 929 1.1 mrg CODE indicates which comparison is to be made. (EQ, GT, ...). 930 1.1 mrg TYPE indicates the type of the result. 931 1.1 mrg Code is inserted before GSI. */ 932 1.1 mrg static tree 933 1.1 mrg fold_build_vec_cmp (tree_code code, tree type, tree arg0, tree arg1, 934 1.1 mrg gimple_stmt_iterator *gsi) 935 1.1 mrg { 936 1.1 mrg tree cmp_type = truth_type_for (type); 937 1.1 mrg tree zero_vec = build_zero_cst (type); 938 1.1 mrg tree minus_one_vec = build_minus_one_cst (type); 939 1.1 mrg tree temp = create_tmp_reg_or_ssa_name (cmp_type); 940 1.1 mrg gimple *g = gimple_build_assign (temp, code, arg0, arg1); 941 1.1 mrg gsi_insert_before (gsi, g, GSI_SAME_STMT); 942 1.1 mrg return fold_build3 (VEC_COND_EXPR, type, temp, minus_one_vec, zero_vec); 943 1.1 mrg } 944 1.1 mrg 945 1.1 mrg /* Helper function to handle the in-between steps for the 946 1.1 mrg vector compare built-ins. */ 947 1.1 mrg static void 948 1.1 mrg fold_compare_helper (gimple_stmt_iterator *gsi, tree_code code, gimple *stmt) 949 1.1 mrg { 950 1.1 mrg tree arg0 = gimple_call_arg (stmt, 0); 951 1.1 mrg tree arg1 = gimple_call_arg (stmt, 1); 952 1.1 mrg tree lhs = gimple_call_lhs (stmt); 953 1.1 mrg tree cmp = fold_build_vec_cmp (code, TREE_TYPE (lhs), arg0, arg1, gsi); 954 1.1 mrg gimple *g = gimple_build_assign (lhs, cmp); 955 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 956 1.1 mrg gsi_replace (gsi, g, true); 957 1.1 mrg } 958 1.1 mrg 959 1.1 mrg /* Helper function to map V2DF and V4SF types to their 960 1.1 mrg integral equivalents (V2DI and V4SI). */ 961 1.1 mrg tree map_to_integral_tree_type (tree input_tree_type) 962 1.1 mrg { 963 1.1 mrg if (INTEGRAL_TYPE_P (TREE_TYPE (input_tree_type))) 964 1.1 mrg return input_tree_type; 965 1.1 mrg else 966 1.1 mrg { 967 1.1 mrg if (types_compatible_p (TREE_TYPE (input_tree_type), 968 1.1 mrg TREE_TYPE (V2DF_type_node))) 969 1.1 mrg return V2DI_type_node; 970 1.1 mrg else if (types_compatible_p (TREE_TYPE (input_tree_type), 971 1.1 mrg TREE_TYPE (V4SF_type_node))) 972 1.1 mrg return V4SI_type_node; 973 1.1 mrg else 974 1.1 mrg gcc_unreachable (); 975 1.1 mrg } 976 1.1 mrg } 977 1.1 mrg 978 1.1 mrg /* Helper function to handle the vector merge[hl] built-ins. The 979 1.1 mrg implementation difference between h and l versions for this code are in 980 1.1 mrg the values used when building of the permute vector for high word versus 981 1.1 mrg low word merge. The variance is keyed off the use_high parameter. */ 982 1.1 mrg static void 983 1.1 mrg fold_mergehl_helper (gimple_stmt_iterator *gsi, gimple *stmt, int use_high) 984 1.1 mrg { 985 1.1 mrg tree arg0 = gimple_call_arg (stmt, 0); 986 1.1 mrg tree arg1 = gimple_call_arg (stmt, 1); 987 1.1 mrg tree lhs = gimple_call_lhs (stmt); 988 1.1 mrg tree lhs_type = TREE_TYPE (lhs); 989 1.1 mrg int n_elts = TYPE_VECTOR_SUBPARTS (lhs_type); 990 1.1 mrg int midpoint = n_elts / 2; 991 1.1 mrg int offset = 0; 992 1.1 mrg 993 1.1 mrg if (use_high == 1) 994 1.1 mrg offset = midpoint; 995 1.1 mrg 996 1.1 mrg /* The permute_type will match the lhs for integral types. For double and 997 1.1 mrg float types, the permute type needs to map to the V2 or V4 type that 998 1.1 mrg matches size. */ 999 1.1 mrg tree permute_type; 1000 1.1 mrg permute_type = map_to_integral_tree_type (lhs_type); 1001 1.1 mrg tree_vector_builder elts (permute_type, VECTOR_CST_NELTS (arg0), 1); 1002 1.1 mrg 1003 1.1 mrg for (int i = 0; i < midpoint; i++) 1004 1.1 mrg { 1005 1.1 mrg elts.safe_push (build_int_cst (TREE_TYPE (permute_type), 1006 1.1 mrg offset + i)); 1007 1.1 mrg elts.safe_push (build_int_cst (TREE_TYPE (permute_type), 1008 1.1 mrg offset + n_elts + i)); 1009 1.1 mrg } 1010 1.1 mrg 1011 1.1 mrg tree permute = elts.build (); 1012 1.1 mrg 1013 1.1 mrg gimple *g = gimple_build_assign (lhs, VEC_PERM_EXPR, arg0, arg1, permute); 1014 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1015 1.1 mrg gsi_replace (gsi, g, true); 1016 1.1 mrg } 1017 1.1 mrg 1018 1.1 mrg /* Helper function to handle the vector merge[eo] built-ins. */ 1019 1.1 mrg static void 1020 1.1 mrg fold_mergeeo_helper (gimple_stmt_iterator *gsi, gimple *stmt, int use_odd) 1021 1.1 mrg { 1022 1.1 mrg tree arg0 = gimple_call_arg (stmt, 0); 1023 1.1 mrg tree arg1 = gimple_call_arg (stmt, 1); 1024 1.1 mrg tree lhs = gimple_call_lhs (stmt); 1025 1.1 mrg tree lhs_type = TREE_TYPE (lhs); 1026 1.1 mrg int n_elts = TYPE_VECTOR_SUBPARTS (lhs_type); 1027 1.1 mrg 1028 1.1 mrg /* The permute_type will match the lhs for integral types. For double and 1029 1.1 mrg float types, the permute type needs to map to the V2 or V4 type that 1030 1.1 mrg matches size. */ 1031 1.1 mrg tree permute_type; 1032 1.1 mrg permute_type = map_to_integral_tree_type (lhs_type); 1033 1.1 mrg 1034 1.1 mrg tree_vector_builder elts (permute_type, VECTOR_CST_NELTS (arg0), 1); 1035 1.1 mrg 1036 1.1 mrg /* Build the permute vector. */ 1037 1.1 mrg for (int i = 0; i < n_elts / 2; i++) 1038 1.1 mrg { 1039 1.1 mrg elts.safe_push (build_int_cst (TREE_TYPE (permute_type), 1040 1.1 mrg 2*i + use_odd)); 1041 1.1 mrg elts.safe_push (build_int_cst (TREE_TYPE (permute_type), 1042 1.1 mrg 2*i + use_odd + n_elts)); 1043 1.1 mrg } 1044 1.1 mrg 1045 1.1 mrg tree permute = elts.build (); 1046 1.1 mrg 1047 1.1 mrg gimple *g = gimple_build_assign (lhs, VEC_PERM_EXPR, arg0, arg1, permute); 1048 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1049 1.1 mrg gsi_replace (gsi, g, true); 1050 1.1 mrg } 1051 1.1 mrg 1052 1.1 mrg /* Helper function to sort out which built-ins may be valid without having 1053 1.1 mrg a LHS. */ 1054 1.1 mrg static bool 1055 1.1 mrg rs6000_builtin_valid_without_lhs (enum rs6000_gen_builtins fn_code, 1056 1.1 mrg tree fndecl) 1057 1.1 mrg { 1058 1.1 mrg if (TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node) 1059 1.1 mrg return true; 1060 1.1 mrg 1061 1.1 mrg switch (fn_code) 1062 1.1 mrg { 1063 1.1 mrg case RS6000_BIF_STVX_V16QI: 1064 1.1 mrg case RS6000_BIF_STVX_V8HI: 1065 1.1 mrg case RS6000_BIF_STVX_V4SI: 1066 1.1 mrg case RS6000_BIF_STVX_V4SF: 1067 1.1 mrg case RS6000_BIF_STVX_V2DI: 1068 1.1 mrg case RS6000_BIF_STVX_V2DF: 1069 1.1 mrg case RS6000_BIF_STXVW4X_V16QI: 1070 1.1 mrg case RS6000_BIF_STXVW4X_V8HI: 1071 1.1 mrg case RS6000_BIF_STXVW4X_V4SF: 1072 1.1 mrg case RS6000_BIF_STXVW4X_V4SI: 1073 1.1 mrg case RS6000_BIF_STXVD2X_V2DF: 1074 1.1 mrg case RS6000_BIF_STXVD2X_V2DI: 1075 1.1 mrg return true; 1076 1.1 mrg default: 1077 1.1 mrg return false; 1078 1.1 mrg } 1079 1.1 mrg } 1080 1.1 mrg 1081 1.1 mrg /* Expand the MMA built-ins early, so that we can convert the pass-by-reference 1082 1.1 mrg __vector_quad arguments into pass-by-value arguments, leading to more 1083 1.1 mrg efficient code generation. */ 1084 1.1 mrg static bool 1085 1.1 mrg rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi, 1086 1.1 mrg rs6000_gen_builtins fn_code) 1087 1.1 mrg { 1088 1.1 mrg gimple *stmt = gsi_stmt (*gsi); 1089 1.1 mrg size_t fncode = (size_t) fn_code; 1090 1.1 mrg 1091 1.1 mrg if (!bif_is_mma (rs6000_builtin_info[fncode])) 1092 1.1 mrg return false; 1093 1.1 mrg 1094 1.1 mrg /* Each call that can be gimple-expanded has an associated built-in 1095 1.1 mrg function that it will expand into. If this one doesn't, we have 1096 1.1 mrg already expanded it! Exceptions: lxvp and stxvp. */ 1097 1.1 mrg if (rs6000_builtin_info[fncode].assoc_bif == RS6000_BIF_NONE 1098 1.1 mrg && fncode != RS6000_BIF_LXVP 1099 1.1 mrg && fncode != RS6000_BIF_STXVP) 1100 1.1 mrg return false; 1101 1.1 mrg 1102 1.1 mrg bifdata *bd = &rs6000_builtin_info[fncode]; 1103 1.1 mrg unsigned nopnds = bd->nargs; 1104 1.1 mrg gimple_seq new_seq = NULL; 1105 1.1 mrg gimple *new_call; 1106 1.1 mrg tree new_decl; 1107 1.1 mrg 1108 1.1 mrg /* Compatibility built-ins; we used to call these 1109 1.1 mrg __builtin_mma_{dis,}assemble_pair, but now we call them 1110 1.1 mrg __builtin_vsx_{dis,}assemble_pair. Handle the old versions. */ 1111 1.1 mrg if (fncode == RS6000_BIF_ASSEMBLE_PAIR) 1112 1.1 mrg fncode = RS6000_BIF_ASSEMBLE_PAIR_V; 1113 1.1 mrg else if (fncode == RS6000_BIF_DISASSEMBLE_PAIR) 1114 1.1 mrg fncode = RS6000_BIF_DISASSEMBLE_PAIR_V; 1115 1.1 mrg 1116 1.1 mrg if (fncode == RS6000_BIF_DISASSEMBLE_ACC 1117 1.1 mrg || fncode == RS6000_BIF_DISASSEMBLE_PAIR_V) 1118 1.1 mrg { 1119 1.1 mrg /* This is an MMA disassemble built-in function. */ 1120 1.1 mrg push_gimplify_context (true); 1121 1.1 mrg unsigned nvec = (fncode == RS6000_BIF_DISASSEMBLE_ACC) ? 4 : 2; 1122 1.1 mrg tree dst_ptr = gimple_call_arg (stmt, 0); 1123 1.1 mrg tree src_ptr = gimple_call_arg (stmt, 1); 1124 1.1 mrg tree src_type = (fncode == RS6000_BIF_DISASSEMBLE_ACC) 1125 1.1 mrg ? build_pointer_type (vector_quad_type_node) 1126 1.1 mrg : build_pointer_type (vector_pair_type_node); 1127 1.1 mrg if (TREE_TYPE (src_ptr) != src_type) 1128 1.1 mrg src_ptr = build1 (NOP_EXPR, src_type, src_ptr); 1129 1.1 mrg 1130 1.1 mrg tree src = create_tmp_reg_or_ssa_name (TREE_TYPE (src_type)); 1131 1.1 mrg gimplify_assign (src, build_simple_mem_ref (src_ptr), &new_seq); 1132 1.1 mrg 1133 1.1 mrg /* If we are not disassembling an accumulator/pair or our destination is 1134 1.1 mrg another accumulator/pair, then just copy the entire thing as is. */ 1135 1.1 mrg if ((fncode == RS6000_BIF_DISASSEMBLE_ACC 1136 1.1 mrg && TREE_TYPE (TREE_TYPE (dst_ptr)) == vector_quad_type_node) 1137 1.1 mrg || (fncode == RS6000_BIF_DISASSEMBLE_PAIR_V 1138 1.1 mrg && TREE_TYPE (TREE_TYPE (dst_ptr)) == vector_pair_type_node)) 1139 1.1 mrg { 1140 1.1 mrg tree dst = build_simple_mem_ref (build1 (VIEW_CONVERT_EXPR, 1141 1.1 mrg src_type, dst_ptr)); 1142 1.1 mrg gimplify_assign (dst, src, &new_seq); 1143 1.1 mrg pop_gimplify_context (NULL); 1144 1.1 mrg gsi_replace_with_seq (gsi, new_seq, true); 1145 1.1 mrg return true; 1146 1.1 mrg } 1147 1.1 mrg 1148 1.1 mrg /* If we're disassembling an accumulator into a different type, we need 1149 1.1 mrg to emit a xxmfacc instruction now, since we cannot do it later. */ 1150 1.1 mrg if (fncode == RS6000_BIF_DISASSEMBLE_ACC) 1151 1.1 mrg { 1152 1.1 mrg new_decl = rs6000_builtin_decls[RS6000_BIF_XXMFACC_INTERNAL]; 1153 1.1 mrg new_call = gimple_build_call (new_decl, 1, src); 1154 1.1 mrg src = create_tmp_reg_or_ssa_name (vector_quad_type_node); 1155 1.1 mrg gimple_call_set_lhs (new_call, src); 1156 1.1 mrg gimple_seq_add_stmt (&new_seq, new_call); 1157 1.1 mrg } 1158 1.1 mrg 1159 1.1 mrg /* Copy the accumulator/pair vector by vector. */ 1160 1.1 mrg new_decl 1161 1.1 mrg = rs6000_builtin_decls[rs6000_builtin_info[fncode].assoc_bif]; 1162 1.1 mrg tree dst_type = build_pointer_type_for_mode (unsigned_V16QI_type_node, 1163 1.1 mrg ptr_mode, true); 1164 1.1 mrg tree dst_base = build1 (VIEW_CONVERT_EXPR, dst_type, dst_ptr); 1165 1.1 mrg for (unsigned i = 0; i < nvec; i++) 1166 1.1 mrg { 1167 1.1 mrg unsigned index = WORDS_BIG_ENDIAN ? i : nvec - 1 - i; 1168 1.1 mrg tree dst = build2 (MEM_REF, unsigned_V16QI_type_node, dst_base, 1169 1.1 mrg build_int_cst (dst_type, index * 16)); 1170 1.1 mrg tree dstssa = create_tmp_reg_or_ssa_name (unsigned_V16QI_type_node); 1171 1.1 mrg new_call = gimple_build_call (new_decl, 2, src, 1172 1.1 mrg build_int_cstu (uint16_type_node, i)); 1173 1.1 mrg gimple_call_set_lhs (new_call, dstssa); 1174 1.1 mrg gimple_seq_add_stmt (&new_seq, new_call); 1175 1.1 mrg gimplify_assign (dst, dstssa, &new_seq); 1176 1.1 mrg } 1177 1.1 mrg pop_gimplify_context (NULL); 1178 1.1 mrg gsi_replace_with_seq (gsi, new_seq, true); 1179 1.1 mrg return true; 1180 1.1 mrg } 1181 1.1 mrg 1182 1.1 mrg /* TODO: Do some factoring on these two chunks. */ 1183 1.1 mrg if (fncode == RS6000_BIF_LXVP) 1184 1.1 mrg { 1185 1.1 mrg push_gimplify_context (true); 1186 1.1 mrg tree offset = gimple_call_arg (stmt, 0); 1187 1.1 mrg tree ptr = gimple_call_arg (stmt, 1); 1188 1.1 mrg tree lhs = gimple_call_lhs (stmt); 1189 1.1 mrg if (TREE_TYPE (TREE_TYPE (ptr)) != vector_pair_type_node) 1190 1.1 mrg ptr = build1 (VIEW_CONVERT_EXPR, 1191 1.1 mrg build_pointer_type (vector_pair_type_node), ptr); 1192 1.1 mrg tree mem = build_simple_mem_ref (build2 (POINTER_PLUS_EXPR, 1193 1.1 mrg TREE_TYPE (ptr), ptr, offset)); 1194 1.1 mrg gimplify_assign (lhs, mem, &new_seq); 1195 1.1 mrg pop_gimplify_context (NULL); 1196 1.1 mrg gsi_replace_with_seq (gsi, new_seq, true); 1197 1.1 mrg return true; 1198 1.1 mrg } 1199 1.1 mrg 1200 1.1 mrg if (fncode == RS6000_BIF_STXVP) 1201 1.1 mrg { 1202 1.1 mrg push_gimplify_context (true); 1203 1.1 mrg tree src = gimple_call_arg (stmt, 0); 1204 1.1 mrg tree offset = gimple_call_arg (stmt, 1); 1205 1.1 mrg tree ptr = gimple_call_arg (stmt, 2); 1206 1.1 mrg if (TREE_TYPE (TREE_TYPE (ptr)) != vector_pair_type_node) 1207 1.1 mrg ptr = build1 (VIEW_CONVERT_EXPR, 1208 1.1 mrg build_pointer_type (vector_pair_type_node), ptr); 1209 1.1 mrg tree mem = build_simple_mem_ref (build2 (POINTER_PLUS_EXPR, 1210 1.1 mrg TREE_TYPE (ptr), ptr, offset)); 1211 1.1 mrg gimplify_assign (mem, src, &new_seq); 1212 1.1 mrg pop_gimplify_context (NULL); 1213 1.1 mrg gsi_replace_with_seq (gsi, new_seq, true); 1214 1.1 mrg return true; 1215 1.1 mrg } 1216 1.1 mrg 1217 1.1 mrg /* Convert this built-in into an internal version that uses pass-by-value 1218 1.1 mrg arguments. The internal built-in is found in the assoc_bif field. */ 1219 1.1 mrg new_decl = rs6000_builtin_decls[rs6000_builtin_info[fncode].assoc_bif]; 1220 1.1 mrg tree lhs, op[MAX_MMA_OPERANDS]; 1221 1.1 mrg tree acc = gimple_call_arg (stmt, 0); 1222 1.1 mrg push_gimplify_context (true); 1223 1.1 mrg 1224 1.1 mrg if (bif_is_quad (*bd)) 1225 1.1 mrg { 1226 1.1 mrg /* This built-in has a pass-by-reference accumulator input, so load it 1227 1.1 mrg into a temporary accumulator for use as a pass-by-value input. */ 1228 1.1 mrg op[0] = create_tmp_reg_or_ssa_name (vector_quad_type_node); 1229 1.1 mrg for (unsigned i = 1; i < nopnds; i++) 1230 1.1 mrg op[i] = gimple_call_arg (stmt, i); 1231 1.1 mrg gimplify_assign (op[0], build_simple_mem_ref (acc), &new_seq); 1232 1.1 mrg } 1233 1.1 mrg else 1234 1.1 mrg { 1235 1.1 mrg /* This built-in does not use its pass-by-reference accumulator argument 1236 1.1 mrg as an input argument, so remove it from the input list. */ 1237 1.1 mrg nopnds--; 1238 1.1 mrg for (unsigned i = 0; i < nopnds; i++) 1239 1.1 mrg op[i] = gimple_call_arg (stmt, i + 1); 1240 1.1 mrg } 1241 1.1 mrg 1242 1.1 mrg switch (nopnds) 1243 1.1 mrg { 1244 1.1 mrg case 0: 1245 1.1 mrg new_call = gimple_build_call (new_decl, 0); 1246 1.1 mrg break; 1247 1.1 mrg case 1: 1248 1.1 mrg new_call = gimple_build_call (new_decl, 1, op[0]); 1249 1.1 mrg break; 1250 1.1 mrg case 2: 1251 1.1 mrg new_call = gimple_build_call (new_decl, 2, op[0], op[1]); 1252 1.1 mrg break; 1253 1.1 mrg case 3: 1254 1.1 mrg new_call = gimple_build_call (new_decl, 3, op[0], op[1], op[2]); 1255 1.1 mrg break; 1256 1.1 mrg case 4: 1257 1.1 mrg new_call = gimple_build_call (new_decl, 4, op[0], op[1], op[2], op[3]); 1258 1.1 mrg break; 1259 1.1 mrg case 5: 1260 1.1 mrg new_call = gimple_build_call (new_decl, 5, op[0], op[1], op[2], op[3], 1261 1.1 mrg op[4]); 1262 1.1 mrg break; 1263 1.1 mrg case 6: 1264 1.1 mrg new_call = gimple_build_call (new_decl, 6, op[0], op[1], op[2], op[3], 1265 1.1 mrg op[4], op[5]); 1266 1.1 mrg break; 1267 1.1 mrg case 7: 1268 1.1 mrg new_call = gimple_build_call (new_decl, 7, op[0], op[1], op[2], op[3], 1269 1.1 mrg op[4], op[5], op[6]); 1270 1.1 mrg break; 1271 1.1 mrg default: 1272 1.1 mrg gcc_unreachable (); 1273 1.1 mrg } 1274 1.1 mrg 1275 1.1 mrg if (fncode == RS6000_BIF_BUILD_PAIR || fncode == RS6000_BIF_ASSEMBLE_PAIR_V) 1276 1.1 mrg lhs = create_tmp_reg_or_ssa_name (vector_pair_type_node); 1277 1.1 mrg else 1278 1.1 mrg lhs = create_tmp_reg_or_ssa_name (vector_quad_type_node); 1279 1.1 mrg gimple_call_set_lhs (new_call, lhs); 1280 1.1 mrg gimple_seq_add_stmt (&new_seq, new_call); 1281 1.1 mrg gimplify_assign (build_simple_mem_ref (acc), lhs, &new_seq); 1282 1.1 mrg pop_gimplify_context (NULL); 1283 1.1 mrg gsi_replace_with_seq (gsi, new_seq, true); 1284 1.1 mrg 1285 1.1 mrg return true; 1286 1.1 mrg } 1287 1.1 mrg 1288 1.1 mrg /* Fold a machine-dependent built-in in GIMPLE. (For folding into 1289 1.1 mrg a constant, use rs6000_fold_builtin.) */ 1290 1.1 mrg bool 1291 1.1 mrg rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi) 1292 1.1 mrg { 1293 1.1 mrg gimple *stmt = gsi_stmt (*gsi); 1294 1.1 mrg tree fndecl = gimple_call_fndecl (stmt); 1295 1.1 mrg gcc_checking_assert (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD); 1296 1.1 mrg enum rs6000_gen_builtins fn_code 1297 1.1 mrg = (enum rs6000_gen_builtins) DECL_MD_FUNCTION_CODE (fndecl); 1298 1.1 mrg tree arg0, arg1, lhs, temp; 1299 1.1 mrg enum tree_code bcode; 1300 1.1 mrg gimple *g; 1301 1.1 mrg 1302 1.1 mrg /* For an unresolved overloaded builtin, return early here since there 1303 1.1 mrg is no builtin info for it and we are unable to fold it. */ 1304 1.1 mrg if (fn_code > RS6000_OVLD_NONE) 1305 1.1 mrg return false; 1306 1.1 mrg 1307 1.1 mrg size_t uns_fncode = (size_t) fn_code; 1308 1.1 mrg enum insn_code icode = rs6000_builtin_info[uns_fncode].icode; 1309 1.1 mrg const char *fn_name1 = rs6000_builtin_info[uns_fncode].bifname; 1310 1.1 mrg const char *fn_name2 = (icode != CODE_FOR_nothing) 1311 1.1 mrg ? get_insn_name ((int) icode) 1312 1.1 mrg : "nothing"; 1313 1.1 mrg 1314 1.1 mrg if (TARGET_DEBUG_BUILTIN) 1315 1.1 mrg fprintf (stderr, "rs6000_gimple_fold_builtin %d %s %s\n", 1316 1.1 mrg fn_code, fn_name1, fn_name2); 1317 1.1 mrg 1318 1.1 mrg /* Prevent gimple folding for code that does not have a LHS, unless it is 1319 1.1 mrg allowed per the rs6000_builtin_valid_without_lhs helper function. */ 1320 1.1 mrg if (!gimple_call_lhs (stmt) 1321 1.1 mrg && !rs6000_builtin_valid_without_lhs (fn_code, fndecl)) 1322 1.1 mrg return false; 1323 1.1 mrg 1324 1.1 mrg /* Don't fold invalid builtins, let rs6000_expand_builtin diagnose it. */ 1325 1.1 mrg if (!rs6000_builtin_is_supported (fn_code)) 1326 1.1 mrg return false; 1327 1.1 mrg 1328 1.1 mrg if (rs6000_gimple_fold_mma_builtin (gsi, fn_code)) 1329 1.1 mrg return true; 1330 1.1 mrg 1331 1.1 mrg switch (fn_code) 1332 1.1 mrg { 1333 1.1 mrg /* Flavors of vec_add. We deliberately don't expand 1334 1.1 mrg RS6000_BIF_VADDUQM as it gets lowered from V1TImode to 1335 1.1 mrg TImode, resulting in much poorer code generation. */ 1336 1.1 mrg case RS6000_BIF_VADDUBM: 1337 1.1 mrg case RS6000_BIF_VADDUHM: 1338 1.1 mrg case RS6000_BIF_VADDUWM: 1339 1.1 mrg case RS6000_BIF_VADDUDM: 1340 1.1 mrg case RS6000_BIF_VADDFP: 1341 1.1 mrg case RS6000_BIF_XVADDDP: 1342 1.1 mrg case RS6000_BIF_XVADDSP: 1343 1.1 mrg bcode = PLUS_EXPR; 1344 1.1 mrg do_binary: 1345 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1346 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1347 1.1 mrg lhs = gimple_call_lhs (stmt); 1348 1.1 mrg if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (lhs))) 1349 1.1 mrg && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (TREE_TYPE (lhs)))) 1350 1.1 mrg { 1351 1.1 mrg /* Ensure the binary operation is performed in a type 1352 1.1 mrg that wraps if it is integral type. */ 1353 1.1 mrg gimple_seq stmts = NULL; 1354 1.1 mrg tree type = unsigned_type_for (TREE_TYPE (lhs)); 1355 1.1 mrg tree uarg0 = gimple_build (&stmts, VIEW_CONVERT_EXPR, 1356 1.1 mrg type, arg0); 1357 1.1 mrg tree uarg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR, 1358 1.1 mrg type, arg1); 1359 1.1 mrg tree res = gimple_build (&stmts, gimple_location (stmt), bcode, 1360 1.1 mrg type, uarg0, uarg1); 1361 1.1 mrg gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); 1362 1.1 mrg g = gimple_build_assign (lhs, VIEW_CONVERT_EXPR, 1363 1.1 mrg build1 (VIEW_CONVERT_EXPR, 1364 1.1 mrg TREE_TYPE (lhs), res)); 1365 1.1 mrg gsi_replace (gsi, g, true); 1366 1.1 mrg return true; 1367 1.1 mrg } 1368 1.1 mrg g = gimple_build_assign (lhs, bcode, arg0, arg1); 1369 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1370 1.1 mrg gsi_replace (gsi, g, true); 1371 1.1 mrg return true; 1372 1.1 mrg /* Flavors of vec_sub. We deliberately don't expand 1373 1.1 mrg RS6000_BIF_VSUBUQM. */ 1374 1.1 mrg case RS6000_BIF_VSUBUBM: 1375 1.1 mrg case RS6000_BIF_VSUBUHM: 1376 1.1 mrg case RS6000_BIF_VSUBUWM: 1377 1.1 mrg case RS6000_BIF_VSUBUDM: 1378 1.1 mrg case RS6000_BIF_VSUBFP: 1379 1.1 mrg case RS6000_BIF_XVSUBDP: 1380 1.1 mrg case RS6000_BIF_XVSUBSP: 1381 1.1 mrg bcode = MINUS_EXPR; 1382 1.1 mrg goto do_binary; 1383 1.1 mrg case RS6000_BIF_XVMULSP: 1384 1.1 mrg case RS6000_BIF_XVMULDP: 1385 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1386 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1387 1.1 mrg lhs = gimple_call_lhs (stmt); 1388 1.1 mrg g = gimple_build_assign (lhs, MULT_EXPR, arg0, arg1); 1389 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1390 1.1 mrg gsi_replace (gsi, g, true); 1391 1.1 mrg return true; 1392 1.1 mrg /* Even element flavors of vec_mul (signed). */ 1393 1.1 mrg case RS6000_BIF_VMULESB: 1394 1.1 mrg case RS6000_BIF_VMULESH: 1395 1.1 mrg case RS6000_BIF_VMULESW: 1396 1.1 mrg /* Even element flavors of vec_mul (unsigned). */ 1397 1.1 mrg case RS6000_BIF_VMULEUB: 1398 1.1 mrg case RS6000_BIF_VMULEUH: 1399 1.1 mrg case RS6000_BIF_VMULEUW: 1400 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1401 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1402 1.1 mrg lhs = gimple_call_lhs (stmt); 1403 1.1 mrg g = gimple_build_assign (lhs, VEC_WIDEN_MULT_EVEN_EXPR, arg0, arg1); 1404 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1405 1.1 mrg gsi_replace (gsi, g, true); 1406 1.1 mrg return true; 1407 1.1 mrg /* Odd element flavors of vec_mul (signed). */ 1408 1.1 mrg case RS6000_BIF_VMULOSB: 1409 1.1 mrg case RS6000_BIF_VMULOSH: 1410 1.1 mrg case RS6000_BIF_VMULOSW: 1411 1.1 mrg /* Odd element flavors of vec_mul (unsigned). */ 1412 1.1 mrg case RS6000_BIF_VMULOUB: 1413 1.1 mrg case RS6000_BIF_VMULOUH: 1414 1.1 mrg case RS6000_BIF_VMULOUW: 1415 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1416 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1417 1.1 mrg lhs = gimple_call_lhs (stmt); 1418 1.1 mrg g = gimple_build_assign (lhs, VEC_WIDEN_MULT_ODD_EXPR, arg0, arg1); 1419 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1420 1.1 mrg gsi_replace (gsi, g, true); 1421 1.1 mrg return true; 1422 1.1 mrg /* Flavors of vec_div (Integer). */ 1423 1.1 mrg case RS6000_BIF_DIV_V2DI: 1424 1.1 mrg case RS6000_BIF_UDIV_V2DI: 1425 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1426 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1427 1.1 mrg lhs = gimple_call_lhs (stmt); 1428 1.1 mrg g = gimple_build_assign (lhs, TRUNC_DIV_EXPR, arg0, arg1); 1429 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1430 1.1 mrg gsi_replace (gsi, g, true); 1431 1.1 mrg return true; 1432 1.1 mrg /* Flavors of vec_div (Float). */ 1433 1.1 mrg case RS6000_BIF_XVDIVSP: 1434 1.1 mrg case RS6000_BIF_XVDIVDP: 1435 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1436 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1437 1.1 mrg lhs = gimple_call_lhs (stmt); 1438 1.1 mrg g = gimple_build_assign (lhs, RDIV_EXPR, arg0, arg1); 1439 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1440 1.1 mrg gsi_replace (gsi, g, true); 1441 1.1 mrg return true; 1442 1.1 mrg /* Flavors of vec_and. */ 1443 1.1 mrg case RS6000_BIF_VAND_V16QI_UNS: 1444 1.1 mrg case RS6000_BIF_VAND_V16QI: 1445 1.1 mrg case RS6000_BIF_VAND_V8HI_UNS: 1446 1.1 mrg case RS6000_BIF_VAND_V8HI: 1447 1.1 mrg case RS6000_BIF_VAND_V4SI_UNS: 1448 1.1 mrg case RS6000_BIF_VAND_V4SI: 1449 1.1 mrg case RS6000_BIF_VAND_V2DI_UNS: 1450 1.1 mrg case RS6000_BIF_VAND_V2DI: 1451 1.1 mrg case RS6000_BIF_VAND_V4SF: 1452 1.1 mrg case RS6000_BIF_VAND_V2DF: 1453 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1454 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1455 1.1 mrg lhs = gimple_call_lhs (stmt); 1456 1.1 mrg g = gimple_build_assign (lhs, BIT_AND_EXPR, arg0, arg1); 1457 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1458 1.1 mrg gsi_replace (gsi, g, true); 1459 1.1 mrg return true; 1460 1.1 mrg /* Flavors of vec_andc. */ 1461 1.1 mrg case RS6000_BIF_VANDC_V16QI_UNS: 1462 1.1 mrg case RS6000_BIF_VANDC_V16QI: 1463 1.1 mrg case RS6000_BIF_VANDC_V8HI_UNS: 1464 1.1 mrg case RS6000_BIF_VANDC_V8HI: 1465 1.1 mrg case RS6000_BIF_VANDC_V4SI_UNS: 1466 1.1 mrg case RS6000_BIF_VANDC_V4SI: 1467 1.1 mrg case RS6000_BIF_VANDC_V2DI_UNS: 1468 1.1 mrg case RS6000_BIF_VANDC_V2DI: 1469 1.1 mrg case RS6000_BIF_VANDC_V4SF: 1470 1.1 mrg case RS6000_BIF_VANDC_V2DF: 1471 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1472 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1473 1.1 mrg lhs = gimple_call_lhs (stmt); 1474 1.1 mrg temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1)); 1475 1.1 mrg g = gimple_build_assign (temp, BIT_NOT_EXPR, arg1); 1476 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1477 1.1 mrg gsi_insert_before (gsi, g, GSI_SAME_STMT); 1478 1.1 mrg g = gimple_build_assign (lhs, BIT_AND_EXPR, arg0, temp); 1479 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1480 1.1 mrg gsi_replace (gsi, g, true); 1481 1.1 mrg return true; 1482 1.1 mrg /* Flavors of vec_nand. */ 1483 1.1 mrg case RS6000_BIF_NAND_V16QI_UNS: 1484 1.1 mrg case RS6000_BIF_NAND_V16QI: 1485 1.1 mrg case RS6000_BIF_NAND_V8HI_UNS: 1486 1.1 mrg case RS6000_BIF_NAND_V8HI: 1487 1.1 mrg case RS6000_BIF_NAND_V4SI_UNS: 1488 1.1 mrg case RS6000_BIF_NAND_V4SI: 1489 1.1 mrg case RS6000_BIF_NAND_V2DI_UNS: 1490 1.1 mrg case RS6000_BIF_NAND_V2DI: 1491 1.1 mrg case RS6000_BIF_NAND_V4SF: 1492 1.1 mrg case RS6000_BIF_NAND_V2DF: 1493 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1494 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1495 1.1 mrg lhs = gimple_call_lhs (stmt); 1496 1.1 mrg temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1)); 1497 1.1 mrg g = gimple_build_assign (temp, BIT_AND_EXPR, arg0, arg1); 1498 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1499 1.1 mrg gsi_insert_before (gsi, g, GSI_SAME_STMT); 1500 1.1 mrg g = gimple_build_assign (lhs, BIT_NOT_EXPR, temp); 1501 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1502 1.1 mrg gsi_replace (gsi, g, true); 1503 1.1 mrg return true; 1504 1.1 mrg /* Flavors of vec_or. */ 1505 1.1 mrg case RS6000_BIF_VOR_V16QI_UNS: 1506 1.1 mrg case RS6000_BIF_VOR_V16QI: 1507 1.1 mrg case RS6000_BIF_VOR_V8HI_UNS: 1508 1.1 mrg case RS6000_BIF_VOR_V8HI: 1509 1.1 mrg case RS6000_BIF_VOR_V4SI_UNS: 1510 1.1 mrg case RS6000_BIF_VOR_V4SI: 1511 1.1 mrg case RS6000_BIF_VOR_V2DI_UNS: 1512 1.1 mrg case RS6000_BIF_VOR_V2DI: 1513 1.1 mrg case RS6000_BIF_VOR_V4SF: 1514 1.1 mrg case RS6000_BIF_VOR_V2DF: 1515 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1516 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1517 1.1 mrg lhs = gimple_call_lhs (stmt); 1518 1.1 mrg g = gimple_build_assign (lhs, BIT_IOR_EXPR, arg0, arg1); 1519 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1520 1.1 mrg gsi_replace (gsi, g, true); 1521 1.1 mrg return true; 1522 1.1 mrg /* flavors of vec_orc. */ 1523 1.1 mrg case RS6000_BIF_ORC_V16QI_UNS: 1524 1.1 mrg case RS6000_BIF_ORC_V16QI: 1525 1.1 mrg case RS6000_BIF_ORC_V8HI_UNS: 1526 1.1 mrg case RS6000_BIF_ORC_V8HI: 1527 1.1 mrg case RS6000_BIF_ORC_V4SI_UNS: 1528 1.1 mrg case RS6000_BIF_ORC_V4SI: 1529 1.1 mrg case RS6000_BIF_ORC_V2DI_UNS: 1530 1.1 mrg case RS6000_BIF_ORC_V2DI: 1531 1.1 mrg case RS6000_BIF_ORC_V4SF: 1532 1.1 mrg case RS6000_BIF_ORC_V2DF: 1533 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1534 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1535 1.1 mrg lhs = gimple_call_lhs (stmt); 1536 1.1 mrg temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1)); 1537 1.1 mrg g = gimple_build_assign (temp, BIT_NOT_EXPR, arg1); 1538 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1539 1.1 mrg gsi_insert_before (gsi, g, GSI_SAME_STMT); 1540 1.1 mrg g = gimple_build_assign (lhs, BIT_IOR_EXPR, arg0, temp); 1541 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1542 1.1 mrg gsi_replace (gsi, g, true); 1543 1.1 mrg return true; 1544 1.1 mrg /* Flavors of vec_xor. */ 1545 1.1 mrg case RS6000_BIF_VXOR_V16QI_UNS: 1546 1.1 mrg case RS6000_BIF_VXOR_V16QI: 1547 1.1 mrg case RS6000_BIF_VXOR_V8HI_UNS: 1548 1.1 mrg case RS6000_BIF_VXOR_V8HI: 1549 1.1 mrg case RS6000_BIF_VXOR_V4SI_UNS: 1550 1.1 mrg case RS6000_BIF_VXOR_V4SI: 1551 1.1 mrg case RS6000_BIF_VXOR_V2DI_UNS: 1552 1.1 mrg case RS6000_BIF_VXOR_V2DI: 1553 1.1 mrg case RS6000_BIF_VXOR_V4SF: 1554 1.1 mrg case RS6000_BIF_VXOR_V2DF: 1555 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1556 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1557 1.1 mrg lhs = gimple_call_lhs (stmt); 1558 1.1 mrg g = gimple_build_assign (lhs, BIT_XOR_EXPR, arg0, arg1); 1559 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1560 1.1 mrg gsi_replace (gsi, g, true); 1561 1.1 mrg return true; 1562 1.1 mrg /* Flavors of vec_nor. */ 1563 1.1 mrg case RS6000_BIF_VNOR_V16QI_UNS: 1564 1.1 mrg case RS6000_BIF_VNOR_V16QI: 1565 1.1 mrg case RS6000_BIF_VNOR_V8HI_UNS: 1566 1.1 mrg case RS6000_BIF_VNOR_V8HI: 1567 1.1 mrg case RS6000_BIF_VNOR_V4SI_UNS: 1568 1.1 mrg case RS6000_BIF_VNOR_V4SI: 1569 1.1 mrg case RS6000_BIF_VNOR_V2DI_UNS: 1570 1.1 mrg case RS6000_BIF_VNOR_V2DI: 1571 1.1 mrg case RS6000_BIF_VNOR_V4SF: 1572 1.1 mrg case RS6000_BIF_VNOR_V2DF: 1573 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1574 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1575 1.1 mrg lhs = gimple_call_lhs (stmt); 1576 1.1 mrg temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1)); 1577 1.1 mrg g = gimple_build_assign (temp, BIT_IOR_EXPR, arg0, arg1); 1578 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1579 1.1 mrg gsi_insert_before (gsi, g, GSI_SAME_STMT); 1580 1.1 mrg g = gimple_build_assign (lhs, BIT_NOT_EXPR, temp); 1581 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1582 1.1 mrg gsi_replace (gsi, g, true); 1583 1.1 mrg return true; 1584 1.1 mrg /* flavors of vec_abs. */ 1585 1.1 mrg case RS6000_BIF_ABS_V16QI: 1586 1.1 mrg case RS6000_BIF_ABS_V8HI: 1587 1.1 mrg case RS6000_BIF_ABS_V4SI: 1588 1.1 mrg case RS6000_BIF_ABS_V4SF: 1589 1.1 mrg case RS6000_BIF_ABS_V2DI: 1590 1.1 mrg case RS6000_BIF_XVABSDP: 1591 1.1 mrg case RS6000_BIF_XVABSSP: 1592 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1593 1.1 mrg if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (arg0))) 1594 1.1 mrg && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (TREE_TYPE (arg0)))) 1595 1.1 mrg return false; 1596 1.1 mrg lhs = gimple_call_lhs (stmt); 1597 1.1 mrg g = gimple_build_assign (lhs, ABS_EXPR, arg0); 1598 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1599 1.1 mrg gsi_replace (gsi, g, true); 1600 1.1 mrg return true; 1601 1.1 mrg /* flavors of vec_min. */ 1602 1.1 mrg case RS6000_BIF_XVMINDP: 1603 1.1 mrg case RS6000_BIF_XVMINSP: 1604 1.1 mrg case RS6000_BIF_VMINFP: 1605 1.1 mrg { 1606 1.1 mrg lhs = gimple_call_lhs (stmt); 1607 1.1 mrg tree type = TREE_TYPE (lhs); 1608 1.1 mrg if (HONOR_NANS (type)) 1609 1.1 mrg return false; 1610 1.1 mrg gcc_fallthrough (); 1611 1.1 mrg } 1612 1.1 mrg case RS6000_BIF_VMINSD: 1613 1.1 mrg case RS6000_BIF_VMINUD: 1614 1.1 mrg case RS6000_BIF_VMINSB: 1615 1.1 mrg case RS6000_BIF_VMINSH: 1616 1.1 mrg case RS6000_BIF_VMINSW: 1617 1.1 mrg case RS6000_BIF_VMINUB: 1618 1.1 mrg case RS6000_BIF_VMINUH: 1619 1.1 mrg case RS6000_BIF_VMINUW: 1620 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1621 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1622 1.1 mrg lhs = gimple_call_lhs (stmt); 1623 1.1 mrg g = gimple_build_assign (lhs, MIN_EXPR, arg0, arg1); 1624 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1625 1.1 mrg gsi_replace (gsi, g, true); 1626 1.1 mrg return true; 1627 1.1 mrg /* flavors of vec_max. */ 1628 1.1 mrg case RS6000_BIF_XVMAXDP: 1629 1.1 mrg case RS6000_BIF_XVMAXSP: 1630 1.1 mrg case RS6000_BIF_VMAXFP: 1631 1.1 mrg { 1632 1.1 mrg lhs = gimple_call_lhs (stmt); 1633 1.1 mrg tree type = TREE_TYPE (lhs); 1634 1.1 mrg if (HONOR_NANS (type)) 1635 1.1 mrg return false; 1636 1.1 mrg gcc_fallthrough (); 1637 1.1 mrg } 1638 1.1 mrg case RS6000_BIF_VMAXSD: 1639 1.1 mrg case RS6000_BIF_VMAXUD: 1640 1.1 mrg case RS6000_BIF_VMAXSB: 1641 1.1 mrg case RS6000_BIF_VMAXSH: 1642 1.1 mrg case RS6000_BIF_VMAXSW: 1643 1.1 mrg case RS6000_BIF_VMAXUB: 1644 1.1 mrg case RS6000_BIF_VMAXUH: 1645 1.1 mrg case RS6000_BIF_VMAXUW: 1646 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1647 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1648 1.1 mrg lhs = gimple_call_lhs (stmt); 1649 1.1 mrg g = gimple_build_assign (lhs, MAX_EXPR, arg0, arg1); 1650 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1651 1.1 mrg gsi_replace (gsi, g, true); 1652 1.1 mrg return true; 1653 1.1 mrg /* Flavors of vec_eqv. */ 1654 1.1 mrg case RS6000_BIF_EQV_V16QI: 1655 1.1 mrg case RS6000_BIF_EQV_V8HI: 1656 1.1 mrg case RS6000_BIF_EQV_V4SI: 1657 1.1 mrg case RS6000_BIF_EQV_V4SF: 1658 1.1 mrg case RS6000_BIF_EQV_V2DF: 1659 1.1 mrg case RS6000_BIF_EQV_V2DI: 1660 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1661 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1662 1.1 mrg lhs = gimple_call_lhs (stmt); 1663 1.1 mrg temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1)); 1664 1.1 mrg g = gimple_build_assign (temp, BIT_XOR_EXPR, arg0, arg1); 1665 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1666 1.1 mrg gsi_insert_before (gsi, g, GSI_SAME_STMT); 1667 1.1 mrg g = gimple_build_assign (lhs, BIT_NOT_EXPR, temp); 1668 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1669 1.1 mrg gsi_replace (gsi, g, true); 1670 1.1 mrg return true; 1671 1.1 mrg /* Flavors of vec_rotate_left. */ 1672 1.1 mrg case RS6000_BIF_VRLB: 1673 1.1 mrg case RS6000_BIF_VRLH: 1674 1.1 mrg case RS6000_BIF_VRLW: 1675 1.1 mrg case RS6000_BIF_VRLD: 1676 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1677 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1678 1.1 mrg lhs = gimple_call_lhs (stmt); 1679 1.1 mrg g = gimple_build_assign (lhs, LROTATE_EXPR, arg0, arg1); 1680 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1681 1.1 mrg gsi_replace (gsi, g, true); 1682 1.1 mrg return true; 1683 1.1 mrg /* Flavors of vector shift right algebraic. 1684 1.1 mrg vec_sra{b,h,w} -> vsra{b,h,w}. */ 1685 1.1 mrg case RS6000_BIF_VSRAB: 1686 1.1 mrg case RS6000_BIF_VSRAH: 1687 1.1 mrg case RS6000_BIF_VSRAW: 1688 1.1 mrg case RS6000_BIF_VSRAD: 1689 1.1 mrg { 1690 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1691 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1692 1.1 mrg lhs = gimple_call_lhs (stmt); 1693 1.1 mrg tree arg1_type = TREE_TYPE (arg1); 1694 1.1 mrg tree unsigned_arg1_type = unsigned_type_for (TREE_TYPE (arg1)); 1695 1.1 mrg tree unsigned_element_type = unsigned_type_for (TREE_TYPE (arg1_type)); 1696 1.1 mrg location_t loc = gimple_location (stmt); 1697 1.1 mrg /* Force arg1 into the range valid matching the arg0 type. */ 1698 1.1 mrg /* Build a vector consisting of the max valid bit-size values. */ 1699 1.1 mrg int n_elts = VECTOR_CST_NELTS (arg1); 1700 1.1 mrg tree element_size = build_int_cst (unsigned_element_type, 1701 1.1 mrg 128 / n_elts); 1702 1.1 mrg tree_vector_builder elts (unsigned_arg1_type, n_elts, 1); 1703 1.1 mrg for (int i = 0; i < n_elts; i++) 1704 1.1 mrg elts.safe_push (element_size); 1705 1.1 mrg tree modulo_tree = elts.build (); 1706 1.1 mrg /* Modulo the provided shift value against that vector. */ 1707 1.1 mrg gimple_seq stmts = NULL; 1708 1.1 mrg tree unsigned_arg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR, 1709 1.1 mrg unsigned_arg1_type, arg1); 1710 1.1 mrg tree new_arg1 = gimple_build (&stmts, loc, TRUNC_MOD_EXPR, 1711 1.1 mrg unsigned_arg1_type, unsigned_arg1, 1712 1.1 mrg modulo_tree); 1713 1.1 mrg gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); 1714 1.1 mrg /* And finally, do the shift. */ 1715 1.1 mrg g = gimple_build_assign (lhs, RSHIFT_EXPR, arg0, new_arg1); 1716 1.1 mrg gimple_set_location (g, loc); 1717 1.1 mrg gsi_replace (gsi, g, true); 1718 1.1 mrg return true; 1719 1.1 mrg } 1720 1.1 mrg /* Flavors of vector shift left. 1721 1.1 mrg builtin_altivec_vsl{b,h,w} -> vsl{b,h,w}. */ 1722 1.1 mrg case RS6000_BIF_VSLB: 1723 1.1 mrg case RS6000_BIF_VSLH: 1724 1.1 mrg case RS6000_BIF_VSLW: 1725 1.1 mrg case RS6000_BIF_VSLD: 1726 1.1 mrg { 1727 1.1 mrg location_t loc; 1728 1.1 mrg gimple_seq stmts = NULL; 1729 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1730 1.1 mrg tree arg0_type = TREE_TYPE (arg0); 1731 1.1 mrg if (INTEGRAL_TYPE_P (TREE_TYPE (arg0_type)) 1732 1.1 mrg && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0_type))) 1733 1.1 mrg return false; 1734 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1735 1.1 mrg tree arg1_type = TREE_TYPE (arg1); 1736 1.1 mrg tree unsigned_arg1_type = unsigned_type_for (TREE_TYPE (arg1)); 1737 1.1 mrg tree unsigned_element_type = unsigned_type_for (TREE_TYPE (arg1_type)); 1738 1.1 mrg loc = gimple_location (stmt); 1739 1.1 mrg lhs = gimple_call_lhs (stmt); 1740 1.1 mrg /* Force arg1 into the range valid matching the arg0 type. */ 1741 1.1 mrg /* Build a vector consisting of the max valid bit-size values. */ 1742 1.1 mrg int n_elts = VECTOR_CST_NELTS (arg1); 1743 1.1 mrg int tree_size_in_bits = TREE_INT_CST_LOW (size_in_bytes (arg1_type)) 1744 1.1 mrg * BITS_PER_UNIT; 1745 1.1 mrg tree element_size = build_int_cst (unsigned_element_type, 1746 1.1 mrg tree_size_in_bits / n_elts); 1747 1.1 mrg tree_vector_builder elts (unsigned_type_for (arg1_type), n_elts, 1); 1748 1.1 mrg for (int i = 0; i < n_elts; i++) 1749 1.1 mrg elts.safe_push (element_size); 1750 1.1 mrg tree modulo_tree = elts.build (); 1751 1.1 mrg /* Modulo the provided shift value against that vector. */ 1752 1.1 mrg tree unsigned_arg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR, 1753 1.1 mrg unsigned_arg1_type, arg1); 1754 1.1 mrg tree new_arg1 = gimple_build (&stmts, loc, TRUNC_MOD_EXPR, 1755 1.1 mrg unsigned_arg1_type, unsigned_arg1, 1756 1.1 mrg modulo_tree); 1757 1.1 mrg gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); 1758 1.1 mrg /* And finally, do the shift. */ 1759 1.1 mrg g = gimple_build_assign (lhs, LSHIFT_EXPR, arg0, new_arg1); 1760 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 1761 1.1 mrg gsi_replace (gsi, g, true); 1762 1.1 mrg return true; 1763 1.1 mrg } 1764 1.1 mrg /* Flavors of vector shift right. */ 1765 1.1 mrg case RS6000_BIF_VSRB: 1766 1.1 mrg case RS6000_BIF_VSRH: 1767 1.1 mrg case RS6000_BIF_VSRW: 1768 1.1 mrg case RS6000_BIF_VSRD: 1769 1.1 mrg { 1770 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1771 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1772 1.1 mrg lhs = gimple_call_lhs (stmt); 1773 1.1 mrg tree arg1_type = TREE_TYPE (arg1); 1774 1.1 mrg tree unsigned_arg1_type = unsigned_type_for (TREE_TYPE (arg1)); 1775 1.1 mrg tree unsigned_element_type = unsigned_type_for (TREE_TYPE (arg1_type)); 1776 1.1 mrg location_t loc = gimple_location (stmt); 1777 1.1 mrg gimple_seq stmts = NULL; 1778 1.1 mrg /* Convert arg0 to unsigned. */ 1779 1.1 mrg tree arg0_unsigned 1780 1.1 mrg = gimple_build (&stmts, VIEW_CONVERT_EXPR, 1781 1.1 mrg unsigned_type_for (TREE_TYPE (arg0)), arg0); 1782 1.1 mrg /* Force arg1 into the range valid matching the arg0 type. */ 1783 1.1 mrg /* Build a vector consisting of the max valid bit-size values. */ 1784 1.1 mrg int n_elts = VECTOR_CST_NELTS (arg1); 1785 1.1 mrg tree element_size = build_int_cst (unsigned_element_type, 1786 1.1 mrg 128 / n_elts); 1787 1.1 mrg tree_vector_builder elts (unsigned_arg1_type, n_elts, 1); 1788 1.1 mrg for (int i = 0; i < n_elts; i++) 1789 1.1 mrg elts.safe_push (element_size); 1790 1.1 mrg tree modulo_tree = elts.build (); 1791 1.1 mrg /* Modulo the provided shift value against that vector. */ 1792 1.1 mrg tree unsigned_arg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR, 1793 1.1 mrg unsigned_arg1_type, arg1); 1794 1.1 mrg tree new_arg1 = gimple_build (&stmts, loc, TRUNC_MOD_EXPR, 1795 1.1 mrg unsigned_arg1_type, unsigned_arg1, 1796 1.1 mrg modulo_tree); 1797 1.1 mrg /* Do the shift. */ 1798 1.1 mrg tree res 1799 1.1 mrg = gimple_build (&stmts, RSHIFT_EXPR, 1800 1.1 mrg TREE_TYPE (arg0_unsigned), arg0_unsigned, new_arg1); 1801 1.1 mrg /* Convert result back to the lhs type. */ 1802 1.1 mrg res = gimple_build (&stmts, VIEW_CONVERT_EXPR, TREE_TYPE (lhs), res); 1803 1.1 mrg gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); 1804 1.1 mrg replace_call_with_value (gsi, res); 1805 1.1 mrg return true; 1806 1.1 mrg } 1807 1.1 mrg /* Vector loads. */ 1808 1.1 mrg case RS6000_BIF_LVX_V16QI: 1809 1.1 mrg case RS6000_BIF_LVX_V8HI: 1810 1.1 mrg case RS6000_BIF_LVX_V4SI: 1811 1.1 mrg case RS6000_BIF_LVX_V4SF: 1812 1.1 mrg case RS6000_BIF_LVX_V2DI: 1813 1.1 mrg case RS6000_BIF_LVX_V2DF: 1814 1.1 mrg case RS6000_BIF_LVX_V1TI: 1815 1.1 mrg { 1816 1.1 mrg arg0 = gimple_call_arg (stmt, 0); // offset 1817 1.1 mrg arg1 = gimple_call_arg (stmt, 1); // address 1818 1.1 mrg lhs = gimple_call_lhs (stmt); 1819 1.1 mrg location_t loc = gimple_location (stmt); 1820 1.1 mrg /* Since arg1 may be cast to a different type, just use ptr_type_node 1821 1.1 mrg here instead of trying to enforce TBAA on pointer types. */ 1822 1.1 mrg tree arg1_type = ptr_type_node; 1823 1.1 mrg tree lhs_type = TREE_TYPE (lhs); 1824 1.1 mrg /* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'. Create 1825 1.1 mrg the tree using the value from arg0. The resulting type will match 1826 1.1 mrg the type of arg1. */ 1827 1.1 mrg gimple_seq stmts = NULL; 1828 1.1 mrg tree temp_offset = gimple_convert (&stmts, loc, sizetype, arg0); 1829 1.1 mrg tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR, 1830 1.1 mrg arg1_type, arg1, temp_offset); 1831 1.1 mrg /* Mask off any lower bits from the address. */ 1832 1.1 mrg tree aligned_addr = gimple_build (&stmts, loc, BIT_AND_EXPR, 1833 1.1 mrg arg1_type, temp_addr, 1834 1.1 mrg build_int_cst (arg1_type, -16)); 1835 1.1 mrg gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); 1836 1.1 mrg if (!is_gimple_mem_ref_addr (aligned_addr)) 1837 1.1 mrg { 1838 1.1 mrg tree t = make_ssa_name (TREE_TYPE (aligned_addr)); 1839 1.1 mrg gimple *g = gimple_build_assign (t, aligned_addr); 1840 1.1 mrg gsi_insert_before (gsi, g, GSI_SAME_STMT); 1841 1.1 mrg aligned_addr = t; 1842 1.1 mrg } 1843 1.1 mrg /* Use the build2 helper to set up the mem_ref. The MEM_REF could also 1844 1.1 mrg take an offset, but since we've already incorporated the offset 1845 1.1 mrg above, here we just pass in a zero. */ 1846 1.1 mrg gimple *g 1847 1.1 mrg = gimple_build_assign (lhs, build2 (MEM_REF, lhs_type, aligned_addr, 1848 1.1 mrg build_int_cst (arg1_type, 0))); 1849 1.1 mrg gimple_set_location (g, loc); 1850 1.1 mrg gsi_replace (gsi, g, true); 1851 1.1 mrg return true; 1852 1.1 mrg } 1853 1.1 mrg /* Vector stores. */ 1854 1.1 mrg case RS6000_BIF_STVX_V16QI: 1855 1.1 mrg case RS6000_BIF_STVX_V8HI: 1856 1.1 mrg case RS6000_BIF_STVX_V4SI: 1857 1.1 mrg case RS6000_BIF_STVX_V4SF: 1858 1.1 mrg case RS6000_BIF_STVX_V2DI: 1859 1.1 mrg case RS6000_BIF_STVX_V2DF: 1860 1.1 mrg { 1861 1.1 mrg arg0 = gimple_call_arg (stmt, 0); /* Value to be stored. */ 1862 1.1 mrg arg1 = gimple_call_arg (stmt, 1); /* Offset. */ 1863 1.1 mrg tree arg2 = gimple_call_arg (stmt, 2); /* Store-to address. */ 1864 1.1 mrg location_t loc = gimple_location (stmt); 1865 1.1 mrg tree arg0_type = TREE_TYPE (arg0); 1866 1.1 mrg /* Use ptr_type_node (no TBAA) for the arg2_type. 1867 1.1 mrg FIXME: (Richard) "A proper fix would be to transition this type as 1868 1.1 mrg seen from the frontend to GIMPLE, for example in a similar way we 1869 1.1 mrg do for MEM_REFs by piggy-backing that on an extra argument, a 1870 1.1 mrg constant zero pointer of the alias pointer type to use (which would 1871 1.1 mrg also serve as a type indicator of the store itself). I'd use a 1872 1.1 mrg target specific internal function for this (not sure if we can have 1873 1.1 mrg those target specific, but I guess if it's folded away then that's 1874 1.1 mrg fine) and get away with the overload set." */ 1875 1.1 mrg tree arg2_type = ptr_type_node; 1876 1.1 mrg /* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'. Create 1877 1.1 mrg the tree using the value from arg0. The resulting type will match 1878 1.1 mrg the type of arg2. */ 1879 1.1 mrg gimple_seq stmts = NULL; 1880 1.1 mrg tree temp_offset = gimple_convert (&stmts, loc, sizetype, arg1); 1881 1.1 mrg tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR, 1882 1.1 mrg arg2_type, arg2, temp_offset); 1883 1.1 mrg /* Mask off any lower bits from the address. */ 1884 1.1 mrg tree aligned_addr = gimple_build (&stmts, loc, BIT_AND_EXPR, 1885 1.1 mrg arg2_type, temp_addr, 1886 1.1 mrg build_int_cst (arg2_type, -16)); 1887 1.1 mrg gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); 1888 1.1 mrg if (!is_gimple_mem_ref_addr (aligned_addr)) 1889 1.1 mrg { 1890 1.1 mrg tree t = make_ssa_name (TREE_TYPE (aligned_addr)); 1891 1.1 mrg gimple *g = gimple_build_assign (t, aligned_addr); 1892 1.1 mrg gsi_insert_before (gsi, g, GSI_SAME_STMT); 1893 1.1 mrg aligned_addr = t; 1894 1.1 mrg } 1895 1.1 mrg /* The desired gimple result should be similar to: 1896 1.1 mrg MEM[(__vector floatD.1407 *)_1] = vf1D.2697; */ 1897 1.1 mrg gimple *g 1898 1.1 mrg = gimple_build_assign (build2 (MEM_REF, arg0_type, aligned_addr, 1899 1.1 mrg build_int_cst (arg2_type, 0)), arg0); 1900 1.1 mrg gimple_set_location (g, loc); 1901 1.1 mrg gsi_replace (gsi, g, true); 1902 1.1 mrg return true; 1903 1.1 mrg } 1904 1.1 mrg 1905 1.1 mrg /* unaligned Vector loads. */ 1906 1.1 mrg case RS6000_BIF_LXVW4X_V16QI: 1907 1.1 mrg case RS6000_BIF_LXVW4X_V8HI: 1908 1.1 mrg case RS6000_BIF_LXVW4X_V4SF: 1909 1.1 mrg case RS6000_BIF_LXVW4X_V4SI: 1910 1.1 mrg case RS6000_BIF_LXVD2X_V2DF: 1911 1.1 mrg case RS6000_BIF_LXVD2X_V2DI: 1912 1.1 mrg { 1913 1.1 mrg arg0 = gimple_call_arg (stmt, 0); // offset 1914 1.1 mrg arg1 = gimple_call_arg (stmt, 1); // address 1915 1.1 mrg lhs = gimple_call_lhs (stmt); 1916 1.1 mrg location_t loc = gimple_location (stmt); 1917 1.1 mrg /* Since arg1 may be cast to a different type, just use ptr_type_node 1918 1.1 mrg here instead of trying to enforce TBAA on pointer types. */ 1919 1.1 mrg tree arg1_type = ptr_type_node; 1920 1.1 mrg tree lhs_type = TREE_TYPE (lhs); 1921 1.1 mrg /* In GIMPLE the type of the MEM_REF specifies the alignment. The 1922 1.1 mrg required alignment (power) is 4 bytes regardless of data type. */ 1923 1.1 mrg tree align_ltype = build_aligned_type (lhs_type, 32); 1924 1.1 mrg /* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'. Create 1925 1.1 mrg the tree using the value from arg0. The resulting type will match 1926 1.1 mrg the type of arg1. */ 1927 1.1 mrg gimple_seq stmts = NULL; 1928 1.1 mrg tree temp_offset = gimple_convert (&stmts, loc, sizetype, arg0); 1929 1.1 mrg tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR, 1930 1.1 mrg arg1_type, arg1, temp_offset); 1931 1.1 mrg gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); 1932 1.1 mrg if (!is_gimple_mem_ref_addr (temp_addr)) 1933 1.1 mrg { 1934 1.1 mrg tree t = make_ssa_name (TREE_TYPE (temp_addr)); 1935 1.1 mrg gimple *g = gimple_build_assign (t, temp_addr); 1936 1.1 mrg gsi_insert_before (gsi, g, GSI_SAME_STMT); 1937 1.1 mrg temp_addr = t; 1938 1.1 mrg } 1939 1.1 mrg /* Use the build2 helper to set up the mem_ref. The MEM_REF could also 1940 1.1 mrg take an offset, but since we've already incorporated the offset 1941 1.1 mrg above, here we just pass in a zero. */ 1942 1.1 mrg gimple *g; 1943 1.1 mrg g = gimple_build_assign (lhs, build2 (MEM_REF, align_ltype, temp_addr, 1944 1.1 mrg build_int_cst (arg1_type, 0))); 1945 1.1 mrg gimple_set_location (g, loc); 1946 1.1 mrg gsi_replace (gsi, g, true); 1947 1.1 mrg return true; 1948 1.1 mrg } 1949 1.1 mrg 1950 1.1 mrg /* unaligned Vector stores. */ 1951 1.1 mrg case RS6000_BIF_STXVW4X_V16QI: 1952 1.1 mrg case RS6000_BIF_STXVW4X_V8HI: 1953 1.1 mrg case RS6000_BIF_STXVW4X_V4SF: 1954 1.1 mrg case RS6000_BIF_STXVW4X_V4SI: 1955 1.1 mrg case RS6000_BIF_STXVD2X_V2DF: 1956 1.1 mrg case RS6000_BIF_STXVD2X_V2DI: 1957 1.1 mrg { 1958 1.1 mrg arg0 = gimple_call_arg (stmt, 0); /* Value to be stored. */ 1959 1.1 mrg arg1 = gimple_call_arg (stmt, 1); /* Offset. */ 1960 1.1 mrg tree arg2 = gimple_call_arg (stmt, 2); /* Store-to address. */ 1961 1.1 mrg location_t loc = gimple_location (stmt); 1962 1.1 mrg tree arg0_type = TREE_TYPE (arg0); 1963 1.1 mrg /* Use ptr_type_node (no TBAA) for the arg2_type. */ 1964 1.1 mrg tree arg2_type = ptr_type_node; 1965 1.1 mrg /* In GIMPLE the type of the MEM_REF specifies the alignment. The 1966 1.1 mrg required alignment (power) is 4 bytes regardless of data type. */ 1967 1.1 mrg tree align_stype = build_aligned_type (arg0_type, 32); 1968 1.1 mrg /* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'. Create 1969 1.1 mrg the tree using the value from arg1. */ 1970 1.1 mrg gimple_seq stmts = NULL; 1971 1.1 mrg tree temp_offset = gimple_convert (&stmts, loc, sizetype, arg1); 1972 1.1 mrg tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR, 1973 1.1 mrg arg2_type, arg2, temp_offset); 1974 1.1 mrg gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); 1975 1.1 mrg if (!is_gimple_mem_ref_addr (temp_addr)) 1976 1.1 mrg { 1977 1.1 mrg tree t = make_ssa_name (TREE_TYPE (temp_addr)); 1978 1.1 mrg gimple *g = gimple_build_assign (t, temp_addr); 1979 1.1 mrg gsi_insert_before (gsi, g, GSI_SAME_STMT); 1980 1.1 mrg temp_addr = t; 1981 1.1 mrg } 1982 1.1 mrg gimple *g; 1983 1.1 mrg g = gimple_build_assign (build2 (MEM_REF, align_stype, temp_addr, 1984 1.1 mrg build_int_cst (arg2_type, 0)), arg0); 1985 1.1 mrg gimple_set_location (g, loc); 1986 1.1 mrg gsi_replace (gsi, g, true); 1987 1.1 mrg return true; 1988 1.1 mrg } 1989 1.1 mrg 1990 1.1 mrg /* Vector Fused multiply-add (fma). */ 1991 1.1 mrg case RS6000_BIF_VMADDFP: 1992 1.1 mrg case RS6000_BIF_XVMADDDP: 1993 1.1 mrg case RS6000_BIF_XVMADDSP: 1994 1.1 mrg case RS6000_BIF_VMLADDUHM: 1995 1.1 mrg { 1996 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 1997 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 1998 1.1 mrg tree arg2 = gimple_call_arg (stmt, 2); 1999 1.1 mrg lhs = gimple_call_lhs (stmt); 2000 1.1 mrg gcall *g = gimple_build_call_internal (IFN_FMA, 3, arg0, arg1, arg2); 2001 1.1 mrg gimple_call_set_lhs (g, lhs); 2002 1.1 mrg gimple_call_set_nothrow (g, true); 2003 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 2004 1.1 mrg gsi_replace (gsi, g, true); 2005 1.1 mrg return true; 2006 1.1 mrg } 2007 1.1 mrg 2008 1.1 mrg /* Vector compares; EQ, NE, GE, GT, LE. */ 2009 1.1 mrg case RS6000_BIF_VCMPEQUB: 2010 1.1 mrg case RS6000_BIF_VCMPEQUH: 2011 1.1 mrg case RS6000_BIF_VCMPEQUW: 2012 1.1 mrg case RS6000_BIF_VCMPEQUD: 2013 1.1 mrg /* We deliberately omit RS6000_BIF_VCMPEQUT for now, because gimple 2014 1.1 mrg folding produces worse code for 128-bit compares. */ 2015 1.1 mrg fold_compare_helper (gsi, EQ_EXPR, stmt); 2016 1.1 mrg return true; 2017 1.1 mrg 2018 1.1 mrg case RS6000_BIF_VCMPNEB: 2019 1.1 mrg case RS6000_BIF_VCMPNEH: 2020 1.1 mrg case RS6000_BIF_VCMPNEW: 2021 1.1 mrg /* We deliberately omit RS6000_BIF_VCMPNET for now, because gimple 2022 1.1 mrg folding produces worse code for 128-bit compares. */ 2023 1.1 mrg fold_compare_helper (gsi, NE_EXPR, stmt); 2024 1.1 mrg return true; 2025 1.1 mrg 2026 1.1 mrg case RS6000_BIF_CMPGE_16QI: 2027 1.1 mrg case RS6000_BIF_CMPGE_U16QI: 2028 1.1 mrg case RS6000_BIF_CMPGE_8HI: 2029 1.1 mrg case RS6000_BIF_CMPGE_U8HI: 2030 1.1 mrg case RS6000_BIF_CMPGE_4SI: 2031 1.1 mrg case RS6000_BIF_CMPGE_U4SI: 2032 1.1 mrg case RS6000_BIF_CMPGE_2DI: 2033 1.1 mrg case RS6000_BIF_CMPGE_U2DI: 2034 1.1 mrg /* We deliberately omit RS6000_BIF_CMPGE_1TI and RS6000_BIF_CMPGE_U1TI 2035 1.1 mrg for now, because gimple folding produces worse code for 128-bit 2036 1.1 mrg compares. */ 2037 1.1 mrg fold_compare_helper (gsi, GE_EXPR, stmt); 2038 1.1 mrg return true; 2039 1.1 mrg 2040 1.1 mrg case RS6000_BIF_VCMPGTSB: 2041 1.1 mrg case RS6000_BIF_VCMPGTUB: 2042 1.1 mrg case RS6000_BIF_VCMPGTSH: 2043 1.1 mrg case RS6000_BIF_VCMPGTUH: 2044 1.1 mrg case RS6000_BIF_VCMPGTSW: 2045 1.1 mrg case RS6000_BIF_VCMPGTUW: 2046 1.1 mrg case RS6000_BIF_VCMPGTUD: 2047 1.1 mrg case RS6000_BIF_VCMPGTSD: 2048 1.1 mrg /* We deliberately omit RS6000_BIF_VCMPGTUT and RS6000_BIF_VCMPGTST 2049 1.1 mrg for now, because gimple folding produces worse code for 128-bit 2050 1.1 mrg compares. */ 2051 1.1 mrg fold_compare_helper (gsi, GT_EXPR, stmt); 2052 1.1 mrg return true; 2053 1.1 mrg 2054 1.1 mrg case RS6000_BIF_CMPLE_16QI: 2055 1.1 mrg case RS6000_BIF_CMPLE_U16QI: 2056 1.1 mrg case RS6000_BIF_CMPLE_8HI: 2057 1.1 mrg case RS6000_BIF_CMPLE_U8HI: 2058 1.1 mrg case RS6000_BIF_CMPLE_4SI: 2059 1.1 mrg case RS6000_BIF_CMPLE_U4SI: 2060 1.1 mrg case RS6000_BIF_CMPLE_2DI: 2061 1.1 mrg case RS6000_BIF_CMPLE_U2DI: 2062 1.1 mrg /* We deliberately omit RS6000_BIF_CMPLE_1TI and RS6000_BIF_CMPLE_U1TI 2063 1.1 mrg for now, because gimple folding produces worse code for 128-bit 2064 1.1 mrg compares. */ 2065 1.1 mrg fold_compare_helper (gsi, LE_EXPR, stmt); 2066 1.1 mrg return true; 2067 1.1 mrg 2068 1.1 mrg /* flavors of vec_splat_[us]{8,16,32}. */ 2069 1.1 mrg case RS6000_BIF_VSPLTISB: 2070 1.1 mrg case RS6000_BIF_VSPLTISH: 2071 1.1 mrg case RS6000_BIF_VSPLTISW: 2072 1.1 mrg { 2073 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 2074 1.1 mrg lhs = gimple_call_lhs (stmt); 2075 1.1 mrg 2076 1.1 mrg /* Only fold the vec_splat_*() if the lower bits of arg 0 is a 2077 1.1 mrg 5-bit signed constant in range -16 to +15. */ 2078 1.1 mrg if (TREE_CODE (arg0) != INTEGER_CST 2079 1.1 mrg || !IN_RANGE (TREE_INT_CST_LOW (arg0), -16, 15)) 2080 1.1 mrg return false; 2081 1.1 mrg gimple_seq stmts = NULL; 2082 1.1 mrg location_t loc = gimple_location (stmt); 2083 1.1 mrg tree splat_value = gimple_convert (&stmts, loc, 2084 1.1 mrg TREE_TYPE (TREE_TYPE (lhs)), arg0); 2085 1.1 mrg gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); 2086 1.1 mrg tree splat_tree = build_vector_from_val (TREE_TYPE (lhs), splat_value); 2087 1.1 mrg g = gimple_build_assign (lhs, splat_tree); 2088 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 2089 1.1 mrg gsi_replace (gsi, g, true); 2090 1.1 mrg return true; 2091 1.1 mrg } 2092 1.1 mrg 2093 1.1 mrg /* Flavors of vec_splat. */ 2094 1.1 mrg /* a = vec_splat (b, 0x3) becomes a = { b[3],b[3],b[3],...}; */ 2095 1.1 mrg case RS6000_BIF_VSPLTB: 2096 1.1 mrg case RS6000_BIF_VSPLTH: 2097 1.1 mrg case RS6000_BIF_VSPLTW: 2098 1.1 mrg case RS6000_BIF_XXSPLTD_V2DI: 2099 1.1 mrg case RS6000_BIF_XXSPLTD_V2DF: 2100 1.1 mrg { 2101 1.1 mrg arg0 = gimple_call_arg (stmt, 0); /* input vector. */ 2102 1.1 mrg arg1 = gimple_call_arg (stmt, 1); /* index into arg0. */ 2103 1.1 mrg /* Only fold the vec_splat_*() if arg1 is both a constant value and 2104 1.1 mrg is a valid index into the arg0 vector. */ 2105 1.1 mrg unsigned int n_elts = VECTOR_CST_NELTS (arg0); 2106 1.1 mrg if (TREE_CODE (arg1) != INTEGER_CST 2107 1.1 mrg || TREE_INT_CST_LOW (arg1) > (n_elts -1)) 2108 1.1 mrg return false; 2109 1.1 mrg lhs = gimple_call_lhs (stmt); 2110 1.1 mrg tree lhs_type = TREE_TYPE (lhs); 2111 1.1 mrg tree arg0_type = TREE_TYPE (arg0); 2112 1.1 mrg tree splat; 2113 1.1 mrg if (TREE_CODE (arg0) == VECTOR_CST) 2114 1.1 mrg splat = VECTOR_CST_ELT (arg0, TREE_INT_CST_LOW (arg1)); 2115 1.1 mrg else 2116 1.1 mrg { 2117 1.1 mrg /* Determine (in bits) the length and start location of the 2118 1.1 mrg splat value for a call to the tree_vec_extract helper. */ 2119 1.1 mrg int splat_elem_size = TREE_INT_CST_LOW (size_in_bytes (arg0_type)) 2120 1.1 mrg * BITS_PER_UNIT / n_elts; 2121 1.1 mrg int splat_start_bit = TREE_INT_CST_LOW (arg1) * splat_elem_size; 2122 1.1 mrg tree len = build_int_cst (bitsizetype, splat_elem_size); 2123 1.1 mrg tree start = build_int_cst (bitsizetype, splat_start_bit); 2124 1.1 mrg splat = tree_vec_extract (gsi, TREE_TYPE (lhs_type), arg0, 2125 1.1 mrg len, start); 2126 1.1 mrg } 2127 1.1 mrg /* And finally, build the new vector. */ 2128 1.1 mrg tree splat_tree = build_vector_from_val (lhs_type, splat); 2129 1.1 mrg g = gimple_build_assign (lhs, splat_tree); 2130 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 2131 1.1 mrg gsi_replace (gsi, g, true); 2132 1.1 mrg return true; 2133 1.1 mrg } 2134 1.1 mrg 2135 1.1 mrg /* vec_mergel (integrals). */ 2136 1.1 mrg case RS6000_BIF_VMRGLH: 2137 1.1 mrg case RS6000_BIF_VMRGLW: 2138 1.1 mrg case RS6000_BIF_XXMRGLW_4SI: 2139 1.1 mrg case RS6000_BIF_VMRGLB: 2140 1.1 mrg case RS6000_BIF_VEC_MERGEL_V2DI: 2141 1.1 mrg case RS6000_BIF_XXMRGLW_4SF: 2142 1.1 mrg case RS6000_BIF_VEC_MERGEL_V2DF: 2143 1.1 mrg fold_mergehl_helper (gsi, stmt, 1); 2144 1.1 mrg return true; 2145 1.1 mrg /* vec_mergeh (integrals). */ 2146 1.1 mrg case RS6000_BIF_VMRGHH: 2147 1.1 mrg case RS6000_BIF_VMRGHW: 2148 1.1 mrg case RS6000_BIF_XXMRGHW_4SI: 2149 1.1 mrg case RS6000_BIF_VMRGHB: 2150 1.1 mrg case RS6000_BIF_VEC_MERGEH_V2DI: 2151 1.1 mrg case RS6000_BIF_XXMRGHW_4SF: 2152 1.1 mrg case RS6000_BIF_VEC_MERGEH_V2DF: 2153 1.1 mrg fold_mergehl_helper (gsi, stmt, 0); 2154 1.1 mrg return true; 2155 1.1 mrg 2156 1.1 mrg /* Flavors of vec_mergee. */ 2157 1.1 mrg case RS6000_BIF_VMRGEW_V4SI: 2158 1.1 mrg case RS6000_BIF_VMRGEW_V2DI: 2159 1.1 mrg case RS6000_BIF_VMRGEW_V4SF: 2160 1.1 mrg case RS6000_BIF_VMRGEW_V2DF: 2161 1.1 mrg fold_mergeeo_helper (gsi, stmt, 0); 2162 1.1 mrg return true; 2163 1.1 mrg /* Flavors of vec_mergeo. */ 2164 1.1 mrg case RS6000_BIF_VMRGOW_V4SI: 2165 1.1 mrg case RS6000_BIF_VMRGOW_V2DI: 2166 1.1 mrg case RS6000_BIF_VMRGOW_V4SF: 2167 1.1 mrg case RS6000_BIF_VMRGOW_V2DF: 2168 1.1 mrg fold_mergeeo_helper (gsi, stmt, 1); 2169 1.1 mrg return true; 2170 1.1 mrg 2171 1.1 mrg /* d = vec_pack (a, b) */ 2172 1.1 mrg case RS6000_BIF_VPKUDUM: 2173 1.1 mrg case RS6000_BIF_VPKUHUM: 2174 1.1 mrg case RS6000_BIF_VPKUWUM: 2175 1.1 mrg { 2176 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 2177 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 2178 1.1 mrg lhs = gimple_call_lhs (stmt); 2179 1.1 mrg gimple *g = gimple_build_assign (lhs, VEC_PACK_TRUNC_EXPR, arg0, arg1); 2180 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 2181 1.1 mrg gsi_replace (gsi, g, true); 2182 1.1 mrg return true; 2183 1.1 mrg } 2184 1.1 mrg 2185 1.1 mrg /* d = vec_unpackh (a) */ 2186 1.1 mrg /* Note that the UNPACK_{HI,LO}_EXPR used in the gimple_build_assign call 2187 1.1 mrg in this code is sensitive to endian-ness, and needs to be inverted to 2188 1.1 mrg handle both LE and BE targets. */ 2189 1.1 mrg case RS6000_BIF_VUPKHSB: 2190 1.1 mrg case RS6000_BIF_VUPKHSH: 2191 1.1 mrg case RS6000_BIF_VUPKHSW: 2192 1.1 mrg { 2193 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 2194 1.1 mrg lhs = gimple_call_lhs (stmt); 2195 1.1 mrg if (BYTES_BIG_ENDIAN) 2196 1.1 mrg g = gimple_build_assign (lhs, VEC_UNPACK_HI_EXPR, arg0); 2197 1.1 mrg else 2198 1.1 mrg g = gimple_build_assign (lhs, VEC_UNPACK_LO_EXPR, arg0); 2199 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 2200 1.1 mrg gsi_replace (gsi, g, true); 2201 1.1 mrg return true; 2202 1.1 mrg } 2203 1.1 mrg /* d = vec_unpackl (a) */ 2204 1.1 mrg case RS6000_BIF_VUPKLSB: 2205 1.1 mrg case RS6000_BIF_VUPKLSH: 2206 1.1 mrg case RS6000_BIF_VUPKLSW: 2207 1.1 mrg { 2208 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 2209 1.1 mrg lhs = gimple_call_lhs (stmt); 2210 1.1 mrg if (BYTES_BIG_ENDIAN) 2211 1.1 mrg g = gimple_build_assign (lhs, VEC_UNPACK_LO_EXPR, arg0); 2212 1.1 mrg else 2213 1.1 mrg g = gimple_build_assign (lhs, VEC_UNPACK_HI_EXPR, arg0); 2214 1.1 mrg gimple_set_location (g, gimple_location (stmt)); 2215 1.1 mrg gsi_replace (gsi, g, true); 2216 1.1 mrg return true; 2217 1.1 mrg } 2218 1.1 mrg /* There is no gimple type corresponding with pixel, so just return. */ 2219 1.1 mrg case RS6000_BIF_VUPKHPX: 2220 1.1 mrg case RS6000_BIF_VUPKLPX: 2221 1.1 mrg return false; 2222 1.1 mrg 2223 1.1 mrg /* vec_perm. */ 2224 1.1 mrg case RS6000_BIF_VPERM_16QI: 2225 1.1 mrg case RS6000_BIF_VPERM_8HI: 2226 1.1 mrg case RS6000_BIF_VPERM_4SI: 2227 1.1 mrg case RS6000_BIF_VPERM_2DI: 2228 1.1 mrg case RS6000_BIF_VPERM_4SF: 2229 1.1 mrg case RS6000_BIF_VPERM_2DF: 2230 1.1 mrg case RS6000_BIF_VPERM_16QI_UNS: 2231 1.1 mrg case RS6000_BIF_VPERM_8HI_UNS: 2232 1.1 mrg case RS6000_BIF_VPERM_4SI_UNS: 2233 1.1 mrg case RS6000_BIF_VPERM_2DI_UNS: 2234 1.1 mrg { 2235 1.1 mrg arg0 = gimple_call_arg (stmt, 0); 2236 1.1 mrg arg1 = gimple_call_arg (stmt, 1); 2237 1.1 mrg tree permute = gimple_call_arg (stmt, 2); 2238 1.1 mrg lhs = gimple_call_lhs (stmt); 2239 1.1 mrg location_t loc = gimple_location (stmt); 2240 1.1 mrg gimple_seq stmts = NULL; 2241 1.1 mrg // convert arg0 and arg1 to match the type of the permute 2242 1.1 mrg // for the VEC_PERM_EXPR operation. 2243 1.1 mrg tree permute_type = (TREE_TYPE (permute)); 2244 1.1 mrg tree arg0_ptype = gimple_build (&stmts, loc, VIEW_CONVERT_EXPR, 2245 1.1 mrg permute_type, arg0); 2246 1.1 mrg tree arg1_ptype = gimple_build (&stmts, loc, VIEW_CONVERT_EXPR, 2247 1.1 mrg permute_type, arg1); 2248 1.1 mrg tree lhs_ptype = gimple_build (&stmts, loc, VEC_PERM_EXPR, 2249 1.1 mrg permute_type, arg0_ptype, arg1_ptype, 2250 1.1 mrg permute); 2251 1.1 mrg // Convert the result back to the desired lhs type upon completion. 2252 1.1 mrg tree temp = gimple_build (&stmts, loc, VIEW_CONVERT_EXPR, 2253 1.1 mrg TREE_TYPE (lhs), lhs_ptype); 2254 1.1 mrg gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); 2255 1.1 mrg g = gimple_build_assign (lhs, temp); 2256 1.1 mrg gimple_set_location (g, loc); 2257 1.1 mrg gsi_replace (gsi, g, true); 2258 1.1 mrg return true; 2259 1.1 mrg } 2260 1.1 mrg 2261 1.1 mrg default: 2262 1.1 mrg if (TARGET_DEBUG_BUILTIN) 2263 1.1 mrg fprintf (stderr, "gimple builtin intrinsic not matched:%d %s %s\n", 2264 1.1 mrg fn_code, fn_name1, fn_name2); 2265 1.1 mrg break; 2266 1.1 mrg } 2267 1.1 mrg 2268 1.1 mrg return false; 2269 1.1 mrg } 2270 1.1 mrg 2271 1.1 mrg /* **** Expansion support **** */ 2272 1.1 mrg 2273 1.1 mrg static rtx 2274 1.1 mrg altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target) 2275 1.1 mrg { 2276 1.1 mrg rtx pat, scratch; 2277 1.1 mrg tree cr6_form = CALL_EXPR_ARG (exp, 0); 2278 1.1 mrg tree arg0 = CALL_EXPR_ARG (exp, 1); 2279 1.1 mrg tree arg1 = CALL_EXPR_ARG (exp, 2); 2280 1.1 mrg rtx op0 = expand_normal (arg0); 2281 1.1 mrg rtx op1 = expand_normal (arg1); 2282 1.1 mrg machine_mode tmode = SImode; 2283 1.1 mrg machine_mode mode0 = insn_data[icode].operand[1].mode; 2284 1.1 mrg machine_mode mode1 = insn_data[icode].operand[2].mode; 2285 1.1 mrg int cr6_form_int; 2286 1.1 mrg 2287 1.1 mrg if (TREE_CODE (cr6_form) != INTEGER_CST) 2288 1.1 mrg { 2289 1.1 mrg error ("argument 1 of %qs must be a constant", 2290 1.1 mrg "__builtin_altivec_predicate"); 2291 1.1 mrg return const0_rtx; 2292 1.1 mrg } 2293 1.1 mrg else 2294 1.1 mrg cr6_form_int = TREE_INT_CST_LOW (cr6_form); 2295 1.1 mrg 2296 1.1 mrg gcc_assert (mode0 == mode1); 2297 1.1 mrg 2298 1.1 mrg /* If we have invalid arguments, bail out before generating bad rtl. */ 2299 1.1 mrg if (arg0 == error_mark_node || arg1 == error_mark_node) 2300 1.1 mrg return const0_rtx; 2301 1.1 mrg 2302 1.1 mrg if (target == 0 2303 1.1 mrg || GET_MODE (target) != tmode 2304 1.1 mrg || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) 2305 1.1 mrg target = gen_reg_rtx (tmode); 2306 1.1 mrg 2307 1.1 mrg if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) 2308 1.1 mrg op0 = copy_to_mode_reg (mode0, op0); 2309 1.1 mrg if (! (*insn_data[icode].operand[2].predicate) (op1, mode1)) 2310 1.1 mrg op1 = copy_to_mode_reg (mode1, op1); 2311 1.1 mrg 2312 1.1 mrg /* Note that for many of the relevant operations (e.g. cmpne or 2313 1.1 mrg cmpeq) with float or double operands, it makes more sense for the 2314 1.1 mrg mode of the allocated scratch register to select a vector of 2315 1.1 mrg integer. But the choice to copy the mode of operand 0 was made 2316 1.1 mrg long ago and there are no plans to change it. */ 2317 1.1 mrg scratch = gen_reg_rtx (mode0); 2318 1.1 mrg 2319 1.1 mrg pat = GEN_FCN (icode) (scratch, op0, op1); 2320 1.1 mrg if (! pat) 2321 1.1 mrg return 0; 2322 1.1 mrg emit_insn (pat); 2323 1.1 mrg 2324 1.1 mrg /* The vec_any* and vec_all* predicates use the same opcodes for two 2325 1.1 mrg different operations, but the bits in CR6 will be different 2326 1.1 mrg depending on what information we want. So we have to play tricks 2327 1.1 mrg with CR6 to get the right bits out. 2328 1.1 mrg 2329 1.1 mrg If you think this is disgusting, look at the specs for the 2330 1.1 mrg AltiVec predicates. */ 2331 1.1 mrg 2332 1.1 mrg switch (cr6_form_int) 2333 1.1 mrg { 2334 1.1 mrg case 0: 2335 1.1 mrg emit_insn (gen_cr6_test_for_zero (target)); 2336 1.1 mrg break; 2337 1.1 mrg case 1: 2338 1.1 mrg emit_insn (gen_cr6_test_for_zero_reverse (target)); 2339 1.1 mrg break; 2340 1.1 mrg case 2: 2341 1.1 mrg emit_insn (gen_cr6_test_for_lt (target)); 2342 1.1 mrg break; 2343 1.1 mrg case 3: 2344 1.1 mrg emit_insn (gen_cr6_test_for_lt_reverse (target)); 2345 1.1 mrg break; 2346 1.1 mrg default: 2347 1.1 mrg error ("argument 1 of %qs is out of range", 2348 1.1 mrg "__builtin_altivec_predicate"); 2349 1.1 mrg break; 2350 1.1 mrg } 2351 1.1 mrg 2352 1.1 mrg return target; 2353 1.1 mrg } 2354 1.1 mrg 2355 1.1 mrg /* Expand vec_init builtin. */ 2356 1.1 mrg static rtx 2357 1.1 mrg altivec_expand_vec_init_builtin (tree type, tree exp, rtx target) 2358 1.1 mrg { 2359 1.1 mrg machine_mode tmode = TYPE_MODE (type); 2360 1.1 mrg machine_mode inner_mode = GET_MODE_INNER (tmode); 2361 1.1 mrg int i, n_elt = GET_MODE_NUNITS (tmode); 2362 1.1 mrg 2363 1.1 mrg gcc_assert (VECTOR_MODE_P (tmode)); 2364 1.1 mrg gcc_assert (n_elt == call_expr_nargs (exp)); 2365 1.1 mrg 2366 1.1 mrg if (!target || !register_operand (target, tmode)) 2367 1.1 mrg target = gen_reg_rtx (tmode); 2368 1.1 mrg 2369 1.1 mrg /* If we have a vector compromised of a single element, such as V1TImode, do 2370 1.1 mrg the initialization directly. */ 2371 1.1 mrg if (n_elt == 1 && GET_MODE_SIZE (tmode) == GET_MODE_SIZE (inner_mode)) 2372 1.1 mrg { 2373 1.1 mrg rtx x = expand_normal (CALL_EXPR_ARG (exp, 0)); 2374 1.1 mrg emit_move_insn (target, gen_lowpart (tmode, x)); 2375 1.1 mrg } 2376 1.1 mrg else 2377 1.1 mrg { 2378 1.1 mrg rtvec v = rtvec_alloc (n_elt); 2379 1.1 mrg 2380 1.1 mrg for (i = 0; i < n_elt; ++i) 2381 1.1 mrg { 2382 1.1 mrg rtx x = expand_normal (CALL_EXPR_ARG (exp, i)); 2383 1.1 mrg RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x); 2384 1.1 mrg } 2385 1.1 mrg 2386 1.1 mrg rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v)); 2387 1.1 mrg } 2388 1.1 mrg 2389 1.1 mrg return target; 2390 1.1 mrg } 2391 1.1 mrg 2392 1.1 mrg /* Return the integer constant in ARG. Constrain it to be in the range 2393 1.1 mrg of the subparts of VEC_TYPE; issue an error if not. */ 2394 1.1 mrg 2395 1.1 mrg static int 2396 1.1 mrg get_element_number (tree vec_type, tree arg) 2397 1.1 mrg { 2398 1.1 mrg unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1; 2399 1.1 mrg 2400 1.1 mrg if (!tree_fits_uhwi_p (arg) 2401 1.1 mrg || (elt = tree_to_uhwi (arg), elt > max)) 2402 1.1 mrg { 2403 1.1 mrg error ("selector must be an integer constant in the range [0, %wi]", max); 2404 1.1 mrg return 0; 2405 1.1 mrg } 2406 1.1 mrg 2407 1.1 mrg return elt; 2408 1.1 mrg } 2409 1.1 mrg 2410 1.1 mrg /* Expand vec_set builtin. */ 2411 1.1 mrg static rtx 2412 1.1 mrg altivec_expand_vec_set_builtin (tree exp) 2413 1.1 mrg { 2414 1.1 mrg machine_mode tmode, mode1; 2415 1.1 mrg tree arg0, arg1, arg2; 2416 1.1 mrg int elt; 2417 1.1 mrg rtx op0, op1; 2418 1.1 mrg 2419 1.1 mrg arg0 = CALL_EXPR_ARG (exp, 0); 2420 1.1 mrg arg1 = CALL_EXPR_ARG (exp, 1); 2421 1.1 mrg arg2 = CALL_EXPR_ARG (exp, 2); 2422 1.1 mrg 2423 1.1 mrg tmode = TYPE_MODE (TREE_TYPE (arg0)); 2424 1.1 mrg mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))); 2425 1.1 mrg gcc_assert (VECTOR_MODE_P (tmode)); 2426 1.1 mrg 2427 1.1 mrg op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL); 2428 1.1 mrg op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL); 2429 1.1 mrg elt = get_element_number (TREE_TYPE (arg0), arg2); 2430 1.1 mrg 2431 1.1 mrg if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode) 2432 1.1 mrg op1 = convert_modes (mode1, GET_MODE (op1), op1, true); 2433 1.1 mrg 2434 1.1 mrg op0 = force_reg (tmode, op0); 2435 1.1 mrg op1 = force_reg (mode1, op1); 2436 1.1 mrg 2437 1.1 mrg rs6000_expand_vector_set (op0, op1, GEN_INT (elt)); 2438 1.1 mrg 2439 1.1 mrg return op0; 2440 1.1 mrg } 2441 1.1 mrg 2442 1.1 mrg /* Expand vec_ext builtin. */ 2443 1.1 mrg static rtx 2444 1.1 mrg altivec_expand_vec_ext_builtin (tree exp, rtx target) 2445 1.1 mrg { 2446 1.1 mrg machine_mode tmode, mode0; 2447 1.1 mrg tree arg0, arg1; 2448 1.1 mrg rtx op0; 2449 1.1 mrg rtx op1; 2450 1.1 mrg 2451 1.1 mrg arg0 = CALL_EXPR_ARG (exp, 0); 2452 1.1 mrg arg1 = CALL_EXPR_ARG (exp, 1); 2453 1.1 mrg 2454 1.1 mrg op0 = expand_normal (arg0); 2455 1.1 mrg op1 = expand_normal (arg1); 2456 1.1 mrg 2457 1.1 mrg if (TREE_CODE (arg1) == INTEGER_CST) 2458 1.1 mrg { 2459 1.1 mrg unsigned HOST_WIDE_INT elt; 2460 1.1 mrg unsigned HOST_WIDE_INT size = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)); 2461 1.1 mrg unsigned int truncated_selector; 2462 1.1 mrg /* Even if !tree_fits_uhwi_p (arg1)), TREE_INT_CST_LOW (arg0) 2463 1.1 mrg returns low-order bits of INTEGER_CST for modulo indexing. */ 2464 1.1 mrg elt = TREE_INT_CST_LOW (arg1); 2465 1.1 mrg truncated_selector = elt % size; 2466 1.1 mrg op1 = GEN_INT (truncated_selector); 2467 1.1 mrg } 2468 1.1 mrg 2469 1.1 mrg tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))); 2470 1.1 mrg mode0 = TYPE_MODE (TREE_TYPE (arg0)); 2471 1.1 mrg gcc_assert (VECTOR_MODE_P (mode0)); 2472 1.1 mrg 2473 1.1 mrg op0 = force_reg (mode0, op0); 2474 1.1 mrg 2475 1.1 mrg if (optimize || !target || !register_operand (target, tmode)) 2476 1.1 mrg target = gen_reg_rtx (tmode); 2477 1.1 mrg 2478 1.1 mrg rs6000_expand_vector_extract (target, op0, op1); 2479 1.1 mrg 2480 1.1 mrg return target; 2481 1.1 mrg } 2482 1.1 mrg 2483 1.1 mrg /* Expand ALTIVEC_BUILTIN_MASK_FOR_LOAD. */ 2484 1.1 mrg rtx 2485 1.1 mrg rs6000_expand_ldst_mask (rtx target, tree arg0) 2486 1.1 mrg { 2487 1.1 mrg int icode2 = BYTES_BIG_ENDIAN ? (int) CODE_FOR_altivec_lvsr_direct 2488 1.1 mrg : (int) CODE_FOR_altivec_lvsl_direct; 2489 1.1 mrg machine_mode tmode = insn_data[icode2].operand[0].mode; 2490 1.1 mrg machine_mode mode = insn_data[icode2].operand[1].mode; 2491 1.1 mrg 2492 1.1 mrg gcc_assert (TARGET_ALTIVEC); 2493 1.1 mrg 2494 1.1 mrg gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg0))); 2495 1.1 mrg rtx op = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL); 2496 1.1 mrg rtx addr = memory_address (mode, op); 2497 1.1 mrg /* We need to negate the address. */ 2498 1.1 mrg op = gen_reg_rtx (GET_MODE (addr)); 2499 1.1 mrg emit_insn (gen_rtx_SET (op, gen_rtx_NEG (GET_MODE (addr), addr))); 2500 1.1 mrg op = gen_rtx_MEM (mode, op); 2501 1.1 mrg 2502 1.1 mrg if (target == 0 2503 1.1 mrg || GET_MODE (target) != tmode 2504 1.1 mrg || !insn_data[icode2].operand[0].predicate (target, tmode)) 2505 1.1 mrg target = gen_reg_rtx (tmode); 2506 1.1 mrg 2507 1.1 mrg rtx pat = GEN_FCN (icode2) (target, op); 2508 1.1 mrg if (!pat) 2509 1.1 mrg return 0; 2510 1.1 mrg emit_insn (pat); 2511 1.1 mrg 2512 1.1 mrg return target; 2513 1.1 mrg } 2514 1.1 mrg 2515 1.1 mrg /* Used by __builtin_cpu_is(), mapping from PLATFORM names to values. */ 2516 1.1 mrg static const struct 2517 1.1 mrg { 2518 1.1 mrg const char *cpu; 2519 1.1 mrg unsigned int cpuid; 2520 1.1 mrg } cpu_is_info[] = { 2521 1.1 mrg { "power10", PPC_PLATFORM_POWER10 }, 2522 1.1 mrg { "power9", PPC_PLATFORM_POWER9 }, 2523 1.1 mrg { "power8", PPC_PLATFORM_POWER8 }, 2524 1.1 mrg { "power7", PPC_PLATFORM_POWER7 }, 2525 1.1 mrg { "power6x", PPC_PLATFORM_POWER6X }, 2526 1.1 mrg { "power6", PPC_PLATFORM_POWER6 }, 2527 1.1 mrg { "power5+", PPC_PLATFORM_POWER5_PLUS }, 2528 1.1 mrg { "power5", PPC_PLATFORM_POWER5 }, 2529 1.1 mrg { "ppc970", PPC_PLATFORM_PPC970 }, 2530 1.1 mrg { "power4", PPC_PLATFORM_POWER4 }, 2531 1.1 mrg { "ppca2", PPC_PLATFORM_PPCA2 }, 2532 1.1 mrg { "ppc476", PPC_PLATFORM_PPC476 }, 2533 1.1 mrg { "ppc464", PPC_PLATFORM_PPC464 }, 2534 1.1 mrg { "ppc440", PPC_PLATFORM_PPC440 }, 2535 1.1 mrg { "ppc405", PPC_PLATFORM_PPC405 }, 2536 1.1 mrg { "ppc-cell-be", PPC_PLATFORM_CELL_BE } 2537 1.1 mrg }; 2538 1.1 mrg 2539 1.1 mrg /* Used by __builtin_cpu_supports(), mapping from HWCAP names to masks. */ 2540 1.1 mrg static const struct 2541 1.1 mrg { 2542 1.1 mrg const char *hwcap; 2543 1.1 mrg int mask; 2544 1.1 mrg unsigned int id; 2545 1.1 mrg } cpu_supports_info[] = { 2546 1.1 mrg /* AT_HWCAP masks. */ 2547 1.1 mrg { "4xxmac", PPC_FEATURE_HAS_4xxMAC, 0 }, 2548 1.1 mrg { "altivec", PPC_FEATURE_HAS_ALTIVEC, 0 }, 2549 1.1 mrg { "arch_2_05", PPC_FEATURE_ARCH_2_05, 0 }, 2550 1.1 mrg { "arch_2_06", PPC_FEATURE_ARCH_2_06, 0 }, 2551 1.1 mrg { "archpmu", PPC_FEATURE_PERFMON_COMPAT, 0 }, 2552 1.1 mrg { "booke", PPC_FEATURE_BOOKE, 0 }, 2553 1.1 mrg { "cellbe", PPC_FEATURE_CELL_BE, 0 }, 2554 1.1 mrg { "dfp", PPC_FEATURE_HAS_DFP, 0 }, 2555 1.1 mrg { "efpdouble", PPC_FEATURE_HAS_EFP_DOUBLE, 0 }, 2556 1.1 mrg { "efpsingle", PPC_FEATURE_HAS_EFP_SINGLE, 0 }, 2557 1.1 mrg { "fpu", PPC_FEATURE_HAS_FPU, 0 }, 2558 1.1 mrg { "ic_snoop", PPC_FEATURE_ICACHE_SNOOP, 0 }, 2559 1.1 mrg { "mmu", PPC_FEATURE_HAS_MMU, 0 }, 2560 1.1 mrg { "notb", PPC_FEATURE_NO_TB, 0 }, 2561 1.1 mrg { "pa6t", PPC_FEATURE_PA6T, 0 }, 2562 1.1 mrg { "power4", PPC_FEATURE_POWER4, 0 }, 2563 1.1 mrg { "power5", PPC_FEATURE_POWER5, 0 }, 2564 1.1 mrg { "power5+", PPC_FEATURE_POWER5_PLUS, 0 }, 2565 1.1 mrg { "power6x", PPC_FEATURE_POWER6_EXT, 0 }, 2566 1.1 mrg { "ppc32", PPC_FEATURE_32, 0 }, 2567 1.1 mrg { "ppc601", PPC_FEATURE_601_INSTR, 0 }, 2568 1.1 mrg { "ppc64", PPC_FEATURE_64, 0 }, 2569 1.1 mrg { "ppcle", PPC_FEATURE_PPC_LE, 0 }, 2570 1.1 mrg { "smt", PPC_FEATURE_SMT, 0 }, 2571 1.1 mrg { "spe", PPC_FEATURE_HAS_SPE, 0 }, 2572 1.1 mrg { "true_le", PPC_FEATURE_TRUE_LE, 0 }, 2573 1.1 mrg { "ucache", PPC_FEATURE_UNIFIED_CACHE, 0 }, 2574 1.1 mrg { "vsx", PPC_FEATURE_HAS_VSX, 0 }, 2575 1.1 mrg 2576 1.1 mrg /* AT_HWCAP2 masks. */ 2577 1.1 mrg { "arch_2_07", PPC_FEATURE2_ARCH_2_07, 1 }, 2578 1.1 mrg { "dscr", PPC_FEATURE2_HAS_DSCR, 1 }, 2579 1.1 mrg { "ebb", PPC_FEATURE2_HAS_EBB, 1 }, 2580 1.1 mrg { "htm", PPC_FEATURE2_HAS_HTM, 1 }, 2581 1.1 mrg { "htm-nosc", PPC_FEATURE2_HTM_NOSC, 1 }, 2582 1.1 mrg { "htm-no-suspend", PPC_FEATURE2_HTM_NO_SUSPEND, 1 }, 2583 1.1 mrg { "isel", PPC_FEATURE2_HAS_ISEL, 1 }, 2584 1.1 mrg { "tar", PPC_FEATURE2_HAS_TAR, 1 }, 2585 1.1 mrg { "vcrypto", PPC_FEATURE2_HAS_VEC_CRYPTO, 1 }, 2586 1.1 mrg { "arch_3_00", PPC_FEATURE2_ARCH_3_00, 1 }, 2587 1.1 mrg { "ieee128", PPC_FEATURE2_HAS_IEEE128, 1 }, 2588 1.1 mrg { "darn", PPC_FEATURE2_DARN, 1 }, 2589 1.1 mrg { "scv", PPC_FEATURE2_SCV, 1 }, 2590 1.1 mrg { "arch_3_1", PPC_FEATURE2_ARCH_3_1, 1 }, 2591 1.1 mrg { "mma", PPC_FEATURE2_MMA, 1 }, 2592 1.1 mrg }; 2593 1.1 mrg 2594 1.1 mrg /* Expand the CPU builtin in FCODE and store the result in TARGET. */ 2595 1.1 mrg static rtx 2596 1.1 mrg cpu_expand_builtin (enum rs6000_gen_builtins fcode, 2597 1.1 mrg tree exp ATTRIBUTE_UNUSED, rtx target) 2598 1.1 mrg { 2599 1.1 mrg /* __builtin_cpu_init () is a nop, so expand to nothing. */ 2600 1.1 mrg if (fcode == RS6000_BIF_CPU_INIT) 2601 1.1 mrg return const0_rtx; 2602 1.1 mrg 2603 1.1 mrg if (target == 0 || GET_MODE (target) != SImode) 2604 1.1 mrg target = gen_reg_rtx (SImode); 2605 1.1 mrg 2606 1.1 mrg /* TODO: Factor the #ifdef'd code into a separate function. */ 2607 1.1 mrg #ifdef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB 2608 1.1 mrg tree arg = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0); 2609 1.1 mrg /* Target clones creates an ARRAY_REF instead of STRING_CST, convert it back 2610 1.1 mrg to a STRING_CST. */ 2611 1.1 mrg if (TREE_CODE (arg) == ARRAY_REF 2612 1.1 mrg && TREE_CODE (TREE_OPERAND (arg, 0)) == STRING_CST 2613 1.1 mrg && TREE_CODE (TREE_OPERAND (arg, 1)) == INTEGER_CST 2614 1.1 mrg && compare_tree_int (TREE_OPERAND (arg, 1), 0) == 0) 2615 1.1 mrg arg = TREE_OPERAND (arg, 0); 2616 1.1 mrg 2617 1.1 mrg if (TREE_CODE (arg) != STRING_CST) 2618 1.1 mrg { 2619 1.1 mrg error ("builtin %qs only accepts a string argument", 2620 1.1 mrg rs6000_builtin_info[(size_t) fcode].bifname); 2621 1.1 mrg return const0_rtx; 2622 1.1 mrg } 2623 1.1 mrg 2624 1.1 mrg if (fcode == RS6000_BIF_CPU_IS) 2625 1.1 mrg { 2626 1.1 mrg const char *cpu = TREE_STRING_POINTER (arg); 2627 1.1 mrg rtx cpuid = NULL_RTX; 2628 1.1 mrg for (size_t i = 0; i < ARRAY_SIZE (cpu_is_info); i++) 2629 1.1 mrg if (strcmp (cpu, cpu_is_info[i].cpu) == 0) 2630 1.1 mrg { 2631 1.1 mrg /* The CPUID value in the TCB is offset by _DL_FIRST_PLATFORM. */ 2632 1.1 mrg cpuid = GEN_INT (cpu_is_info[i].cpuid + _DL_FIRST_PLATFORM); 2633 1.1 mrg break; 2634 1.1 mrg } 2635 1.1 mrg if (cpuid == NULL_RTX) 2636 1.1 mrg { 2637 1.1 mrg /* Invalid CPU argument. */ 2638 1.1 mrg error ("cpu %qs is an invalid argument to builtin %qs", 2639 1.1 mrg cpu, rs6000_builtin_info[(size_t) fcode].bifname); 2640 1.1 mrg return const0_rtx; 2641 1.1 mrg } 2642 1.1 mrg 2643 1.1 mrg rtx platform = gen_reg_rtx (SImode); 2644 1.1 mrg rtx address = gen_rtx_PLUS (Pmode, 2645 1.1 mrg gen_rtx_REG (Pmode, TLS_REGNUM), 2646 1.1 mrg GEN_INT (TCB_PLATFORM_OFFSET)); 2647 1.1 mrg rtx tcbmem = gen_const_mem (SImode, address); 2648 1.1 mrg emit_move_insn (platform, tcbmem); 2649 1.1 mrg emit_insn (gen_eqsi3 (target, platform, cpuid)); 2650 1.1 mrg } 2651 1.1 mrg else if (fcode == RS6000_BIF_CPU_SUPPORTS) 2652 1.1 mrg { 2653 1.1 mrg const char *hwcap = TREE_STRING_POINTER (arg); 2654 1.1 mrg rtx mask = NULL_RTX; 2655 1.1 mrg int hwcap_offset; 2656 1.1 mrg for (size_t i = 0; i < ARRAY_SIZE (cpu_supports_info); i++) 2657 1.1 mrg if (strcmp (hwcap, cpu_supports_info[i].hwcap) == 0) 2658 1.1 mrg { 2659 1.1 mrg mask = GEN_INT (cpu_supports_info[i].mask); 2660 1.1 mrg hwcap_offset = TCB_HWCAP_OFFSET (cpu_supports_info[i].id); 2661 1.1 mrg break; 2662 1.1 mrg } 2663 1.1 mrg if (mask == NULL_RTX) 2664 1.1 mrg { 2665 1.1 mrg /* Invalid HWCAP argument. */ 2666 1.1 mrg error ("%s %qs is an invalid argument to builtin %qs", 2667 1.1 mrg "hwcap", hwcap, 2668 1.1 mrg rs6000_builtin_info[(size_t) fcode].bifname); 2669 1.1 mrg return const0_rtx; 2670 1.1 mrg } 2671 1.1 mrg 2672 1.1 mrg rtx tcb_hwcap = gen_reg_rtx (SImode); 2673 1.1 mrg rtx address = gen_rtx_PLUS (Pmode, 2674 1.1 mrg gen_rtx_REG (Pmode, TLS_REGNUM), 2675 1.1 mrg GEN_INT (hwcap_offset)); 2676 1.1 mrg rtx tcbmem = gen_const_mem (SImode, address); 2677 1.1 mrg emit_move_insn (tcb_hwcap, tcbmem); 2678 1.1 mrg rtx scratch1 = gen_reg_rtx (SImode); 2679 1.1 mrg emit_insn (gen_rtx_SET (scratch1, 2680 1.1 mrg gen_rtx_AND (SImode, tcb_hwcap, mask))); 2681 1.1 mrg rtx scratch2 = gen_reg_rtx (SImode); 2682 1.1 mrg emit_insn (gen_eqsi3 (scratch2, scratch1, const0_rtx)); 2683 1.1 mrg emit_insn (gen_rtx_SET (target, 2684 1.1 mrg gen_rtx_XOR (SImode, scratch2, const1_rtx))); 2685 1.1 mrg } 2686 1.1 mrg else 2687 1.1 mrg gcc_unreachable (); 2688 1.1 mrg 2689 1.1 mrg /* Record that we have expanded a CPU builtin, so that we can later 2690 1.1 mrg emit a reference to the special symbol exported by LIBC to ensure we 2691 1.1 mrg do not link against an old LIBC that doesn't support this feature. */ 2692 1.1 mrg cpu_builtin_p = true; 2693 1.1 mrg 2694 1.1 mrg #else 2695 1.1 mrg warning (0, "builtin %qs needs GLIBC (2.23 and newer) that exports hardware " 2696 1.1 mrg "capability bits", rs6000_builtin_info[(size_t) fcode].bifname); 2697 1.1 mrg 2698 1.1 mrg /* For old LIBCs, always return FALSE. */ 2699 1.1 mrg emit_move_insn (target, GEN_INT (0)); 2700 1.1 mrg #endif /* TARGET_LIBC_PROVIDES_HWCAP_IN_TCB */ 2701 1.1 mrg 2702 1.1 mrg return target; 2703 1.1 mrg } 2704 1.1 mrg 2705 1.1 mrg /* For the element-reversing load/store built-ins, produce the correct 2706 1.1 mrg insn_code depending on the target endianness. */ 2707 1.1 mrg static insn_code 2708 1.1 mrg elemrev_icode (rs6000_gen_builtins fcode) 2709 1.1 mrg { 2710 1.1 mrg switch (fcode) 2711 1.1 mrg { 2712 1.1 mrg case RS6000_BIF_ST_ELEMREV_V1TI: 2713 1.1 mrg return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v1ti 2714 1.1 mrg : CODE_FOR_vsx_st_elemrev_v1ti; 2715 1.1 mrg 2716 1.1 mrg case RS6000_BIF_ST_ELEMREV_V2DF: 2717 1.1 mrg return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2df 2718 1.1 mrg : CODE_FOR_vsx_st_elemrev_v2df; 2719 1.1 mrg 2720 1.1 mrg case RS6000_BIF_ST_ELEMREV_V2DI: 2721 1.1 mrg return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2di 2722 1.1 mrg : CODE_FOR_vsx_st_elemrev_v2di; 2723 1.1 mrg 2724 1.1 mrg case RS6000_BIF_ST_ELEMREV_V4SF: 2725 1.1 mrg return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4sf 2726 1.1 mrg : CODE_FOR_vsx_st_elemrev_v4sf; 2727 1.1 mrg 2728 1.1 mrg case RS6000_BIF_ST_ELEMREV_V4SI: 2729 1.1 mrg return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4si 2730 1.1 mrg : CODE_FOR_vsx_st_elemrev_v4si; 2731 1.1 mrg 2732 1.1 mrg case RS6000_BIF_ST_ELEMREV_V8HI: 2733 1.1 mrg return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v8hi 2734 1.1 mrg : CODE_FOR_vsx_st_elemrev_v8hi; 2735 1.1 mrg 2736 1.1 mrg case RS6000_BIF_ST_ELEMREV_V16QI: 2737 1.1 mrg return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v16qi 2738 1.1 mrg : CODE_FOR_vsx_st_elemrev_v16qi; 2739 1.1 mrg 2740 1.1 mrg case RS6000_BIF_LD_ELEMREV_V2DF: 2741 1.1 mrg return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2df 2742 1.1 mrg : CODE_FOR_vsx_ld_elemrev_v2df; 2743 1.1 mrg 2744 1.1 mrg case RS6000_BIF_LD_ELEMREV_V1TI: 2745 1.1 mrg return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v1ti 2746 1.1 mrg : CODE_FOR_vsx_ld_elemrev_v1ti; 2747 1.1 mrg 2748 1.1 mrg case RS6000_BIF_LD_ELEMREV_V2DI: 2749 1.1 mrg return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2di 2750 1.1 mrg : CODE_FOR_vsx_ld_elemrev_v2di; 2751 1.1 mrg 2752 1.1 mrg case RS6000_BIF_LD_ELEMREV_V4SF: 2753 1.1 mrg return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4sf 2754 1.1 mrg : CODE_FOR_vsx_ld_elemrev_v4sf; 2755 1.1 mrg 2756 1.1 mrg case RS6000_BIF_LD_ELEMREV_V4SI: 2757 1.1 mrg return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4si 2758 1.1 mrg : CODE_FOR_vsx_ld_elemrev_v4si; 2759 1.1 mrg 2760 1.1 mrg case RS6000_BIF_LD_ELEMREV_V8HI: 2761 1.1 mrg return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v8hi 2762 1.1 mrg : CODE_FOR_vsx_ld_elemrev_v8hi; 2763 1.1 mrg 2764 1.1 mrg case RS6000_BIF_LD_ELEMREV_V16QI: 2765 1.1 mrg return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v16qi 2766 1.1 mrg : CODE_FOR_vsx_ld_elemrev_v16qi; 2767 1.1 mrg default: 2768 1.1 mrg ; 2769 1.1 mrg } 2770 1.1 mrg 2771 1.1 mrg gcc_unreachable (); 2772 1.1 mrg } 2773 1.1 mrg 2774 1.1 mrg /* Expand an AltiVec vector load builtin, and return the expanded rtx. */ 2775 1.1 mrg static rtx 2776 1.1 mrg ldv_expand_builtin (rtx target, insn_code icode, rtx *op, machine_mode tmode) 2777 1.1 mrg { 2778 1.1 mrg if (target == 0 2779 1.1 mrg || GET_MODE (target) != tmode 2780 1.1 mrg || !insn_data[icode].operand[0].predicate (target, tmode)) 2781 1.1 mrg target = gen_reg_rtx (tmode); 2782 1.1 mrg 2783 1.1 mrg op[1] = copy_to_mode_reg (Pmode, op[1]); 2784 1.1 mrg 2785 1.1 mrg /* These CELL built-ins use BLKmode instead of tmode for historical 2786 1.1 mrg (i.e., unknown) reasons. TODO: Is this necessary? */ 2787 1.1 mrg bool blk = (icode == CODE_FOR_altivec_lvlx 2788 1.1 mrg || icode == CODE_FOR_altivec_lvlxl 2789 1.1 mrg || icode == CODE_FOR_altivec_lvrx 2790 1.1 mrg || icode == CODE_FOR_altivec_lvrxl); 2791 1.1 mrg 2792 1.1 mrg /* For LVX, express the RTL accurately by ANDing the address with -16. 2793 1.1 mrg LVXL and LVE*X expand to use UNSPECs to hide their special behavior, 2794 1.1 mrg so the raw address is fine. */ 2795 1.1 mrg /* TODO: That statement seems wrong, as the UNSPECs don't surround the 2796 1.1 mrg memory expression, so a latent bug may lie here. The &-16 is likely 2797 1.1 mrg needed for all VMX-style loads. */ 2798 1.1 mrg if (icode == CODE_FOR_altivec_lvx_v1ti 2799 1.1 mrg || icode == CODE_FOR_altivec_lvx_v2df 2800 1.1 mrg || icode == CODE_FOR_altivec_lvx_v2di 2801 1.1 mrg || icode == CODE_FOR_altivec_lvx_v4sf 2802 1.1 mrg || icode == CODE_FOR_altivec_lvx_v4si 2803 1.1 mrg || icode == CODE_FOR_altivec_lvx_v8hi 2804 1.1 mrg || icode == CODE_FOR_altivec_lvx_v16qi) 2805 1.1 mrg { 2806 1.1 mrg rtx rawaddr; 2807 1.1 mrg if (op[0] == const0_rtx) 2808 1.1 mrg rawaddr = op[1]; 2809 1.1 mrg else 2810 1.1 mrg { 2811 1.1 mrg op[0] = copy_to_mode_reg (Pmode, op[0]); 2812 1.1 mrg rawaddr = gen_rtx_PLUS (Pmode, op[1], op[0]); 2813 1.1 mrg } 2814 1.1 mrg rtx addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16)); 2815 1.1 mrg addr = gen_rtx_MEM (blk ? BLKmode : tmode, addr); 2816 1.1 mrg 2817 1.1 mrg emit_insn (gen_rtx_SET (target, addr)); 2818 1.1 mrg } 2819 1.1 mrg else 2820 1.1 mrg { 2821 1.1 mrg rtx addr; 2822 1.1 mrg if (op[0] == const0_rtx) 2823 1.1 mrg addr = gen_rtx_MEM (blk ? BLKmode : tmode, op[1]); 2824 1.1 mrg else 2825 1.1 mrg { 2826 1.1 mrg op[0] = copy_to_mode_reg (Pmode, op[0]); 2827 1.1 mrg addr = gen_rtx_MEM (blk ? BLKmode : tmode, 2828 1.1 mrg gen_rtx_PLUS (Pmode, op[1], op[0])); 2829 1.1 mrg } 2830 1.1 mrg 2831 1.1 mrg rtx pat = GEN_FCN (icode) (target, addr); 2832 1.1 mrg if (!pat) 2833 1.1 mrg return 0; 2834 1.1 mrg emit_insn (pat); 2835 1.1 mrg } 2836 1.1 mrg 2837 1.1 mrg return target; 2838 1.1 mrg } 2839 1.1 mrg 2840 1.1 mrg /* Expand a builtin function that loads a scalar into a vector register 2841 1.1 mrg with sign extension, and return the expanded rtx. */ 2842 1.1 mrg static rtx 2843 1.1 mrg lxvrse_expand_builtin (rtx target, insn_code icode, rtx *op, 2844 1.1 mrg machine_mode tmode, machine_mode smode) 2845 1.1 mrg { 2846 1.1 mrg rtx pat, addr; 2847 1.1 mrg op[1] = copy_to_mode_reg (Pmode, op[1]); 2848 1.1 mrg 2849 1.1 mrg if (op[0] == const0_rtx) 2850 1.1 mrg addr = gen_rtx_MEM (tmode, op[1]); 2851 1.1 mrg else 2852 1.1 mrg { 2853 1.1 mrg op[0] = copy_to_mode_reg (Pmode, op[0]); 2854 1.1 mrg addr = gen_rtx_MEM (smode, 2855 1.1 mrg gen_rtx_PLUS (Pmode, op[1], op[0])); 2856 1.1 mrg } 2857 1.1 mrg 2858 1.1 mrg rtx discratch = gen_reg_rtx (V2DImode); 2859 1.1 mrg rtx tiscratch = gen_reg_rtx (TImode); 2860 1.1 mrg 2861 1.1 mrg /* Emit the lxvr*x insn. */ 2862 1.1 mrg pat = GEN_FCN (icode) (tiscratch, addr); 2863 1.1 mrg if (!pat) 2864 1.1 mrg return 0; 2865 1.1 mrg emit_insn (pat); 2866 1.1 mrg 2867 1.1 mrg /* Emit a sign extension from V16QI,V8HI,V4SI to V2DI. */ 2868 1.1 mrg rtx temp1; 2869 1.1 mrg if (icode == CODE_FOR_vsx_lxvrbx) 2870 1.1 mrg { 2871 1.1 mrg temp1 = simplify_gen_subreg (V16QImode, tiscratch, TImode, 0); 2872 1.1 mrg emit_insn (gen_vsx_sign_extend_v16qi_v2di (discratch, temp1)); 2873 1.1 mrg } 2874 1.1 mrg else if (icode == CODE_FOR_vsx_lxvrhx) 2875 1.1 mrg { 2876 1.1 mrg temp1 = simplify_gen_subreg (V8HImode, tiscratch, TImode, 0); 2877 1.1 mrg emit_insn (gen_vsx_sign_extend_v8hi_v2di (discratch, temp1)); 2878 1.1 mrg } 2879 1.1 mrg else if (icode == CODE_FOR_vsx_lxvrwx) 2880 1.1 mrg { 2881 1.1 mrg temp1 = simplify_gen_subreg (V4SImode, tiscratch, TImode, 0); 2882 1.1 mrg emit_insn (gen_vsx_sign_extend_v4si_v2di (discratch, temp1)); 2883 1.1 mrg } 2884 1.1 mrg else if (icode == CODE_FOR_vsx_lxvrdx) 2885 1.1 mrg discratch = simplify_gen_subreg (V2DImode, tiscratch, TImode, 0); 2886 1.1 mrg else 2887 1.1 mrg gcc_unreachable (); 2888 1.1 mrg 2889 1.1 mrg /* Emit the sign extension from V2DI (double) to TI (quad). */ 2890 1.1 mrg rtx temp2 = simplify_gen_subreg (TImode, discratch, V2DImode, 0); 2891 1.1 mrg emit_insn (gen_extendditi2_vector (target, temp2)); 2892 1.1 mrg 2893 1.1 mrg return target; 2894 1.1 mrg } 2895 1.1 mrg 2896 1.1 mrg /* Expand a builtin function that loads a scalar into a vector register 2897 1.1 mrg with zero extension, and return the expanded rtx. */ 2898 1.1 mrg static rtx 2899 1.1 mrg lxvrze_expand_builtin (rtx target, insn_code icode, rtx *op, 2900 1.1 mrg machine_mode tmode, machine_mode smode) 2901 1.1 mrg { 2902 1.1 mrg rtx pat, addr; 2903 1.1 mrg op[1] = copy_to_mode_reg (Pmode, op[1]); 2904 1.1 mrg 2905 1.1 mrg if (op[0] == const0_rtx) 2906 1.1 mrg addr = gen_rtx_MEM (tmode, op[1]); 2907 1.1 mrg else 2908 1.1 mrg { 2909 1.1 mrg op[0] = copy_to_mode_reg (Pmode, op[0]); 2910 1.1 mrg addr = gen_rtx_MEM (smode, 2911 1.1 mrg gen_rtx_PLUS (Pmode, op[1], op[0])); 2912 1.1 mrg } 2913 1.1 mrg 2914 1.1 mrg pat = GEN_FCN (icode) (target, addr); 2915 1.1 mrg if (!pat) 2916 1.1 mrg return 0; 2917 1.1 mrg emit_insn (pat); 2918 1.1 mrg return target; 2919 1.1 mrg } 2920 1.1 mrg 2921 1.1 mrg /* Expand an AltiVec vector store builtin, and return the expanded rtx. */ 2922 1.1 mrg static rtx 2923 1.1 mrg stv_expand_builtin (insn_code icode, rtx *op, 2924 1.1 mrg machine_mode tmode, machine_mode smode) 2925 1.1 mrg { 2926 1.1 mrg op[2] = copy_to_mode_reg (Pmode, op[2]); 2927 1.1 mrg 2928 1.1 mrg /* For STVX, express the RTL accurately by ANDing the address with -16. 2929 1.1 mrg STVXL and STVE*X expand to use UNSPECs to hide their special behavior, 2930 1.1 mrg so the raw address is fine. */ 2931 1.1 mrg /* TODO: That statement seems wrong, as the UNSPECs don't surround the 2932 1.1 mrg memory expression, so a latent bug may lie here. The &-16 is likely 2933 1.1 mrg needed for all VMX-style stores. */ 2934 1.1 mrg if (icode == CODE_FOR_altivec_stvx_v2df 2935 1.1 mrg || icode == CODE_FOR_altivec_stvx_v2di 2936 1.1 mrg || icode == CODE_FOR_altivec_stvx_v4sf 2937 1.1 mrg || icode == CODE_FOR_altivec_stvx_v4si 2938 1.1 mrg || icode == CODE_FOR_altivec_stvx_v8hi 2939 1.1 mrg || icode == CODE_FOR_altivec_stvx_v16qi) 2940 1.1 mrg { 2941 1.1 mrg rtx rawaddr; 2942 1.1 mrg if (op[1] == const0_rtx) 2943 1.1 mrg rawaddr = op[2]; 2944 1.1 mrg else 2945 1.1 mrg { 2946 1.1 mrg op[1] = copy_to_mode_reg (Pmode, op[1]); 2947 1.1 mrg rawaddr = gen_rtx_PLUS (Pmode, op[2], op[1]); 2948 1.1 mrg } 2949 1.1 mrg 2950 1.1 mrg rtx addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16)); 2951 1.1 mrg addr = gen_rtx_MEM (tmode, addr); 2952 1.1 mrg op[0] = copy_to_mode_reg (tmode, op[0]); 2953 1.1 mrg emit_insn (gen_rtx_SET (addr, op[0])); 2954 1.1 mrg } 2955 1.1 mrg else if (icode == CODE_FOR_vsx_stxvrbx 2956 1.1 mrg || icode == CODE_FOR_vsx_stxvrhx 2957 1.1 mrg || icode == CODE_FOR_vsx_stxvrwx 2958 1.1 mrg || icode == CODE_FOR_vsx_stxvrdx) 2959 1.1 mrg { 2960 1.1 mrg rtx truncrtx = gen_rtx_TRUNCATE (tmode, op[0]); 2961 1.1 mrg op[0] = copy_to_mode_reg (E_TImode, truncrtx); 2962 1.1 mrg 2963 1.1 mrg rtx addr; 2964 1.1 mrg if (op[1] == const0_rtx) 2965 1.1 mrg addr = gen_rtx_MEM (tmode, op[2]); 2966 1.1 mrg else 2967 1.1 mrg { 2968 1.1 mrg op[1] = copy_to_mode_reg (Pmode, op[1]); 2969 1.1 mrg addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op[2], op[1])); 2970 1.1 mrg } 2971 1.1 mrg rtx pat = GEN_FCN (icode) (addr, op[0]); 2972 1.1 mrg if (pat) 2973 1.1 mrg emit_insn (pat); 2974 1.1 mrg } 2975 1.1 mrg else 2976 1.1 mrg { 2977 1.1 mrg if (!insn_data[icode].operand[1].predicate (op[0], smode)) 2978 1.1 mrg op[0] = copy_to_mode_reg (smode, op[0]); 2979 1.1 mrg 2980 1.1 mrg rtx addr; 2981 1.1 mrg if (op[1] == const0_rtx) 2982 1.1 mrg addr = gen_rtx_MEM (tmode, op[2]); 2983 1.1 mrg else 2984 1.1 mrg { 2985 1.1 mrg op[1] = copy_to_mode_reg (Pmode, op[1]); 2986 1.1 mrg addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op[2], op[1])); 2987 1.1 mrg } 2988 1.1 mrg 2989 1.1 mrg rtx pat = GEN_FCN (icode) (addr, op[0]); 2990 1.1 mrg if (pat) 2991 1.1 mrg emit_insn (pat); 2992 1.1 mrg } 2993 1.1 mrg 2994 1.1 mrg return NULL_RTX; 2995 1.1 mrg } 2996 1.1 mrg 2997 1.1 mrg /* Expand the MMA built-in in EXP, and return it. */ 2998 1.1 mrg static rtx 2999 1.1 mrg mma_expand_builtin (tree exp, rtx target, insn_code icode, 3000 1.1 mrg rs6000_gen_builtins fcode) 3001 1.1 mrg { 3002 1.1 mrg tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 3003 1.1 mrg bool void_func = TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node; 3004 1.1 mrg machine_mode tmode = VOIDmode; 3005 1.1 mrg rtx op[MAX_MMA_OPERANDS]; 3006 1.1 mrg unsigned nopnds = 0; 3007 1.1 mrg 3008 1.1 mrg if (!void_func) 3009 1.1 mrg { 3010 1.1 mrg tmode = insn_data[icode].operand[0].mode; 3011 1.1 mrg if (!(target 3012 1.1 mrg && GET_MODE (target) == tmode 3013 1.1 mrg && insn_data[icode].operand[0].predicate (target, tmode))) 3014 1.1 mrg target = gen_reg_rtx (tmode); 3015 1.1 mrg op[nopnds++] = target; 3016 1.1 mrg } 3017 1.1 mrg else 3018 1.1 mrg target = const0_rtx; 3019 1.1 mrg 3020 1.1 mrg call_expr_arg_iterator iter; 3021 1.1 mrg tree arg; 3022 1.1 mrg FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) 3023 1.1 mrg { 3024 1.1 mrg if (arg == error_mark_node) 3025 1.1 mrg return const0_rtx; 3026 1.1 mrg 3027 1.1 mrg rtx opnd; 3028 1.1 mrg const struct insn_operand_data *insn_op; 3029 1.1 mrg insn_op = &insn_data[icode].operand[nopnds]; 3030 1.1 mrg if (TREE_CODE (arg) == ADDR_EXPR 3031 1.1 mrg && MEM_P (DECL_RTL (TREE_OPERAND (arg, 0)))) 3032 1.1 mrg opnd = DECL_RTL (TREE_OPERAND (arg, 0)); 3033 1.1 mrg else 3034 1.1 mrg opnd = expand_normal (arg); 3035 1.1 mrg 3036 1.1 mrg if (!insn_op->predicate (opnd, insn_op->mode)) 3037 1.1 mrg { 3038 1.1 mrg /* TODO: This use of constraints needs explanation. */ 3039 1.1 mrg if (!strcmp (insn_op->constraint, "n")) 3040 1.1 mrg { 3041 1.1 mrg if (!CONST_INT_P (opnd)) 3042 1.1 mrg error ("argument %d must be an unsigned literal", nopnds); 3043 1.1 mrg else 3044 1.1 mrg error ("argument %d is an unsigned literal that is " 3045 1.1 mrg "out of range", nopnds); 3046 1.1 mrg return const0_rtx; 3047 1.1 mrg } 3048 1.1 mrg opnd = copy_to_mode_reg (insn_op->mode, opnd); 3049 1.1 mrg } 3050 1.1 mrg 3051 1.1 mrg /* Some MMA instructions have INOUT accumulator operands, so force 3052 1.1 mrg their target register to be the same as their input register. */ 3053 1.1 mrg if (!void_func 3054 1.1 mrg && nopnds == 1 3055 1.1 mrg && !strcmp (insn_op->constraint, "0") 3056 1.1 mrg && insn_op->mode == tmode 3057 1.1 mrg && REG_P (opnd) 3058 1.1 mrg && insn_data[icode].operand[0].predicate (opnd, tmode)) 3059 1.1 mrg target = op[0] = opnd; 3060 1.1 mrg 3061 1.1 mrg op[nopnds++] = opnd; 3062 1.1 mrg } 3063 1.1 mrg 3064 1.1 mrg rtx pat; 3065 1.1 mrg switch (nopnds) 3066 1.1 mrg { 3067 1.1 mrg case 1: 3068 1.1 mrg pat = GEN_FCN (icode) (op[0]); 3069 1.1 mrg break; 3070 1.1 mrg case 2: 3071 1.1 mrg pat = GEN_FCN (icode) (op[0], op[1]); 3072 1.1 mrg break; 3073 1.1 mrg case 3: 3074 1.1 mrg /* The ASSEMBLE builtin source operands are reversed in little-endian 3075 1.1 mrg mode, so reorder them. */ 3076 1.1 mrg if (fcode == RS6000_BIF_ASSEMBLE_PAIR_V_INTERNAL && !WORDS_BIG_ENDIAN) 3077 1.1 mrg std::swap (op[1], op[2]); 3078 1.1 mrg pat = GEN_FCN (icode) (op[0], op[1], op[2]); 3079 1.1 mrg break; 3080 1.1 mrg case 4: 3081 1.1 mrg pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]); 3082 1.1 mrg break; 3083 1.1 mrg case 5: 3084 1.1 mrg /* The ASSEMBLE builtin source operands are reversed in little-endian 3085 1.1 mrg mode, so reorder them. */ 3086 1.1 mrg if (fcode == RS6000_BIF_ASSEMBLE_ACC_INTERNAL && !WORDS_BIG_ENDIAN) 3087 1.1 mrg { 3088 1.1 mrg std::swap (op[1], op[4]); 3089 1.1 mrg std::swap (op[2], op[3]); 3090 1.1 mrg } 3091 1.1 mrg pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4]); 3092 1.1 mrg break; 3093 1.1 mrg case 6: 3094 1.1 mrg pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5]); 3095 1.1 mrg break; 3096 1.1 mrg case 7: 3097 1.1 mrg pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5], op[6]); 3098 1.1 mrg break; 3099 1.1 mrg default: 3100 1.1 mrg gcc_unreachable (); 3101 1.1 mrg } 3102 1.1 mrg 3103 1.1 mrg if (!pat) 3104 1.1 mrg return NULL_RTX; 3105 1.1 mrg 3106 1.1 mrg emit_insn (pat); 3107 1.1 mrg return target; 3108 1.1 mrg } 3109 1.1 mrg 3110 1.1 mrg /* Return the correct ICODE value depending on whether we are 3111 1.1 mrg setting or reading the HTM SPRs. */ 3112 1.1 mrg static inline enum insn_code 3113 1.1 mrg rs6000_htm_spr_icode (bool nonvoid) 3114 1.1 mrg { 3115 1.1 mrg if (nonvoid) 3116 1.1 mrg return (TARGET_POWERPC64) ? CODE_FOR_htm_mfspr_di : CODE_FOR_htm_mfspr_si; 3117 1.1 mrg else 3118 1.1 mrg return (TARGET_POWERPC64) ? CODE_FOR_htm_mtspr_di : CODE_FOR_htm_mtspr_si; 3119 1.1 mrg } 3120 1.1 mrg 3121 1.1 mrg /* Return the appropriate SPR number associated with the given builtin. */ 3122 1.1 mrg static inline HOST_WIDE_INT 3123 1.1 mrg htm_spr_num (enum rs6000_gen_builtins code) 3124 1.1 mrg { 3125 1.1 mrg if (code == RS6000_BIF_GET_TFHAR 3126 1.1 mrg || code == RS6000_BIF_SET_TFHAR) 3127 1.1 mrg return TFHAR_SPR; 3128 1.1 mrg else if (code == RS6000_BIF_GET_TFIAR 3129 1.1 mrg || code == RS6000_BIF_SET_TFIAR) 3130 1.1 mrg return TFIAR_SPR; 3131 1.1 mrg else if (code == RS6000_BIF_GET_TEXASR 3132 1.1 mrg || code == RS6000_BIF_SET_TEXASR) 3133 1.1 mrg return TEXASR_SPR; 3134 1.1 mrg gcc_assert (code == RS6000_BIF_GET_TEXASRU 3135 1.1 mrg || code == RS6000_BIF_SET_TEXASRU); 3136 1.1 mrg return TEXASRU_SPR; 3137 1.1 mrg } 3138 1.1 mrg 3139 1.1 mrg /* Expand the HTM builtin in EXP and store the result in TARGET. 3140 1.1 mrg Return the expanded rtx. */ 3141 1.1 mrg static rtx 3142 1.1 mrg htm_expand_builtin (bifdata *bifaddr, rs6000_gen_builtins fcode, 3143 1.1 mrg tree exp, rtx target) 3144 1.1 mrg { 3145 1.1 mrg if (!TARGET_POWERPC64 3146 1.1 mrg && (fcode == RS6000_BIF_TABORTDC 3147 1.1 mrg || fcode == RS6000_BIF_TABORTDCI)) 3148 1.1 mrg { 3149 1.1 mrg error ("builtin %qs is only valid in 64-bit mode", bifaddr->bifname); 3150 1.1 mrg return const0_rtx; 3151 1.1 mrg } 3152 1.1 mrg 3153 1.1 mrg tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 3154 1.1 mrg bool nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node; 3155 1.1 mrg bool uses_spr = bif_is_htmspr (*bifaddr); 3156 1.1 mrg insn_code icode = bifaddr->icode; 3157 1.1 mrg 3158 1.1 mrg if (uses_spr) 3159 1.1 mrg icode = rs6000_htm_spr_icode (nonvoid); 3160 1.1 mrg 3161 1.1 mrg rtx op[MAX_HTM_OPERANDS]; 3162 1.1 mrg int nopnds = 0; 3163 1.1 mrg const insn_operand_data *insn_op = &insn_data[icode].operand[0]; 3164 1.1 mrg 3165 1.1 mrg if (nonvoid) 3166 1.1 mrg { 3167 1.1 mrg machine_mode tmode = (uses_spr) ? insn_op->mode : E_SImode; 3168 1.1 mrg if (!target 3169 1.1 mrg || GET_MODE (target) != tmode 3170 1.1 mrg || (uses_spr && !insn_op->predicate (target, tmode))) 3171 1.1 mrg target = gen_reg_rtx (tmode); 3172 1.1 mrg if (uses_spr) 3173 1.1 mrg op[nopnds++] = target; 3174 1.1 mrg } 3175 1.1 mrg 3176 1.1 mrg tree arg; 3177 1.1 mrg call_expr_arg_iterator iter; 3178 1.1 mrg 3179 1.1 mrg FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) 3180 1.1 mrg { 3181 1.1 mrg if (arg == error_mark_node || nopnds >= MAX_HTM_OPERANDS) 3182 1.1 mrg return const0_rtx; 3183 1.1 mrg 3184 1.1 mrg insn_op = &insn_data[icode].operand[nopnds]; 3185 1.1 mrg op[nopnds] = expand_normal (arg); 3186 1.1 mrg 3187 1.1 mrg if (!insn_op->predicate (op[nopnds], insn_op->mode)) 3188 1.1 mrg { 3189 1.1 mrg /* TODO: This use of constraints could use explanation. 3190 1.1 mrg This happens a couple of places, perhaps make that a 3191 1.1 mrg function to document what's happening. */ 3192 1.1 mrg if (!strcmp (insn_op->constraint, "n")) 3193 1.1 mrg { 3194 1.1 mrg int arg_num = nonvoid ? nopnds : nopnds + 1; 3195 1.1 mrg if (!CONST_INT_P (op[nopnds])) 3196 1.1 mrg error ("argument %d must be an unsigned literal", arg_num); 3197 1.1 mrg else 3198 1.1 mrg error ("argument %d is an unsigned literal that is " 3199 1.1 mrg "out of range", arg_num); 3200 1.1 mrg return const0_rtx; 3201 1.1 mrg } 3202 1.1 mrg op[nopnds] = copy_to_mode_reg (insn_op->mode, op[nopnds]); 3203 1.1 mrg } 3204 1.1 mrg 3205 1.1 mrg nopnds++; 3206 1.1 mrg } 3207 1.1 mrg 3208 1.1 mrg /* Handle the builtins for extended mnemonics. These accept 3209 1.1 mrg no arguments, but map to builtins that take arguments. */ 3210 1.1 mrg switch (fcode) 3211 1.1 mrg { 3212 1.1 mrg case RS6000_BIF_TENDALL: /* Alias for: tend. 1 */ 3213 1.1 mrg case RS6000_BIF_TRESUME: /* Alias for: tsr. 1 */ 3214 1.1 mrg op[nopnds++] = GEN_INT (1); 3215 1.1 mrg break; 3216 1.1 mrg case RS6000_BIF_TSUSPEND: /* Alias for: tsr. 0 */ 3217 1.1 mrg op[nopnds++] = GEN_INT (0); 3218 1.1 mrg break; 3219 1.1 mrg default: 3220 1.1 mrg break; 3221 1.1 mrg } 3222 1.1 mrg 3223 1.1 mrg /* If this builtin accesses SPRs, then pass in the appropriate 3224 1.1 mrg SPR number and SPR regno as the last two operands. */ 3225 1.1 mrg rtx cr = NULL_RTX; 3226 1.1 mrg if (uses_spr) 3227 1.1 mrg { 3228 1.1 mrg machine_mode mode = TARGET_POWERPC64 ? DImode : SImode; 3229 1.1 mrg op[nopnds++] = gen_rtx_CONST_INT (mode, htm_spr_num (fcode)); 3230 1.1 mrg } 3231 1.1 mrg /* If this builtin accesses a CR field, then pass in a scratch 3232 1.1 mrg CR field as the last operand. */ 3233 1.1 mrg else if (bif_is_htmcr (*bifaddr)) 3234 1.1 mrg { 3235 1.1 mrg cr = gen_reg_rtx (CCmode); 3236 1.1 mrg op[nopnds++] = cr; 3237 1.1 mrg } 3238 1.1 mrg 3239 1.1 mrg rtx pat; 3240 1.1 mrg switch (nopnds) 3241 1.1 mrg { 3242 1.1 mrg case 1: 3243 1.1 mrg pat = GEN_FCN (icode) (op[0]); 3244 1.1 mrg break; 3245 1.1 mrg case 2: 3246 1.1 mrg pat = GEN_FCN (icode) (op[0], op[1]); 3247 1.1 mrg break; 3248 1.1 mrg case 3: 3249 1.1 mrg pat = GEN_FCN (icode) (op[0], op[1], op[2]); 3250 1.1 mrg break; 3251 1.1 mrg case 4: 3252 1.1 mrg pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]); 3253 1.1 mrg break; 3254 1.1 mrg default: 3255 1.1 mrg gcc_unreachable (); 3256 1.1 mrg } 3257 1.1 mrg if (!pat) 3258 1.1 mrg return NULL_RTX; 3259 1.1 mrg emit_insn (pat); 3260 1.1 mrg 3261 1.1 mrg if (bif_is_htmcr (*bifaddr)) 3262 1.1 mrg { 3263 1.1 mrg if (fcode == RS6000_BIF_TBEGIN) 3264 1.1 mrg { 3265 1.1 mrg /* Emit code to set TARGET to true or false depending on 3266 1.1 mrg whether the tbegin. instruction succeeded or failed 3267 1.1 mrg to start a transaction. We do this by placing the 1's 3268 1.1 mrg complement of CR's EQ bit into TARGET. */ 3269 1.1 mrg rtx scratch = gen_reg_rtx (SImode); 3270 1.1 mrg emit_insn (gen_rtx_SET (scratch, 3271 1.1 mrg gen_rtx_EQ (SImode, cr, 3272 1.1 mrg const0_rtx))); 3273 1.1 mrg emit_insn (gen_rtx_SET (target, 3274 1.1 mrg gen_rtx_XOR (SImode, scratch, 3275 1.1 mrg GEN_INT (1)))); 3276 1.1 mrg } 3277 1.1 mrg else 3278 1.1 mrg { 3279 1.1 mrg /* Emit code to copy the 4-bit condition register field 3280 1.1 mrg CR into the least significant end of register TARGET. */ 3281 1.1 mrg rtx scratch1 = gen_reg_rtx (SImode); 3282 1.1 mrg rtx scratch2 = gen_reg_rtx (SImode); 3283 1.1 mrg rtx subreg = simplify_gen_subreg (CCmode, scratch1, SImode, 0); 3284 1.1 mrg emit_insn (gen_movcc (subreg, cr)); 3285 1.1 mrg emit_insn (gen_lshrsi3 (scratch2, scratch1, GEN_INT (28))); 3286 1.1 mrg emit_insn (gen_andsi3 (target, scratch2, GEN_INT (0xf))); 3287 1.1 mrg } 3288 1.1 mrg } 3289 1.1 mrg 3290 1.1 mrg if (nonvoid) 3291 1.1 mrg return target; 3292 1.1 mrg return const0_rtx; 3293 1.1 mrg } 3294 1.1 mrg 3295 1.1 mrg /* Expand an expression EXP that calls a built-in function, 3296 1.1 mrg with result going to TARGET if that's convenient 3297 1.1 mrg (and in mode MODE if that's convenient). 3298 1.1 mrg SUBTARGET may be used as the target for computing one of EXP's operands. 3299 1.1 mrg IGNORE is nonzero if the value is to be ignored. 3300 1.1 mrg Use the new builtin infrastructure. */ 3301 1.1 mrg rtx 3302 1.1 mrg rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */, 3303 1.1 mrg machine_mode /* mode */, int ignore) 3304 1.1 mrg { 3305 1.1 mrg tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 3306 1.1 mrg enum rs6000_gen_builtins fcode 3307 1.1 mrg = (enum rs6000_gen_builtins) DECL_MD_FUNCTION_CODE (fndecl); 3308 1.1 mrg 3309 1.1 mrg /* Emit error message if it's an unresolved overloaded builtin. */ 3310 1.1 mrg if (fcode > RS6000_OVLD_NONE) 3311 1.1 mrg { 3312 1.1 mrg error ("unresolved overload for builtin %qF", fndecl); 3313 1.1 mrg return const0_rtx; 3314 1.1 mrg } 3315 1.1 mrg 3316 1.1 mrg size_t uns_fcode = (size_t)fcode; 3317 1.1 mrg enum insn_code icode = rs6000_builtin_info[uns_fcode].icode; 3318 1.1 mrg 3319 1.1 mrg /* TODO: The following commentary and code is inherited from the original 3320 1.1 mrg builtin processing code. The commentary is a bit confusing, with the 3321 1.1 mrg intent being that KFmode is always IEEE-128, IFmode is always IBM 3322 1.1 mrg double-double, and TFmode is the current long double. The code is 3323 1.1 mrg confusing in that it converts from KFmode to TFmode pattern names, 3324 1.1 mrg when the other direction is more intuitive. Try to address this. */ 3325 1.1 mrg 3326 1.1 mrg /* We have two different modes (KFmode, TFmode) that are the IEEE 3327 1.1 mrg 128-bit floating point type, depending on whether long double is the 3328 1.1 mrg IBM extended double (KFmode) or long double is IEEE 128-bit (TFmode). 3329 1.1 mrg It is simpler if we only define one variant of the built-in function, 3330 1.1 mrg and switch the code when defining it, rather than defining two built- 3331 1.1 mrg ins and using the overload table in rs6000-c.cc to switch between the 3332 1.1 mrg two. If we don't have the proper assembler, don't do this switch 3333 1.1 mrg because CODE_FOR_*kf* and CODE_FOR_*tf* will be CODE_FOR_nothing. */ 3334 1.1 mrg if (FLOAT128_IEEE_P (TFmode)) 3335 1.1 mrg switch (icode) 3336 1.1 mrg { 3337 1.1 mrg case CODE_FOR_sqrtkf2_odd: 3338 1.1 mrg icode = CODE_FOR_sqrttf2_odd; 3339 1.1 mrg break; 3340 1.1 mrg case CODE_FOR_trunckfdf2_odd: 3341 1.1 mrg icode = CODE_FOR_trunctfdf2_odd; 3342 1.1 mrg break; 3343 1.1 mrg case CODE_FOR_addkf3_odd: 3344 1.1 mrg icode = CODE_FOR_addtf3_odd; 3345 1.1 mrg break; 3346 1.1 mrg case CODE_FOR_subkf3_odd: 3347 1.1 mrg icode = CODE_FOR_subtf3_odd; 3348 1.1 mrg break; 3349 1.1 mrg case CODE_FOR_mulkf3_odd: 3350 1.1 mrg icode = CODE_FOR_multf3_odd; 3351 1.1 mrg break; 3352 1.1 mrg case CODE_FOR_divkf3_odd: 3353 1.1 mrg icode = CODE_FOR_divtf3_odd; 3354 1.1 mrg break; 3355 1.1 mrg case CODE_FOR_fmakf4_odd: 3356 1.1 mrg icode = CODE_FOR_fmatf4_odd; 3357 1.1 mrg break; 3358 1.1 mrg case CODE_FOR_xsxexpqp_kf: 3359 1.1 mrg icode = CODE_FOR_xsxexpqp_tf; 3360 1.1 mrg break; 3361 1.1 mrg case CODE_FOR_xsxsigqp_kf: 3362 1.1 mrg icode = CODE_FOR_xsxsigqp_tf; 3363 1.1 mrg break; 3364 1.1 mrg case CODE_FOR_xststdcnegqp_kf: 3365 1.1 mrg icode = CODE_FOR_xststdcnegqp_tf; 3366 1.1 mrg break; 3367 1.1 mrg case CODE_FOR_xsiexpqp_kf: 3368 1.1 mrg icode = CODE_FOR_xsiexpqp_tf; 3369 1.1 mrg break; 3370 1.1 mrg case CODE_FOR_xsiexpqpf_kf: 3371 1.1 mrg icode = CODE_FOR_xsiexpqpf_tf; 3372 1.1 mrg break; 3373 1.1 mrg case CODE_FOR_xststdcqp_kf: 3374 1.1 mrg icode = CODE_FOR_xststdcqp_tf; 3375 1.1 mrg break; 3376 1.1 mrg case CODE_FOR_xscmpexpqp_eq_kf: 3377 1.1 mrg icode = CODE_FOR_xscmpexpqp_eq_tf; 3378 1.1 mrg break; 3379 1.1 mrg case CODE_FOR_xscmpexpqp_lt_kf: 3380 1.1 mrg icode = CODE_FOR_xscmpexpqp_lt_tf; 3381 1.1 mrg break; 3382 1.1 mrg case CODE_FOR_xscmpexpqp_gt_kf: 3383 1.1 mrg icode = CODE_FOR_xscmpexpqp_gt_tf; 3384 1.1 mrg break; 3385 1.1 mrg case CODE_FOR_xscmpexpqp_unordered_kf: 3386 1.1 mrg icode = CODE_FOR_xscmpexpqp_unordered_tf; 3387 1.1 mrg break; 3388 1.1 mrg default: 3389 1.1 mrg break; 3390 1.1 mrg } 3391 1.1 mrg 3392 1.1 mrg /* In case of "#pragma target" changes, we initialize all builtins 3393 1.1 mrg but check for actual availability now, during expand time. For 3394 1.1 mrg invalid builtins, generate a normal call. */ 3395 1.1 mrg bifdata *bifaddr = &rs6000_builtin_info[uns_fcode]; 3396 1.1 mrg bif_enable e = bifaddr->enable; 3397 1.1 mrg 3398 1.1 mrg if (!(e == ENB_ALWAYS 3399 1.1 mrg || (e == ENB_P5 && TARGET_POPCNTB) 3400 1.1 mrg || (e == ENB_P6 && TARGET_CMPB) 3401 1.1 mrg || (e == ENB_P6_64 && TARGET_CMPB && TARGET_POWERPC64) 3402 1.1 mrg || (e == ENB_ALTIVEC && TARGET_ALTIVEC) 3403 1.1 mrg || (e == ENB_CELL && TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL) 3404 1.1 mrg || (e == ENB_VSX && TARGET_VSX) 3405 1.1 mrg || (e == ENB_P7 && TARGET_POPCNTD) 3406 1.1 mrg || (e == ENB_P7_64 && TARGET_POPCNTD && TARGET_POWERPC64) 3407 1.1 mrg || (e == ENB_P8 && TARGET_DIRECT_MOVE) 3408 1.1 mrg || (e == ENB_P8V && TARGET_P8_VECTOR) 3409 1.1 mrg || (e == ENB_P9 && TARGET_MODULO) 3410 1.1 mrg || (e == ENB_P9_64 && TARGET_MODULO && TARGET_POWERPC64) 3411 1.1 mrg || (e == ENB_P9V && TARGET_P9_VECTOR) 3412 1.1 mrg || (e == ENB_IEEE128_HW && TARGET_FLOAT128_HW) 3413 1.1 mrg || (e == ENB_DFP && TARGET_DFP) 3414 1.1 mrg || (e == ENB_CRYPTO && TARGET_CRYPTO) 3415 1.1 mrg || (e == ENB_HTM && TARGET_HTM) 3416 1.1 mrg || (e == ENB_P10 && TARGET_POWER10) 3417 1.1 mrg || (e == ENB_P10_64 && TARGET_POWER10 && TARGET_POWERPC64) 3418 1.1 mrg || (e == ENB_MMA && TARGET_MMA))) 3419 1.1 mrg { 3420 1.1 mrg rs6000_invalid_builtin (fcode); 3421 1.1 mrg return expand_call (exp, target, ignore); 3422 1.1 mrg } 3423 1.1 mrg 3424 1.1 mrg if (bif_is_nosoft (*bifaddr) 3425 1.1 mrg && rs6000_isa_flags & OPTION_MASK_SOFT_FLOAT) 3426 1.1 mrg { 3427 1.1 mrg error ("%qs not supported with %<-msoft-float%>", 3428 1.1 mrg bifaddr->bifname); 3429 1.1 mrg return const0_rtx; 3430 1.1 mrg } 3431 1.1 mrg 3432 1.1 mrg if (bif_is_no32bit (*bifaddr) && TARGET_32BIT) 3433 1.1 mrg { 3434 1.1 mrg error ("%qs is not supported in 32-bit mode", bifaddr->bifname); 3435 1.1 mrg return const0_rtx; 3436 1.1 mrg } 3437 1.1 mrg 3438 1.1 mrg if (bif_is_ibmld (*bifaddr) && !FLOAT128_2REG_P (TFmode)) 3439 1.1 mrg { 3440 1.1 mrg error ("%qs requires %<long double%> to be IBM 128-bit format", 3441 1.1 mrg bifaddr->bifname); 3442 1.1 mrg return const0_rtx; 3443 1.1 mrg } 3444 1.1 mrg 3445 1.1 mrg if (bif_is_ibm128 (*bifaddr) && !ibm128_float_type_node) 3446 1.1 mrg { 3447 1.1 mrg error ("%qs requires %<__ibm128%> type support", 3448 1.1 mrg bifaddr->bifname); 3449 1.1 mrg return const0_rtx; 3450 1.1 mrg } 3451 1.1 mrg 3452 1.1 mrg if (bif_is_cpu (*bifaddr)) 3453 1.1 mrg return cpu_expand_builtin (fcode, exp, target); 3454 1.1 mrg 3455 1.1 mrg if (bif_is_init (*bifaddr)) 3456 1.1 mrg return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target); 3457 1.1 mrg 3458 1.1 mrg if (bif_is_set (*bifaddr)) 3459 1.1 mrg return altivec_expand_vec_set_builtin (exp); 3460 1.1 mrg 3461 1.1 mrg if (bif_is_extract (*bifaddr)) 3462 1.1 mrg return altivec_expand_vec_ext_builtin (exp, target); 3463 1.1 mrg 3464 1.1 mrg if (bif_is_predicate (*bifaddr)) 3465 1.1 mrg return altivec_expand_predicate_builtin (icode, exp, target); 3466 1.1 mrg 3467 1.1 mrg if (bif_is_htm (*bifaddr)) 3468 1.1 mrg return htm_expand_builtin (bifaddr, fcode, exp, target); 3469 1.1 mrg 3470 1.1 mrg if (bif_is_32bit (*bifaddr) && TARGET_32BIT) 3471 1.1 mrg { 3472 1.1 mrg if (fcode == RS6000_BIF_MFTB) 3473 1.1 mrg icode = CODE_FOR_rs6000_mftb_si; 3474 1.1 mrg else if (fcode == RS6000_BIF_BPERMD) 3475 1.1 mrg icode = CODE_FOR_bpermd_si; 3476 1.1 mrg else if (fcode == RS6000_BIF_DARN) 3477 1.1 mrg icode = CODE_FOR_darn_64_si; 3478 1.1 mrg else if (fcode == RS6000_BIF_DARN_32) 3479 1.1 mrg icode = CODE_FOR_darn_32_si; 3480 1.1 mrg else if (fcode == RS6000_BIF_DARN_RAW) 3481 1.1 mrg icode = CODE_FOR_darn_raw_si; 3482 1.1 mrg else 3483 1.1 mrg gcc_unreachable (); 3484 1.1 mrg } 3485 1.1 mrg 3486 1.1 mrg if (bif_is_endian (*bifaddr) && BYTES_BIG_ENDIAN) 3487 1.1 mrg { 3488 1.1 mrg if (fcode == RS6000_BIF_LD_ELEMREV_V1TI) 3489 1.1 mrg icode = CODE_FOR_vsx_load_v1ti; 3490 1.1 mrg else if (fcode == RS6000_BIF_LD_ELEMREV_V2DF) 3491 1.1 mrg icode = CODE_FOR_vsx_load_v2df; 3492 1.1 mrg else if (fcode == RS6000_BIF_LD_ELEMREV_V2DI) 3493 1.1 mrg icode = CODE_FOR_vsx_load_v2di; 3494 1.1 mrg else if (fcode == RS6000_BIF_LD_ELEMREV_V4SF) 3495 1.1 mrg icode = CODE_FOR_vsx_load_v4sf; 3496 1.1 mrg else if (fcode == RS6000_BIF_LD_ELEMREV_V4SI) 3497 1.1 mrg icode = CODE_FOR_vsx_load_v4si; 3498 1.1 mrg else if (fcode == RS6000_BIF_LD_ELEMREV_V8HI) 3499 1.1 mrg icode = CODE_FOR_vsx_load_v8hi; 3500 1.1 mrg else if (fcode == RS6000_BIF_LD_ELEMREV_V16QI) 3501 1.1 mrg icode = CODE_FOR_vsx_load_v16qi; 3502 1.1 mrg else if (fcode == RS6000_BIF_ST_ELEMREV_V1TI) 3503 1.1 mrg icode = CODE_FOR_vsx_store_v1ti; 3504 1.1 mrg else if (fcode == RS6000_BIF_ST_ELEMREV_V2DF) 3505 1.1 mrg icode = CODE_FOR_vsx_store_v2df; 3506 1.1 mrg else if (fcode == RS6000_BIF_ST_ELEMREV_V2DI) 3507 1.1 mrg icode = CODE_FOR_vsx_store_v2di; 3508 1.1 mrg else if (fcode == RS6000_BIF_ST_ELEMREV_V4SF) 3509 1.1 mrg icode = CODE_FOR_vsx_store_v4sf; 3510 1.1 mrg else if (fcode == RS6000_BIF_ST_ELEMREV_V4SI) 3511 1.1 mrg icode = CODE_FOR_vsx_store_v4si; 3512 1.1 mrg else if (fcode == RS6000_BIF_ST_ELEMREV_V8HI) 3513 1.1 mrg icode = CODE_FOR_vsx_store_v8hi; 3514 1.1 mrg else if (fcode == RS6000_BIF_ST_ELEMREV_V16QI) 3515 1.1 mrg icode = CODE_FOR_vsx_store_v16qi; 3516 1.1 mrg else if (fcode == RS6000_BIF_VCLZLSBB_V16QI) 3517 1.1 mrg icode = CODE_FOR_vclzlsbb_v16qi; 3518 1.1 mrg else if (fcode == RS6000_BIF_VCLZLSBB_V4SI) 3519 1.1 mrg icode = CODE_FOR_vclzlsbb_v4si; 3520 1.1 mrg else if (fcode == RS6000_BIF_VCLZLSBB_V8HI) 3521 1.1 mrg icode = CODE_FOR_vclzlsbb_v8hi; 3522 1.1 mrg else if (fcode == RS6000_BIF_VCTZLSBB_V16QI) 3523 1.1 mrg icode = CODE_FOR_vctzlsbb_v16qi; 3524 1.1 mrg else if (fcode == RS6000_BIF_VCTZLSBB_V4SI) 3525 1.1 mrg icode = CODE_FOR_vctzlsbb_v4si; 3526 1.1 mrg else if (fcode == RS6000_BIF_VCTZLSBB_V8HI) 3527 1.1 mrg icode = CODE_FOR_vctzlsbb_v8hi; 3528 1.1 mrg else 3529 1.1 mrg gcc_unreachable (); 3530 1.1 mrg } 3531 1.1 mrg 3532 1.1 mrg if (bif_is_ibm128 (*bifaddr) && TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD) 3533 1.1 mrg { 3534 1.1 mrg if (fcode == RS6000_BIF_PACK_IF) 3535 1.1 mrg { 3536 1.1 mrg icode = CODE_FOR_packtf; 3537 1.1 mrg fcode = RS6000_BIF_PACK_TF; 3538 1.1 mrg uns_fcode = (size_t) fcode; 3539 1.1 mrg } 3540 1.1 mrg else if (fcode == RS6000_BIF_UNPACK_IF) 3541 1.1 mrg { 3542 1.1 mrg icode = CODE_FOR_unpacktf; 3543 1.1 mrg fcode = RS6000_BIF_UNPACK_TF; 3544 1.1 mrg uns_fcode = (size_t) fcode; 3545 1.1 mrg } 3546 1.1 mrg } 3547 1.1 mrg 3548 1.1 mrg /* TRUE iff the built-in function returns void. */ 3549 1.1 mrg bool void_func = TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node; 3550 1.1 mrg /* Position of first argument (0 for void-returning functions, else 1). */ 3551 1.1 mrg int k; 3552 1.1 mrg /* Modes for the return value, if any, and arguments. */ 3553 1.1 mrg const int MAX_BUILTIN_ARGS = 6; 3554 1.1 mrg machine_mode mode[MAX_BUILTIN_ARGS + 1]; 3555 1.1 mrg 3556 1.1 mrg if (void_func) 3557 1.1 mrg k = 0; 3558 1.1 mrg else 3559 1.1 mrg { 3560 1.1 mrg k = 1; 3561 1.1 mrg mode[0] = insn_data[icode].operand[0].mode; 3562 1.1 mrg } 3563 1.1 mrg 3564 1.1 mrg /* Tree expressions for each argument. */ 3565 1.1 mrg tree arg[MAX_BUILTIN_ARGS]; 3566 1.1 mrg /* RTL expressions for each argument. */ 3567 1.1 mrg rtx op[MAX_BUILTIN_ARGS]; 3568 1.1 mrg 3569 1.1 mrg int nargs = bifaddr->nargs; 3570 1.1 mrg gcc_assert (nargs <= MAX_BUILTIN_ARGS); 3571 1.1 mrg 3572 1.1 mrg 3573 1.1 mrg for (int i = 0; i < nargs; i++) 3574 1.1 mrg { 3575 1.1 mrg arg[i] = CALL_EXPR_ARG (exp, i); 3576 1.1 mrg if (arg[i] == error_mark_node) 3577 1.1 mrg return const0_rtx; 3578 1.1 mrg STRIP_NOPS (arg[i]); 3579 1.1 mrg op[i] = expand_normal (arg[i]); 3580 1.1 mrg /* We have a couple of pesky patterns that don't specify the mode... */ 3581 1.1 mrg mode[i+k] = insn_data[icode].operand[i+k].mode; 3582 1.1 mrg if (!mode[i+k]) 3583 1.1 mrg mode[i+k] = Pmode; 3584 1.1 mrg } 3585 1.1 mrg 3586 1.1 mrg /* Check for restricted constant arguments. */ 3587 1.1 mrg for (size_t i = 0; i < ARRAY_SIZE (bifaddr->restr); i++) 3588 1.1 mrg { 3589 1.1 mrg switch (bifaddr->restr[i]) 3590 1.1 mrg { 3591 1.1 mrg case RES_BITS: 3592 1.1 mrg { 3593 1.1 mrg size_t mask = 1; 3594 1.1 mrg mask <<= bifaddr->restr_val1[i]; 3595 1.1 mrg mask--; 3596 1.1 mrg tree restr_arg = arg[bifaddr->restr_opnd[i] - 1]; 3597 1.1 mrg STRIP_NOPS (restr_arg); 3598 1.1 mrg if (!(TREE_CODE (restr_arg) == INTEGER_CST 3599 1.1 mrg && (TREE_INT_CST_LOW (restr_arg) & ~mask) == 0)) 3600 1.1 mrg { 3601 1.1 mrg unsigned p = (1U << bifaddr->restr_val1[i]) - 1; 3602 1.1 mrg error ("argument %d must be a literal between 0 and %d," 3603 1.1 mrg " inclusive", 3604 1.1 mrg bifaddr->restr_opnd[i], p); 3605 1.1 mrg return const0_rtx; 3606 1.1 mrg } 3607 1.1 mrg break; 3608 1.1 mrg } 3609 1.1 mrg case RES_RANGE: 3610 1.1 mrg { 3611 1.1 mrg tree restr_arg = arg[bifaddr->restr_opnd[i] - 1]; 3612 1.1 mrg STRIP_NOPS (restr_arg); 3613 1.1 mrg if (!(TREE_CODE (restr_arg) == INTEGER_CST 3614 1.1 mrg && IN_RANGE (tree_to_shwi (restr_arg), 3615 1.1 mrg bifaddr->restr_val1[i], 3616 1.1 mrg bifaddr->restr_val2[i]))) 3617 1.1 mrg { 3618 1.1 mrg error ("argument %d must be a literal between %d and %d," 3619 1.1 mrg " inclusive", 3620 1.1 mrg bifaddr->restr_opnd[i], bifaddr->restr_val1[i], 3621 1.1 mrg bifaddr->restr_val2[i]); 3622 1.1 mrg return const0_rtx; 3623 1.1 mrg } 3624 1.1 mrg break; 3625 1.1 mrg } 3626 1.1 mrg case RES_VAR_RANGE: 3627 1.1 mrg { 3628 1.1 mrg tree restr_arg = arg[bifaddr->restr_opnd[i] - 1]; 3629 1.1 mrg STRIP_NOPS (restr_arg); 3630 1.1 mrg if (TREE_CODE (restr_arg) == INTEGER_CST 3631 1.1 mrg && !IN_RANGE (tree_to_shwi (restr_arg), 3632 1.1 mrg bifaddr->restr_val1[i], 3633 1.1 mrg bifaddr->restr_val2[i])) 3634 1.1 mrg { 3635 1.1 mrg error ("argument %d must be a variable or a literal " 3636 1.1 mrg "between %d and %d, inclusive", 3637 1.1 mrg bifaddr->restr_opnd[i], bifaddr->restr_val1[i], 3638 1.1 mrg bifaddr->restr_val2[i]); 3639 1.1 mrg return const0_rtx; 3640 1.1 mrg } 3641 1.1 mrg break; 3642 1.1 mrg } 3643 1.1 mrg case RES_VALUES: 3644 1.1 mrg { 3645 1.1 mrg tree restr_arg = arg[bifaddr->restr_opnd[i] - 1]; 3646 1.1 mrg STRIP_NOPS (restr_arg); 3647 1.1 mrg if (!(TREE_CODE (restr_arg) == INTEGER_CST 3648 1.1 mrg && (tree_to_shwi (restr_arg) == bifaddr->restr_val1[i] 3649 1.1 mrg || tree_to_shwi (restr_arg) == bifaddr->restr_val2[i]))) 3650 1.1 mrg { 3651 1.1 mrg error ("argument %d must be either a literal %d or a " 3652 1.1 mrg "literal %d", 3653 1.1 mrg bifaddr->restr_opnd[i], bifaddr->restr_val1[i], 3654 1.1 mrg bifaddr->restr_val2[i]); 3655 1.1 mrg return const0_rtx; 3656 1.1 mrg } 3657 1.1 mrg break; 3658 1.1 mrg } 3659 1.1 mrg default: 3660 1.1 mrg case RES_NONE: 3661 1.1 mrg break; 3662 1.1 mrg } 3663 1.1 mrg } 3664 1.1 mrg 3665 1.1 mrg if (bif_is_ldstmask (*bifaddr)) 3666 1.1 mrg return rs6000_expand_ldst_mask (target, arg[0]); 3667 1.1 mrg 3668 1.1 mrg if (bif_is_stvec (*bifaddr)) 3669 1.1 mrg { 3670 1.1 mrg if (bif_is_reve (*bifaddr)) 3671 1.1 mrg icode = elemrev_icode (fcode); 3672 1.1 mrg return stv_expand_builtin (icode, op, mode[0], mode[1]); 3673 1.1 mrg } 3674 1.1 mrg 3675 1.1 mrg if (bif_is_ldvec (*bifaddr)) 3676 1.1 mrg { 3677 1.1 mrg if (bif_is_reve (*bifaddr)) 3678 1.1 mrg icode = elemrev_icode (fcode); 3679 1.1 mrg return ldv_expand_builtin (target, icode, op, mode[0]); 3680 1.1 mrg } 3681 1.1 mrg 3682 1.1 mrg if (bif_is_lxvrse (*bifaddr)) 3683 1.1 mrg return lxvrse_expand_builtin (target, icode, op, mode[0], mode[1]); 3684 1.1 mrg 3685 1.1 mrg if (bif_is_lxvrze (*bifaddr)) 3686 1.1 mrg return lxvrze_expand_builtin (target, icode, op, mode[0], mode[1]); 3687 1.1 mrg 3688 1.1 mrg if (bif_is_mma (*bifaddr)) 3689 1.1 mrg return mma_expand_builtin (exp, target, icode, fcode); 3690 1.1 mrg 3691 1.1 mrg if (TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node) 3692 1.1 mrg target = NULL_RTX; 3693 1.1 mrg else if (target == 0 3694 1.1 mrg || GET_MODE (target) != mode[0] 3695 1.1 mrg || !insn_data[icode].operand[0].predicate (target, mode[0])) 3696 1.1 mrg target = gen_reg_rtx (mode[0]); 3697 1.1 mrg 3698 1.1 mrg for (int i = 0; i < nargs; i++) 3699 1.1 mrg if (!insn_data[icode].operand[i+k].predicate (op[i], mode[i+k])) 3700 1.1 mrg op[i] = copy_to_mode_reg (mode[i+k], op[i]); 3701 1.1 mrg 3702 1.1 mrg rtx pat; 3703 1.1 mrg 3704 1.1 mrg switch (nargs) 3705 1.1 mrg { 3706 1.1 mrg case 0: 3707 1.1 mrg pat = (void_func 3708 1.1 mrg ? GEN_FCN (icode) () 3709 1.1 mrg : GEN_FCN (icode) (target)); 3710 1.1 mrg break; 3711 1.1 mrg case 1: 3712 1.1 mrg pat = (void_func 3713 1.1 mrg ? GEN_FCN (icode) (op[0]) 3714 1.1 mrg : GEN_FCN (icode) (target, op[0])); 3715 1.1 mrg break; 3716 1.1 mrg case 2: 3717 1.1 mrg pat = (void_func 3718 1.1 mrg ? GEN_FCN (icode) (op[0], op[1]) 3719 1.1 mrg : GEN_FCN (icode) (target, op[0], op[1])); 3720 1.1 mrg break; 3721 1.1 mrg case 3: 3722 1.1 mrg pat = (void_func 3723 1.1 mrg ? GEN_FCN (icode) (op[0], op[1], op[2]) 3724 1.1 mrg : GEN_FCN (icode) (target, op[0], op[1], op[2])); 3725 1.1 mrg break; 3726 1.1 mrg case 4: 3727 1.1 mrg pat = (void_func 3728 1.1 mrg ? GEN_FCN (icode) (op[0], op[1], op[2], op[3]) 3729 1.1 mrg : GEN_FCN (icode) (target, op[0], op[1], op[2], op[3])); 3730 1.1 mrg break; 3731 1.1 mrg case 5: 3732 1.1 mrg pat = (void_func 3733 1.1 mrg ? GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4]) 3734 1.1 mrg : GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4])); 3735 1.1 mrg break; 3736 1.1 mrg case 6: 3737 1.1 mrg pat = (void_func 3738 1.1 mrg ? GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5]) 3739 1.1 mrg : GEN_FCN (icode) (target, op[0], op[1], 3740 1.1 mrg op[2], op[3], op[4], op[5])); 3741 1.1 mrg break; 3742 1.1 mrg default: 3743 1.1 mrg gcc_assert (MAX_BUILTIN_ARGS == 6); 3744 1.1 mrg gcc_unreachable (); 3745 1.1 mrg } 3746 1.1 mrg 3747 1.1 mrg if (!pat) 3748 1.1 mrg return 0; 3749 1.1 mrg 3750 1.1 mrg emit_insn (pat); 3751 1.1 mrg return target; 3752 1.1 mrg } 3753