Home | History | Annotate | Line # | Download | only in rs6000
      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