Home | History | Annotate | Line # | Download | only in d
      1 /* intrinsics.cc -- D language compiler intrinsics.
      2    Copyright (C) 2006-2022 Free Software Foundation, Inc.
      3 
      4 GCC is free software; you can redistribute it and/or modify
      5 it under the terms of the GNU General Public License as published by
      6 the Free Software Foundation; either version 3, or (at your option)
      7 any later version.
      8 
      9 GCC is distributed in the hope that it will be useful,
     10 but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 GNU General Public License for more details.
     13 
     14 You should have received a copy of the GNU General Public License
     15 along with GCC; see the file COPYING3.  If not see
     16 <http://www.gnu.org/licenses/>.  */
     17 
     18 #include "config.h"
     19 #include "system.h"
     20 #include "coretypes.h"
     21 
     22 #include "dmd/declaration.h"
     23 #include "dmd/expression.h"
     24 #include "dmd/identifier.h"
     25 #include "dmd/mangle.h"
     26 #include "dmd/module.h"
     27 #include "dmd/template.h"
     28 
     29 #include "tm.h"
     30 #include "function.h"
     31 #include "tree.h"
     32 #include "fold-const.h"
     33 #include "stringpool.h"
     34 #include "builtins.h"
     35 
     36 #include "d-tree.h"
     37 
     38 
     39 /* An internal struct used to hold information on D intrinsics.  */
     40 
     41 struct intrinsic_decl
     42 {
     43   /* The DECL_INTRINSIC_CODE of this decl.  */
     44   intrinsic_code code;
     45 
     46   /* The DECL_FUNCTION_CODE of this decl, if it directly maps to any.  */
     47   built_in_function built_in;
     48 
     49   /* The name of the intrinsic.  */
     50   const char *name;
     51 
     52   /* The module where the intrinsic is located.  */
     53   const char *module;
     54 
     55   /* The mangled signature decoration of the intrinsic.  */
     56   const char *deco;
     57 
     58   /* True if the intrinsic is only handled in CTFE.  */
     59   bool ctfeonly;
     60 };
     61 
     62 static const intrinsic_decl intrinsic_decls[] =
     63 {
     64 #define DEF_D_INTRINSIC(CODE, BUILTIN, NAME, MODULE, DECO, CTFE) \
     65     { CODE, BUILTIN, NAME, MODULE, DECO, CTFE },
     66 
     67 #include "intrinsics.def"
     68 
     69 #undef DEF_D_INTRINSIC
     70 };
     71 
     72 /* Checks if DECL is an intrinsic or run time library function that requires
     73    special processing.  Sets DECL_INTRINSIC_CODE so it can be identified
     74    later in maybe_expand_intrinsic.  */
     75 
     76 void
     77 maybe_set_intrinsic (FuncDeclaration *decl)
     78 {
     79   if (!decl->ident || decl->builtin != BUILTIN::unknown)
     80     return;
     81 
     82   /* The builtin flag is updated only if we can evaluate the intrinsic
     83      at compile-time.  Such as the math or bitop intrinsics.  */
     84   decl->builtin = BUILTIN::unimp;
     85 
     86   /* Check if it's a compiler intrinsic.  We only require that any
     87      internally recognised intrinsics are declared in a module with
     88      an explicit module declaration.  */
     89   Module *m = decl->getModule ();
     90 
     91   if (!m || !m->md)
     92     return;
     93 
     94   TemplateInstance *ti = decl->isInstantiated ();
     95   TemplateDeclaration *td = ti ? ti->tempdecl->isTemplateDeclaration () : NULL;
     96 
     97   const char *tname = decl->ident->toChars ();
     98   const char *tmodule = m->md->toChars ();
     99   const char *tdeco = (td == NULL) ? decl->type->deco : NULL;
    100 
    101   /* Look through all D intrinsics.  */
    102   for (size_t i = 0; i < (int) INTRINSIC_LAST; i++)
    103     {
    104       if (!intrinsic_decls[i].name)
    105 	continue;
    106 
    107       if (strcmp (intrinsic_decls[i].name, tname) != 0
    108 	  || strcmp (intrinsic_decls[i].module, tmodule) != 0)
    109 	continue;
    110 
    111       /* Instantiated functions would have the wrong type deco, get it from the
    112 	 template member instead.  */
    113       if (tdeco == NULL)
    114 	{
    115 	  if (!td || !td->onemember)
    116 	    return;
    117 
    118 	  FuncDeclaration *fd = td->onemember->isFuncDeclaration ();
    119 	  if (fd == NULL)
    120 	    return;
    121 
    122 	  OutBuffer buf;
    123 	  mangleToBuffer (fd->type, &buf);
    124 	  tdeco = buf.extractChars ();
    125 	}
    126 
    127       /* Matching the type deco may be a bit too strict, as it means that all
    128 	 function attributes that end up in the signature must be kept aligned
    129 	 between the compiler and library declaration.  */
    130       if (strcmp (intrinsic_decls[i].deco, tdeco) == 0)
    131 	{
    132 	  intrinsic_code code = intrinsic_decls[i].code;
    133 
    134 	  if (decl->csym == NULL)
    135 	    get_symbol_decl (decl);
    136 
    137 	  /* If there is no function body, then the implementation is always
    138 	     provided by the compiler.  */
    139 	  if (!decl->fbody)
    140 	    set_decl_built_in_function (decl->csym, BUILT_IN_FRONTEND, code);
    141 
    142 	  /* Infer whether the intrinsic can be used for CTFE, let the
    143 	     front-end know that it can be evaluated at compile-time.  */
    144 	  switch (code)
    145 	    {
    146 	    case INTRINSIC_VA_ARG:
    147 	    case INTRINSIC_C_VA_ARG:
    148 	    case INTRINSIC_VASTART:
    149 	    case INTRINSIC_ADDS:
    150 	    case INTRINSIC_ADDSL:
    151 	    case INTRINSIC_ADDU:
    152 	    case INTRINSIC_ADDUL:
    153 	    case INTRINSIC_SUBS:
    154 	    case INTRINSIC_SUBSL:
    155 	    case INTRINSIC_SUBU:
    156 	    case INTRINSIC_SUBUL:
    157 	    case INTRINSIC_MULS:
    158 	    case INTRINSIC_MULSL:
    159 	    case INTRINSIC_MULU:
    160 	    case INTRINSIC_MULUI:
    161 	    case INTRINSIC_MULUL:
    162 	    case INTRINSIC_NEGS:
    163 	    case INTRINSIC_NEGSL:
    164 	    case INTRINSIC_VLOAD8:
    165 	    case INTRINSIC_VLOAD16:
    166 	    case INTRINSIC_VLOAD32:
    167 	    case INTRINSIC_VLOAD64:
    168 	    case INTRINSIC_VSTORE8:
    169 	    case INTRINSIC_VSTORE16:
    170 	    case INTRINSIC_VSTORE32:
    171 	    case INTRINSIC_VSTORE64:
    172 	      break;
    173 
    174 	    case INTRINSIC_POW:
    175 	    {
    176 	      /* Check that this overload of pow() is has an equivalent
    177 		 built-in function.  It could be `int pow(int, int)'.  */
    178 	      tree rettype = TREE_TYPE (TREE_TYPE (decl->csym));
    179 	      if (mathfn_built_in (rettype, BUILT_IN_POW) != NULL_TREE)
    180 		decl->builtin = BUILTIN::gcc;
    181 	      break;
    182 	    }
    183 
    184 	    default:
    185 	      decl->builtin = BUILTIN::gcc;
    186 	      break;
    187 	    }
    188 
    189 	  /* The intrinsic was marked as CTFE-only.  */
    190 	  if (intrinsic_decls[i].ctfeonly)
    191 	    DECL_BUILT_IN_CTFE (decl->csym) = 1;
    192 
    193 	  DECL_INTRINSIC_CODE (decl->csym) = code;
    194 	  break;
    195 	}
    196     }
    197 }
    198 
    199 /* Construct a function call to the built-in function CODE, N is the number of
    200    arguments, and the `...' parameters are the argument expressions.
    201    The original call expression is held in CALLEXP.  */
    202 
    203 static tree
    204 call_builtin_fn (tree callexp, built_in_function code, int n, ...)
    205 {
    206   tree *argarray = XALLOCAVEC (tree, n);
    207   va_list ap;
    208 
    209   va_start (ap, n);
    210   for (int i = 0; i < n; i++)
    211     argarray[i] = va_arg (ap, tree);
    212   va_end (ap);
    213 
    214   tree exp = build_call_expr_loc_array (EXPR_LOCATION (callexp),
    215 					builtin_decl_explicit (code),
    216 					n, argarray);
    217   return convert (TREE_TYPE (callexp), fold (exp));
    218 }
    219 
    220 /* Expand a front-end instrinsic call to bsf().  This takes one argument,
    221    the signature to which can be either:
    222 
    223 	int bsf (uint arg);
    224 	int bsf (ulong arg);
    225 
    226    This scans all bits in the given argument starting with the first,
    227    returning the bit number of the first bit set.  The original call
    228    expression is held in CALLEXP.  */
    229 
    230 static tree
    231 expand_intrinsic_bsf (tree callexp)
    232 {
    233   /* The bsr() intrinsic gets turned into __builtin_ctz(arg).
    234      The return value is supposed to be undefined if arg is zero.  */
    235   tree arg = CALL_EXPR_ARG (callexp, 0);
    236   int argsize = TYPE_PRECISION (TREE_TYPE (arg));
    237 
    238   /* Which variant of __builtin_ctz* should we call?  */
    239   built_in_function code = (argsize <= INT_TYPE_SIZE) ? BUILT_IN_CTZ
    240     : (argsize <= LONG_TYPE_SIZE) ? BUILT_IN_CTZL
    241     : (argsize <= LONG_LONG_TYPE_SIZE) ? BUILT_IN_CTZLL
    242     : END_BUILTINS;
    243 
    244   gcc_assert (code != END_BUILTINS);
    245 
    246   return call_builtin_fn (callexp, code, 1, arg);
    247 }
    248 
    249 /* Expand a front-end instrinsic call to bsr().  This takes one argument,
    250    the signature to which can be either:
    251 
    252 	int bsr (uint arg);
    253 	int bsr (ulong arg);
    254 
    255    This scans all bits in the given argument from the most significant bit
    256    to the least significant, returning the bit number of the first bit set.
    257    The original call expression is held in CALLEXP.  */
    258 
    259 static tree
    260 expand_intrinsic_bsr (tree callexp)
    261 {
    262   /* The bsr() intrinsic gets turned into (size - 1) - __builtin_clz(arg).
    263      The return value is supposed to be undefined if arg is zero.  */
    264   tree arg = CALL_EXPR_ARG (callexp, 0);
    265   tree type = TREE_TYPE (arg);
    266   int argsize = TYPE_PRECISION (type);
    267 
    268   /* Which variant of __builtin_clz* should we call?  */
    269   built_in_function code = (argsize <= INT_TYPE_SIZE) ? BUILT_IN_CLZ
    270     : (argsize <= LONG_TYPE_SIZE) ? BUILT_IN_CLZL
    271     : (argsize <= LONG_LONG_TYPE_SIZE) ? BUILT_IN_CLZLL
    272     : END_BUILTINS;
    273 
    274   gcc_assert (code != END_BUILTINS);
    275 
    276   tree result = call_builtin_fn (callexp, code, 1, arg);
    277 
    278   /* Handle int -> long conversions.  */
    279   if (TREE_TYPE (result) != type)
    280     result = fold_convert (type, result);
    281 
    282   result = fold_build2 (MINUS_EXPR, type,
    283 			build_integer_cst (argsize - 1, type), result);
    284   return fold_convert (TREE_TYPE (callexp), result);
    285 }
    286 
    287 /* Expand a front-end intrinsic call to INTRINSIC, which is either a call to
    288    bt(), btc(), btr(), or bts().  These intrinsics expect to take two arguments,
    289    the signature to which is:
    290 
    291 	int bt (size_t* ptr, size_t bitnum);
    292 
    293    All intrinsics test if a bit is set and return the result of that condition.
    294    Variants of `bt' will then update that bit. `btc' compliments the bit, `bts'
    295    sets the bit, and `btr' resets the bit.  The original call expression is
    296    held in CALLEXP.  */
    297 
    298 static tree
    299 expand_intrinsic_bt (intrinsic_code intrinsic, tree callexp)
    300 {
    301   tree ptr = CALL_EXPR_ARG (callexp, 0);
    302   tree bitnum = CALL_EXPR_ARG (callexp, 1);
    303   tree type = TREE_TYPE (TREE_TYPE (ptr));
    304 
    305   /* size_t bitsize = sizeof(*ptr) * BITS_PER_UNIT;  */
    306   tree bitsize = fold_convert (type, TYPE_SIZE (TREE_TYPE (ptr)));
    307 
    308   /* ptr[bitnum / bitsize]  */
    309   ptr = build_array_index (ptr, fold_build2 (TRUNC_DIV_EXPR, type,
    310 					     bitnum, bitsize));
    311   ptr = indirect_ref (type, ptr);
    312 
    313   /* mask = 1 << (bitnum % bitsize);  */
    314   bitnum = fold_build2 (TRUNC_MOD_EXPR, type, bitnum, bitsize);
    315   bitnum = fold_build2 (LSHIFT_EXPR, type, build_one_cst (type), bitnum);
    316 
    317   /* cond = ptr[bitnum / size] & mask;  */
    318   tree cond = fold_build2 (BIT_AND_EXPR, type, ptr, bitnum);
    319 
    320   /* cond ? -1 : 0;  */
    321   cond = build_condition (TREE_TYPE (callexp), d_truthvalue_conversion (cond),
    322 			  build_minus_one_cst (TREE_TYPE (callexp)),
    323 			  build_zero_cst (TREE_TYPE (callexp)));
    324 
    325   /* Update the bit as needed, only testing the bit for bt().  */
    326   tree_code code;
    327 
    328   switch (intrinsic)
    329     {
    330     case INTRINSIC_BT:
    331     case INTRINSIC_BT64:
    332       return cond;
    333 
    334     case INTRINSIC_BTC:
    335     case INTRINSIC_BTC64:
    336       code = BIT_XOR_EXPR;
    337       break;
    338 
    339     case INTRINSIC_BTR:
    340     case INTRINSIC_BTR64:
    341       bitnum = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (bitnum), bitnum);
    342       code = BIT_AND_EXPR;
    343       break;
    344 
    345     case INTRINSIC_BTS:
    346     case INTRINSIC_BTS64:
    347       code = BIT_IOR_EXPR;
    348       break;
    349 
    350     default:
    351       gcc_unreachable ();
    352     }
    353 
    354   /* ptr[bitnum / size] op= mask;  */
    355   ptr = modify_expr (ptr, fold_build2 (code, TREE_TYPE (ptr), ptr, bitnum));
    356 
    357   /* Store the condition result in a temporary, and return expressions in
    358      correct order of evaluation.  */
    359   tree tmp = build_local_temp (TREE_TYPE (callexp));
    360   cond = modify_expr (tmp, cond);
    361 
    362   return compound_expr (cond, compound_expr (ptr, tmp));
    363 }
    364 
    365 /* Expand a front-end intrinsic call to popcnt().  This takes one argument, the
    366    signature to which can be either:
    367 
    368 	int popcnt (uint arg);
    369 	int popcnt (ulong arg);
    370 
    371    Calculates the number of set bits in an integer.  The original call
    372    expression is held in CALLEXP.  */
    373 
    374 static tree
    375 expand_intrinsic_popcnt (tree callexp)
    376 {
    377   tree arg = CALL_EXPR_ARG (callexp, 0);
    378   int argsize = TYPE_PRECISION (TREE_TYPE (arg));
    379 
    380   /* Which variant of __builtin_popcount* should we call?  */
    381   built_in_function code = (argsize <= INT_TYPE_SIZE) ? BUILT_IN_POPCOUNT
    382     : (argsize <= LONG_TYPE_SIZE) ? BUILT_IN_POPCOUNTL
    383     : (argsize <= LONG_LONG_TYPE_SIZE) ? BUILT_IN_POPCOUNTLL
    384     : END_BUILTINS;
    385 
    386   gcc_assert (code != END_BUILTINS);
    387 
    388   return call_builtin_fn (callexp, code, 1, arg);
    389 }
    390 
    391 /* Expand a front-end intrinsic call to INTRINSIC, which is either a call to
    392    rol() or ror().  These intrinsics expect to take one or two arguments,
    393    the signature to which can be either:
    394 
    395 	T rol(T) (const T value, const uint count);
    396 	T rol(uint count, T) (const T value);
    397 	T ror(T) (const T value, const uint count);
    398 	T ror(uint count, T) (const T value);
    399 
    400    This bitwise rotates VALUE left or right by COUNT bit positions.  */
    401 
    402 static tree
    403 expand_intrinsic_rotate (intrinsic_code intrinsic, tree callexp)
    404 {
    405   tree type = TREE_TYPE (callexp);
    406   tree value = CALL_EXPR_ARG (callexp, 0);
    407   tree count;
    408   tree_code code;
    409 
    410   /* Get the equivalent tree code for the intrinsic.  */
    411   if (intrinsic == INTRINSIC_ROL || intrinsic == INTRINSIC_ROL_TIARG)
    412     code = LROTATE_EXPR;
    413   else if (intrinsic == INTRINSIC_ROR || intrinsic == INTRINSIC_ROR_TIARG)
    414     code = RROTATE_EXPR;
    415   else
    416     gcc_unreachable ();
    417 
    418   /* Get the COUNT parameter.  Either from the call expression arguments or the
    419      template instantiation arguments.  */
    420   if (intrinsic == INTRINSIC_ROL || intrinsic == INTRINSIC_ROR)
    421     count = CALL_EXPR_ARG (callexp, 1);
    422   else
    423     {
    424       tree callee = CALL_EXPR_FN (callexp);
    425 
    426       if (TREE_CODE (callee) == ADDR_EXPR)
    427 	callee = TREE_OPERAND (callee, 0);
    428 
    429       /* Retrieve from the encoded template instantation.  */
    430       TemplateInstance *ti = DECL_LANG_FRONTEND (callee)->isInstantiated ();
    431       gcc_assert (ti && ti->tiargs && ti->tiargs->length == 2);
    432 
    433       Expression *e = isExpression ((*ti->tiargs)[0]);
    434       gcc_assert (e && e->op == EXP::int64);
    435       count = build_expr (e, true);
    436     }
    437 
    438   return fold_build2 (code, type, value, count);
    439 }
    440 
    441 /* Expand a front-end intrinsic call to copysign().  This takes two arguments,
    442    the signature to which can be either:
    443 
    444 	float copysign (T to, float from);
    445 	double copysign (T to, double from);
    446 	real copysign (T to, real from);
    447 
    448    This computes a value composed of TO with the sign bit of FROM.  The original
    449    call expression is held in CALLEXP.  */
    450 
    451 static tree
    452 expand_intrinsic_copysign (tree callexp)
    453 {
    454   tree to = CALL_EXPR_ARG (callexp, 0);
    455   tree from = CALL_EXPR_ARG (callexp, 1);
    456   tree type = TREE_TYPE (to);
    457 
    458   /* Convert parameters to the same type.  Prefer the first parameter unless it
    459      is an integral type.  */
    460   if (INTEGRAL_TYPE_P (type))
    461     {
    462       to = fold_convert (TREE_TYPE (from), to);
    463       type = TREE_TYPE (to);
    464     }
    465   else
    466     from = fold_convert (type, from);
    467 
    468   /* Which variant of __builtin_copysign* should we call?  */
    469   built_in_function code = (type == float_type_node) ? BUILT_IN_COPYSIGNF
    470     : (type == double_type_node) ? BUILT_IN_COPYSIGN
    471     : (type == long_double_type_node) ? BUILT_IN_COPYSIGNL
    472     : END_BUILTINS;
    473 
    474   gcc_assert (code != END_BUILTINS);
    475 
    476   return call_builtin_fn (callexp, code, 2, to, from);
    477 }
    478 
    479 /* Expand a front-end intrinsic call to pow().  This takes two arguments, the
    480    signature to which can be either:
    481 
    482 	float pow (float base, T exponent);
    483 	double pow (double base, T exponent);
    484 	real pow (real base, T exponent);
    485 
    486    This computes the value of BASE raised to the power of EXPONENT.
    487    The original call expression is held in CALLEXP.  */
    488 
    489 static tree
    490 expand_intrinsic_pow (tree callexp)
    491 {
    492   tree base = CALL_EXPR_ARG (callexp, 0);
    493   tree exponent = CALL_EXPR_ARG (callexp, 1);
    494   tree exptype = TREE_TYPE (exponent);
    495 
    496   /* Which variant of __builtin_pow* should we call?  */
    497   built_in_function code = SCALAR_FLOAT_TYPE_P (exptype) ? BUILT_IN_POW
    498     : INTEGRAL_TYPE_P (exptype) ? BUILT_IN_POWI
    499     : END_BUILTINS;
    500   gcc_assert (code != END_BUILTINS);
    501 
    502   tree builtin = mathfn_built_in (TREE_TYPE (base), code);
    503   gcc_assert (builtin != NULL_TREE);
    504 
    505   return call_builtin_fn (callexp, DECL_FUNCTION_CODE (builtin), 2,
    506 			  base, exponent);
    507 }
    508 
    509 /* Expand a front-end intrinsic call to toPrec().  This takes one argument, the
    510    signature to which can be either:
    511 
    512 	T toPrec(T)(float f);
    513 	T toPrec(T)(double f);
    514 	T toPrec(T)(real f);
    515 
    516     This rounds the argument F to the precision of the specified floating
    517     point type T.  The original call expression is held in CALLEXP.  */
    518 
    519 static tree
    520 expand_intrinsic_toprec (tree callexp)
    521 {
    522   tree f = CALL_EXPR_ARG (callexp, 0);
    523   tree type = TREE_TYPE (callexp);
    524 
    525   return convert (type, f);
    526 }
    527 
    528 /* Expand a front-end intrinsic call to va_arg().  This takes either one or two
    529    arguments, the signature to which can be either:
    530 
    531 	T va_arg(T) (ref va_list ap);
    532 	void va_arg(T) (va_list ap, ref T parmn);
    533 
    534    This retrieves the next variadic parameter that is type T from the given
    535    va_list.  If also given, store the value into parmn, otherwise return it.
    536    The original call expression is held in CALLEXP.  */
    537 
    538 static tree
    539 expand_intrinsic_vaarg (tree callexp)
    540 {
    541   tree ap = CALL_EXPR_ARG (callexp, 0);
    542   tree parmn = NULL_TREE;
    543   tree type;
    544 
    545   STRIP_NOPS (ap);
    546 
    547   if (call_expr_nargs (callexp) == 1)
    548     type = TREE_TYPE (callexp);
    549   else
    550     {
    551       parmn = CALL_EXPR_ARG (callexp, 1);
    552       STRIP_NOPS (parmn);
    553 
    554       /* The `ref' argument to va_arg is either an address or reference,
    555 	 get the value of it.  */
    556       if (TREE_CODE (parmn) == PARM_DECL && POINTER_TYPE_P (TREE_TYPE (parmn)))
    557 	parmn = build_deref (parmn);
    558       else
    559 	{
    560 	  gcc_assert (TREE_CODE (parmn) == ADDR_EXPR);
    561 	  parmn = TREE_OPERAND (parmn, 0);
    562 	}
    563 
    564       type = TREE_TYPE (parmn);
    565     }
    566 
    567   /* (T) VA_ARG_EXP<ap>;  */
    568   tree exp = build1_loc (EXPR_LOCATION (callexp), VA_ARG_EXPR, type, ap);
    569 
    570   /* parmn = (T) VA_ARG_EXP<ap>;  */
    571   if (parmn != NULL_TREE)
    572     exp = modify_expr (parmn, exp);
    573 
    574   return exp;
    575 }
    576 
    577 /* Expand a front-end intrinsic call to va_start(), which takes two arguments,
    578    the signature to which is:
    579 
    580 	void va_start(T) (out va_list ap, ref T parmn);
    581 
    582    This initializes the va_list type, where parmn should be the last named
    583    parameter.  The original call expression is held in CALLEXP.  */
    584 
    585 static tree
    586 expand_intrinsic_vastart (tree callexp)
    587 {
    588   tree ap = CALL_EXPR_ARG (callexp, 0);
    589   tree parmn = CALL_EXPR_ARG (callexp, 1);
    590 
    591   STRIP_NOPS (ap);
    592   STRIP_NOPS (parmn);
    593 
    594   /* The va_list argument should already have its address taken.  The second
    595      argument, however, is inout and that needs to be fixed to prevent a
    596      warning.  Could be casting, so need to check type too?  */
    597   gcc_assert (TREE_CODE (ap) == ADDR_EXPR
    598 	      || (TREE_CODE (ap) == PARM_DECL
    599 		  && POINTER_TYPE_P (TREE_TYPE (ap))));
    600 
    601   /* Assuming nobody tries to change the return type.  */
    602   if (TREE_CODE (parmn) != PARM_DECL)
    603     {
    604       gcc_assert (TREE_CODE (parmn) == ADDR_EXPR);
    605       parmn = TREE_OPERAND (parmn, 0);
    606     }
    607 
    608   return call_builtin_fn (callexp, BUILT_IN_VA_START, 2, ap, parmn);
    609 }
    610 
    611 /* Expand a front-end instrinsic call to INTRINSIC, which is either a call to
    612    adds(), addu(), subs(), subu(), negs(), muls(), or mulu().  These intrinsics
    613    expect to take two or three arguments, the signature to which can be either:
    614 
    615 	int adds (int x, int y, ref bool overflow);
    616 	long adds (long x, long y, ref bool overflow);
    617 	int negs (int x, ref bool overflow);
    618 	long negs (long x, ref bool overflow);
    619 
    620    This performs an operation on two signed or unsigned integers, checking for
    621    overflow.  The overflow is sticky, meaning that a sequence of operations
    622    can be done and overflow need only be checked at the end.  The original call
    623    expression is held in CALLEXP.  */
    624 
    625 static tree
    626 expand_intrinsic_checkedint (intrinsic_code intrinsic, tree callexp)
    627 {
    628   tree type = TREE_TYPE (callexp);
    629   tree x;
    630   tree y;
    631   tree overflow;
    632   internal_fn icode;
    633 
    634   /* Which variant of *_OVERFLOW should we generate?  */
    635   switch (intrinsic)
    636     {
    637     case INTRINSIC_ADDS:
    638     case INTRINSIC_ADDSL:
    639     case INTRINSIC_ADDU:
    640     case INTRINSIC_ADDUL:
    641       x = CALL_EXPR_ARG (callexp, 0);
    642       y = CALL_EXPR_ARG (callexp, 1);
    643       overflow = CALL_EXPR_ARG (callexp, 2);
    644       icode = IFN_ADD_OVERFLOW;
    645       break;
    646 
    647     case INTRINSIC_SUBS:
    648     case INTRINSIC_SUBSL:
    649     case INTRINSIC_SUBU:
    650     case INTRINSIC_SUBUL:
    651       x = CALL_EXPR_ARG (callexp, 0);
    652       y = CALL_EXPR_ARG (callexp, 1);
    653       overflow = CALL_EXPR_ARG (callexp, 2);
    654       icode = IFN_SUB_OVERFLOW;
    655       break;
    656 
    657     case INTRINSIC_MULS:
    658     case INTRINSIC_MULSL:
    659     case INTRINSIC_MULU:
    660     case INTRINSIC_MULUI:
    661     case INTRINSIC_MULUL:
    662       x = CALL_EXPR_ARG (callexp, 0);
    663       y = CALL_EXPR_ARG (callexp, 1);
    664       overflow = CALL_EXPR_ARG (callexp, 2);
    665       icode = IFN_MUL_OVERFLOW;
    666       break;
    667 
    668     case INTRINSIC_NEGS:
    669     case INTRINSIC_NEGSL:
    670       /* The negs() intrinsic gets turned into SUB_OVERFLOW (0, y).  */
    671       x = fold_convert (type, integer_zero_node);
    672       y = CALL_EXPR_ARG (callexp, 0);
    673       overflow = CALL_EXPR_ARG (callexp, 1);
    674       icode = IFN_SUB_OVERFLOW;
    675       break;
    676 
    677     default:
    678       gcc_unreachable ();
    679     }
    680 
    681   tree result
    682     = build_call_expr_internal_loc (EXPR_LOCATION (callexp), icode,
    683 				    build_complex_type (type), 2, x, y);
    684 
    685   STRIP_NOPS (overflow);
    686   overflow = build_deref (overflow);
    687 
    688   /* Assign returned result to overflow parameter, however if overflow is
    689      already true, maintain its value.  */
    690   type = TREE_TYPE (overflow);
    691   result = save_expr (result);
    692 
    693   tree exp = fold_build2 (BIT_IOR_EXPR, type, overflow,
    694 			  fold_convert (type, imaginary_part (result)));
    695   exp = modify_expr (overflow, exp);
    696 
    697   /* Return the value of result.  */
    698   return compound_expr (exp, real_part (result));
    699 }
    700 
    701 /* Expand a front-end instrinsic call to volatileLoad().  This takes one
    702    argument, the signature to which can be either:
    703 
    704 	ubyte volatileLoad (ubyte* ptr);
    705 	ushort volatileLoad (ushort* ptr);
    706 	uint volatileLoad (uint* ptr);
    707 	ulong volatileLoad (ulong* ptr);
    708 
    709    This reads a value from the memory location indicated by ptr.  Calls to
    710    them are be guaranteed to not be removed (such as during DCE) or reordered
    711    in the same thread.  The original call expression is held in CALLEXP.  */
    712 
    713 static tree
    714 expand_volatile_load (tree callexp)
    715 {
    716   tree ptr = CALL_EXPR_ARG (callexp, 0);
    717   tree ptrtype = TREE_TYPE (ptr);
    718   gcc_assert (POINTER_TYPE_P (ptrtype));
    719 
    720   /* (T) *(volatile T *) ptr;  */
    721   tree type = build_qualified_type (TREE_TYPE (ptrtype), TYPE_QUAL_VOLATILE);
    722   tree result = indirect_ref (type, ptr);
    723   TREE_THIS_VOLATILE (result) = 1;
    724   TREE_SIDE_EFFECTS (result) = 1;
    725 
    726   return result;
    727 }
    728 
    729 /* Expand a front-end instrinsic call to volatileStore().  This takes two
    730    arguments, the signature to which can be either:
    731 
    732 	void volatileStore (ubyte* ptr, ubyte value);
    733 	void volatileStore (ushort* ptr, ushort value);
    734 	void volatileStore (uint* ptr, uint value);
    735 	void volatileStore (ulong* ptr, ulong value);
    736 
    737    This writes a value to the memory location indicated by ptr.  Calls to
    738    them are be guaranteed to not be removed (such as during DCE) or reordered
    739    in the same thread.  The original call expression is held in CALLEXP.  */
    740 
    741 static tree
    742 expand_volatile_store (tree callexp)
    743 {
    744   tree ptr = CALL_EXPR_ARG (callexp, 0);
    745   tree ptrtype = TREE_TYPE (ptr);
    746   gcc_assert (POINTER_TYPE_P (ptrtype));
    747 
    748   /* (T) *(volatile T *) ptr;  */
    749   tree type = build_qualified_type (TREE_TYPE (ptrtype), TYPE_QUAL_VOLATILE);
    750   tree result = indirect_ref (type, ptr);
    751   TREE_THIS_VOLATILE (result) = 1;
    752   TREE_SIDE_EFFECTS (result) = 1;
    753 
    754   /* (*(volatile T *) ptr) = value;  */
    755   tree value = CALL_EXPR_ARG (callexp, 1);
    756   return modify_expr (result, value);
    757 }
    758 
    759 /* If CALLEXP is for an intrinsic , expand and return inlined compiler
    760    generated instructions.  Most map directly to GCC builtins, others
    761    require a little extra work around them.  */
    762 
    763 tree
    764 maybe_expand_intrinsic (tree callexp)
    765 {
    766   tree callee = CALL_EXPR_FN (callexp);
    767 
    768   if (TREE_CODE (callee) == ADDR_EXPR)
    769     callee = TREE_OPERAND (callee, 0);
    770 
    771   if (TREE_CODE (callee) != FUNCTION_DECL)
    772     return callexp;
    773 
    774   /* Don't expand CTFE-only intrinsics outside of semantic processing.  */
    775   if (DECL_BUILT_IN_CTFE (callee) && !doing_semantic_analysis_p)
    776     return callexp;
    777 
    778   intrinsic_code intrinsic = DECL_INTRINSIC_CODE (callee);
    779   built_in_function code;
    780 
    781   switch (intrinsic)
    782     {
    783     case INTRINSIC_NONE:
    784       return callexp;
    785 
    786     case INTRINSIC_BSF:
    787     case INTRINSIC_BSF64:
    788       return expand_intrinsic_bsf (callexp);
    789 
    790     case INTRINSIC_BSR:
    791     case INTRINSIC_BSR64:
    792       return expand_intrinsic_bsr (callexp);
    793 
    794     case INTRINSIC_BT:
    795     case INTRINSIC_BT64:
    796     case INTRINSIC_BTC:
    797     case INTRINSIC_BTC64:
    798     case INTRINSIC_BTR:
    799     case INTRINSIC_BTR64:
    800     case INTRINSIC_BTS:
    801     case INTRINSIC_BTS64:
    802       return expand_intrinsic_bt (intrinsic, callexp);
    803 
    804     case INTRINSIC_POPCNT32:
    805     case INTRINSIC_POPCNT64:
    806       return expand_intrinsic_popcnt (callexp);
    807 
    808     case INTRINSIC_ROL:
    809     case INTRINSIC_ROL_TIARG:
    810     case INTRINSIC_ROR:
    811     case INTRINSIC_ROR_TIARG:
    812       return expand_intrinsic_rotate (intrinsic, callexp);
    813 
    814     case INTRINSIC_BSWAP16:
    815     case INTRINSIC_BSWAP32:
    816     case INTRINSIC_BSWAP64:
    817     case INTRINSIC_CEIL:
    818     case INTRINSIC_CEILF:
    819     case INTRINSIC_CEILL:
    820     case INTRINSIC_COS:
    821     case INTRINSIC_COSF:
    822     case INTRINSIC_COSL:
    823     case INTRINSIC_EXP:
    824     case INTRINSIC_EXP2:
    825     case INTRINSIC_EXPM1:
    826     case INTRINSIC_FABS:
    827     case INTRINSIC_FABSF:
    828     case INTRINSIC_FABSL:
    829     case INTRINSIC_FLOOR:
    830     case INTRINSIC_FLOORF:
    831     case INTRINSIC_FLOORL:
    832     case INTRINSIC_ISFINITE:
    833     case INTRINSIC_ISINFINITY:
    834     case INTRINSIC_ISNAN:
    835     case INTRINSIC_LOG:
    836     case INTRINSIC_LOG10:
    837     case INTRINSIC_LOG2:
    838     case INTRINSIC_RINT:
    839     case INTRINSIC_RINTF:
    840     case INTRINSIC_RINTL:
    841     case INTRINSIC_RNDTOL:
    842     case INTRINSIC_RNDTOLF:
    843     case INTRINSIC_RNDTOLL:
    844     case INTRINSIC_ROUND:
    845     case INTRINSIC_SIN:
    846     case INTRINSIC_SINF:
    847     case INTRINSIC_SINL:
    848     case INTRINSIC_SQRT:
    849     case INTRINSIC_SQRTF:
    850     case INTRINSIC_SQRTL:
    851     case INTRINSIC_TAN:
    852     case INTRINSIC_TRUNC:
    853       code = intrinsic_decls[intrinsic].built_in;
    854       gcc_assert (code != BUILT_IN_NONE);
    855       return call_builtin_fn (callexp, code, 1,
    856 			      CALL_EXPR_ARG (callexp, 0));
    857 
    858     case INTRINSIC_FMAX:
    859     case INTRINSIC_FMIN:
    860     case INTRINSIC_LDEXP:
    861     case INTRINSIC_LDEXPF:
    862     case INTRINSIC_LDEXPL:
    863       code = intrinsic_decls[intrinsic].built_in;
    864       gcc_assert (code != BUILT_IN_NONE);
    865       return call_builtin_fn (callexp, code, 2,
    866 			      CALL_EXPR_ARG (callexp, 0),
    867 			      CALL_EXPR_ARG (callexp, 1));
    868 
    869     case INTRINSIC_FMA:
    870       code = intrinsic_decls[intrinsic].built_in;
    871       gcc_assert (code != BUILT_IN_NONE);
    872       return call_builtin_fn (callexp, code, 3,
    873 			      CALL_EXPR_ARG (callexp, 0),
    874 			      CALL_EXPR_ARG (callexp, 1),
    875 			      CALL_EXPR_ARG (callexp, 2));
    876 
    877     case INTRINSIC_COPYSIGN:
    878     case INTRINSIC_COPYSIGNI:
    879       return expand_intrinsic_copysign (callexp);
    880 
    881     case INTRINSIC_POW:
    882       return expand_intrinsic_pow (callexp);
    883 
    884     case INTRINSIC_TOPREC:
    885     case INTRINSIC_TOPRECF:
    886     case INTRINSIC_TOPRECL:
    887       return expand_intrinsic_toprec (callexp);
    888 
    889     case INTRINSIC_VA_ARG:
    890     case INTRINSIC_C_VA_ARG:
    891       return expand_intrinsic_vaarg (callexp);
    892 
    893     case INTRINSIC_VASTART:
    894       return expand_intrinsic_vastart (callexp);
    895 
    896     case INTRINSIC_ADDS:
    897     case INTRINSIC_ADDSL:
    898     case INTRINSIC_ADDU:
    899     case INTRINSIC_ADDUL:
    900     case INTRINSIC_SUBS:
    901     case INTRINSIC_SUBSL:
    902     case INTRINSIC_SUBU:
    903     case INTRINSIC_SUBUL:
    904     case INTRINSIC_MULS:
    905     case INTRINSIC_MULSL:
    906     case INTRINSIC_MULU:
    907     case INTRINSIC_MULUI:
    908     case INTRINSIC_MULUL:
    909     case INTRINSIC_NEGS:
    910     case INTRINSIC_NEGSL:
    911       return expand_intrinsic_checkedint (intrinsic, callexp);
    912 
    913     case INTRINSIC_VLOAD8:
    914     case INTRINSIC_VLOAD16:
    915     case INTRINSIC_VLOAD32:
    916     case INTRINSIC_VLOAD64:
    917       return expand_volatile_load (callexp);
    918 
    919     case INTRINSIC_VSTORE8:
    920     case INTRINSIC_VSTORE16:
    921     case INTRINSIC_VSTORE32:
    922     case INTRINSIC_VSTORE64:
    923       return expand_volatile_store (callexp);
    924 
    925     default:
    926       gcc_unreachable ();
    927     }
    928 }
    929