]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/builtins.c
PR debug/36278
[thirdparty/gcc.git] / gcc / builtins.c
CommitLineData
53800dbe 1/* Expand builtin functions.
61f1dccc 2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
f0b5f617 3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
f96bd2bf 4 Free Software Foundation, Inc.
53800dbe 5
f12b58b3 6This file is part of GCC.
53800dbe 7
f12b58b3 8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
8c4c00c1 10Software Foundation; either version 3, or (at your option) any later
f12b58b3 11version.
53800dbe 12
f12b58b3 13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
53800dbe 17
18You should have received a copy of the GNU General Public License
8c4c00c1 19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
53800dbe 21
22#include "config.h"
23#include "system.h"
805e22b2 24#include "coretypes.h"
25#include "tm.h"
53800dbe 26#include "machmode.h"
ef258422 27#include "real.h"
53800dbe 28#include "rtl.h"
29#include "tree.h"
75a70cf9 30#include "gimple.h"
53800dbe 31#include "flags.h"
32#include "regs.h"
33#include "hard-reg-set.h"
34#include "except.h"
35#include "function.h"
53800dbe 36#include "insn-config.h"
37#include "expr.h"
d8fc4d0b 38#include "optabs.h"
39#include "libfuncs.h"
53800dbe 40#include "recog.h"
41#include "output.h"
42#include "typeclass.h"
53800dbe 43#include "toplev.h"
689df48e 44#include "predict.h"
1dd6c958 45#include "tm_p.h"
fc2a2dcb 46#include "target.h"
63c62881 47#include "langhooks.h"
0ec80471 48#include "basic-block.h"
fd62c19a 49#include "tree-mudflap.h"
5a84fdd6 50#include "tree-flow.h"
162719b3 51#include "value-prof.h"
07311427 52#include "diagnostic.h"
53800dbe 53
726e2588 54#ifndef PAD_VARARGS_DOWN
55#define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
56#endif
57
ab7943b9 58/* Define the names of the builtin function types and codes. */
8934cb0c 59const char *const built_in_class_names[4]
ab7943b9 60 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
61
9cfddb70 62#define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
0dfc45b5 63const char * built_in_names[(int) END_BUILTINS] =
4e9d90c7 64{
65#include "builtins.def"
66};
67#undef DEF_BUILTIN
ab7943b9 68
df94cd3b 69/* Setup an array of _DECL trees, make sure each element is
70 initialized to NULL_TREE. */
d2d4bdde 71tree built_in_decls[(int) END_BUILTINS];
0a68165a 72/* Declarations used when constructing the builtin implicitly in the compiler.
73 It may be NULL_TREE when this is invalid (for instance runtime is not
4ee9c684 74 required to implement the function call in all cases). */
0a68165a 75tree implicit_built_in_decls[(int) END_BUILTINS];
df94cd3b 76
aecda0d6 77static const char *c_getstr (tree);
78static rtx c_readstr (const char *, enum machine_mode);
79static int target_char_cast (tree, char *);
d8ae1baa 80static rtx get_memory_rtx (tree, tree);
aecda0d6 81static int apply_args_size (void);
82static int apply_result_size (void);
d8c9779c 83#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
aecda0d6 84static rtx result_vector (int, rtx);
d8c9779c 85#endif
843d08a9 86static void expand_builtin_update_setjmp_buf (rtx);
aecda0d6 87static void expand_builtin_prefetch (tree);
88static rtx expand_builtin_apply_args (void);
89static rtx expand_builtin_apply_args_1 (void);
90static rtx expand_builtin_apply (rtx, rtx, rtx);
91static void expand_builtin_return (rtx);
92static enum type_class type_to_class (tree);
93static rtx expand_builtin_classify_type (tree);
94static void expand_errno_check (tree, rtx);
95static rtx expand_builtin_mathfn (tree, rtx, rtx);
96static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
6b43bae4 97static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
a67a90e5 98static rtx expand_builtin_interclass_mathfn (tree, rtx, rtx);
c3147c1a 99static rtx expand_builtin_sincos (tree);
d735c391 100static rtx expand_builtin_cexpi (tree, rtx, rtx);
ff1b14e4 101static rtx expand_builtin_int_roundingfn (tree, rtx);
102static rtx expand_builtin_int_roundingfn_2 (tree, rtx);
aecda0d6 103static rtx expand_builtin_args_info (tree);
79012a9d 104static rtx expand_builtin_next_arg (void);
aecda0d6 105static rtx expand_builtin_va_start (tree);
106static rtx expand_builtin_va_end (tree);
107static rtx expand_builtin_va_copy (tree);
7959b13b 108static rtx expand_builtin_memchr (tree, rtx, enum machine_mode);
c2f47e15 109static rtx expand_builtin_memcmp (tree, rtx, enum machine_mode);
aecda0d6 110static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
111static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
112static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
7da1412b 113static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
aecda0d6 114static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
115static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
116static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
117static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
c2f47e15 118static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode);
119static rtx expand_builtin_mempcpy_args (tree, tree, tree, tree, rtx,
120 enum machine_mode, int);
121static rtx expand_builtin_memmove (tree, rtx, enum machine_mode, int);
122static rtx expand_builtin_memmove_args (tree, tree, tree, tree, rtx,
123 enum machine_mode, int);
124static rtx expand_builtin_bcopy (tree, int);
1d89860b 125static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
c2f47e15 126static rtx expand_builtin_strcpy_args (tree, tree, tree, rtx, enum machine_mode);
aecda0d6 127static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
aecda0d6 128static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
aecda0d6 129static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
c2f47e15 130static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
131static rtx expand_builtin_memset_args (tree, tree, tree, rtx, enum machine_mode, tree);
aecda0d6 132static rtx expand_builtin_bzero (tree);
133static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
c2f47e15 134static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
135static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
136static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
137static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
aecda0d6 138static rtx expand_builtin_alloca (tree, rtx);
139static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
140static rtx expand_builtin_frame_address (tree, tree);
19bf118a 141static rtx expand_builtin_fputs (tree, rtx, bool);
142static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
143static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
6411575e 144static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
aecda0d6 145static tree stabilize_va_list (tree, int);
146static rtx expand_builtin_expect (tree, rtx);
147static tree fold_builtin_constant_p (tree);
76f5a783 148static tree fold_builtin_expect (tree, tree);
aecda0d6 149static tree fold_builtin_classify_type (tree);
e6e27594 150static tree fold_builtin_strlen (tree);
aecda0d6 151static tree fold_builtin_inf (tree, int);
152static tree fold_builtin_nan (tree, tree, int);
c2f47e15 153static tree rewrite_call_expr (tree, int, tree, int, ...);
b7bf20db 154static bool validate_arg (const_tree, enum tree_code code);
277f8dd2 155static bool integer_valued_real_p (tree);
76b9b24b 156static tree fold_trunc_transparent_mathfn (tree, tree);
aecda0d6 157static bool readonly_data_expr (tree);
158static rtx expand_builtin_fabs (tree, rtx, rtx);
27f261ef 159static rtx expand_builtin_signbit (tree, rtx);
e6e27594 160static tree fold_builtin_sqrt (tree, tree);
161static tree fold_builtin_cbrt (tree, tree);
c2f47e15 162static tree fold_builtin_pow (tree, tree, tree, tree);
163static tree fold_builtin_powi (tree, tree, tree, tree);
e6e27594 164static tree fold_builtin_cos (tree, tree, tree);
cacdc1af 165static tree fold_builtin_cosh (tree, tree, tree);
bffb7645 166static tree fold_builtin_tan (tree, tree);
7169af54 167static tree fold_builtin_trunc (tree, tree);
168static tree fold_builtin_floor (tree, tree);
169static tree fold_builtin_ceil (tree, tree);
170static tree fold_builtin_round (tree, tree);
ad52b9b7 171static tree fold_builtin_int_roundingfn (tree, tree);
10b9666f 172static tree fold_builtin_bitop (tree, tree);
c2f47e15 173static tree fold_builtin_memory_op (tree, tree, tree, tree, bool, int);
174static tree fold_builtin_strchr (tree, tree, tree);
7959b13b 175static tree fold_builtin_memchr (tree, tree, tree, tree);
c2f47e15 176static tree fold_builtin_memcmp (tree, tree, tree);
177static tree fold_builtin_strcmp (tree, tree);
178static tree fold_builtin_strncmp (tree, tree, tree);
64c18e8d 179static tree fold_builtin_signbit (tree, tree);
c2f47e15 180static tree fold_builtin_copysign (tree, tree, tree, tree);
467214fd 181static tree fold_builtin_isascii (tree);
182static tree fold_builtin_toascii (tree);
183static tree fold_builtin_isdigit (tree);
d1aade50 184static tree fold_builtin_fabs (tree, tree);
185static tree fold_builtin_abs (tree, tree);
c2f47e15 186static tree fold_builtin_unordered_cmp (tree, tree, tree, enum tree_code,
d5019fe8 187 enum tree_code);
c2f47e15 188static tree fold_builtin_n (tree, tree *, int, bool);
189static tree fold_builtin_0 (tree, bool);
3d3d84b8 190static tree fold_builtin_1 (tree, tree, bool);
c2f47e15 191static tree fold_builtin_2 (tree, tree, tree, bool);
192static tree fold_builtin_3 (tree, tree, tree, tree, bool);
193static tree fold_builtin_4 (tree, tree, tree, tree, tree, bool);
194static tree fold_builtin_varargs (tree, tree, bool);
195
196static tree fold_builtin_strpbrk (tree, tree, tree);
197static tree fold_builtin_strstr (tree, tree, tree);
198static tree fold_builtin_strrchr (tree, tree, tree);
199static tree fold_builtin_strcat (tree, tree);
200static tree fold_builtin_strncat (tree, tree, tree);
201static tree fold_builtin_strspn (tree, tree);
202static tree fold_builtin_strcspn (tree, tree);
203static tree fold_builtin_sprintf (tree, tree, tree, int);
4ee9c684 204
0a39fd54 205static rtx expand_builtin_object_size (tree);
206static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
207 enum built_in_function);
208static void maybe_emit_chk_warning (tree, enum built_in_function);
209static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
c2f47e15 210static tree fold_builtin_object_size (tree, tree);
211static tree fold_builtin_strcat_chk (tree, tree, tree, tree);
212static tree fold_builtin_strncat_chk (tree, tree, tree, tree, tree);
0a39fd54 213static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
c2f47e15 214static tree fold_builtin_printf (tree, tree, tree, bool, enum built_in_function);
215static tree fold_builtin_fprintf (tree, tree, tree, tree, bool,
216 enum built_in_function);
99eabcc1 217static bool init_target_chars (void);
218
219static unsigned HOST_WIDE_INT target_newline;
220static unsigned HOST_WIDE_INT target_percent;
221static unsigned HOST_WIDE_INT target_c;
222static unsigned HOST_WIDE_INT target_s;
223static char target_percent_c[3];
224static char target_percent_s[3];
225static char target_percent_s_newline[4];
728bac60 226static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
227 const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool);
f0c477f2 228static tree do_mpfr_arg2 (tree, tree, tree,
229 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
9917422b 230static tree do_mpfr_arg3 (tree, tree, tree, tree,
231 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
d92f994c 232static tree do_mpfr_sincos (tree, tree, tree);
65dd1378 233#if MPFR_VERSION >= MPFR_VERSION_NUM(2,3,0)
234static tree do_mpfr_bessel_n (tree, tree, tree,
235 int (*)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
236 const REAL_VALUE_TYPE *, bool);
e5407ca6 237static tree do_mpfr_remquo (tree, tree, tree);
e84da7c1 238static tree do_mpfr_lgamma_r (tree, tree, tree);
65dd1378 239#endif
0a39fd54 240
b6a5fc45 241/* Return true if NODE should be considered for inline expansion regardless
242 of the optimization level. This means whenever a function is invoked with
243 its "internal" name, which normally contains the prefix "__builtin". */
244
245static bool called_as_built_in (tree node)
246{
247 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
248 if (strncmp (name, "__builtin_", 10) == 0)
249 return true;
250 if (strncmp (name, "__sync_", 7) == 0)
251 return true;
252 return false;
253}
4ee9c684 254
53800dbe 255/* Return the alignment in bits of EXP, a pointer valued expression.
256 But don't return more than MAX_ALIGN no matter what.
257 The alignment returned is, by default, the alignment of the thing that
27d0c333 258 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
53800dbe 259
260 Otherwise, look at the expression to see if we can do better, i.e., if the
261 expression is actually pointing at an object whose alignment is tighter. */
262
f656b751 263int
aecda0d6 264get_pointer_alignment (tree exp, unsigned int max_align)
53800dbe 265{
27d0c333 266 unsigned int align, inner;
53800dbe 267
189575ff 268 /* We rely on TER to compute accurate alignment information. */
269 if (!(optimize && flag_tree_ter))
270 return 0;
271
535e2026 272 if (!POINTER_TYPE_P (TREE_TYPE (exp)))
273 return 0;
274
53800dbe 275 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
276 align = MIN (align, max_align);
277
278 while (1)
279 {
280 switch (TREE_CODE (exp))
281 {
72dd6141 282 CASE_CONVERT:
53800dbe 283 exp = TREE_OPERAND (exp, 0);
552752f7 284 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
53800dbe 285 return align;
325d1c45 286
53800dbe 287 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
288 align = MIN (inner, max_align);
289 break;
290
0de36bdb 291 case POINTER_PLUS_EXPR:
53800dbe 292 /* If sum of pointer + int, restrict our maximum alignment to that
293 imposed by the integer. If not, we can't do any better than
294 ALIGN. */
325d1c45 295 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
53800dbe 296 return align;
297
0994d2ed 298 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
299 & (max_align / BITS_PER_UNIT - 1))
53800dbe 300 != 0)
301 max_align >>= 1;
302
303 exp = TREE_OPERAND (exp, 0);
304 break;
305
306 case ADDR_EXPR:
307 /* See what we are pointing at and look at its alignment. */
308 exp = TREE_OPERAND (exp, 0);
3c15318e 309 inner = max_align;
d2df7679 310 if (handled_component_p (exp))
1eee24cf 311 {
d2df7679 312 HOST_WIDE_INT bitsize, bitpos;
313 tree offset;
314 enum machine_mode mode;
315 int unsignedp, volatilep;
316
317 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
318 &mode, &unsignedp, &volatilep, true);
319 if (bitpos)
320 inner = MIN (inner, (unsigned) (bitpos & -bitpos));
321 if (offset && TREE_CODE (offset) == PLUS_EXPR
322 && host_integerp (TREE_OPERAND (offset, 1), 1))
323 {
324 /* Any overflow in calculating offset_bits won't change
325 the alignment. */
326 unsigned offset_bits
327 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
328 * BITS_PER_UNIT);
329
330 if (offset_bits)
331 inner = MIN (inner, (offset_bits & -offset_bits));
332 offset = TREE_OPERAND (offset, 0);
333 }
334 if (offset && TREE_CODE (offset) == MULT_EXPR
335 && host_integerp (TREE_OPERAND (offset, 1), 1))
336 {
337 /* Any overflow in calculating offset_factor won't change
338 the alignment. */
339 unsigned offset_factor
340 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
341 * BITS_PER_UNIT);
342
343 if (offset_factor)
344 inner = MIN (inner, (offset_factor & -offset_factor));
345 }
346 else if (offset)
347 inner = MIN (inner, BITS_PER_UNIT);
1eee24cf 348 }
6c96b31e 349 if (DECL_P (exp))
3c15318e 350 align = MIN (inner, DECL_ALIGN (exp));
53800dbe 351#ifdef CONSTANT_ALIGNMENT
ce45a448 352 else if (CONSTANT_CLASS_P (exp))
e068b646 353 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
53800dbe 354#endif
d2df7679 355 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
356 || TREE_CODE (exp) == INDIRECT_REF)
357 align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
3c15318e 358 else
359 align = MIN (align, inner);
360 return MIN (align, max_align);
53800dbe 361
362 default:
363 return align;
364 }
365 }
366}
367
368/* Compute the length of a C string. TREE_STRING_LENGTH is not the right
369 way, because it could contain a zero byte in the middle.
370 TREE_STRING_LENGTH is the size of the character array, not the string.
371
4172d65e 372 ONLY_VALUE should be nonzero if the result is not going to be emitted
c09841f6 373 into the instruction stream and zero if it is going to be expanded.
4172d65e 374 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
681fab1e 375 is returned, otherwise NULL, since
376 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
377 evaluate the side-effects.
378
902de8ed 379 The value returned is of type `ssizetype'.
380
53800dbe 381 Unfortunately, string_constant can't access the values of const char
382 arrays with initializers, so neither can we do so here. */
383
4ee9c684 384tree
681fab1e 385c_strlen (tree src, int only_value)
53800dbe 386{
387 tree offset_node;
27d0c333 388 HOST_WIDE_INT offset;
389 int max;
44acf429 390 const char *ptr;
53800dbe 391
681fab1e 392 STRIP_NOPS (src);
393 if (TREE_CODE (src) == COND_EXPR
394 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
395 {
396 tree len1, len2;
397
398 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
399 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
0862b7e9 400 if (tree_int_cst_equal (len1, len2))
681fab1e 401 return len1;
402 }
403
404 if (TREE_CODE (src) == COMPOUND_EXPR
405 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
406 return c_strlen (TREE_OPERAND (src, 1), only_value);
407
53800dbe 408 src = string_constant (src, &offset_node);
409 if (src == 0)
c2f47e15 410 return NULL_TREE;
902de8ed 411
83d79705 412 max = TREE_STRING_LENGTH (src) - 1;
53800dbe 413 ptr = TREE_STRING_POINTER (src);
902de8ed 414
53800dbe 415 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
416 {
417 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
418 compute the offset to the following null if we don't know where to
419 start searching for it. */
420 int i;
902de8ed 421
53800dbe 422 for (i = 0; i < max; i++)
423 if (ptr[i] == 0)
c2f47e15 424 return NULL_TREE;
902de8ed 425
53800dbe 426 /* We don't know the starting offset, but we do know that the string
427 has no internal zero bytes. We can assume that the offset falls
428 within the bounds of the string; otherwise, the programmer deserves
429 what he gets. Subtract the offset from the length of the string,
902de8ed 430 and return that. This would perhaps not be valid if we were dealing
431 with named arrays in addition to literal string constants. */
432
433 return size_diffop (size_int (max), offset_node);
53800dbe 434 }
435
436 /* We have a known offset into the string. Start searching there for
27d0c333 437 a null character if we can represent it as a single HOST_WIDE_INT. */
dabc4084 438 if (offset_node == 0)
53800dbe 439 offset = 0;
dabc4084 440 else if (! host_integerp (offset_node, 0))
441 offset = -1;
53800dbe 442 else
27d0c333 443 offset = tree_low_cst (offset_node, 0);
902de8ed 444
53800dbe 445 /* If the offset is known to be out of bounds, warn, and call strlen at
446 runtime. */
447 if (offset < 0 || offset > max)
448 {
7e3b64b4 449 /* Suppress multiple warnings for propagated constant strings. */
450 if (! TREE_NO_WARNING (src))
451 {
452 warning (0, "offset outside bounds of constant string");
453 TREE_NO_WARNING (src) = 1;
454 }
c2f47e15 455 return NULL_TREE;
53800dbe 456 }
902de8ed 457
53800dbe 458 /* Use strlen to search for the first zero byte. Since any strings
459 constructed with build_string will have nulls appended, we win even
460 if we get handed something like (char[4])"abcd".
461
462 Since OFFSET is our starting index into the string, no further
463 calculation is needed. */
902de8ed 464 return ssize_int (strlen (ptr + offset));
53800dbe 465}
466
83d79705 467/* Return a char pointer for a C string if it is a string constant
468 or sum of string constant and integer constant. */
469
470static const char *
aecda0d6 471c_getstr (tree src)
83d79705 472{
473 tree offset_node;
83d79705 474
475 src = string_constant (src, &offset_node);
476 if (src == 0)
477 return 0;
478
8c85fcb7 479 if (offset_node == 0)
480 return TREE_STRING_POINTER (src);
481 else if (!host_integerp (offset_node, 1)
482 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
83d79705 483 return 0;
83d79705 484
8c85fcb7 485 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
83d79705 486}
487
8c85fcb7 488/* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
489 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
ecc318ff 490
6840589f 491static rtx
aecda0d6 492c_readstr (const char *str, enum machine_mode mode)
6840589f 493{
494 HOST_WIDE_INT c[2];
495 HOST_WIDE_INT ch;
496 unsigned int i, j;
497
64db345d 498 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
7d3f6cc7 499
6840589f 500 c[0] = 0;
501 c[1] = 0;
502 ch = 1;
503 for (i = 0; i < GET_MODE_SIZE (mode); i++)
504 {
505 j = i;
506 if (WORDS_BIG_ENDIAN)
507 j = GET_MODE_SIZE (mode) - i - 1;
508 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
509 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
510 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
511 j *= BITS_PER_UNIT;
64db345d 512 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
7d3f6cc7 513
6840589f 514 if (ch)
515 ch = (unsigned char) str[i];
516 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
517 }
518 return immed_double_const (c[0], c[1], mode);
519}
520
ecc318ff 521/* Cast a target constant CST to target CHAR and if that value fits into
5206b159 522 host char type, return zero and put that value into variable pointed to by
ecc318ff 523 P. */
524
525static int
aecda0d6 526target_char_cast (tree cst, char *p)
ecc318ff 527{
528 unsigned HOST_WIDE_INT val, hostval;
529
27d0c333 530 if (!host_integerp (cst, 1)
ecc318ff 531 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
532 return 1;
533
27d0c333 534 val = tree_low_cst (cst, 1);
ecc318ff 535 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
536 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
537
538 hostval = val;
539 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
540 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
541
542 if (val != hostval)
543 return 1;
544
545 *p = hostval;
546 return 0;
547}
548
4ee9c684 549/* Similar to save_expr, but assumes that arbitrary code is not executed
550 in between the multiple evaluations. In particular, we assume that a
551 non-addressable local variable will not be modified. */
552
553static tree
554builtin_save_expr (tree exp)
555{
556 if (TREE_ADDRESSABLE (exp) == 0
557 && (TREE_CODE (exp) == PARM_DECL
558 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
559 return exp;
560
561 return save_expr (exp);
562}
563
53800dbe 564/* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
565 times to get the address of either a higher stack frame, or a return
566 address located within it (depending on FNDECL_CODE). */
902de8ed 567
c626df3d 568static rtx
869d0ef0 569expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
53800dbe 570{
571 int i;
572
869d0ef0 573#ifdef INITIAL_FRAME_ADDRESS_RTX
574 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
575#else
e3e15c50 576 rtx tem;
577
1b74fde7 578 /* For a zero count with __builtin_return_address, we don't care what
579 frame address we return, because target-specific definitions will
580 override us. Therefore frame pointer elimination is OK, and using
581 the soft frame pointer is OK.
582
fa7637bd 583 For a nonzero count, or a zero count with __builtin_frame_address,
1b74fde7 584 we require a stable offset from the current frame pointer to the
585 previous one, so we must use the hard frame pointer, and
e3e15c50 586 we must disable frame pointer elimination. */
1b74fde7 587 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
e3e15c50 588 tem = frame_pointer_rtx;
a0c938f0 589 else
e3e15c50 590 {
591 tem = hard_frame_pointer_rtx;
592
593 /* Tell reload not to eliminate the frame pointer. */
18d50ae6 594 crtl->accesses_prior_frames = 1;
e3e15c50 595 }
869d0ef0 596#endif
597
53800dbe 598 /* Some machines need special handling before we can access
3a69c60c 599 arbitrary frames. For example, on the SPARC, we must first flush
53800dbe 600 all register windows to the stack. */
601#ifdef SETUP_FRAME_ADDRESSES
602 if (count > 0)
603 SETUP_FRAME_ADDRESSES ();
604#endif
605
3a69c60c 606 /* On the SPARC, the return address is not in the frame, it is in a
53800dbe 607 register. There is no way to access it off of the current frame
608 pointer, but it can be accessed off the previous frame pointer by
609 reading the value from the register window save area. */
610#ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
611 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
612 count--;
613#endif
614
615 /* Scan back COUNT frames to the specified frame. */
616 for (i = 0; i < count; i++)
617 {
618 /* Assume the dynamic chain pointer is in the word that the
619 frame address points to, unless otherwise specified. */
620#ifdef DYNAMIC_CHAIN_ADDRESS
621 tem = DYNAMIC_CHAIN_ADDRESS (tem);
622#endif
623 tem = memory_address (Pmode, tem);
00060fc2 624 tem = gen_frame_mem (Pmode, tem);
83fc1478 625 tem = copy_to_reg (tem);
53800dbe 626 }
627
3a69c60c 628 /* For __builtin_frame_address, return what we've got. But, on
629 the SPARC for example, we may have to add a bias. */
53800dbe 630 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
3a69c60c 631#ifdef FRAME_ADDR_RTX
632 return FRAME_ADDR_RTX (tem);
633#else
53800dbe 634 return tem;
3a69c60c 635#endif
53800dbe 636
3a69c60c 637 /* For __builtin_return_address, get the return address from that frame. */
53800dbe 638#ifdef RETURN_ADDR_RTX
639 tem = RETURN_ADDR_RTX (count, tem);
640#else
641 tem = memory_address (Pmode,
642 plus_constant (tem, GET_MODE_SIZE (Pmode)));
00060fc2 643 tem = gen_frame_mem (Pmode, tem);
53800dbe 644#endif
645 return tem;
646}
647
f7c44134 648/* Alias set used for setjmp buffer. */
32c2fdea 649static alias_set_type setjmp_alias_set = -1;
f7c44134 650
6b7f6858 651/* Construct the leading half of a __builtin_setjmp call. Control will
2c8a1497 652 return to RECEIVER_LABEL. This is also called directly by the SJLJ
653 exception handling code. */
53800dbe 654
6b7f6858 655void
aecda0d6 656expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
53800dbe 657{
53800dbe 658 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
53800dbe 659 rtx stack_save;
f7c44134 660 rtx mem;
53800dbe 661
f7c44134 662 if (setjmp_alias_set == -1)
663 setjmp_alias_set = new_alias_set ();
664
85d654dd 665 buf_addr = convert_memory_address (Pmode, buf_addr);
53800dbe 666
37ae8504 667 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
53800dbe 668
6b7f6858 669 /* We store the frame pointer and the address of receiver_label in
670 the buffer and use the rest of it for the stack save area, which
671 is machine-dependent. */
53800dbe 672
f7c44134 673 mem = gen_rtx_MEM (Pmode, buf_addr);
ab6ab77e 674 set_mem_alias_set (mem, setjmp_alias_set);
e3e026e8 675 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
f7c44134 676
677 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
ab6ab77e 678 set_mem_alias_set (mem, setjmp_alias_set);
f7c44134 679
680 emit_move_insn (validize_mem (mem),
6b7f6858 681 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
53800dbe 682
683 stack_save = gen_rtx_MEM (sa_mode,
684 plus_constant (buf_addr,
685 2 * GET_MODE_SIZE (Pmode)));
ab6ab77e 686 set_mem_alias_set (stack_save, setjmp_alias_set);
53800dbe 687 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
688
689 /* If there is further processing to do, do it. */
690#ifdef HAVE_builtin_setjmp_setup
691 if (HAVE_builtin_setjmp_setup)
692 emit_insn (gen_builtin_setjmp_setup (buf_addr));
693#endif
694
6b7f6858 695 /* Tell optimize_save_area_alloca that extra work is going to
696 need to go on during alloca. */
18d50ae6 697 cfun->calls_setjmp = 1;
80ab81b9 698
29f09705 699 /* We have a nonlocal label. */
18d50ae6 700 cfun->has_nonlocal_label = 1;
6b7f6858 701}
53800dbe 702
2c8a1497 703/* Construct the trailing part of a __builtin_setjmp call. This is
704 also called directly by the SJLJ exception handling code. */
6b7f6858 705
706void
aecda0d6 707expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
6b7f6858 708{
53800dbe 709 /* Clobber the FP when we get here, so we have to make sure it's
710 marked as used by this function. */
18b42941 711 emit_use (hard_frame_pointer_rtx);
53800dbe 712
713 /* Mark the static chain as clobbered here so life information
714 doesn't get messed up for it. */
18b42941 715 emit_clobber (static_chain_rtx);
53800dbe 716
717 /* Now put in the code to restore the frame pointer, and argument
491e04ef 718 pointer, if needed. */
53800dbe 719#ifdef HAVE_nonlocal_goto
720 if (! HAVE_nonlocal_goto)
721#endif
5a1c3f40 722 {
723 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
724 /* This might change the hard frame pointer in ways that aren't
725 apparent to early optimization passes, so force a clobber. */
18b42941 726 emit_clobber (hard_frame_pointer_rtx);
5a1c3f40 727 }
53800dbe 728
729#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
730 if (fixed_regs[ARG_POINTER_REGNUM])
731 {
732#ifdef ELIMINABLE_REGS
733 size_t i;
e99c3a1d 734 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
53800dbe 735
3098b2d3 736 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
53800dbe 737 if (elim_regs[i].from == ARG_POINTER_REGNUM
738 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
739 break;
740
3098b2d3 741 if (i == ARRAY_SIZE (elim_regs))
53800dbe 742#endif
743 {
744 /* Now restore our arg pointer from the address at which it
05927e40 745 was saved in our stack frame. */
27a7a23a 746 emit_move_insn (crtl->args.internal_arg_pointer,
b079a207 747 copy_to_reg (get_arg_pointer_save_area ()));
53800dbe 748 }
749 }
750#endif
751
752#ifdef HAVE_builtin_setjmp_receiver
753 if (HAVE_builtin_setjmp_receiver)
6b7f6858 754 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
53800dbe 755 else
756#endif
757#ifdef HAVE_nonlocal_goto_receiver
758 if (HAVE_nonlocal_goto_receiver)
759 emit_insn (gen_nonlocal_goto_receiver ());
760 else
761#endif
6b7f6858 762 { /* Nothing */ }
57f6bb94 763
3072d30e 764 /* We must not allow the code we just generated to be reordered by
765 scheduling. Specifically, the update of the frame pointer must
766 happen immediately, not later. */
767 emit_insn (gen_blockage ());
6b7f6858 768}
53800dbe 769
53800dbe 770/* __builtin_longjmp is passed a pointer to an array of five words (not
771 all will be used on all machines). It operates similarly to the C
772 library function of the same name, but is more efficient. Much of
2c8a1497 773 the code below is copied from the handling of non-local gotos. */
53800dbe 774
c626df3d 775static void
aecda0d6 776expand_builtin_longjmp (rtx buf_addr, rtx value)
53800dbe 777{
4712c7d6 778 rtx fp, lab, stack, insn, last;
53800dbe 779 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
780
27a7a23a 781 /* DRAP is needed for stack realign if longjmp is expanded to current
782 function */
783 if (SUPPORTS_STACK_ALIGNMENT)
784 crtl->need_drap = true;
785
f7c44134 786 if (setjmp_alias_set == -1)
787 setjmp_alias_set = new_alias_set ();
788
85d654dd 789 buf_addr = convert_memory_address (Pmode, buf_addr);
479e4d5e 790
53800dbe 791 buf_addr = force_reg (Pmode, buf_addr);
792
793 /* We used to store value in static_chain_rtx, but that fails if pointers
794 are smaller than integers. We instead require that the user must pass
795 a second argument of 1, because that is what builtin_setjmp will
796 return. This also makes EH slightly more efficient, since we are no
797 longer copying around a value that we don't care about. */
64db345d 798 gcc_assert (value == const1_rtx);
53800dbe 799
4712c7d6 800 last = get_last_insn ();
53800dbe 801#ifdef HAVE_builtin_longjmp
802 if (HAVE_builtin_longjmp)
803 emit_insn (gen_builtin_longjmp (buf_addr));
804 else
805#endif
806 {
807 fp = gen_rtx_MEM (Pmode, buf_addr);
808 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
809 GET_MODE_SIZE (Pmode)));
810
811 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
812 2 * GET_MODE_SIZE (Pmode)));
ab6ab77e 813 set_mem_alias_set (fp, setjmp_alias_set);
814 set_mem_alias_set (lab, setjmp_alias_set);
815 set_mem_alias_set (stack, setjmp_alias_set);
53800dbe 816
817 /* Pick up FP, label, and SP from the block and jump. This code is
818 from expand_goto in stmt.c; see there for detailed comments. */
03fd9d2c 819#ifdef HAVE_nonlocal_goto
53800dbe 820 if (HAVE_nonlocal_goto)
821 /* We have to pass a value to the nonlocal_goto pattern that will
822 get copied into the static_chain pointer, but it does not matter
823 what that value is, because builtin_setjmp does not use it. */
28d202a8 824 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
53800dbe 825 else
826#endif
827 {
828 lab = copy_to_reg (lab);
829
18b42941 830 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
831 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
2a871ad1 832
53800dbe 833 emit_move_insn (hard_frame_pointer_rtx, fp);
834 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
835
18b42941 836 emit_use (hard_frame_pointer_rtx);
837 emit_use (stack_pointer_rtx);
53800dbe 838 emit_indirect_jump (lab);
839 }
840 }
615166bb 841
842 /* Search backwards and mark the jump insn as a non-local goto.
843 Note that this precludes the use of __builtin_longjmp to a
844 __builtin_setjmp target in the same function. However, we've
845 already cautioned the user that these functions are for
846 internal exception handling use only. */
449c0509 847 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
848 {
64db345d 849 gcc_assert (insn != last);
7d3f6cc7 850
6d7dc5b9 851 if (JUMP_P (insn))
449c0509 852 {
a1ddb869 853 add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
449c0509 854 break;
855 }
6d7dc5b9 856 else if (CALL_P (insn))
9342ee68 857 break;
449c0509 858 }
53800dbe 859}
860
4ee9c684 861/* Expand a call to __builtin_nonlocal_goto. We're passed the target label
862 and the address of the save area. */
863
864static rtx
c2f47e15 865expand_builtin_nonlocal_goto (tree exp)
4ee9c684 866{
867 tree t_label, t_save_area;
868 rtx r_label, r_save_area, r_fp, r_sp, insn;
869
c2f47e15 870 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4ee9c684 871 return NULL_RTX;
872
c2f47e15 873 t_label = CALL_EXPR_ARG (exp, 0);
874 t_save_area = CALL_EXPR_ARG (exp, 1);
4ee9c684 875
8ec3c5c2 876 r_label = expand_normal (t_label);
3dce56cc 877 r_label = convert_memory_address (Pmode, r_label);
8ec3c5c2 878 r_save_area = expand_normal (t_save_area);
3dce56cc 879 r_save_area = convert_memory_address (Pmode, r_save_area);
51adbc8a 880 /* Copy the address of the save location to a register just in case it was based
881 on the frame pointer. */
882 r_save_area = copy_to_reg (r_save_area);
4ee9c684 883 r_fp = gen_rtx_MEM (Pmode, r_save_area);
884 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
885 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
886
18d50ae6 887 crtl->has_nonlocal_goto = 1;
4ee9c684 888
03fd9d2c 889#ifdef HAVE_nonlocal_goto
4ee9c684 890 /* ??? We no longer need to pass the static chain value, afaik. */
891 if (HAVE_nonlocal_goto)
892 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
893 else
894#endif
895 {
896 r_label = copy_to_reg (r_label);
897
18b42941 898 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
899 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
491e04ef 900
4ee9c684 901 /* Restore frame pointer for containing function.
902 This sets the actual hard register used for the frame pointer
903 to the location of the function's incoming static chain info.
904 The non-local goto handler will then adjust it to contain the
905 proper value and reload the argument pointer, if needed. */
906 emit_move_insn (hard_frame_pointer_rtx, r_fp);
907 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
491e04ef 908
4ee9c684 909 /* USE of hard_frame_pointer_rtx added for consistency;
910 not clear if really needed. */
18b42941 911 emit_use (hard_frame_pointer_rtx);
912 emit_use (stack_pointer_rtx);
ad0d0af8 913
914 /* If the architecture is using a GP register, we must
915 conservatively assume that the target function makes use of it.
916 The prologue of functions with nonlocal gotos must therefore
917 initialize the GP register to the appropriate value, and we
918 must then make sure that this value is live at the point
919 of the jump. (Note that this doesn't necessarily apply
920 to targets with a nonlocal_goto pattern; they are free
921 to implement it in their own way. Note also that this is
922 a no-op if the GP register is a global invariant.) */
923 if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
924 && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
18b42941 925 emit_use (pic_offset_table_rtx);
ad0d0af8 926
4ee9c684 927 emit_indirect_jump (r_label);
928 }
491e04ef 929
4ee9c684 930 /* Search backwards to the jump insn and mark it as a
931 non-local goto. */
932 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
933 {
6d7dc5b9 934 if (JUMP_P (insn))
4ee9c684 935 {
a1ddb869 936 add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
4ee9c684 937 break;
938 }
6d7dc5b9 939 else if (CALL_P (insn))
4ee9c684 940 break;
941 }
942
943 return const0_rtx;
944}
945
843d08a9 946/* __builtin_update_setjmp_buf is passed a pointer to an array of five words
947 (not all will be used on all machines) that was passed to __builtin_setjmp.
948 It updates the stack pointer in that block to correspond to the current
949 stack pointer. */
950
951static void
952expand_builtin_update_setjmp_buf (rtx buf_addr)
953{
954 enum machine_mode sa_mode = Pmode;
955 rtx stack_save;
956
957
958#ifdef HAVE_save_stack_nonlocal
959 if (HAVE_save_stack_nonlocal)
960 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
961#endif
962#ifdef STACK_SAVEAREA_MODE
963 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
964#endif
965
966 stack_save
967 = gen_rtx_MEM (sa_mode,
968 memory_address
969 (sa_mode,
970 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
971
972#ifdef HAVE_setjmp
973 if (HAVE_setjmp)
974 emit_insn (gen_setjmp ());
975#endif
976
977 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
978}
979
5e3608d8 980/* Expand a call to __builtin_prefetch. For a target that does not support
981 data prefetch, evaluate the memory address argument in case it has side
982 effects. */
983
984static void
c2f47e15 985expand_builtin_prefetch (tree exp)
5e3608d8 986{
987 tree arg0, arg1, arg2;
c2f47e15 988 int nargs;
5e3608d8 989 rtx op0, op1, op2;
990
c2f47e15 991 if (!validate_arglist (exp, POINTER_TYPE, 0))
26a5cadb 992 return;
993
c2f47e15 994 arg0 = CALL_EXPR_ARG (exp, 0);
995
26a5cadb 996 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
997 zero (read) and argument 2 (locality) defaults to 3 (high degree of
998 locality). */
c2f47e15 999 nargs = call_expr_nargs (exp);
1000 if (nargs > 1)
1001 arg1 = CALL_EXPR_ARG (exp, 1);
26a5cadb 1002 else
c2f47e15 1003 arg1 = integer_zero_node;
1004 if (nargs > 2)
1005 arg2 = CALL_EXPR_ARG (exp, 2);
1006 else
1007 arg2 = build_int_cst (NULL_TREE, 3);
5e3608d8 1008
1009 /* Argument 0 is an address. */
1010 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
1011
1012 /* Argument 1 (read/write flag) must be a compile-time constant int. */
1013 if (TREE_CODE (arg1) != INTEGER_CST)
1014 {
07e3a3d2 1015 error ("second argument to %<__builtin_prefetch%> must be a constant");
9342ee68 1016 arg1 = integer_zero_node;
5e3608d8 1017 }
8ec3c5c2 1018 op1 = expand_normal (arg1);
5e3608d8 1019 /* Argument 1 must be either zero or one. */
1020 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
1021 {
c3ceba8e 1022 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
07e3a3d2 1023 " using zero");
5e3608d8 1024 op1 = const0_rtx;
1025 }
1026
1027 /* Argument 2 (locality) must be a compile-time constant int. */
1028 if (TREE_CODE (arg2) != INTEGER_CST)
1029 {
07e3a3d2 1030 error ("third argument to %<__builtin_prefetch%> must be a constant");
5e3608d8 1031 arg2 = integer_zero_node;
1032 }
8ec3c5c2 1033 op2 = expand_normal (arg2);
5e3608d8 1034 /* Argument 2 must be 0, 1, 2, or 3. */
1035 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1036 {
c3ceba8e 1037 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
5e3608d8 1038 op2 = const0_rtx;
1039 }
1040
1041#ifdef HAVE_prefetch
1042 if (HAVE_prefetch)
1043 {
f0ce3b1f 1044 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
4cd21437 1045 (op0,
f0ce3b1f 1046 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
19bf118a 1047 || (GET_MODE (op0) != Pmode))
9342ee68 1048 {
85d654dd 1049 op0 = convert_memory_address (Pmode, op0);
9342ee68 1050 op0 = force_reg (Pmode, op0);
1051 }
5e3608d8 1052 emit_insn (gen_prefetch (op0, op1, op2));
1053 }
5e3608d8 1054#endif
0a534ba7 1055
f0ce3b1f 1056 /* Don't do anything with direct references to volatile memory, but
1057 generate code to handle other side effects. */
e16ceb8e 1058 if (!MEM_P (op0) && side_effects_p (op0))
f0ce3b1f 1059 emit_insn (op0);
5e3608d8 1060}
1061
f7c44134 1062/* Get a MEM rtx for expression EXP which is the address of an operand
d8ae1baa 1063 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1064 the maximum length of the block of memory that might be accessed or
1065 NULL if unknown. */
f7c44134 1066
53800dbe 1067static rtx
d8ae1baa 1068get_memory_rtx (tree exp, tree len)
53800dbe 1069{
bb2327a8 1070 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1071 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
2a631e19 1072
f7c44134 1073 /* Get an expression we can use to find the attributes to assign to MEM.
1074 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1075 we can. First remove any nops. */
72dd6141 1076 while (CONVERT_EXPR_P (exp)
f7c44134 1077 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1078 exp = TREE_OPERAND (exp, 0);
1079
1080 if (TREE_CODE (exp) == ADDR_EXPR)
a1a25d19 1081 exp = TREE_OPERAND (exp, 0);
f7c44134 1082 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
a1a25d19 1083 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1084 else
1085 exp = NULL;
1086
1087 /* Honor attributes derived from exp, except for the alias set
1088 (as builtin stringops may alias with anything) and the size
1089 (as stringops may access multiple array elements). */
1090 if (exp)
eec8e941 1091 {
a1a25d19 1092 set_mem_attributes (mem, exp, 0);
d8ae1baa 1093
1094 /* Allow the string and memory builtins to overflow from one
1095 field into another, see http://gcc.gnu.org/PR23561.
1096 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1097 memory accessed by the string or memory builtin will fit
1098 within the field. */
1099 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1100 {
1101 tree mem_expr = MEM_EXPR (mem);
1102 HOST_WIDE_INT offset = -1, length = -1;
1103 tree inner = exp;
1104
1105 while (TREE_CODE (inner) == ARRAY_REF
72dd6141 1106 || CONVERT_EXPR_P (inner)
d8ae1baa 1107 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1108 || TREE_CODE (inner) == SAVE_EXPR)
1109 inner = TREE_OPERAND (inner, 0);
1110
1111 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1112
1113 if (MEM_OFFSET (mem)
1114 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1115 offset = INTVAL (MEM_OFFSET (mem));
1116
1117 if (offset >= 0 && len && host_integerp (len, 0))
1118 length = tree_low_cst (len, 0);
1119
1120 while (TREE_CODE (inner) == COMPONENT_REF)
1121 {
1122 tree field = TREE_OPERAND (inner, 1);
d8ae1baa 1123 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1124 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1125
6933ebec 1126 /* Bitfields are generally not byte-addressable. */
1127 gcc_assert (!DECL_BIT_FIELD (field)
1128 || ((tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1129 % BITS_PER_UNIT) == 0
1130 && host_integerp (DECL_SIZE (field), 0)
1131 && (TREE_INT_CST_LOW (DECL_SIZE (field))
1132 % BITS_PER_UNIT) == 0));
1133
b2f0b2a3 1134 /* If we can prove that the memory starting at XEXP (mem, 0) and
1135 ending at XEXP (mem, 0) + LENGTH will fit into this field, we
1136 can keep the COMPONENT_REF in MEM_EXPR. But be careful with
1137 fields without DECL_SIZE_UNIT like flexible array members. */
d8ae1baa 1138 if (length >= 0
b2f0b2a3 1139 && DECL_SIZE_UNIT (field)
6933ebec 1140 && host_integerp (DECL_SIZE_UNIT (field), 0))
d8ae1baa 1141 {
1142 HOST_WIDE_INT size
6933ebec 1143 = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field));
d8ae1baa 1144 if (offset <= size
1145 && length <= size
1146 && offset + length <= size)
1147 break;
1148 }
1149
1150 if (offset >= 0
1151 && host_integerp (DECL_FIELD_OFFSET (field), 0))
6933ebec 1152 offset += TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field))
d8ae1baa 1153 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1154 / BITS_PER_UNIT;
1155 else
1156 {
1157 offset = -1;
1158 length = -1;
1159 }
1160
1161 mem_expr = TREE_OPERAND (mem_expr, 0);
1162 inner = TREE_OPERAND (inner, 0);
d8ae1baa 1163 }
1164
1165 if (mem_expr == NULL)
1166 offset = -1;
1167 if (mem_expr != MEM_EXPR (mem))
1168 {
1169 set_mem_expr (mem, mem_expr);
1170 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1171 }
1172 }
eec8e941 1173 set_mem_alias_set (mem, 0);
a1a25d19 1174 set_mem_size (mem, NULL_RTX);
eec8e941 1175 }
53800dbe 1176
53800dbe 1177 return mem;
1178}
1179\f
1180/* Built-in functions to perform an untyped call and return. */
1181
1182/* For each register that may be used for calling a function, this
1183 gives a mode used to copy the register's value. VOIDmode indicates
1184 the register is not used for calling a function. If the machine
1185 has register windows, this gives only the outbound registers.
1186 INCOMING_REGNO gives the corresponding inbound register. */
1187static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1188
1189/* For each register that may be used for returning values, this gives
1190 a mode used to copy the register's value. VOIDmode indicates the
1191 register is not used for returning values. If the machine has
1192 register windows, this gives only the outbound registers.
1193 INCOMING_REGNO gives the corresponding inbound register. */
1194static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1195
1196/* For each register that may be used for calling a function, this
1197 gives the offset of that register into the block returned by
1198 __builtin_apply_args. 0 indicates that the register is not
1199 used for calling a function. */
1200static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1201
53800dbe 1202/* Return the size required for the block returned by __builtin_apply_args,
1203 and initialize apply_args_mode. */
1204
1205static int
aecda0d6 1206apply_args_size (void)
53800dbe 1207{
1208 static int size = -1;
58e9ce8f 1209 int align;
1210 unsigned int regno;
53800dbe 1211 enum machine_mode mode;
1212
1213 /* The values computed by this function never change. */
1214 if (size < 0)
1215 {
1216 /* The first value is the incoming arg-pointer. */
1217 size = GET_MODE_SIZE (Pmode);
1218
1219 /* The second value is the structure value address unless this is
1220 passed as an "invisible" first argument. */
6812c89e 1221 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
53800dbe 1222 size += GET_MODE_SIZE (Pmode);
1223
1224 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1225 if (FUNCTION_ARG_REGNO_P (regno))
1226 {
0862b7e9 1227 mode = reg_raw_mode[regno];
1228
64db345d 1229 gcc_assert (mode != VOIDmode);
53800dbe 1230
1231 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1232 if (size % align != 0)
1233 size = CEIL (size, align) * align;
1234 apply_args_reg_offset[regno] = size;
1235 size += GET_MODE_SIZE (mode);
1236 apply_args_mode[regno] = mode;
1237 }
1238 else
1239 {
1240 apply_args_mode[regno] = VOIDmode;
1241 apply_args_reg_offset[regno] = 0;
1242 }
1243 }
1244 return size;
1245}
1246
1247/* Return the size required for the block returned by __builtin_apply,
1248 and initialize apply_result_mode. */
1249
1250static int
aecda0d6 1251apply_result_size (void)
53800dbe 1252{
1253 static int size = -1;
1254 int align, regno;
1255 enum machine_mode mode;
1256
1257 /* The values computed by this function never change. */
1258 if (size < 0)
1259 {
1260 size = 0;
1261
1262 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1263 if (FUNCTION_VALUE_REGNO_P (regno))
1264 {
0862b7e9 1265 mode = reg_raw_mode[regno];
1266
64db345d 1267 gcc_assert (mode != VOIDmode);
53800dbe 1268
1269 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1270 if (size % align != 0)
1271 size = CEIL (size, align) * align;
1272 size += GET_MODE_SIZE (mode);
1273 apply_result_mode[regno] = mode;
1274 }
1275 else
1276 apply_result_mode[regno] = VOIDmode;
1277
1278 /* Allow targets that use untyped_call and untyped_return to override
1279 the size so that machine-specific information can be stored here. */
1280#ifdef APPLY_RESULT_SIZE
1281 size = APPLY_RESULT_SIZE;
1282#endif
1283 }
1284 return size;
1285}
1286
1287#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1288/* Create a vector describing the result block RESULT. If SAVEP is true,
1289 the result block is used to save the values; otherwise it is used to
1290 restore the values. */
1291
1292static rtx
aecda0d6 1293result_vector (int savep, rtx result)
53800dbe 1294{
1295 int regno, size, align, nelts;
1296 enum machine_mode mode;
1297 rtx reg, mem;
364c0c59 1298 rtx *savevec = XALLOCAVEC (rtx, FIRST_PSEUDO_REGISTER);
bf8e3599 1299
53800dbe 1300 size = nelts = 0;
1301 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1302 if ((mode = apply_result_mode[regno]) != VOIDmode)
1303 {
1304 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1305 if (size % align != 0)
1306 size = CEIL (size, align) * align;
1307 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
e513d163 1308 mem = adjust_address (result, mode, size);
53800dbe 1309 savevec[nelts++] = (savep
1310 ? gen_rtx_SET (VOIDmode, mem, reg)
1311 : gen_rtx_SET (VOIDmode, reg, mem));
1312 size += GET_MODE_SIZE (mode);
1313 }
1314 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1315}
1316#endif /* HAVE_untyped_call or HAVE_untyped_return */
1317
1318/* Save the state required to perform an untyped call with the same
1319 arguments as were passed to the current function. */
1320
1321static rtx
aecda0d6 1322expand_builtin_apply_args_1 (void)
53800dbe 1323{
1c7e61a7 1324 rtx registers, tem;
53800dbe 1325 int size, align, regno;
1326 enum machine_mode mode;
6812c89e 1327 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
53800dbe 1328
1329 /* Create a block where the arg-pointer, structure value address,
1330 and argument registers can be saved. */
1331 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1332
1333 /* Walk past the arg-pointer and structure value address. */
1334 size = GET_MODE_SIZE (Pmode);
6812c89e 1335 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
53800dbe 1336 size += GET_MODE_SIZE (Pmode);
1337
1338 /* Save each register used in calling a function to the block. */
1339 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1340 if ((mode = apply_args_mode[regno]) != VOIDmode)
1341 {
53800dbe 1342 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1343 if (size % align != 0)
1344 size = CEIL (size, align) * align;
1345
1346 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1347
e513d163 1348 emit_move_insn (adjust_address (registers, mode, size), tem);
53800dbe 1349 size += GET_MODE_SIZE (mode);
1350 }
1351
1352 /* Save the arg pointer to the block. */
27a7a23a 1353 tem = copy_to_reg (crtl->args.internal_arg_pointer);
f083a92b 1354#ifdef STACK_GROWS_DOWNWARD
1c7e61a7 1355 /* We need the pointer as the caller actually passed them to us, not
9d4b544c 1356 as we might have pretended they were passed. Make sure it's a valid
1357 operand, as emit_move_insn isn't expected to handle a PLUS. */
1358 tem
abe32cce 1359 = force_operand (plus_constant (tem, crtl->args.pretend_args_size),
9d4b544c 1360 NULL_RTX);
1c7e61a7 1361#endif
1362 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
0862b7e9 1363
53800dbe 1364 size = GET_MODE_SIZE (Pmode);
1365
1366 /* Save the structure value address unless this is passed as an
1367 "invisible" first argument. */
45550790 1368 if (struct_incoming_value)
53800dbe 1369 {
e513d163 1370 emit_move_insn (adjust_address (registers, Pmode, size),
45550790 1371 copy_to_reg (struct_incoming_value));
53800dbe 1372 size += GET_MODE_SIZE (Pmode);
1373 }
1374
1375 /* Return the address of the block. */
1376 return copy_addr_to_reg (XEXP (registers, 0));
1377}
1378
1379/* __builtin_apply_args returns block of memory allocated on
1380 the stack into which is stored the arg pointer, structure
1381 value address, static chain, and all the registers that might
1382 possibly be used in performing a function call. The code is
1383 moved to the start of the function so the incoming values are
1384 saved. */
27d0c333 1385
53800dbe 1386static rtx
aecda0d6 1387expand_builtin_apply_args (void)
53800dbe 1388{
1389 /* Don't do __builtin_apply_args more than once in a function.
1390 Save the result of the first call and reuse it. */
1391 if (apply_args_value != 0)
1392 return apply_args_value;
1393 {
1394 /* When this function is called, it means that registers must be
1395 saved on entry to this function. So we migrate the
1396 call to the first insn of this function. */
1397 rtx temp;
1398 rtx seq;
1399
1400 start_sequence ();
1401 temp = expand_builtin_apply_args_1 ();
1402 seq = get_insns ();
1403 end_sequence ();
1404
1405 apply_args_value = temp;
1406
31d3e01c 1407 /* Put the insns after the NOTE that starts the function.
1408 If this is inside a start_sequence, make the outer-level insn
53800dbe 1409 chain current, so the code is placed at the start of the
1410 function. */
1411 push_topmost_sequence ();
0ec80471 1412 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
53800dbe 1413 pop_topmost_sequence ();
1414 return temp;
1415 }
1416}
1417
1418/* Perform an untyped call and save the state required to perform an
1419 untyped return of whatever value was returned by the given function. */
1420
1421static rtx
aecda0d6 1422expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
53800dbe 1423{
1424 int size, align, regno;
1425 enum machine_mode mode;
2a631e19 1426 rtx incoming_args, result, reg, dest, src, call_insn;
53800dbe 1427 rtx old_stack_level = 0;
1428 rtx call_fusage = 0;
6812c89e 1429 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
53800dbe 1430
85d654dd 1431 arguments = convert_memory_address (Pmode, arguments);
726ec87c 1432
53800dbe 1433 /* Create a block where the return registers can be saved. */
1434 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1435
53800dbe 1436 /* Fetch the arg pointer from the ARGUMENTS block. */
1437 incoming_args = gen_reg_rtx (Pmode);
726ec87c 1438 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
53800dbe 1439#ifndef STACK_GROWS_DOWNWARD
ad99e708 1440 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1441 incoming_args, 0, OPTAB_LIB_WIDEN);
53800dbe 1442#endif
1443
04a46d40 1444 /* Push a new argument block and copy the arguments. Do not allow
1445 the (potential) memcpy call below to interfere with our stack
1446 manipulations. */
53800dbe 1447 do_pending_stack_adjust ();
04a46d40 1448 NO_DEFER_POP;
53800dbe 1449
2358393e 1450 /* Save the stack with nonlocal if available. */
53800dbe 1451#ifdef HAVE_save_stack_nonlocal
1452 if (HAVE_save_stack_nonlocal)
1453 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1454 else
1455#endif
1456 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1457
59647703 1458 /* Allocate a block of memory onto the stack and copy the memory
1459 arguments to the outgoing arguments address. */
1460 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
27a7a23a 1461
1462 /* Set DRAP flag to true, even though allocate_dynamic_stack_space
1463 may have already set current_function_calls_alloca to true.
1464 current_function_calls_alloca won't be set if argsize is zero,
1465 so we have to guarantee need_drap is true here. */
1466 if (SUPPORTS_STACK_ALIGNMENT)
1467 crtl->need_drap = true;
1468
59647703 1469 dest = virtual_outgoing_args_rtx;
1470#ifndef STACK_GROWS_DOWNWARD
1471 if (GET_CODE (argsize) == CONST_INT)
1472 dest = plus_constant (dest, -INTVAL (argsize));
1473 else
1474 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1475#endif
2a631e19 1476 dest = gen_rtx_MEM (BLKmode, dest);
1477 set_mem_align (dest, PARM_BOUNDARY);
1478 src = gen_rtx_MEM (BLKmode, incoming_args);
1479 set_mem_align (src, PARM_BOUNDARY);
0378dbdc 1480 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
53800dbe 1481
1482 /* Refer to the argument block. */
1483 apply_args_size ();
1484 arguments = gen_rtx_MEM (BLKmode, arguments);
2a631e19 1485 set_mem_align (arguments, PARM_BOUNDARY);
53800dbe 1486
1487 /* Walk past the arg-pointer and structure value address. */
1488 size = GET_MODE_SIZE (Pmode);
45550790 1489 if (struct_value)
53800dbe 1490 size += GET_MODE_SIZE (Pmode);
1491
1492 /* Restore each of the registers previously saved. Make USE insns
1493 for each of these registers for use in making the call. */
1494 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1495 if ((mode = apply_args_mode[regno]) != VOIDmode)
1496 {
1497 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1498 if (size % align != 0)
1499 size = CEIL (size, align) * align;
1500 reg = gen_rtx_REG (mode, regno);
e513d163 1501 emit_move_insn (reg, adjust_address (arguments, mode, size));
53800dbe 1502 use_reg (&call_fusage, reg);
1503 size += GET_MODE_SIZE (mode);
1504 }
1505
1506 /* Restore the structure value address unless this is passed as an
1507 "invisible" first argument. */
1508 size = GET_MODE_SIZE (Pmode);
45550790 1509 if (struct_value)
53800dbe 1510 {
1511 rtx value = gen_reg_rtx (Pmode);
e513d163 1512 emit_move_insn (value, adjust_address (arguments, Pmode, size));
45550790 1513 emit_move_insn (struct_value, value);
8ad4c111 1514 if (REG_P (struct_value))
45550790 1515 use_reg (&call_fusage, struct_value);
53800dbe 1516 size += GET_MODE_SIZE (Pmode);
1517 }
1518
1519 /* All arguments and registers used for the call are set up by now! */
4ee9c684 1520 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
53800dbe 1521
1522 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1523 and we don't want to load it into a register as an optimization,
1524 because prepare_call_address already did it if it should be done. */
1525 if (GET_CODE (function) != SYMBOL_REF)
1526 function = memory_address (FUNCTION_MODE, function);
1527
1528 /* Generate the actual call instruction and save the return value. */
1529#ifdef HAVE_untyped_call
1530 if (HAVE_untyped_call)
1531 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1532 result, result_vector (1, result)));
1533 else
1534#endif
1535#ifdef HAVE_call_value
1536 if (HAVE_call_value)
1537 {
1538 rtx valreg = 0;
1539
1540 /* Locate the unique return register. It is not possible to
1541 express a call that sets more than one return register using
1542 call_value; use untyped_call for that. In fact, untyped_call
1543 only needs to save the return registers in the given block. */
1544 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1545 if ((mode = apply_result_mode[regno]) != VOIDmode)
1546 {
64db345d 1547 gcc_assert (!valreg); /* HAVE_untyped_call required. */
7d3f6cc7 1548
53800dbe 1549 valreg = gen_rtx_REG (mode, regno);
1550 }
1551
2ed6c343 1552 emit_call_insn (GEN_CALL_VALUE (valreg,
53800dbe 1553 gen_rtx_MEM (FUNCTION_MODE, function),
1554 const0_rtx, NULL_RTX, const0_rtx));
1555
e513d163 1556 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
53800dbe 1557 }
1558 else
1559#endif
64db345d 1560 gcc_unreachable ();
53800dbe 1561
d5f9786f 1562 /* Find the CALL insn we just emitted, and attach the register usage
1563 information. */
1564 call_insn = last_call_insn ();
1565 add_function_usage_to (call_insn, call_fusage);
53800dbe 1566
1567 /* Restore the stack. */
1568#ifdef HAVE_save_stack_nonlocal
1569 if (HAVE_save_stack_nonlocal)
1570 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1571 else
1572#endif
1573 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1574
04a46d40 1575 OK_DEFER_POP;
1576
53800dbe 1577 /* Return the address of the result block. */
85d654dd 1578 result = copy_addr_to_reg (XEXP (result, 0));
1579 return convert_memory_address (ptr_mode, result);
53800dbe 1580}
1581
1582/* Perform an untyped return. */
1583
1584static void
aecda0d6 1585expand_builtin_return (rtx result)
53800dbe 1586{
1587 int size, align, regno;
1588 enum machine_mode mode;
1589 rtx reg;
1590 rtx call_fusage = 0;
1591
85d654dd 1592 result = convert_memory_address (Pmode, result);
726ec87c 1593
53800dbe 1594 apply_result_size ();
1595 result = gen_rtx_MEM (BLKmode, result);
1596
1597#ifdef HAVE_untyped_return
1598 if (HAVE_untyped_return)
1599 {
1600 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1601 emit_barrier ();
1602 return;
1603 }
1604#endif
1605
1606 /* Restore the return value and note that each value is used. */
1607 size = 0;
1608 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1609 if ((mode = apply_result_mode[regno]) != VOIDmode)
1610 {
1611 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1612 if (size % align != 0)
1613 size = CEIL (size, align) * align;
1614 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
e513d163 1615 emit_move_insn (reg, adjust_address (result, mode, size));
53800dbe 1616
1617 push_to_sequence (call_fusage);
18b42941 1618 emit_use (reg);
53800dbe 1619 call_fusage = get_insns ();
1620 end_sequence ();
1621 size += GET_MODE_SIZE (mode);
1622 }
1623
1624 /* Put the USE insns before the return. */
31d3e01c 1625 emit_insn (call_fusage);
53800dbe 1626
1627 /* Return whatever values was restored by jumping directly to the end
1628 of the function. */
62380d2d 1629 expand_naked_return ();
53800dbe 1630}
1631
539a3a92 1632/* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
27d0c333 1633
539a3a92 1634static enum type_class
aecda0d6 1635type_to_class (tree type)
539a3a92 1636{
1637 switch (TREE_CODE (type))
1638 {
1639 case VOID_TYPE: return void_type_class;
1640 case INTEGER_TYPE: return integer_type_class;
539a3a92 1641 case ENUMERAL_TYPE: return enumeral_type_class;
1642 case BOOLEAN_TYPE: return boolean_type_class;
1643 case POINTER_TYPE: return pointer_type_class;
1644 case REFERENCE_TYPE: return reference_type_class;
1645 case OFFSET_TYPE: return offset_type_class;
1646 case REAL_TYPE: return real_type_class;
1647 case COMPLEX_TYPE: return complex_type_class;
1648 case FUNCTION_TYPE: return function_type_class;
1649 case METHOD_TYPE: return method_type_class;
1650 case RECORD_TYPE: return record_type_class;
1651 case UNION_TYPE:
1652 case QUAL_UNION_TYPE: return union_type_class;
1653 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1654 ? string_type_class : array_type_class);
539a3a92 1655 case LANG_TYPE: return lang_type_class;
1656 default: return no_type_class;
1657 }
1658}
bf8e3599 1659
c2f47e15 1660/* Expand a call EXP to __builtin_classify_type. */
27d0c333 1661
53800dbe 1662static rtx
c2f47e15 1663expand_builtin_classify_type (tree exp)
53800dbe 1664{
c2f47e15 1665 if (call_expr_nargs (exp))
1666 return GEN_INT (type_to_class (TREE_TYPE (CALL_EXPR_ARG (exp, 0))));
53800dbe 1667 return GEN_INT (no_type_class);
1668}
1669
07976da7 1670/* This helper macro, meant to be used in mathfn_built_in below,
1671 determines which among a set of three builtin math functions is
1672 appropriate for a given type mode. The `F' and `L' cases are
1673 automatically generated from the `double' case. */
1674#define CASE_MATHFN(BUILT_IN_MATHFN) \
1675 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1676 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1677 fcodel = BUILT_IN_MATHFN##L ; break;
cd2656b0 1678/* Similar to above, but appends _R after any F/L suffix. */
1679#define CASE_MATHFN_REENT(BUILT_IN_MATHFN) \
1680 case BUILT_IN_MATHFN##_R: case BUILT_IN_MATHFN##F_R: case BUILT_IN_MATHFN##L_R: \
1681 fcode = BUILT_IN_MATHFN##_R; fcodef = BUILT_IN_MATHFN##F_R ; \
1682 fcodel = BUILT_IN_MATHFN##L_R ; break;
07976da7 1683
1684/* Return mathematic function equivalent to FN but operating directly
c319d56a 1685 on TYPE, if available. If IMPLICIT is true find the function in
1686 implicit_built_in_decls[], otherwise use built_in_decls[]. If we
1687 can't do the conversion, return zero. */
1688
1689static tree
1690mathfn_built_in_1 (tree type, enum built_in_function fn, bool implicit)
0a68165a 1691{
c319d56a 1692 tree const *const fn_arr
1693 = implicit ? implicit_built_in_decls : built_in_decls;
07976da7 1694 enum built_in_function fcode, fcodef, fcodel;
1695
1696 switch (fn)
1697 {
746114e8 1698 CASE_MATHFN (BUILT_IN_ACOS)
1699 CASE_MATHFN (BUILT_IN_ACOSH)
1700 CASE_MATHFN (BUILT_IN_ASIN)
1701 CASE_MATHFN (BUILT_IN_ASINH)
07976da7 1702 CASE_MATHFN (BUILT_IN_ATAN)
746114e8 1703 CASE_MATHFN (BUILT_IN_ATAN2)
1704 CASE_MATHFN (BUILT_IN_ATANH)
1705 CASE_MATHFN (BUILT_IN_CBRT)
07976da7 1706 CASE_MATHFN (BUILT_IN_CEIL)
d735c391 1707 CASE_MATHFN (BUILT_IN_CEXPI)
746114e8 1708 CASE_MATHFN (BUILT_IN_COPYSIGN)
07976da7 1709 CASE_MATHFN (BUILT_IN_COS)
746114e8 1710 CASE_MATHFN (BUILT_IN_COSH)
1711 CASE_MATHFN (BUILT_IN_DREM)
1712 CASE_MATHFN (BUILT_IN_ERF)
1713 CASE_MATHFN (BUILT_IN_ERFC)
07976da7 1714 CASE_MATHFN (BUILT_IN_EXP)
746114e8 1715 CASE_MATHFN (BUILT_IN_EXP10)
1716 CASE_MATHFN (BUILT_IN_EXP2)
1717 CASE_MATHFN (BUILT_IN_EXPM1)
1718 CASE_MATHFN (BUILT_IN_FABS)
1719 CASE_MATHFN (BUILT_IN_FDIM)
07976da7 1720 CASE_MATHFN (BUILT_IN_FLOOR)
746114e8 1721 CASE_MATHFN (BUILT_IN_FMA)
1722 CASE_MATHFN (BUILT_IN_FMAX)
1723 CASE_MATHFN (BUILT_IN_FMIN)
1724 CASE_MATHFN (BUILT_IN_FMOD)
1725 CASE_MATHFN (BUILT_IN_FREXP)
1726 CASE_MATHFN (BUILT_IN_GAMMA)
cd2656b0 1727 CASE_MATHFN_REENT (BUILT_IN_GAMMA) /* GAMMA_R */
746114e8 1728 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1729 CASE_MATHFN (BUILT_IN_HYPOT)
1730 CASE_MATHFN (BUILT_IN_ILOGB)
1731 CASE_MATHFN (BUILT_IN_INF)
69b779ea 1732 CASE_MATHFN (BUILT_IN_ISINF)
746114e8 1733 CASE_MATHFN (BUILT_IN_J0)
1734 CASE_MATHFN (BUILT_IN_J1)
1735 CASE_MATHFN (BUILT_IN_JN)
ac148751 1736 CASE_MATHFN (BUILT_IN_LCEIL)
746114e8 1737 CASE_MATHFN (BUILT_IN_LDEXP)
ad52b9b7 1738 CASE_MATHFN (BUILT_IN_LFLOOR)
746114e8 1739 CASE_MATHFN (BUILT_IN_LGAMMA)
cd2656b0 1740 CASE_MATHFN_REENT (BUILT_IN_LGAMMA) /* LGAMMA_R */
ac148751 1741 CASE_MATHFN (BUILT_IN_LLCEIL)
ad52b9b7 1742 CASE_MATHFN (BUILT_IN_LLFLOOR)
746114e8 1743 CASE_MATHFN (BUILT_IN_LLRINT)
1744 CASE_MATHFN (BUILT_IN_LLROUND)
07976da7 1745 CASE_MATHFN (BUILT_IN_LOG)
746114e8 1746 CASE_MATHFN (BUILT_IN_LOG10)
1747 CASE_MATHFN (BUILT_IN_LOG1P)
1748 CASE_MATHFN (BUILT_IN_LOG2)
1749 CASE_MATHFN (BUILT_IN_LOGB)
1750 CASE_MATHFN (BUILT_IN_LRINT)
1751 CASE_MATHFN (BUILT_IN_LROUND)
1752 CASE_MATHFN (BUILT_IN_MODF)
1753 CASE_MATHFN (BUILT_IN_NAN)
1754 CASE_MATHFN (BUILT_IN_NANS)
07976da7 1755 CASE_MATHFN (BUILT_IN_NEARBYINT)
746114e8 1756 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1757 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1758 CASE_MATHFN (BUILT_IN_POW)
757c219d 1759 CASE_MATHFN (BUILT_IN_POWI)
746114e8 1760 CASE_MATHFN (BUILT_IN_POW10)
1761 CASE_MATHFN (BUILT_IN_REMAINDER)
1762 CASE_MATHFN (BUILT_IN_REMQUO)
1763 CASE_MATHFN (BUILT_IN_RINT)
07976da7 1764 CASE_MATHFN (BUILT_IN_ROUND)
746114e8 1765 CASE_MATHFN (BUILT_IN_SCALB)
1766 CASE_MATHFN (BUILT_IN_SCALBLN)
1767 CASE_MATHFN (BUILT_IN_SCALBN)
c319d56a 1768 CASE_MATHFN (BUILT_IN_SIGNBIT)
746114e8 1769 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
07976da7 1770 CASE_MATHFN (BUILT_IN_SIN)
746114e8 1771 CASE_MATHFN (BUILT_IN_SINCOS)
1772 CASE_MATHFN (BUILT_IN_SINH)
07976da7 1773 CASE_MATHFN (BUILT_IN_SQRT)
1774 CASE_MATHFN (BUILT_IN_TAN)
746114e8 1775 CASE_MATHFN (BUILT_IN_TANH)
1776 CASE_MATHFN (BUILT_IN_TGAMMA)
07976da7 1777 CASE_MATHFN (BUILT_IN_TRUNC)
746114e8 1778 CASE_MATHFN (BUILT_IN_Y0)
1779 CASE_MATHFN (BUILT_IN_Y1)
1780 CASE_MATHFN (BUILT_IN_YN)
07976da7 1781
0a68165a 1782 default:
c2f47e15 1783 return NULL_TREE;
0a68165a 1784 }
07976da7 1785
96b9f485 1786 if (TYPE_MAIN_VARIANT (type) == double_type_node)
c319d56a 1787 return fn_arr[fcode];
96b9f485 1788 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
c319d56a 1789 return fn_arr[fcodef];
96b9f485 1790 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
c319d56a 1791 return fn_arr[fcodel];
07976da7 1792 else
c2f47e15 1793 return NULL_TREE;
0a68165a 1794}
1795
c319d56a 1796/* Like mathfn_built_in_1(), but always use the implicit array. */
1797
1798tree
1799mathfn_built_in (tree type, enum built_in_function fn)
1800{
1801 return mathfn_built_in_1 (type, fn, /*implicit=*/ 1);
1802}
1803
0fd605a5 1804/* If errno must be maintained, expand the RTL to check if the result,
1805 TARGET, of a built-in function call, EXP, is NaN, and if so set
1806 errno to EDOM. */
1807
1808static void
aecda0d6 1809expand_errno_check (tree exp, rtx target)
0fd605a5 1810{
7f05340e 1811 rtx lab = gen_label_rtx ();
0fd605a5 1812
7f05340e 1813 /* Test the result; if it is NaN, set errno=EDOM because
1814 the argument was not in the domain. */
1815 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1816 0, lab);
0fd605a5 1817
1818#ifdef TARGET_EDOM
7f05340e 1819 /* If this built-in doesn't throw an exception, set errno directly. */
c2f47e15 1820 if (TREE_NOTHROW (TREE_OPERAND (CALL_EXPR_FN (exp), 0)))
7f05340e 1821 {
0fd605a5 1822#ifdef GEN_ERRNO_RTX
7f05340e 1823 rtx errno_rtx = GEN_ERRNO_RTX;
0fd605a5 1824#else
7f05340e 1825 rtx errno_rtx
0fd605a5 1826 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1827#endif
7f05340e 1828 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
0fd605a5 1829 emit_label (lab);
7f05340e 1830 return;
0fd605a5 1831 }
7f05340e 1832#endif
1833
08491912 1834 /* Make sure the library call isn't expanded as a tail call. */
1835 CALL_EXPR_TAILCALL (exp) = 0;
1836
7f05340e 1837 /* We can't set errno=EDOM directly; let the library call do it.
1838 Pop the arguments right away in case the call gets deleted. */
1839 NO_DEFER_POP;
1840 expand_call (exp, target, 0);
1841 OK_DEFER_POP;
1842 emit_label (lab);
0fd605a5 1843}
1844
6b43bae4 1845/* Expand a call to one of the builtin math functions (sqrt, exp, or log).
c2f47e15 1846 Return NULL_RTX if a normal call should be emitted rather than expanding
1847 the function in-line. EXP is the expression that is a call to the builtin
53800dbe 1848 function; if convenient, the result should be placed in TARGET.
1849 SUBTARGET may be used as the target for computing one of EXP's operands. */
27d0c333 1850
53800dbe 1851static rtx
aecda0d6 1852expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
53800dbe 1853{
bf8e3599 1854 optab builtin_optab;
bd421108 1855 rtx op0, insns, before_call;
c6e6ecb1 1856 tree fndecl = get_callee_fndecl (exp);
7f05340e 1857 enum machine_mode mode;
528ee710 1858 bool errno_set = false;
abfea505 1859 tree arg;
53800dbe 1860
c2f47e15 1861 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
1862 return NULL_RTX;
53800dbe 1863
c2f47e15 1864 arg = CALL_EXPR_ARG (exp, 0);
53800dbe 1865
1866 switch (DECL_FUNCTION_CODE (fndecl))
1867 {
4f35b1fc 1868 CASE_FLT_FN (BUILT_IN_SQRT):
7f05340e 1869 errno_set = ! tree_expr_nonnegative_p (arg);
1870 builtin_optab = sqrt_optab;
1871 break;
4f35b1fc 1872 CASE_FLT_FN (BUILT_IN_EXP):
528ee710 1873 errno_set = true; builtin_optab = exp_optab; break;
4f35b1fc 1874 CASE_FLT_FN (BUILT_IN_EXP10):
1875 CASE_FLT_FN (BUILT_IN_POW10):
750ef9f5 1876 errno_set = true; builtin_optab = exp10_optab; break;
4f35b1fc 1877 CASE_FLT_FN (BUILT_IN_EXP2):
750ef9f5 1878 errno_set = true; builtin_optab = exp2_optab; break;
4f35b1fc 1879 CASE_FLT_FN (BUILT_IN_EXPM1):
a6b4eed2 1880 errno_set = true; builtin_optab = expm1_optab; break;
4f35b1fc 1881 CASE_FLT_FN (BUILT_IN_LOGB):
4efbc641 1882 errno_set = true; builtin_optab = logb_optab; break;
4f35b1fc 1883 CASE_FLT_FN (BUILT_IN_LOG):
528ee710 1884 errno_set = true; builtin_optab = log_optab; break;
4f35b1fc 1885 CASE_FLT_FN (BUILT_IN_LOG10):
d3cd9bde 1886 errno_set = true; builtin_optab = log10_optab; break;
4f35b1fc 1887 CASE_FLT_FN (BUILT_IN_LOG2):
d3cd9bde 1888 errno_set = true; builtin_optab = log2_optab; break;
4f35b1fc 1889 CASE_FLT_FN (BUILT_IN_LOG1P):
f474cd93 1890 errno_set = true; builtin_optab = log1p_optab; break;
4f35b1fc 1891 CASE_FLT_FN (BUILT_IN_ASIN):
8de2f465 1892 builtin_optab = asin_optab; break;
4f35b1fc 1893 CASE_FLT_FN (BUILT_IN_ACOS):
8de2f465 1894 builtin_optab = acos_optab; break;
4f35b1fc 1895 CASE_FLT_FN (BUILT_IN_TAN):
528ee710 1896 builtin_optab = tan_optab; break;
4f35b1fc 1897 CASE_FLT_FN (BUILT_IN_ATAN):
528ee710 1898 builtin_optab = atan_optab; break;
4f35b1fc 1899 CASE_FLT_FN (BUILT_IN_FLOOR):
528ee710 1900 builtin_optab = floor_optab; break;
4f35b1fc 1901 CASE_FLT_FN (BUILT_IN_CEIL):
528ee710 1902 builtin_optab = ceil_optab; break;
4f35b1fc 1903 CASE_FLT_FN (BUILT_IN_TRUNC):
a7cc195f 1904 builtin_optab = btrunc_optab; break;
4f35b1fc 1905 CASE_FLT_FN (BUILT_IN_ROUND):
528ee710 1906 builtin_optab = round_optab; break;
4f35b1fc 1907 CASE_FLT_FN (BUILT_IN_NEARBYINT):
0ddf4ad9 1908 builtin_optab = nearbyint_optab;
1909 if (flag_trapping_math)
1910 break;
1911 /* Else fallthrough and expand as rint. */
4f35b1fc 1912 CASE_FLT_FN (BUILT_IN_RINT):
aef94a0f 1913 builtin_optab = rint_optab; break;
42721db0 1914 default:
64db345d 1915 gcc_unreachable ();
53800dbe 1916 }
1917
7f05340e 1918 /* Make a suitable register to place result in. */
1919 mode = TYPE_MODE (TREE_TYPE (exp));
fc4eef90 1920
7f05340e 1921 if (! flag_errno_math || ! HONOR_NANS (mode))
1922 errno_set = false;
1923
bd421108 1924 /* Before working hard, check whether the instruction is available. */
99bdde56 1925 if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing)
68e6cb9d 1926 {
bd421108 1927 target = gen_reg_rtx (mode);
7f05340e 1928
bd421108 1929 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1930 need to expand the argument again. This way, we will not perform
1931 side-effects more the once. */
abfea505 1932 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
7f05340e 1933
1db6d067 1934 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
7f05340e 1935
bd421108 1936 start_sequence ();
53800dbe 1937
bd421108 1938 /* Compute into TARGET.
1939 Set TARGET to wherever the result comes back. */
1940 target = expand_unop (mode, builtin_optab, op0, target, 0);
1941
1942 if (target != 0)
1943 {
1944 if (errno_set)
1945 expand_errno_check (exp, target);
1946
1947 /* Output the entire sequence. */
1948 insns = get_insns ();
1949 end_sequence ();
1950 emit_insn (insns);
1951 return target;
1952 }
1953
1954 /* If we were unable to expand via the builtin, stop the sequence
1955 (without outputting the insns) and call to the library function
1956 with the stabilized argument list. */
53800dbe 1957 end_sequence ();
53800dbe 1958 }
1959
bd421108 1960 before_call = get_last_insn ();
1961
1e5b92fa 1962 return expand_call (exp, target, target == const0_rtx);
0fd605a5 1963}
1964
1965/* Expand a call to the builtin binary math functions (pow and atan2).
c2f47e15 1966 Return NULL_RTX if a normal call should be emitted rather than expanding the
0fd605a5 1967 function in-line. EXP is the expression that is a call to the builtin
1968 function; if convenient, the result should be placed in TARGET.
1969 SUBTARGET may be used as the target for computing one of EXP's
1970 operands. */
1971
1972static rtx
aecda0d6 1973expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
0fd605a5 1974{
1975 optab builtin_optab;
1976 rtx op0, op1, insns;
4737caf2 1977 int op1_type = REAL_TYPE;
c6e6ecb1 1978 tree fndecl = get_callee_fndecl (exp);
abfea505 1979 tree arg0, arg1;
7f05340e 1980 enum machine_mode mode;
0fd605a5 1981 bool errno_set = true;
0fd605a5 1982
73a954a1 1983 switch (DECL_FUNCTION_CODE (fndecl))
1984 {
1985 CASE_FLT_FN (BUILT_IN_SCALBN):
1986 CASE_FLT_FN (BUILT_IN_SCALBLN):
1987 CASE_FLT_FN (BUILT_IN_LDEXP):
1988 op1_type = INTEGER_TYPE;
1989 default:
1990 break;
1991 }
4737caf2 1992
c2f47e15 1993 if (!validate_arglist (exp, REAL_TYPE, op1_type, VOID_TYPE))
1994 return NULL_RTX;
0fd605a5 1995
c2f47e15 1996 arg0 = CALL_EXPR_ARG (exp, 0);
1997 arg1 = CALL_EXPR_ARG (exp, 1);
0fd605a5 1998
0fd605a5 1999 switch (DECL_FUNCTION_CODE (fndecl))
2000 {
4f35b1fc 2001 CASE_FLT_FN (BUILT_IN_POW):
0fd605a5 2002 builtin_optab = pow_optab; break;
4f35b1fc 2003 CASE_FLT_FN (BUILT_IN_ATAN2):
0fd605a5 2004 builtin_optab = atan2_optab; break;
73a954a1 2005 CASE_FLT_FN (BUILT_IN_SCALB):
2006 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2007 return 0;
2008 builtin_optab = scalb_optab; break;
2009 CASE_FLT_FN (BUILT_IN_SCALBN):
2010 CASE_FLT_FN (BUILT_IN_SCALBLN):
2011 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2012 return 0;
2013 /* Fall through... */
4f35b1fc 2014 CASE_FLT_FN (BUILT_IN_LDEXP):
4737caf2 2015 builtin_optab = ldexp_optab; break;
4f35b1fc 2016 CASE_FLT_FN (BUILT_IN_FMOD):
80ed5c06 2017 builtin_optab = fmod_optab; break;
ef722005 2018 CASE_FLT_FN (BUILT_IN_REMAINDER):
4f35b1fc 2019 CASE_FLT_FN (BUILT_IN_DREM):
ef722005 2020 builtin_optab = remainder_optab; break;
0fd605a5 2021 default:
64db345d 2022 gcc_unreachable ();
0fd605a5 2023 }
2024
7f05340e 2025 /* Make a suitable register to place result in. */
2026 mode = TYPE_MODE (TREE_TYPE (exp));
fc4eef90 2027
2028 /* Before working hard, check whether the instruction is available. */
99bdde56 2029 if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing)
c2f47e15 2030 return NULL_RTX;
fc4eef90 2031
7f05340e 2032 target = gen_reg_rtx (mode);
2033
2034 if (! flag_errno_math || ! HONOR_NANS (mode))
2035 errno_set = false;
2036
4ee9c684 2037 /* Always stabilize the argument list. */
abfea505 2038 CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
2039 CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1);
7f05340e 2040
8ec3c5c2 2041 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2042 op1 = expand_normal (arg1);
7f05340e 2043
7f05340e 2044 start_sequence ();
2045
0fd605a5 2046 /* Compute into TARGET.
2047 Set TARGET to wherever the result comes back. */
7f05340e 2048 target = expand_binop (mode, builtin_optab, op0, op1,
0fd605a5 2049 target, 0, OPTAB_DIRECT);
53800dbe 2050
68e6cb9d 2051 /* If we were unable to expand via the builtin, stop the sequence
2052 (without outputting the insns) and call to the library function
2053 with the stabilized argument list. */
0fd605a5 2054 if (target == 0)
2055 {
2056 end_sequence ();
68e6cb9d 2057 return expand_call (exp, target, target == const0_rtx);
53800dbe 2058 }
2059
a4356fb9 2060 if (errno_set)
2061 expand_errno_check (exp, target);
0fd605a5 2062
53800dbe 2063 /* Output the entire sequence. */
2064 insns = get_insns ();
2065 end_sequence ();
31d3e01c 2066 emit_insn (insns);
bf8e3599 2067
53800dbe 2068 return target;
2069}
2070
6b43bae4 2071/* Expand a call to the builtin sin and cos math functions.
c2f47e15 2072 Return NULL_RTX if a normal call should be emitted rather than expanding the
6b43bae4 2073 function in-line. EXP is the expression that is a call to the builtin
2074 function; if convenient, the result should be placed in TARGET.
2075 SUBTARGET may be used as the target for computing one of EXP's
2076 operands. */
2077
2078static rtx
2079expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2080{
2081 optab builtin_optab;
7511b819 2082 rtx op0, insns;
6b43bae4 2083 tree fndecl = get_callee_fndecl (exp);
6b43bae4 2084 enum machine_mode mode;
abfea505 2085 tree arg;
6b43bae4 2086
c2f47e15 2087 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2088 return NULL_RTX;
6b43bae4 2089
c2f47e15 2090 arg = CALL_EXPR_ARG (exp, 0);
6b43bae4 2091
2092 switch (DECL_FUNCTION_CODE (fndecl))
2093 {
4f35b1fc 2094 CASE_FLT_FN (BUILT_IN_SIN):
2095 CASE_FLT_FN (BUILT_IN_COS):
6b43bae4 2096 builtin_optab = sincos_optab; break;
2097 default:
64db345d 2098 gcc_unreachable ();
6b43bae4 2099 }
2100
2101 /* Make a suitable register to place result in. */
2102 mode = TYPE_MODE (TREE_TYPE (exp));
2103
6b43bae4 2104 /* Check if sincos insn is available, otherwise fallback
0bed3869 2105 to sin or cos insn. */
99bdde56 2106 if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing)
6b43bae4 2107 switch (DECL_FUNCTION_CODE (fndecl))
2108 {
4f35b1fc 2109 CASE_FLT_FN (BUILT_IN_SIN):
6b43bae4 2110 builtin_optab = sin_optab; break;
4f35b1fc 2111 CASE_FLT_FN (BUILT_IN_COS):
6b43bae4 2112 builtin_optab = cos_optab; break;
2113 default:
64db345d 2114 gcc_unreachable ();
6b43bae4 2115 }
6b43bae4 2116
2117 /* Before working hard, check whether the instruction is available. */
99bdde56 2118 if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing)
6b43bae4 2119 {
2120 target = gen_reg_rtx (mode);
2121
2122 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2123 need to expand the argument again. This way, we will not perform
2124 side-effects more the once. */
abfea505 2125 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
6b43bae4 2126
1db6d067 2127 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
6b43bae4 2128
6b43bae4 2129 start_sequence ();
2130
2131 /* Compute into TARGET.
2132 Set TARGET to wherever the result comes back. */
2133 if (builtin_optab == sincos_optab)
2134 {
64db345d 2135 int result;
7d3f6cc7 2136
6b43bae4 2137 switch (DECL_FUNCTION_CODE (fndecl))
2138 {
4f35b1fc 2139 CASE_FLT_FN (BUILT_IN_SIN):
64db345d 2140 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
6b43bae4 2141 break;
4f35b1fc 2142 CASE_FLT_FN (BUILT_IN_COS):
64db345d 2143 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
6b43bae4 2144 break;
2145 default:
64db345d 2146 gcc_unreachable ();
6b43bae4 2147 }
64db345d 2148 gcc_assert (result);
6b43bae4 2149 }
2150 else
2151 {
2152 target = expand_unop (mode, builtin_optab, op0, target, 0);
2153 }
2154
2155 if (target != 0)
2156 {
6b43bae4 2157 /* Output the entire sequence. */
2158 insns = get_insns ();
2159 end_sequence ();
2160 emit_insn (insns);
2161 return target;
2162 }
2163
2164 /* If we were unable to expand via the builtin, stop the sequence
2165 (without outputting the insns) and call to the library function
2166 with the stabilized argument list. */
2167 end_sequence ();
2168 }
2169
6b43bae4 2170 target = expand_call (exp, target, target == const0_rtx);
2171
2172 return target;
2173}
2174
a67a90e5 2175/* Expand a call to one of the builtin math functions that operate on
2176 floating point argument and output an integer result (ilogb, isinf,
2177 isnan, etc).
2178 Return 0 if a normal call should be emitted rather than expanding the
2179 function in-line. EXP is the expression that is a call to the builtin
2180 function; if convenient, the result should be placed in TARGET.
2181 SUBTARGET may be used as the target for computing one of EXP's operands. */
2182
2183static rtx
2184expand_builtin_interclass_mathfn (tree exp, rtx target, rtx subtarget)
2185{
cde061c1 2186 optab builtin_optab = 0;
2187 enum insn_code icode = CODE_FOR_nothing;
a67a90e5 2188 rtx op0;
2189 tree fndecl = get_callee_fndecl (exp);
a67a90e5 2190 enum machine_mode mode;
2191 bool errno_set = false;
abfea505 2192 tree arg;
a67a90e5 2193
c2f47e15 2194 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2195 return NULL_RTX;
a67a90e5 2196
c2f47e15 2197 arg = CALL_EXPR_ARG (exp, 0);
a67a90e5 2198
2199 switch (DECL_FUNCTION_CODE (fndecl))
2200 {
2201 CASE_FLT_FN (BUILT_IN_ILOGB):
2202 errno_set = true; builtin_optab = ilogb_optab; break;
69b779ea 2203 CASE_FLT_FN (BUILT_IN_ISINF):
2204 builtin_optab = isinf_optab; break;
8a1a9cb7 2205 case BUILT_IN_ISNORMAL:
cde061c1 2206 case BUILT_IN_ISFINITE:
2207 CASE_FLT_FN (BUILT_IN_FINITE):
2208 /* These builtins have no optabs (yet). */
2209 break;
a67a90e5 2210 default:
2211 gcc_unreachable ();
2212 }
2213
2214 /* There's no easy way to detect the case we need to set EDOM. */
2215 if (flag_errno_math && errno_set)
2216 return NULL_RTX;
2217
2218 /* Optab mode depends on the mode of the input argument. */
2219 mode = TYPE_MODE (TREE_TYPE (arg));
2220
cde061c1 2221 if (builtin_optab)
99bdde56 2222 icode = optab_handler (builtin_optab, mode)->insn_code;
a67a90e5 2223
2224 /* Before working hard, check whether the instruction is available. */
2225 if (icode != CODE_FOR_nothing)
2226 {
2227 /* Make a suitable register to place result in. */
2228 if (!target
2229 || GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
2230 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
2231
2232 gcc_assert (insn_data[icode].operand[0].predicate
2233 (target, GET_MODE (target)));
2234
2235 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2236 need to expand the argument again. This way, we will not perform
2237 side-effects more the once. */
abfea505 2238 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
a67a90e5 2239
1db6d067 2240 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
a67a90e5 2241
2242 if (mode != GET_MODE (op0))
2243 op0 = convert_to_mode (mode, op0, 0);
2244
2245 /* Compute into TARGET.
2246 Set TARGET to wherever the result comes back. */
2247 emit_unop_insn (icode, target, op0, UNKNOWN);
2248 return target;
2249 }
2250
06f7a99d 2251 /* If there is no optab, try generic code. */
2252 switch (DECL_FUNCTION_CODE (fndecl))
2253 {
2254 tree result;
2255
2256 CASE_FLT_FN (BUILT_IN_ISINF):
2257 {
2258 /* isinf(x) -> isgreater(fabs(x),DBL_MAX). */
2259 tree const isgr_fn = built_in_decls[BUILT_IN_ISGREATER];
2260 tree const type = TREE_TYPE (arg);
2261 REAL_VALUE_TYPE r;
2262 char buf[128];
2263
2264 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2265 real_from_string (&r, buf);
2266 result = build_call_expr (isgr_fn, 2,
2267 fold_build1 (ABS_EXPR, type, arg),
2268 build_real (type, r));
2269 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2270 }
cde061c1 2271 CASE_FLT_FN (BUILT_IN_FINITE):
2272 case BUILT_IN_ISFINITE:
2273 {
2274 /* isfinite(x) -> islessequal(fabs(x),DBL_MAX). */
2275 tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
2276 tree const type = TREE_TYPE (arg);
2277 REAL_VALUE_TYPE r;
2278 char buf[128];
2279
2280 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2281 real_from_string (&r, buf);
2282 result = build_call_expr (isle_fn, 2,
2283 fold_build1 (ABS_EXPR, type, arg),
2284 build_real (type, r));
2285 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2286 }
8a1a9cb7 2287 case BUILT_IN_ISNORMAL:
2288 {
2289 /* isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) &
2290 islessequal(fabs(x),DBL_MAX). */
2291 tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
2292 tree const isge_fn = built_in_decls[BUILT_IN_ISGREATEREQUAL];
2293 tree const type = TREE_TYPE (arg);
2294 REAL_VALUE_TYPE rmax, rmin;
2295 char buf[128];
2296
2297 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2298 real_from_string (&rmax, buf);
2299 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
2300 real_from_string (&rmin, buf);
2301 arg = builtin_save_expr (fold_build1 (ABS_EXPR, type, arg));
2302 result = build_call_expr (isle_fn, 2, arg,
2303 build_real (type, rmax));
2304 result = fold_build2 (BIT_AND_EXPR, integer_type_node, result,
2305 build_call_expr (isge_fn, 2, arg,
2306 build_real (type, rmin)));
2307 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2308 }
06f7a99d 2309 default:
2310 break;
2311 }
2312
a67a90e5 2313 target = expand_call (exp, target, target == const0_rtx);
2314
2315 return target;
2316}
2317
c3147c1a 2318/* Expand a call to the builtin sincos math function.
c2f47e15 2319 Return NULL_RTX if a normal call should be emitted rather than expanding the
c3147c1a 2320 function in-line. EXP is the expression that is a call to the builtin
2321 function. */
2322
2323static rtx
2324expand_builtin_sincos (tree exp)
2325{
2326 rtx op0, op1, op2, target1, target2;
c3147c1a 2327 enum machine_mode mode;
2328 tree arg, sinp, cosp;
2329 int result;
2330
c2f47e15 2331 if (!validate_arglist (exp, REAL_TYPE,
2332 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2333 return NULL_RTX;
c3147c1a 2334
c2f47e15 2335 arg = CALL_EXPR_ARG (exp, 0);
2336 sinp = CALL_EXPR_ARG (exp, 1);
2337 cosp = CALL_EXPR_ARG (exp, 2);
c3147c1a 2338
2339 /* Make a suitable register to place result in. */
2340 mode = TYPE_MODE (TREE_TYPE (arg));
2341
2342 /* Check if sincos insn is available, otherwise emit the call. */
99bdde56 2343 if (optab_handler (sincos_optab, mode)->insn_code == CODE_FOR_nothing)
c3147c1a 2344 return NULL_RTX;
2345
2346 target1 = gen_reg_rtx (mode);
2347 target2 = gen_reg_rtx (mode);
2348
8ec3c5c2 2349 op0 = expand_normal (arg);
2350 op1 = expand_normal (build_fold_indirect_ref (sinp));
2351 op2 = expand_normal (build_fold_indirect_ref (cosp));
c3147c1a 2352
2353 /* Compute into target1 and target2.
2354 Set TARGET to wherever the result comes back. */
2355 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2356 gcc_assert (result);
2357
2358 /* Move target1 and target2 to the memory locations indicated
2359 by op1 and op2. */
2360 emit_move_insn (op1, target1);
2361 emit_move_insn (op2, target2);
2362
2363 return const0_rtx;
2364}
2365
d735c391 2366/* Expand a call to the internal cexpi builtin to the sincos math function.
2367 EXP is the expression that is a call to the builtin function; if convenient,
2368 the result should be placed in TARGET. SUBTARGET may be used as the target
2369 for computing one of EXP's operands. */
2370
2371static rtx
2372expand_builtin_cexpi (tree exp, rtx target, rtx subtarget)
2373{
2374 tree fndecl = get_callee_fndecl (exp);
d735c391 2375 tree arg, type;
c2f47e15 2376 enum machine_mode mode;
d735c391 2377 rtx op0, op1, op2;
2378
c2f47e15 2379 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2380 return NULL_RTX;
d735c391 2381
c2f47e15 2382 arg = CALL_EXPR_ARG (exp, 0);
d735c391 2383 type = TREE_TYPE (arg);
2384 mode = TYPE_MODE (TREE_TYPE (arg));
2385
2386 /* Try expanding via a sincos optab, fall back to emitting a libcall
18b8d8ae 2387 to sincos or cexp. We are sure we have sincos or cexp because cexpi
2388 is only generated from sincos, cexp or if we have either of them. */
99bdde56 2389 if (optab_handler (sincos_optab, mode)->insn_code != CODE_FOR_nothing)
d735c391 2390 {
2391 op1 = gen_reg_rtx (mode);
2392 op2 = gen_reg_rtx (mode);
2393
1db6d067 2394 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
d735c391 2395
2396 /* Compute into op1 and op2. */
2397 expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
2398 }
18b8d8ae 2399 else if (TARGET_HAS_SINCOS)
d735c391 2400 {
c2f47e15 2401 tree call, fn = NULL_TREE;
d735c391 2402 tree top1, top2;
2403 rtx op1a, op2a;
2404
2405 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2406 fn = built_in_decls[BUILT_IN_SINCOSF];
2407 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2408 fn = built_in_decls[BUILT_IN_SINCOS];
2409 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2410 fn = built_in_decls[BUILT_IN_SINCOSL];
c2f47e15 2411 else
2412 gcc_unreachable ();
d735c391 2413
2414 op1 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2415 op2 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2416 op1a = copy_to_mode_reg (Pmode, XEXP (op1, 0));
2417 op2a = copy_to_mode_reg (Pmode, XEXP (op2, 0));
2418 top1 = make_tree (build_pointer_type (TREE_TYPE (arg)), op1a);
2419 top2 = make_tree (build_pointer_type (TREE_TYPE (arg)), op2a);
2420
d735c391 2421 /* Make sure not to fold the sincos call again. */
2422 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
c2f47e15 2423 expand_normal (build_call_nary (TREE_TYPE (TREE_TYPE (fn)),
2424 call, 3, arg, top1, top2));
d735c391 2425 }
18b8d8ae 2426 else
2427 {
0ecbc158 2428 tree call, fn = NULL_TREE, narg;
18b8d8ae 2429 tree ctype = build_complex_type (type);
2430
0ecbc158 2431 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2432 fn = built_in_decls[BUILT_IN_CEXPF];
2433 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2434 fn = built_in_decls[BUILT_IN_CEXP];
2435 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2436 fn = built_in_decls[BUILT_IN_CEXPL];
c2f47e15 2437 else
2438 gcc_unreachable ();
fc0dfa6e 2439
2440 /* If we don't have a decl for cexp create one. This is the
2441 friendliest fallback if the user calls __builtin_cexpi
2442 without full target C99 function support. */
2443 if (fn == NULL_TREE)
2444 {
2445 tree fntype;
2446 const char *name = NULL;
2447
2448 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2449 name = "cexpf";
2450 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2451 name = "cexp";
2452 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2453 name = "cexpl";
2454
2455 fntype = build_function_type_list (ctype, ctype, NULL_TREE);
2456 fn = build_fn_decl (name, fntype);
2457 }
2458
18b8d8ae 2459 narg = fold_build2 (COMPLEX_EXPR, ctype,
2460 build_real (type, dconst0), arg);
2461
2462 /* Make sure not to fold the cexp call again. */
2463 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
3737e769 2464 return expand_expr (build_call_nary (ctype, call, 1, narg),
1db6d067 2465 target, VOIDmode, EXPAND_NORMAL);
18b8d8ae 2466 }
d735c391 2467
2468 /* Now build the proper return type. */
2469 return expand_expr (build2 (COMPLEX_EXPR, build_complex_type (type),
2470 make_tree (TREE_TYPE (arg), op2),
2471 make_tree (TREE_TYPE (arg), op1)),
1db6d067 2472 target, VOIDmode, EXPAND_NORMAL);
d735c391 2473}
2474
7d3afc77 2475/* Expand a call to one of the builtin rounding functions gcc defines
2476 as an extension (lfloor and lceil). As these are gcc extensions we
2477 do not need to worry about setting errno to EDOM.
ad52b9b7 2478 If expanding via optab fails, lower expression to (int)(floor(x)).
2479 EXP is the expression that is a call to the builtin function;
ff1b14e4 2480 if convenient, the result should be placed in TARGET. */
ad52b9b7 2481
2482static rtx
ff1b14e4 2483expand_builtin_int_roundingfn (tree exp, rtx target)
ad52b9b7 2484{
9c42dd28 2485 convert_optab builtin_optab;
ad52b9b7 2486 rtx op0, insns, tmp;
2487 tree fndecl = get_callee_fndecl (exp);
ad52b9b7 2488 enum built_in_function fallback_fn;
2489 tree fallback_fndecl;
2490 enum machine_mode mode;
4de0924f 2491 tree arg;
ad52b9b7 2492
c2f47e15 2493 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
ad52b9b7 2494 gcc_unreachable ();
2495
c2f47e15 2496 arg = CALL_EXPR_ARG (exp, 0);
ad52b9b7 2497
2498 switch (DECL_FUNCTION_CODE (fndecl))
2499 {
4f35b1fc 2500 CASE_FLT_FN (BUILT_IN_LCEIL):
2501 CASE_FLT_FN (BUILT_IN_LLCEIL):
ac148751 2502 builtin_optab = lceil_optab;
2503 fallback_fn = BUILT_IN_CEIL;
2504 break;
2505
4f35b1fc 2506 CASE_FLT_FN (BUILT_IN_LFLOOR):
2507 CASE_FLT_FN (BUILT_IN_LLFLOOR):
ad52b9b7 2508 builtin_optab = lfloor_optab;
2509 fallback_fn = BUILT_IN_FLOOR;
2510 break;
2511
2512 default:
2513 gcc_unreachable ();
2514 }
2515
2516 /* Make a suitable register to place result in. */
2517 mode = TYPE_MODE (TREE_TYPE (exp));
2518
9c42dd28 2519 target = gen_reg_rtx (mode);
ad52b9b7 2520
9c42dd28 2521 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2522 need to expand the argument again. This way, we will not perform
2523 side-effects more the once. */
abfea505 2524 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
ad52b9b7 2525
ff1b14e4 2526 op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
ad52b9b7 2527
9c42dd28 2528 start_sequence ();
ad52b9b7 2529
9c42dd28 2530 /* Compute into TARGET. */
2531 if (expand_sfix_optab (target, op0, builtin_optab))
2532 {
2533 /* Output the entire sequence. */
2534 insns = get_insns ();
ad52b9b7 2535 end_sequence ();
9c42dd28 2536 emit_insn (insns);
2537 return target;
ad52b9b7 2538 }
2539
9c42dd28 2540 /* If we were unable to expand via the builtin, stop the sequence
2541 (without outputting the insns). */
2542 end_sequence ();
2543
ad52b9b7 2544 /* Fall back to floating point rounding optab. */
2545 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
fc0dfa6e 2546
2547 /* For non-C99 targets we may end up without a fallback fndecl here
2548 if the user called __builtin_lfloor directly. In this case emit
2549 a call to the floor/ceil variants nevertheless. This should result
2550 in the best user experience for not full C99 targets. */
2551 if (fallback_fndecl == NULL_TREE)
2552 {
2553 tree fntype;
2554 const char *name = NULL;
2555
2556 switch (DECL_FUNCTION_CODE (fndecl))
2557 {
2558 case BUILT_IN_LCEIL:
2559 case BUILT_IN_LLCEIL:
2560 name = "ceil";
2561 break;
2562 case BUILT_IN_LCEILF:
2563 case BUILT_IN_LLCEILF:
2564 name = "ceilf";
2565 break;
2566 case BUILT_IN_LCEILL:
2567 case BUILT_IN_LLCEILL:
2568 name = "ceill";
2569 break;
2570 case BUILT_IN_LFLOOR:
2571 case BUILT_IN_LLFLOOR:
2572 name = "floor";
2573 break;
2574 case BUILT_IN_LFLOORF:
2575 case BUILT_IN_LLFLOORF:
2576 name = "floorf";
2577 break;
2578 case BUILT_IN_LFLOORL:
2579 case BUILT_IN_LLFLOORL:
2580 name = "floorl";
2581 break;
2582 default:
2583 gcc_unreachable ();
2584 }
2585
2586 fntype = build_function_type_list (TREE_TYPE (arg),
2587 TREE_TYPE (arg), NULL_TREE);
2588 fallback_fndecl = build_fn_decl (name, fntype);
2589 }
2590
c2f47e15 2591 exp = build_call_expr (fallback_fndecl, 1, arg);
ad52b9b7 2592
d4c690af 2593 tmp = expand_normal (exp);
ad52b9b7 2594
2595 /* Truncate the result of floating point optab to integer
2596 via expand_fix (). */
2597 target = gen_reg_rtx (mode);
2598 expand_fix (target, tmp, 0);
2599
2600 return target;
2601}
2602
7d3afc77 2603/* Expand a call to one of the builtin math functions doing integer
2604 conversion (lrint).
2605 Return 0 if a normal call should be emitted rather than expanding the
2606 function in-line. EXP is the expression that is a call to the builtin
ff1b14e4 2607 function; if convenient, the result should be placed in TARGET. */
7d3afc77 2608
2609static rtx
ff1b14e4 2610expand_builtin_int_roundingfn_2 (tree exp, rtx target)
7d3afc77 2611{
5f51ee59 2612 convert_optab builtin_optab;
7d3afc77 2613 rtx op0, insns;
2614 tree fndecl = get_callee_fndecl (exp);
4de0924f 2615 tree arg;
c2f47e15 2616 enum machine_mode mode;
7d3afc77 2617
2618 /* There's no easy way to detect the case we need to set EDOM. */
2619 if (flag_errno_math)
2620 return NULL_RTX;
2621
c2f47e15 2622 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2623 gcc_unreachable ();
2624
2625 arg = CALL_EXPR_ARG (exp, 0);
7d3afc77 2626
2627 switch (DECL_FUNCTION_CODE (fndecl))
2628 {
2629 CASE_FLT_FN (BUILT_IN_LRINT):
2630 CASE_FLT_FN (BUILT_IN_LLRINT):
2631 builtin_optab = lrint_optab; break;
ef2f1a10 2632 CASE_FLT_FN (BUILT_IN_LROUND):
2633 CASE_FLT_FN (BUILT_IN_LLROUND):
2634 builtin_optab = lround_optab; break;
7d3afc77 2635 default:
2636 gcc_unreachable ();
2637 }
2638
2639 /* Make a suitable register to place result in. */
2640 mode = TYPE_MODE (TREE_TYPE (exp));
2641
5f51ee59 2642 target = gen_reg_rtx (mode);
7d3afc77 2643
5f51ee59 2644 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2645 need to expand the argument again. This way, we will not perform
2646 side-effects more the once. */
abfea505 2647 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
7d3afc77 2648
ff1b14e4 2649 op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
7d3afc77 2650
5f51ee59 2651 start_sequence ();
7d3afc77 2652
5f51ee59 2653 if (expand_sfix_optab (target, op0, builtin_optab))
2654 {
2655 /* Output the entire sequence. */
2656 insns = get_insns ();
7d3afc77 2657 end_sequence ();
5f51ee59 2658 emit_insn (insns);
2659 return target;
7d3afc77 2660 }
2661
5f51ee59 2662 /* If we were unable to expand via the builtin, stop the sequence
2663 (without outputting the insns) and call to the library function
2664 with the stabilized argument list. */
2665 end_sequence ();
2666
7d3afc77 2667 target = expand_call (exp, target, target == const0_rtx);
2668
2669 return target;
2670}
2671
f1b844c6 2672/* To evaluate powi(x,n), the floating point value x raised to the
2673 constant integer exponent n, we use a hybrid algorithm that
2674 combines the "window method" with look-up tables. For an
2675 introduction to exponentiation algorithms and "addition chains",
2676 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2677 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2678 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2679 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2680
2681/* Provide a default value for POWI_MAX_MULTS, the maximum number of
2682 multiplications to inline before calling the system library's pow
2683 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2684 so this default never requires calling pow, powf or powl. */
0862b7e9 2685
f1b844c6 2686#ifndef POWI_MAX_MULTS
2687#define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2688#endif
2689
2690/* The size of the "optimal power tree" lookup table. All
2691 exponents less than this value are simply looked up in the
2692 powi_table below. This threshold is also used to size the
2693 cache of pseudo registers that hold intermediate results. */
2694#define POWI_TABLE_SIZE 256
2695
2696/* The size, in bits of the window, used in the "window method"
2697 exponentiation algorithm. This is equivalent to a radix of
2698 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2699#define POWI_WINDOW_SIZE 3
2700
2701/* The following table is an efficient representation of an
2702 "optimal power tree". For each value, i, the corresponding
2703 value, j, in the table states than an optimal evaluation
2704 sequence for calculating pow(x,i) can be found by evaluating
2705 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2706 100 integers is given in Knuth's "Seminumerical algorithms". */
2707
2708static const unsigned char powi_table[POWI_TABLE_SIZE] =
2709 {
2710 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2711 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2712 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2713 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2714 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2715 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2716 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2717 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2718 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2719 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2720 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2721 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2722 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2723 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2724 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2725 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2726 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2727 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2728 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2729 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2730 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2731 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2732 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2733 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2734 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2735 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2736 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2737 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2738 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2739 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2740 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2741 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2742 };
2743
2744
2745/* Return the number of multiplications required to calculate
2746 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2747 subroutine of powi_cost. CACHE is an array indicating
2748 which exponents have already been calculated. */
2749
2750static int
2751powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2752{
2753 /* If we've already calculated this exponent, then this evaluation
2754 doesn't require any additional multiplications. */
2755 if (cache[n])
2756 return 0;
2757
2758 cache[n] = true;
2759 return powi_lookup_cost (n - powi_table[n], cache)
2760 + powi_lookup_cost (powi_table[n], cache) + 1;
2761}
2762
2763/* Return the number of multiplications required to calculate
2764 powi(x,n) for an arbitrary x, given the exponent N. This
2765 function needs to be kept in sync with expand_powi below. */
2766
2767static int
2768powi_cost (HOST_WIDE_INT n)
2769{
2770 bool cache[POWI_TABLE_SIZE];
2771 unsigned HOST_WIDE_INT digit;
2772 unsigned HOST_WIDE_INT val;
2773 int result;
2774
2775 if (n == 0)
2776 return 0;
2777
2778 /* Ignore the reciprocal when calculating the cost. */
2779 val = (n < 0) ? -n : n;
2780
2781 /* Initialize the exponent cache. */
2782 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2783 cache[1] = true;
2784
2785 result = 0;
2786
2787 while (val >= POWI_TABLE_SIZE)
2788 {
2789 if (val & 1)
2790 {
2791 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2792 result += powi_lookup_cost (digit, cache)
2793 + POWI_WINDOW_SIZE + 1;
2794 val >>= POWI_WINDOW_SIZE;
2795 }
2796 else
2797 {
2798 val >>= 1;
2799 result++;
2800 }
2801 }
0862b7e9 2802
6881dbab 2803 return result + powi_lookup_cost (val, cache);
f1b844c6 2804}
2805
2806/* Recursive subroutine of expand_powi. This function takes the array,
2807 CACHE, of already calculated exponents and an exponent N and returns
2808 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2809
2810static rtx
2811expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2812{
2813 unsigned HOST_WIDE_INT digit;
2814 rtx target, result;
2815 rtx op0, op1;
2816
2817 if (n < POWI_TABLE_SIZE)
2818 {
2819 if (cache[n])
a0c938f0 2820 return cache[n];
f1b844c6 2821
2822 target = gen_reg_rtx (mode);
2823 cache[n] = target;
2824
2825 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2826 op1 = expand_powi_1 (mode, powi_table[n], cache);
2827 }
2828 else if (n & 1)
2829 {
2830 target = gen_reg_rtx (mode);
2831 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2832 op0 = expand_powi_1 (mode, n - digit, cache);
2833 op1 = expand_powi_1 (mode, digit, cache);
2834 }
2835 else
2836 {
2837 target = gen_reg_rtx (mode);
2838 op0 = expand_powi_1 (mode, n >> 1, cache);
2839 op1 = op0;
2840 }
2841
2842 result = expand_mult (mode, op0, op1, target, 0);
2843 if (result != target)
2844 emit_move_insn (target, result);
2845 return target;
2846}
2847
2848/* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2849 floating point operand in mode MODE, and N is the exponent. This
2850 function needs to be kept in sync with powi_cost above. */
0862b7e9 2851
f1b844c6 2852static rtx
2853expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2854{
2855 unsigned HOST_WIDE_INT val;
2856 rtx cache[POWI_TABLE_SIZE];
2857 rtx result;
2858
2859 if (n == 0)
2860 return CONST1_RTX (mode);
2861
2862 val = (n < 0) ? -n : n;
2863
19bf118a 2864 memset (cache, 0, sizeof (cache));
f1b844c6 2865 cache[1] = x;
2866
2867 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2868
2869 /* If the original exponent was negative, reciprocate the result. */
2870 if (n < 0)
2871 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2872 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2873
2874 return result;
2875}
2876
c2f47e15 2877/* Expand a call to the pow built-in mathematical function. Return NULL_RTX if
f1b844c6 2878 a normal call should be emitted rather than expanding the function
2879 in-line. EXP is the expression that is a call to the builtin
2880 function; if convenient, the result should be placed in TARGET. */
2881
2882static rtx
2883expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2884{
c2f47e15 2885 tree arg0, arg1;
2886 tree fn, narg0;
1c4709b4 2887 tree type = TREE_TYPE (exp);
2888 REAL_VALUE_TYPE cint, c, c2;
2889 HOST_WIDE_INT n;
2890 rtx op, op2;
2891 enum machine_mode mode = TYPE_MODE (type);
f1b844c6 2892
c2f47e15 2893 if (! validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2894 return NULL_RTX;
f1b844c6 2895
c2f47e15 2896 arg0 = CALL_EXPR_ARG (exp, 0);
2897 arg1 = CALL_EXPR_ARG (exp, 1);
f1b844c6 2898
1c4709b4 2899 if (TREE_CODE (arg1) != REAL_CST
f96bd2bf 2900 || TREE_OVERFLOW (arg1))
1c4709b4 2901 return expand_builtin_mathfn_2 (exp, target, subtarget);
2902
2903 /* Handle constant exponents. */
2904
2905 /* For integer valued exponents we can expand to an optimal multiplication
2906 sequence using expand_powi. */
2907 c = TREE_REAL_CST (arg1);
2908 n = real_to_integer (&c);
2909 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2910 if (real_identical (&c, &cint)
2911 && ((n >= -1 && n <= 2)
2912 || (flag_unsafe_math_optimizations
2913 && !optimize_size
2914 && powi_cost (n) <= POWI_MAX_MULTS)))
f1b844c6 2915 {
1db6d067 2916 op = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
1c4709b4 2917 if (n != 1)
2918 {
2919 op = force_reg (mode, op);
2920 op = expand_powi (op, mode, n);
2921 }
2922 return op;
2923 }
2924
2925 narg0 = builtin_save_expr (arg0);
f1b844c6 2926
1c4709b4 2927 /* If the exponent is not integer valued, check if it is half of an integer.
2928 In this case we can expand to sqrt (x) * x**(n/2). */
2929 fn = mathfn_built_in (type, BUILT_IN_SQRT);
2930 if (fn != NULL_TREE)
2931 {
2932 real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
2933 n = real_to_integer (&c2);
f1b844c6 2934 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
1c4709b4 2935 if (real_identical (&c2, &cint)
2936 && ((flag_unsafe_math_optimizations
2937 && !optimize_size
2938 && powi_cost (n/2) <= POWI_MAX_MULTS)
2939 || n == 1))
f1b844c6 2940 {
c2f47e15 2941 tree call_expr = build_call_expr (fn, 1, narg0);
8697cf4d 2942 /* Use expand_expr in case the newly built call expression
2943 was folded to a non-call. */
2944 op = expand_expr (call_expr, subtarget, mode, EXPAND_NORMAL);
1c4709b4 2945 if (n != 1)
8c5cac78 2946 {
1db6d067 2947 op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL);
1c4709b4 2948 op2 = force_reg (mode, op2);
2949 op2 = expand_powi (op2, mode, abs (n / 2));
2950 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
2951 0, OPTAB_LIB_WIDEN);
2952 /* If the original exponent was negative, reciprocate the
2953 result. */
2954 if (n < 0)
2955 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2956 op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
8c5cac78 2957 }
1c4709b4 2958 return op;
f1b844c6 2959 }
2960 }
b613c2a6 2961
1c4709b4 2962 /* Try if the exponent is a third of an integer. In this case
5a84ba55 2963 we can expand to x**(n/3) * cbrt(x)**(n%3). As cbrt (x) is
2964 different from pow (x, 1./3.) due to rounding and behavior
2965 with negative x we need to constrain this transformation to
2966 unsafe math and positive x or finite math. */
1c4709b4 2967 fn = mathfn_built_in (type, BUILT_IN_CBRT);
5a84ba55 2968 if (fn != NULL_TREE
2969 && flag_unsafe_math_optimizations
2970 && (tree_expr_nonnegative_p (arg0)
2971 || !HONOR_NANS (mode)))
1c4709b4 2972 {
3fa759a9 2973 REAL_VALUE_TYPE dconst3;
2974 real_from_integer (&dconst3, VOIDmode, 3, 0, 0);
1c4709b4 2975 real_arithmetic (&c2, MULT_EXPR, &c, &dconst3);
2976 real_round (&c2, mode, &c2);
2977 n = real_to_integer (&c2);
2978 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2979 real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
2980 real_convert (&c2, mode, &c2);
2981 if (real_identical (&c2, &c)
2982 && ((!optimize_size
1c4709b4 2983 && powi_cost (n/3) <= POWI_MAX_MULTS)
2984 || n == 1))
2985 {
c2f47e15 2986 tree call_expr = build_call_expr (fn, 1,narg0);
1c4709b4 2987 op = expand_builtin (call_expr, NULL_RTX, subtarget, mode, 0);
2988 if (abs (n) % 3 == 2)
2989 op = expand_simple_binop (mode, MULT, op, op, op,
2990 0, OPTAB_LIB_WIDEN);
2991 if (n != 1)
2992 {
1db6d067 2993 op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL);
1c4709b4 2994 op2 = force_reg (mode, op2);
2995 op2 = expand_powi (op2, mode, abs (n / 3));
2996 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
2997 0, OPTAB_LIB_WIDEN);
2998 /* If the original exponent was negative, reciprocate the
2999 result. */
3000 if (n < 0)
3001 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
3002 op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
3003 }
3004 return op;
3005 }
3006 }
3007
3008 /* Fall back to optab expansion. */
b613c2a6 3009 return expand_builtin_mathfn_2 (exp, target, subtarget);
f1b844c6 3010}
3011
c2f47e15 3012/* Expand a call to the powi built-in mathematical function. Return NULL_RTX if
757c219d 3013 a normal call should be emitted rather than expanding the function
3014 in-line. EXP is the expression that is a call to the builtin
3015 function; if convenient, the result should be placed in TARGET. */
3016
3017static rtx
3018expand_builtin_powi (tree exp, rtx target, rtx subtarget)
3019{
757c219d 3020 tree arg0, arg1;
3021 rtx op0, op1;
3022 enum machine_mode mode;
d0405f40 3023 enum machine_mode mode2;
757c219d 3024
c2f47e15 3025 if (! validate_arglist (exp, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
3026 return NULL_RTX;
757c219d 3027
c2f47e15 3028 arg0 = CALL_EXPR_ARG (exp, 0);
3029 arg1 = CALL_EXPR_ARG (exp, 1);
757c219d 3030 mode = TYPE_MODE (TREE_TYPE (exp));
3031
3032 /* Handle constant power. */
3033
3034 if (TREE_CODE (arg1) == INTEGER_CST
f96bd2bf 3035 && !TREE_OVERFLOW (arg1))
757c219d 3036 {
3037 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
3038
3039 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
3040 Otherwise, check the number of multiplications required. */
3041 if ((TREE_INT_CST_HIGH (arg1) == 0
3042 || TREE_INT_CST_HIGH (arg1) == -1)
3043 && ((n >= -1 && n <= 2)
3044 || (! optimize_size
3045 && powi_cost (n) <= POWI_MAX_MULTS)))
3046 {
1db6d067 3047 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
757c219d 3048 op0 = force_reg (mode, op0);
3049 return expand_powi (op0, mode, n);
3050 }
3051 }
3052
3053 /* Emit a libcall to libgcc. */
3054
c2f47e15 3055 /* Mode of the 2nd argument must match that of an int. */
d0405f40 3056 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
3057
757c219d 3058 if (target == NULL_RTX)
3059 target = gen_reg_rtx (mode);
3060
1db6d067 3061 op0 = expand_expr (arg0, subtarget, mode, EXPAND_NORMAL);
757c219d 3062 if (GET_MODE (op0) != mode)
3063 op0 = convert_to_mode (mode, op0, 0);
1db6d067 3064 op1 = expand_expr (arg1, NULL_RTX, mode2, EXPAND_NORMAL);
d0405f40 3065 if (GET_MODE (op1) != mode2)
3066 op1 = convert_to_mode (mode2, op1, 0);
757c219d 3067
f36b9f69 3068 target = emit_library_call_value (optab_libfunc (powi_optab, mode),
2dd6f9ed 3069 target, LCT_CONST, mode, 2,
d0405f40 3070 op0, mode, op1, mode2);
757c219d 3071
3072 return target;
3073}
3074
c2f47e15 3075/* Expand expression EXP which is a call to the strlen builtin. Return
3076 NULL_RTX if we failed the caller should emit a normal call, otherwise
aed0bd19 3077 try to get the result in TARGET, if convenient. */
f7c44134 3078
53800dbe 3079static rtx
c2f47e15 3080expand_builtin_strlen (tree exp, rtx target,
aecda0d6 3081 enum machine_mode target_mode)
53800dbe 3082{
c2f47e15 3083 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
3084 return NULL_RTX;
53800dbe 3085 else
3086 {
911c0150 3087 rtx pat;
c2f47e15 3088 tree len;
3089 tree src = CALL_EXPR_ARG (exp, 0);
911c0150 3090 rtx result, src_reg, char_rtx, before_strlen;
80cd7a5e 3091 enum machine_mode insn_mode = target_mode, char_mode;
ef2c4a29 3092 enum insn_code icode = CODE_FOR_nothing;
6248e345 3093 int align;
3094
3095 /* If the length can be computed at compile-time, return it. */
681fab1e 3096 len = c_strlen (src, 0);
6248e345 3097 if (len)
80cd7a5e 3098 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
6248e345 3099
681fab1e 3100 /* If the length can be computed at compile-time and is constant
3101 integer, but there are side-effects in src, evaluate
3102 src for side-effects, then return len.
3103 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
3104 can be optimized into: i++; x = 3; */
3105 len = c_strlen (src, 1);
3106 if (len && TREE_CODE (len) == INTEGER_CST)
3107 {
3108 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3109 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
3110 }
3111
6248e345 3112 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
53800dbe 3113
53800dbe 3114 /* If SRC is not a pointer type, don't do this operation inline. */
3115 if (align == 0)
c2f47e15 3116 return NULL_RTX;
53800dbe 3117
911c0150 3118 /* Bail out if we can't compute strlen in the right mode. */
53800dbe 3119 while (insn_mode != VOIDmode)
3120 {
99bdde56 3121 icode = optab_handler (strlen_optab, insn_mode)->insn_code;
53800dbe 3122 if (icode != CODE_FOR_nothing)
c28ae87f 3123 break;
53800dbe 3124
3125 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
3126 }
3127 if (insn_mode == VOIDmode)
c2f47e15 3128 return NULL_RTX;
53800dbe 3129
3130 /* Make a place to write the result of the instruction. */
3131 result = target;
3132 if (! (result != 0
8ad4c111 3133 && REG_P (result)
53800dbe 3134 && GET_MODE (result) == insn_mode
3135 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3136 result = gen_reg_rtx (insn_mode);
3137
911c0150 3138 /* Make a place to hold the source address. We will not expand
3139 the actual source until we are sure that the expansion will
3140 not fail -- there are trees that cannot be expanded twice. */
3141 src_reg = gen_reg_rtx (Pmode);
53800dbe 3142
911c0150 3143 /* Mark the beginning of the strlen sequence so we can emit the
3144 source operand later. */
f0ce3b1f 3145 before_strlen = get_last_insn ();
53800dbe 3146
53800dbe 3147 char_rtx = const0_rtx;
f7c44134 3148 char_mode = insn_data[(int) icode].operand[2].mode;
3149 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
3150 char_mode))
53800dbe 3151 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
3152
911c0150 3153 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
3154 char_rtx, GEN_INT (align));
3155 if (! pat)
c2f47e15 3156 return NULL_RTX;
911c0150 3157 emit_insn (pat);
3158
3159 /* Now that we are assured of success, expand the source. */
3160 start_sequence ();
c5aba89c 3161 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
911c0150 3162 if (pat != src_reg)
3163 emit_move_insn (src_reg, pat);
31d3e01c 3164 pat = get_insns ();
911c0150 3165 end_sequence ();
bceb0d1f 3166
3167 if (before_strlen)
3168 emit_insn_after (pat, before_strlen);
3169 else
3170 emit_insn_before (pat, get_insns ());
53800dbe 3171
3172 /* Return the value in the proper mode for this function. */
80cd7a5e 3173 if (GET_MODE (result) == target_mode)
911c0150 3174 target = result;
53800dbe 3175 else if (target != 0)
911c0150 3176 convert_move (target, result, 0);
53800dbe 3177 else
80cd7a5e 3178 target = convert_to_mode (target_mode, result, 0);
911c0150 3179
3180 return target;
53800dbe 3181 }
3182}
3183
c2f47e15 3184/* Expand a call to the strstr builtin. Return NULL_RTX if we failed the
17f5ea87 3185 caller should emit a normal call, otherwise try to get the result
3186 in TARGET, if convenient (and in mode MODE if that's convenient). */
3187
3188static rtx
c2f47e15 3189expand_builtin_strstr (tree exp, rtx target, enum machine_mode mode)
17f5ea87 3190{
c2f47e15 3191 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
17f5ea87 3192 {
c2f47e15 3193 tree type = TREE_TYPE (exp);
3194 tree result = fold_builtin_strstr (CALL_EXPR_ARG (exp, 0),
3195 CALL_EXPR_ARG (exp, 1), type);
2c84ee37 3196 if (result)
3197 return expand_expr (result, target, mode, EXPAND_NORMAL);
17f5ea87 3198 }
c2f47e15 3199 return NULL_RTX;
17f5ea87 3200}
3201
c2f47e15 3202/* Expand a call to the strchr builtin. Return NULL_RTX if we failed the
46f3a74a 3203 caller should emit a normal call, otherwise try to get the result
3204 in TARGET, if convenient (and in mode MODE if that's convenient). */
3205
3206static rtx
c2f47e15 3207expand_builtin_strchr (tree exp, rtx target, enum machine_mode mode)
46f3a74a 3208{
c2f47e15 3209 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
46f3a74a 3210 {
c2f47e15 3211 tree type = TREE_TYPE (exp);
3212 tree result = fold_builtin_strchr (CALL_EXPR_ARG (exp, 0),
3213 CALL_EXPR_ARG (exp, 1), type);
2c84ee37 3214 if (result)
3215 return expand_expr (result, target, mode, EXPAND_NORMAL);
83d79705 3216
2c84ee37 3217 /* FIXME: Should use strchrM optab so that ports can optimize this. */
83d79705 3218 }
c2f47e15 3219 return NULL_RTX;
83d79705 3220}
3221
c2f47e15 3222/* Expand a call to the strrchr builtin. Return NULL_RTX if we failed the
83d79705 3223 caller should emit a normal call, otherwise try to get the result
3224 in TARGET, if convenient (and in mode MODE if that's convenient). */
3225
3226static rtx
c2f47e15 3227expand_builtin_strrchr (tree exp, rtx target, enum machine_mode mode)
83d79705 3228{
c2f47e15 3229 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
83d79705 3230 {
c2f47e15 3231 tree type = TREE_TYPE (exp);
3232 tree result = fold_builtin_strrchr (CALL_EXPR_ARG (exp, 0),
3233 CALL_EXPR_ARG (exp, 1), type);
2c84ee37 3234 if (result)
3235 return expand_expr (result, target, mode, EXPAND_NORMAL);
83d79705 3236 }
c2f47e15 3237 return NULL_RTX;
83d79705 3238}
3239
c2f47e15 3240/* Expand a call to the strpbrk builtin. Return NULL_RTX if we failed the
83d79705 3241 caller should emit a normal call, otherwise try to get the result
3242 in TARGET, if convenient (and in mode MODE if that's convenient). */
3243
3244static rtx
c2f47e15 3245expand_builtin_strpbrk (tree exp, rtx target, enum machine_mode mode)
83d79705 3246{
c2f47e15 3247 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
83d79705 3248 {
c2f47e15 3249 tree type = TREE_TYPE (exp);
3250 tree result = fold_builtin_strpbrk (CALL_EXPR_ARG (exp, 0),
3251 CALL_EXPR_ARG (exp, 1), type);
2c84ee37 3252 if (result)
3253 return expand_expr (result, target, mode, EXPAND_NORMAL);
46f3a74a 3254 }
c2f47e15 3255 return NULL_RTX;
46f3a74a 3256}
3257
6840589f 3258/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3259 bytes from constant string DATA + OFFSET and return it as target
3260 constant. */
3261
3262static rtx
aecda0d6 3263builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
3264 enum machine_mode mode)
6840589f 3265{
3266 const char *str = (const char *) data;
3267
64db345d 3268 gcc_assert (offset >= 0
3269 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
3270 <= strlen (str) + 1));
6840589f 3271
3272 return c_readstr (str + offset, mode);
3273}
3274
c2f47e15 3275/* Expand a call EXP to the memcpy builtin.
3276 Return NULL_RTX if we failed, the caller should emit a normal call,
3b824fa6 3277 otherwise try to get the result in TARGET, if convenient (and in
9fe0e1b8 3278 mode MODE if that's convenient). */
c2f47e15 3279
53800dbe 3280static rtx
5a0de151 3281expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
53800dbe 3282{
8e76ec06 3283 tree fndecl = get_callee_fndecl (exp);
c2f47e15 3284
3285 if (!validate_arglist (exp,
3286 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3287 return NULL_RTX;
53800dbe 3288 else
3289 {
c2f47e15 3290 tree dest = CALL_EXPR_ARG (exp, 0);
3291 tree src = CALL_EXPR_ARG (exp, 1);
3292 tree len = CALL_EXPR_ARG (exp, 2);
6840589f 3293 const char *src_str;
27d0c333 3294 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3295 unsigned int dest_align
3296 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
53800dbe 3297 rtx dest_mem, src_mem, dest_addr, len_rtx;
c2f47e15 3298 tree result = fold_builtin_memory_op (dest, src, len,
3299 TREE_TYPE (TREE_TYPE (fndecl)),
4f46f2b9 3300 false, /*endp=*/0);
162719b3 3301 HOST_WIDE_INT expected_size = -1;
3302 unsigned int expected_align = 0;
75a70cf9 3303 tree_ann_common_t ann;
5a0de151 3304
3305 if (result)
4f46f2b9 3306 {
3307 while (TREE_CODE (result) == COMPOUND_EXPR)
3308 {
3309 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3310 EXPAND_NORMAL);
3311 result = TREE_OPERAND (result, 1);
3312 }
3313 return expand_expr (result, target, mode, EXPAND_NORMAL);
3314 }
53800dbe 3315
6f428e8b 3316 /* If DEST is not a pointer type, call the normal function. */
3317 if (dest_align == 0)
c2f47e15 3318 return NULL_RTX;
6f428e8b 3319
6f428e8b 3320 /* If either SRC is not a pointer type, don't do this
a0c938f0 3321 operation in-line. */
6f428e8b 3322 if (src_align == 0)
c2f47e15 3323 return NULL_RTX;
162719b3 3324
75a70cf9 3325 ann = tree_common_ann (exp);
3326 if (ann)
3327 stringop_block_profile (ann->stmt, &expected_align, &expected_size);
3328
162719b3 3329 if (expected_align < dest_align)
3330 expected_align = dest_align;
d8ae1baa 3331 dest_mem = get_memory_rtx (dest, len);
2a631e19 3332 set_mem_align (dest_mem, dest_align);
8ec3c5c2 3333 len_rtx = expand_normal (len);
6840589f 3334 src_str = c_getstr (src);
3335
3336 /* If SRC is a string constant and block move would be done
3337 by pieces, we can avoid loading the string from memory
3338 and only stored the computed constants. */
3339 if (src_str
6840589f 3340 && GET_CODE (len_rtx) == CONST_INT
3341 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3342 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
364c0c59 3343 CONST_CAST (char *, src_str),
3344 dest_align, false))
6840589f 3345 {
9fe0e1b8 3346 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3347 builtin_memcpy_read_str,
364c0c59 3348 CONST_CAST (char *, src_str),
3349 dest_align, false, 0);
e5716f7e 3350 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3351 dest_mem = convert_memory_address (ptr_mode, dest_mem);
9fe0e1b8 3352 return dest_mem;
6840589f 3353 }
3354
d8ae1baa 3355 src_mem = get_memory_rtx (src, len);
2a631e19 3356 set_mem_align (src_mem, src_align);
53800dbe 3357
53800dbe 3358 /* Copy word part most expediently. */
162719b3 3359 dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx,
3360 CALL_EXPR_TAILCALL (exp)
3361 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3362 expected_align, expected_size);
53800dbe 3363
3364 if (dest_addr == 0)
e5716f7e 3365 {
3366 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3367 dest_addr = convert_memory_address (ptr_mode, dest_addr);
e5716f7e 3368 }
9fe0e1b8 3369 return dest_addr;
53800dbe 3370 }
3371}
3372
c2f47e15 3373/* Expand a call EXP to the mempcpy builtin.
3374 Return NULL_RTX if we failed; the caller should emit a normal call,
647661c6 3375 otherwise try to get the result in TARGET, if convenient (and in
9fe0e1b8 3376 mode MODE if that's convenient). If ENDP is 0 return the
3377 destination pointer, if ENDP is 1 return the end pointer ala
3378 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3379 stpcpy. */
647661c6 3380
3381static rtx
c2f47e15 3382expand_builtin_mempcpy(tree exp, rtx target, enum machine_mode mode)
647661c6 3383{
c2f47e15 3384 if (!validate_arglist (exp,
3385 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3386 return NULL_RTX;
3387 else
3388 {
3389 tree dest = CALL_EXPR_ARG (exp, 0);
3390 tree src = CALL_EXPR_ARG (exp, 1);
3391 tree len = CALL_EXPR_ARG (exp, 2);
3392 return expand_builtin_mempcpy_args (dest, src, len,
3393 TREE_TYPE (exp),
3394 target, mode, /*endp=*/ 1);
3395 }
3396}
3397
3398/* Helper function to do the actual work for expand_builtin_mempcpy. The
3399 arguments to the builtin_mempcpy call DEST, SRC, and LEN are broken out
3400 so that this can also be called without constructing an actual CALL_EXPR.
3401 TYPE is the return type of the call. The other arguments and return value
3402 are the same as for expand_builtin_mempcpy. */
3403
3404static rtx
3405expand_builtin_mempcpy_args (tree dest, tree src, tree len, tree type,
3406 rtx target, enum machine_mode mode, int endp)
3407{
3408 /* If return value is ignored, transform mempcpy into memcpy. */
3409 if (target == const0_rtx)
9fe0e1b8 3410 {
3411 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3412
3413 if (!fn)
c2f47e15 3414 return NULL_RTX;
9fe0e1b8 3415
c2f47e15 3416 return expand_expr (build_call_expr (fn, 3, dest, src, len),
9fe0e1b8 3417 target, mode, EXPAND_NORMAL);
3418 }
647661c6 3419 else
3420 {
9fe0e1b8 3421 const char *src_str;
3422 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3423 unsigned int dest_align
3424 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3425 rtx dest_mem, src_mem, len_rtx;
c2f47e15 3426 tree result = fold_builtin_memory_op (dest, src, len, type, false, endp);
9fe0e1b8 3427
7da1412b 3428 if (result)
4f46f2b9 3429 {
3430 while (TREE_CODE (result) == COMPOUND_EXPR)
3431 {
3432 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3433 EXPAND_NORMAL);
3434 result = TREE_OPERAND (result, 1);
3435 }
3436 return expand_expr (result, target, mode, EXPAND_NORMAL);
3437 }
a0c938f0 3438
7da1412b 3439 /* If either SRC or DEST is not a pointer type, don't do this
a0c938f0 3440 operation in-line. */
7da1412b 3441 if (dest_align == 0 || src_align == 0)
c2f47e15 3442 return NULL_RTX;
9fe0e1b8 3443
6217c238 3444 /* If LEN is not constant, call the normal function. */
3445 if (! host_integerp (len, 1))
c2f47e15 3446 return NULL_RTX;
0862b7e9 3447
8ec3c5c2 3448 len_rtx = expand_normal (len);
9fe0e1b8 3449 src_str = c_getstr (src);
647661c6 3450
9fe0e1b8 3451 /* If SRC is a string constant and block move would be done
3452 by pieces, we can avoid loading the string from memory
3453 and only stored the computed constants. */
3454 if (src_str
3455 && GET_CODE (len_rtx) == CONST_INT
3456 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3457 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
364c0c59 3458 CONST_CAST (char *, src_str),
3459 dest_align, false))
9fe0e1b8 3460 {
d8ae1baa 3461 dest_mem = get_memory_rtx (dest, len);
9fe0e1b8 3462 set_mem_align (dest_mem, dest_align);
3463 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3464 builtin_memcpy_read_str,
364c0c59 3465 CONST_CAST (char *, src_str),
3466 dest_align, false, endp);
9fe0e1b8 3467 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3468 dest_mem = convert_memory_address (ptr_mode, dest_mem);
9fe0e1b8 3469 return dest_mem;
647661c6 3470 }
3471
9fe0e1b8 3472 if (GET_CODE (len_rtx) == CONST_INT
3473 && can_move_by_pieces (INTVAL (len_rtx),
3474 MIN (dest_align, src_align)))
3475 {
d8ae1baa 3476 dest_mem = get_memory_rtx (dest, len);
9fe0e1b8 3477 set_mem_align (dest_mem, dest_align);
d8ae1baa 3478 src_mem = get_memory_rtx (src, len);
9fe0e1b8 3479 set_mem_align (src_mem, src_align);
3480 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3481 MIN (dest_align, src_align), endp);
3482 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3483 dest_mem = convert_memory_address (ptr_mode, dest_mem);
9fe0e1b8 3484 return dest_mem;
3485 }
3486
c2f47e15 3487 return NULL_RTX;
647661c6 3488 }
3489}
3490
c2f47e15 3491/* Expand expression EXP, which is a call to the memmove builtin. Return
3492 NULL_RTX if we failed; the caller should emit a normal call. */
c4950093 3493
3494static rtx
c2f47e15 3495expand_builtin_memmove (tree exp, rtx target, enum machine_mode mode, int ignore)
c4950093 3496{
c2f47e15 3497 if (!validate_arglist (exp,
3498 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3499 return NULL_RTX;
c4950093 3500 else
3501 {
c2f47e15 3502 tree dest = CALL_EXPR_ARG (exp, 0);
3503 tree src = CALL_EXPR_ARG (exp, 1);
3504 tree len = CALL_EXPR_ARG (exp, 2);
3505 return expand_builtin_memmove_args (dest, src, len, TREE_TYPE (exp),
3506 target, mode, ignore);
3507 }
3508}
7e72af53 3509
c2f47e15 3510/* Helper function to do the actual work for expand_builtin_memmove. The
3511 arguments to the builtin_memmove call DEST, SRC, and LEN are broken out
3512 so that this can also be called without constructing an actual CALL_EXPR.
3513 TYPE is the return type of the call. The other arguments and return value
3514 are the same as for expand_builtin_memmove. */
3515
3516static rtx
3517expand_builtin_memmove_args (tree dest, tree src, tree len,
3518 tree type, rtx target, enum machine_mode mode,
3519 int ignore)
3520{
3521 tree result = fold_builtin_memory_op (dest, src, len, type, ignore, /*endp=*/3);
3522
3523 if (result)
3524 {
05be68f3 3525 STRIP_TYPE_NOPS (result);
c2f47e15 3526 while (TREE_CODE (result) == COMPOUND_EXPR)
4f46f2b9 3527 {
c2f47e15 3528 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3529 EXPAND_NORMAL);
3530 result = TREE_OPERAND (result, 1);
4f46f2b9 3531 }
c2f47e15 3532 return expand_expr (result, target, mode, EXPAND_NORMAL);
3533 }
3534
3535 /* Otherwise, call the normal function. */
3536 return NULL_RTX;
c4950093 3537}
3538
c2f47e15 3539/* Expand expression EXP, which is a call to the bcopy builtin. Return
3540 NULL_RTX if we failed the caller should emit a normal call. */
c4950093 3541
3542static rtx
c2f47e15 3543expand_builtin_bcopy (tree exp, int ignore)
c4950093 3544{
0b25db21 3545 tree type = TREE_TYPE (exp);
c2f47e15 3546 tree src, dest, size;
c4950093 3547
c2f47e15 3548 if (!validate_arglist (exp,
3549 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
c4950093 3550 return NULL_RTX;
3551
c2f47e15 3552 src = CALL_EXPR_ARG (exp, 0);
3553 dest = CALL_EXPR_ARG (exp, 1);
3554 size = CALL_EXPR_ARG (exp, 2);
c4950093 3555
c2f47e15 3556 /* Transform bcopy(ptr x, ptr y, int z) to memmove(ptr y, ptr x, size_t z).
3557 This is done this way so that if it isn't expanded inline, we fall
3558 back to calling bcopy instead of memmove. */
3559 return expand_builtin_memmove_args (dest, src,
3560 fold_convert (sizetype, size),
3561 type, const0_rtx, VOIDmode,
3562 ignore);
c4950093 3563}
3564
727c62dd 3565#ifndef HAVE_movstr
3566# define HAVE_movstr 0
3567# define CODE_FOR_movstr CODE_FOR_nothing
3568#endif
3569
c2f47e15 3570/* Expand into a movstr instruction, if one is available. Return NULL_RTX if
727c62dd 3571 we failed, the caller should emit a normal call, otherwise try to
3572 get the result in TARGET, if convenient. If ENDP is 0 return the
3573 destination pointer, if ENDP is 1 return the end pointer ala
3574 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3575 stpcpy. */
3576
3577static rtx
3578expand_movstr (tree dest, tree src, rtx target, int endp)
3579{
3580 rtx end;
3581 rtx dest_mem;
3582 rtx src_mem;
3583 rtx insn;
3584 const struct insn_data * data;
3585
3586 if (!HAVE_movstr)
c2f47e15 3587 return NULL_RTX;
727c62dd 3588
d8ae1baa 3589 dest_mem = get_memory_rtx (dest, NULL);
3590 src_mem = get_memory_rtx (src, NULL);
727c62dd 3591 if (!endp)
3592 {
3593 target = force_reg (Pmode, XEXP (dest_mem, 0));
3594 dest_mem = replace_equiv_address (dest_mem, target);
3595 end = gen_reg_rtx (Pmode);
3596 }
3597 else
3598 {
3599 if (target == 0 || target == const0_rtx)
3600 {
3601 end = gen_reg_rtx (Pmode);
3602 if (target == 0)
3603 target = end;
3604 }
3605 else
3606 end = target;
3607 }
3608
3609 data = insn_data + CODE_FOR_movstr;
3610
3611 if (data->operand[0].mode != VOIDmode)
3612 end = gen_lowpart (data->operand[0].mode, end);
3613
3614 insn = data->genfun (end, dest_mem, src_mem);
3615
64db345d 3616 gcc_assert (insn);
727c62dd 3617
3618 emit_insn (insn);
3619
3620 /* movstr is supposed to set end to the address of the NUL
3621 terminator. If the caller requested a mempcpy-like return value,
3622 adjust it. */
3623 if (endp == 1 && target != const0_rtx)
c5aba89c 3624 {
3625 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3626 emit_move_insn (target, force_operand (tem, NULL_RTX));
3627 }
727c62dd 3628
3629 return target;
3630}
3631
c2f47e15 3632/* Expand expression EXP, which is a call to the strcpy builtin. Return
3633 NULL_RTX if we failed the caller should emit a normal call, otherwise
3634 try to get the result in TARGET, if convenient (and in mode MODE if that's
6f428e8b 3635 convenient). */
902de8ed 3636
53800dbe 3637static rtx
c2f47e15 3638expand_builtin_strcpy (tree fndecl, tree exp, rtx target, enum machine_mode mode)
53800dbe 3639{
c2f47e15 3640 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3641 {
3642 tree dest = CALL_EXPR_ARG (exp, 0);
3643 tree src = CALL_EXPR_ARG (exp, 1);
3644 return expand_builtin_strcpy_args (fndecl, dest, src, target, mode);
3645 }
3646 return NULL_RTX;
3647}
3648
3649/* Helper function to do the actual work for expand_builtin_strcpy. The
3650 arguments to the builtin_strcpy call DEST and SRC are broken out
3651 so that this can also be called without constructing an actual CALL_EXPR.
3652 The other arguments and return value are the same as for
3653 expand_builtin_strcpy. */
3654
3655static rtx
3656expand_builtin_strcpy_args (tree fndecl, tree dest, tree src,
3657 rtx target, enum machine_mode mode)
3658{
3659 tree result = fold_builtin_strcpy (fndecl, dest, src, 0);
3660 if (result)
3661 return expand_expr (result, target, mode, EXPAND_NORMAL);
3662 return expand_movstr (dest, src, target, /*endp=*/0);
902de8ed 3663
53800dbe 3664}
3665
c2f47e15 3666/* Expand a call EXP to the stpcpy builtin.
3667 Return NULL_RTX if we failed the caller should emit a normal call,
3b824fa6 3668 otherwise try to get the result in TARGET, if convenient (and in
3669 mode MODE if that's convenient). */
3670
3671static rtx
dc369150 3672expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3b824fa6 3673{
c2f47e15 3674 tree dst, src;
3675
3676 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3677 return NULL_RTX;
3678
3679 dst = CALL_EXPR_ARG (exp, 0);
3680 src = CALL_EXPR_ARG (exp, 1);
3681
727c62dd 3682 /* If return value is ignored, transform stpcpy into strcpy. */
3683 if (target == const0_rtx)
978836e5 3684 {
3685 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3686 if (!fn)
c2f47e15 3687 return NULL_RTX;
978836e5 3688
c2f47e15 3689 return expand_expr (build_call_expr (fn, 2, dst, src),
3690 target, mode, EXPAND_NORMAL);
978836e5 3691 }
3b824fa6 3692 else
3693 {
c2f47e15 3694 tree len, lenp1;
727c62dd 3695 rtx ret;
647661c6 3696
9fe0e1b8 3697 /* Ensure we get an actual string whose length can be evaluated at
a0c938f0 3698 compile-time, not an expression containing a string. This is
3699 because the latter will potentially produce pessimized code
3700 when used to produce the return value. */
681fab1e 3701 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
c2f47e15 3702 return expand_movstr (dst, src, target, /*endp=*/2);
3b824fa6 3703
7d705727 3704 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
c2f47e15 3705 ret = expand_builtin_mempcpy_args (dst, src, lenp1, TREE_TYPE (exp),
3706 target, mode, /*endp=*/2);
727c62dd 3707
3708 if (ret)
3709 return ret;
3710
3711 if (TREE_CODE (len) == INTEGER_CST)
3712 {
8ec3c5c2 3713 rtx len_rtx = expand_normal (len);
727c62dd 3714
3715 if (GET_CODE (len_rtx) == CONST_INT)
3716 {
c2f47e15 3717 ret = expand_builtin_strcpy_args (get_callee_fndecl (exp),
3718 dst, src, target, mode);
727c62dd 3719
3720 if (ret)
3721 {
3722 if (! target)
7ac87324 3723 {
3724 if (mode != VOIDmode)
3725 target = gen_reg_rtx (mode);
3726 else
3727 target = gen_reg_rtx (GET_MODE (ret));
3728 }
727c62dd 3729 if (GET_MODE (target) != GET_MODE (ret))
3730 ret = gen_lowpart (GET_MODE (target), ret);
3731
c5aba89c 3732 ret = plus_constant (ret, INTVAL (len_rtx));
3733 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
64db345d 3734 gcc_assert (ret);
727c62dd 3735
3736 return target;
3737 }
3738 }
3739 }
3740
c2f47e15 3741 return expand_movstr (dst, src, target, /*endp=*/2);
3b824fa6 3742 }
3743}
3744
6840589f 3745/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3746 bytes from constant string DATA + OFFSET and return it as target
3747 constant. */
3748
09879952 3749rtx
aecda0d6 3750builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3751 enum machine_mode mode)
6840589f 3752{
3753 const char *str = (const char *) data;
3754
3755 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3756 return const0_rtx;
3757
3758 return c_readstr (str + offset, mode);
3759}
3760
c2f47e15 3761/* Expand expression EXP, which is a call to the strncpy builtin. Return
3762 NULL_RTX if we failed the caller should emit a normal call. */
ed09096d 3763
3764static rtx
8ff6a5cd 3765expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
ed09096d 3766{
ea726109 3767 tree fndecl = get_callee_fndecl (exp);
c2f47e15 3768
3769 if (validate_arglist (exp,
3770 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
ed09096d 3771 {
c2f47e15 3772 tree dest = CALL_EXPR_ARG (exp, 0);
3773 tree src = CALL_EXPR_ARG (exp, 1);
3774 tree len = CALL_EXPR_ARG (exp, 2);
3775 tree slen = c_strlen (src, 1);
3776 tree result = fold_builtin_strncpy (fndecl, dest, src, len, slen);
a0c938f0 3777
8ff6a5cd 3778 if (result)
4f46f2b9 3779 {
3780 while (TREE_CODE (result) == COMPOUND_EXPR)
3781 {
3782 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3783 EXPAND_NORMAL);
3784 result = TREE_OPERAND (result, 1);
3785 }
3786 return expand_expr (result, target, mode, EXPAND_NORMAL);
3787 }
6840589f 3788
8ff6a5cd 3789 /* We must be passed a constant len and src parameter. */
3790 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
c2f47e15 3791 return NULL_RTX;
ed09096d 3792
3793 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3794
3795 /* We're required to pad with trailing zeros if the requested
a0c938f0 3796 len is greater than strlen(s2)+1. In that case try to
6840589f 3797 use store_by_pieces, if it fails, punt. */
ed09096d 3798 if (tree_int_cst_lt (slen, len))
6840589f 3799 {
27d0c333 3800 unsigned int dest_align
3801 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
c2f47e15 3802 const char *p = c_getstr (src);
6840589f 3803 rtx dest_mem;
3804
27d0c333 3805 if (!p || dest_align == 0 || !host_integerp (len, 1)
3806 || !can_store_by_pieces (tree_low_cst (len, 1),
6840589f 3807 builtin_strncpy_read_str,
364c0c59 3808 CONST_CAST (char *, p),
3809 dest_align, false))
c2f47e15 3810 return NULL_RTX;
6840589f 3811
d8ae1baa 3812 dest_mem = get_memory_rtx (dest, len);
27d0c333 3813 store_by_pieces (dest_mem, tree_low_cst (len, 1),
6840589f 3814 builtin_strncpy_read_str,
364c0c59 3815 CONST_CAST (char *, p), dest_align, false, 0);
e5716f7e 3816 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3817 dest_mem = convert_memory_address (ptr_mode, dest_mem);
e5716f7e 3818 return dest_mem;
6840589f 3819 }
ed09096d 3820 }
c2f47e15 3821 return NULL_RTX;
ed09096d 3822}
3823
ecc318ff 3824/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3825 bytes from constant string DATA + OFFSET and return it as target
3826 constant. */
3827
f656b751 3828rtx
aecda0d6 3829builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3830 enum machine_mode mode)
ecc318ff 3831{
3832 const char *c = (const char *) data;
364c0c59 3833 char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
ecc318ff 3834
3835 memset (p, *c, GET_MODE_SIZE (mode));
3836
3837 return c_readstr (p, mode);
3838}
3839
a7ec6974 3840/* Callback routine for store_by_pieces. Return the RTL of a register
3841 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3842 char value given in the RTL register data. For example, if mode is
3843 4 bytes wide, return the RTL for 0x01010101*data. */
3844
3845static rtx
aecda0d6 3846builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3847 enum machine_mode mode)
a7ec6974 3848{
3849 rtx target, coeff;
3850 size_t size;
3851 char *p;
3852
3853 size = GET_MODE_SIZE (mode);
f0ce3b1f 3854 if (size == 1)
3855 return (rtx) data;
a7ec6974 3856
364c0c59 3857 p = XALLOCAVEC (char, size);
a7ec6974 3858 memset (p, 1, size);
3859 coeff = c_readstr (p, mode);
3860
f0ce3b1f 3861 target = convert_to_mode (mode, (rtx) data, 1);
a7ec6974 3862 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3863 return force_reg (mode, target);
3864}
3865
c2f47e15 3866/* Expand expression EXP, which is a call to the memset builtin. Return
3867 NULL_RTX if we failed the caller should emit a normal call, otherwise
3868 try to get the result in TARGET, if convenient (and in mode MODE if that's
6f428e8b 3869 convenient). */
902de8ed 3870
53800dbe 3871static rtx
c2f47e15 3872expand_builtin_memset (tree exp, rtx target, enum machine_mode mode)
53800dbe 3873{
c2f47e15 3874 if (!validate_arglist (exp,
3875 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3876 return NULL_RTX;
53800dbe 3877 else
3878 {
c2f47e15 3879 tree dest = CALL_EXPR_ARG (exp, 0);
3880 tree val = CALL_EXPR_ARG (exp, 1);
3881 tree len = CALL_EXPR_ARG (exp, 2);
3882 return expand_builtin_memset_args (dest, val, len, target, mode, exp);
3883 }
3884}
53800dbe 3885
c2f47e15 3886/* Helper function to do the actual work for expand_builtin_memset. The
3887 arguments to the builtin_memset call DEST, VAL, and LEN are broken out
3888 so that this can also be called without constructing an actual CALL_EXPR.
3889 The other arguments and return value are the same as for
3890 expand_builtin_memset. */
6b961939 3891
c2f47e15 3892static rtx
3893expand_builtin_memset_args (tree dest, tree val, tree len,
3894 rtx target, enum machine_mode mode, tree orig_exp)
3895{
3896 tree fndecl, fn;
3897 enum built_in_function fcode;
3898 char c;
3899 unsigned int dest_align;
3900 rtx dest_mem, dest_addr, len_rtx;
3901 HOST_WIDE_INT expected_size = -1;
3902 unsigned int expected_align = 0;
75a70cf9 3903 tree_ann_common_t ann;
53800dbe 3904
c2f47e15 3905 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
162719b3 3906
c2f47e15 3907 /* If DEST is not a pointer type, don't do this operation in-line. */
3908 if (dest_align == 0)
3909 return NULL_RTX;
6f428e8b 3910
75a70cf9 3911 ann = tree_common_ann (orig_exp);
3912 if (ann)
3913 stringop_block_profile (ann->stmt, &expected_align, &expected_size);
3914
c2f47e15 3915 if (expected_align < dest_align)
3916 expected_align = dest_align;
6b961939 3917
c2f47e15 3918 /* If the LEN parameter is zero, return DEST. */
3919 if (integer_zerop (len))
3920 {
3921 /* Evaluate and ignore VAL in case it has side-effects. */
3922 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3923 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3924 }
7a3e5564 3925
c2f47e15 3926 /* Stabilize the arguments in case we fail. */
3927 dest = builtin_save_expr (dest);
3928 val = builtin_save_expr (val);
3929 len = builtin_save_expr (len);
a7ec6974 3930
c2f47e15 3931 len_rtx = expand_normal (len);
3932 dest_mem = get_memory_rtx (dest, len);
a7ec6974 3933
c2f47e15 3934 if (TREE_CODE (val) != INTEGER_CST)
3935 {
3936 rtx val_rtx;
a7ec6974 3937
c2f47e15 3938 val_rtx = expand_normal (val);
3939 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3940 val_rtx, 0);
53800dbe 3941
c2f47e15 3942 /* Assume that we can memset by pieces if we can store
3943 * the coefficients by pieces (in the required modes).
3944 * We can't pass builtin_memset_gen_str as that emits RTL. */
3945 c = 1;
3946 if (host_integerp (len, 1)
c2f47e15 3947 && can_store_by_pieces (tree_low_cst (len, 1),
4b297e2e 3948 builtin_memset_read_str, &c, dest_align,
3949 true))
c2f47e15 3950 {
3951 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3952 val_rtx);
3953 store_by_pieces (dest_mem, tree_low_cst (len, 1),
4b297e2e 3954 builtin_memset_gen_str, val_rtx, dest_align,
3955 true, 0);
c2f47e15 3956 }
3957 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3958 dest_align, expected_align,
3959 expected_size))
6b961939 3960 goto do_libcall;
c2f47e15 3961
3962 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3963 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3964 return dest_mem;
3965 }
53800dbe 3966
c2f47e15 3967 if (target_char_cast (val, &c))
3968 goto do_libcall;
ecc318ff 3969
c2f47e15 3970 if (c)
3971 {
3972 if (host_integerp (len, 1)
c2f47e15 3973 && can_store_by_pieces (tree_low_cst (len, 1),
4b297e2e 3974 builtin_memset_read_str, &c, dest_align,
3975 true))
c2f47e15 3976 store_by_pieces (dest_mem, tree_low_cst (len, 1),
4b297e2e 3977 builtin_memset_read_str, &c, dest_align, true, 0);
c2f47e15 3978 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3979 dest_align, expected_align,
3980 expected_size))
3981 goto do_libcall;
3982
3983 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3984 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3985 return dest_mem;
3986 }
ecc318ff 3987
c2f47e15 3988 set_mem_align (dest_mem, dest_align);
3989 dest_addr = clear_storage_hints (dest_mem, len_rtx,
3990 CALL_EXPR_TAILCALL (orig_exp)
3991 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3992 expected_align, expected_size);
53800dbe 3993
c2f47e15 3994 if (dest_addr == 0)
3995 {
3996 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3997 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3998 }
53800dbe 3999
c2f47e15 4000 return dest_addr;
6b961939 4001
c2f47e15 4002 do_libcall:
4003 fndecl = get_callee_fndecl (orig_exp);
4004 fcode = DECL_FUNCTION_CODE (fndecl);
4005 if (fcode == BUILT_IN_MEMSET)
4006 fn = build_call_expr (fndecl, 3, dest, val, len);
4007 else if (fcode == BUILT_IN_BZERO)
4008 fn = build_call_expr (fndecl, 2, dest, len);
4009 else
4010 gcc_unreachable ();
4011 if (TREE_CODE (fn) == CALL_EXPR)
4012 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
4013 return expand_call (fn, target, target == const0_rtx);
53800dbe 4014}
4015
c2f47e15 4016/* Expand expression EXP, which is a call to the bzero builtin. Return
4017 NULL_RTX if we failed the caller should emit a normal call. */
27d0c333 4018
ffc83088 4019static rtx
0b25db21 4020expand_builtin_bzero (tree exp)
ffc83088 4021{
c2f47e15 4022 tree dest, size;
ffc83088 4023
c2f47e15 4024 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7369e7ba 4025 return NULL_RTX;
ffc83088 4026
c2f47e15 4027 dest = CALL_EXPR_ARG (exp, 0);
4028 size = CALL_EXPR_ARG (exp, 1);
bf8e3599 4029
7369e7ba 4030 /* New argument list transforming bzero(ptr x, int y) to
6f428e8b 4031 memset(ptr x, int 0, size_t y). This is done this way
4032 so that if it isn't expanded inline, we fallback to
4033 calling bzero instead of memset. */
bf8e3599 4034
c2f47e15 4035 return expand_builtin_memset_args (dest, integer_zero_node,
4036 fold_convert (sizetype, size),
4037 const0_rtx, VOIDmode, exp);
ffc83088 4038}
4039
7959b13b 4040/* Expand a call to the memchr builtin. Return NULL_RTX if we failed the
4041 caller should emit a normal call, otherwise try to get the result
4042 in TARGET, if convenient (and in mode MODE if that's convenient). */
4043
4044static rtx
4045expand_builtin_memchr (tree exp, rtx target, enum machine_mode mode)
4046{
4047 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE,
4048 INTEGER_TYPE, VOID_TYPE))
4049 {
4050 tree type = TREE_TYPE (exp);
4051 tree result = fold_builtin_memchr (CALL_EXPR_ARG (exp, 0),
4052 CALL_EXPR_ARG (exp, 1),
4053 CALL_EXPR_ARG (exp, 2), type);
4054 if (result)
4055 return expand_expr (result, target, mode, EXPAND_NORMAL);
4056 }
4057 return NULL_RTX;
4058}
4059
7a3f89b5 4060/* Expand expression EXP, which is a call to the memcmp built-in function.
c2f47e15 4061 Return NULL_RTX if we failed and the
53800dbe 4062 caller should emit a normal call, otherwise try to get the result in
6f428e8b 4063 TARGET, if convenient (and in mode MODE, if that's convenient). */
27d0c333 4064
53800dbe 4065static rtx
c2f47e15 4066expand_builtin_memcmp (tree exp, rtx target, enum machine_mode mode)
53800dbe 4067{
c2f47e15 4068 if (!validate_arglist (exp,
4069 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4070 return NULL_RTX;
218bc19e 4071 else
6f428e8b 4072 {
c2f47e15 4073 tree result = fold_builtin_memcmp (CALL_EXPR_ARG (exp, 0),
4074 CALL_EXPR_ARG (exp, 1),
4075 CALL_EXPR_ARG (exp, 2));
218bc19e 4076 if (result)
4077 return expand_expr (result, target, mode, EXPAND_NORMAL);
6f428e8b 4078 }
4079
6ac5504b 4080#if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
53800dbe 4081 {
0cd832f0 4082 rtx arg1_rtx, arg2_rtx, arg3_rtx;
53800dbe 4083 rtx result;
0cd832f0 4084 rtx insn;
c2f47e15 4085 tree arg1 = CALL_EXPR_ARG (exp, 0);
4086 tree arg2 = CALL_EXPR_ARG (exp, 1);
4087 tree len = CALL_EXPR_ARG (exp, 2);
53800dbe 4088
4089 int arg1_align
4090 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4091 int arg2_align
4092 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
b428c0a5 4093 enum machine_mode insn_mode;
4094
4095#ifdef HAVE_cmpmemsi
4096 if (HAVE_cmpmemsi)
4097 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
4098 else
4099#endif
6ac5504b 4100#ifdef HAVE_cmpstrnsi
4101 if (HAVE_cmpstrnsi)
4102 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
b428c0a5 4103 else
4104#endif
c2f47e15 4105 return NULL_RTX;
53800dbe 4106
4107 /* If we don't have POINTER_TYPE, call the function. */
4108 if (arg1_align == 0 || arg2_align == 0)
c2f47e15 4109 return NULL_RTX;
53800dbe 4110
4111 /* Make a place to write the result of the instruction. */
4112 result = target;
4113 if (! (result != 0
8ad4c111 4114 && REG_P (result) && GET_MODE (result) == insn_mode
53800dbe 4115 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4116 result = gen_reg_rtx (insn_mode);
4117
d8ae1baa 4118 arg1_rtx = get_memory_rtx (arg1, len);
4119 arg2_rtx = get_memory_rtx (arg2, len);
8ec3c5c2 4120 arg3_rtx = expand_normal (len);
83f88f8e 4121
4122 /* Set MEM_SIZE as appropriate. */
4123 if (GET_CODE (arg3_rtx) == CONST_INT)
4124 {
4125 set_mem_size (arg1_rtx, arg3_rtx);
4126 set_mem_size (arg2_rtx, arg3_rtx);
4127 }
4128
b428c0a5 4129#ifdef HAVE_cmpmemsi
4130 if (HAVE_cmpmemsi)
4131 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4132 GEN_INT (MIN (arg1_align, arg2_align)));
0cd832f0 4133 else
b428c0a5 4134#endif
6ac5504b 4135#ifdef HAVE_cmpstrnsi
4136 if (HAVE_cmpstrnsi)
4137 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4138 GEN_INT (MIN (arg1_align, arg2_align)));
b428c0a5 4139 else
4140#endif
64db345d 4141 gcc_unreachable ();
0cd832f0 4142
4143 if (insn)
4144 emit_insn (insn);
4145 else
2dd6f9ed 4146 emit_library_call_value (memcmp_libfunc, result, LCT_PURE,
0cd832f0 4147 TYPE_MODE (integer_type_node), 3,
4148 XEXP (arg1_rtx, 0), Pmode,
4149 XEXP (arg2_rtx, 0), Pmode,
4150 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
78a8ed03 4151 TYPE_UNSIGNED (sizetype)),
0cd832f0 4152 TYPE_MODE (sizetype));
53800dbe 4153
4154 /* Return the value in the proper mode for this function. */
4155 mode = TYPE_MODE (TREE_TYPE (exp));
4156 if (GET_MODE (result) == mode)
4157 return result;
4158 else if (target != 0)
4159 {
4160 convert_move (target, result, 0);
4161 return target;
4162 }
4163 else
4164 return convert_to_mode (mode, result, 0);
4165 }
83d79705 4166#endif
53800dbe 4167
c2f47e15 4168 return NULL_RTX;
6f428e8b 4169}
4170
c2f47e15 4171/* Expand expression EXP, which is a call to the strcmp builtin. Return NULL_RTX
53800dbe 4172 if we failed the caller should emit a normal call, otherwise try to get
4173 the result in TARGET, if convenient. */
902de8ed 4174
53800dbe 4175static rtx
aecda0d6 4176expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
53800dbe 4177{
c2f47e15 4178 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4179 return NULL_RTX;
218bc19e 4180 else
ef6c187e 4181 {
c2f47e15 4182 tree result = fold_builtin_strcmp (CALL_EXPR_ARG (exp, 0),
4183 CALL_EXPR_ARG (exp, 1));
218bc19e 4184 if (result)
4185 return expand_expr (result, target, mode, EXPAND_NORMAL);
ef6c187e 4186 }
bf8e3599 4187
6ac5504b 4188#if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
4189 if (cmpstr_optab[SImode] != CODE_FOR_nothing
4190 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
4191 {
4192 rtx arg1_rtx, arg2_rtx;
4193 rtx result, insn = NULL_RTX;
4194 tree fndecl, fn;
c2f47e15 4195 tree arg1 = CALL_EXPR_ARG (exp, 0);
4196 tree arg2 = CALL_EXPR_ARG (exp, 1);
a0c938f0 4197
6ac5504b 4198 int arg1_align
4199 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4200 int arg2_align
4201 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4202
4203 /* If we don't have POINTER_TYPE, call the function. */
4204 if (arg1_align == 0 || arg2_align == 0)
c2f47e15 4205 return NULL_RTX;
7a3f89b5 4206
6ac5504b 4207 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
4208 arg1 = builtin_save_expr (arg1);
4209 arg2 = builtin_save_expr (arg2);
7a3f89b5 4210
d8ae1baa 4211 arg1_rtx = get_memory_rtx (arg1, NULL);
4212 arg2_rtx = get_memory_rtx (arg2, NULL);
53800dbe 4213
6ac5504b 4214#ifdef HAVE_cmpstrsi
4215 /* Try to call cmpstrsi. */
4216 if (HAVE_cmpstrsi)
4217 {
a0c938f0 4218 enum machine_mode insn_mode
6ac5504b 4219 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
4220
4221 /* Make a place to write the result of the instruction. */
4222 result = target;
4223 if (! (result != 0
4224 && REG_P (result) && GET_MODE (result) == insn_mode
4225 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4226 result = gen_reg_rtx (insn_mode);
4227
4228 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
4229 GEN_INT (MIN (arg1_align, arg2_align)));
4230 }
4231#endif
03fd9d2c 4232#ifdef HAVE_cmpstrnsi
6ac5504b 4233 /* Try to determine at least one length and call cmpstrnsi. */
a0c938f0 4234 if (!insn && HAVE_cmpstrnsi)
6ac5504b 4235 {
4236 tree len;
4237 rtx arg3_rtx;
4238
a0c938f0 4239 enum machine_mode insn_mode
6ac5504b 4240 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
4241 tree len1 = c_strlen (arg1, 1);
4242 tree len2 = c_strlen (arg2, 1);
4243
4244 if (len1)
4245 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
4246 if (len2)
4247 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
4248
4249 /* If we don't have a constant length for the first, use the length
4250 of the second, if we know it. We don't require a constant for
4251 this case; some cost analysis could be done if both are available
4252 but neither is constant. For now, assume they're equally cheap,
4253 unless one has side effects. If both strings have constant lengths,
4254 use the smaller. */
4255
4256 if (!len1)
4257 len = len2;
4258 else if (!len2)
4259 len = len1;
4260 else if (TREE_SIDE_EFFECTS (len1))
4261 len = len2;
4262 else if (TREE_SIDE_EFFECTS (len2))
4263 len = len1;
4264 else if (TREE_CODE (len1) != INTEGER_CST)
4265 len = len2;
4266 else if (TREE_CODE (len2) != INTEGER_CST)
4267 len = len1;
4268 else if (tree_int_cst_lt (len1, len2))
4269 len = len1;
4270 else
4271 len = len2;
4272
4273 /* If both arguments have side effects, we cannot optimize. */
4274 if (!len || TREE_SIDE_EFFECTS (len))
6b961939 4275 goto do_libcall;
53800dbe 4276
8ec3c5c2 4277 arg3_rtx = expand_normal (len);
902de8ed 4278
6ac5504b 4279 /* Make a place to write the result of the instruction. */
4280 result = target;
4281 if (! (result != 0
4282 && REG_P (result) && GET_MODE (result) == insn_mode
4283 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4284 result = gen_reg_rtx (insn_mode);
53800dbe 4285
6ac5504b 4286 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4287 GEN_INT (MIN (arg1_align, arg2_align)));
4288 }
4289#endif
3f8aefe2 4290
6ac5504b 4291 if (insn)
4292 {
4293 emit_insn (insn);
3f8aefe2 4294
6ac5504b 4295 /* Return the value in the proper mode for this function. */
4296 mode = TYPE_MODE (TREE_TYPE (exp));
4297 if (GET_MODE (result) == mode)
4298 return result;
4299 if (target == 0)
4300 return convert_to_mode (mode, result, 0);
4301 convert_move (target, result, 0);
4302 return target;
4303 }
902de8ed 4304
6ac5504b 4305 /* Expand the library call ourselves using a stabilized argument
4306 list to avoid re-evaluating the function's arguments twice. */
2694880e 4307#ifdef HAVE_cmpstrnsi
6b961939 4308 do_libcall:
2694880e 4309#endif
6ac5504b 4310 fndecl = get_callee_fndecl (exp);
c2f47e15 4311 fn = build_call_expr (fndecl, 2, arg1, arg2);
6ac5504b 4312 if (TREE_CODE (fn) == CALL_EXPR)
4313 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4314 return expand_call (fn, target, target == const0_rtx);
4315 }
7a3f89b5 4316#endif
c2f47e15 4317 return NULL_RTX;
83d79705 4318}
53800dbe 4319
c2f47e15 4320/* Expand expression EXP, which is a call to the strncmp builtin. Return
4321 NULL_RTX if we failed the caller should emit a normal call, otherwise try to get
ed09096d 4322 the result in TARGET, if convenient. */
27d0c333 4323
ed09096d 4324static rtx
aecda0d6 4325expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
ed09096d 4326{
c2f47e15 4327 if (!validate_arglist (exp,
4328 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4329 return NULL_RTX;
218bc19e 4330 else
ef6c187e 4331 {
c2f47e15 4332 tree result = fold_builtin_strncmp (CALL_EXPR_ARG (exp, 0),
4333 CALL_EXPR_ARG (exp, 1),
4334 CALL_EXPR_ARG (exp, 2));
218bc19e 4335 if (result)
4336 return expand_expr (result, target, mode, EXPAND_NORMAL);
ef6c187e 4337 }
ed09096d 4338
6e34e617 4339 /* If c_strlen can determine an expression for one of the string
6ac5504b 4340 lengths, and it doesn't have side effects, then emit cmpstrnsi
7a3f89b5 4341 using length MIN(strlen(string)+1, arg3). */
6ac5504b 4342#ifdef HAVE_cmpstrnsi
4343 if (HAVE_cmpstrnsi)
7a3f89b5 4344 {
4345 tree len, len1, len2;
4346 rtx arg1_rtx, arg2_rtx, arg3_rtx;
4347 rtx result, insn;
0b25db21 4348 tree fndecl, fn;
c2f47e15 4349 tree arg1 = CALL_EXPR_ARG (exp, 0);
4350 tree arg2 = CALL_EXPR_ARG (exp, 1);
4351 tree arg3 = CALL_EXPR_ARG (exp, 2);
6f428e8b 4352
7a3f89b5 4353 int arg1_align
4354 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4355 int arg2_align
4356 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4357 enum machine_mode insn_mode
6ac5504b 4358 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
bf8e3599 4359
681fab1e 4360 len1 = c_strlen (arg1, 1);
4361 len2 = c_strlen (arg2, 1);
7a3f89b5 4362
4363 if (len1)
4364 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
4365 if (len2)
4366 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
4367
4368 /* If we don't have a constant length for the first, use the length
4369 of the second, if we know it. We don't require a constant for
4370 this case; some cost analysis could be done if both are available
4371 but neither is constant. For now, assume they're equally cheap,
4372 unless one has side effects. If both strings have constant lengths,
4373 use the smaller. */
4374
4375 if (!len1)
4376 len = len2;
4377 else if (!len2)
4378 len = len1;
4379 else if (TREE_SIDE_EFFECTS (len1))
4380 len = len2;
4381 else if (TREE_SIDE_EFFECTS (len2))
4382 len = len1;
4383 else if (TREE_CODE (len1) != INTEGER_CST)
4384 len = len2;
4385 else if (TREE_CODE (len2) != INTEGER_CST)
4386 len = len1;
4387 else if (tree_int_cst_lt (len1, len2))
4388 len = len1;
4389 else
4390 len = len2;
6e34e617 4391
7a3f89b5 4392 /* If both arguments have side effects, we cannot optimize. */
4393 if (!len || TREE_SIDE_EFFECTS (len))
c2f47e15 4394 return NULL_RTX;
bf8e3599 4395
7a3f89b5 4396 /* The actual new length parameter is MIN(len,arg3). */
49d00087 4397 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
4398 fold_convert (TREE_TYPE (len), arg3));
7a3f89b5 4399
4400 /* If we don't have POINTER_TYPE, call the function. */
4401 if (arg1_align == 0 || arg2_align == 0)
c2f47e15 4402 return NULL_RTX;
7a3f89b5 4403
4404 /* Make a place to write the result of the instruction. */
4405 result = target;
4406 if (! (result != 0
8ad4c111 4407 && REG_P (result) && GET_MODE (result) == insn_mode
7a3f89b5 4408 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4409 result = gen_reg_rtx (insn_mode);
4410
6ac5504b 4411 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
4ee9c684 4412 arg1 = builtin_save_expr (arg1);
4413 arg2 = builtin_save_expr (arg2);
4414 len = builtin_save_expr (len);
3f8aefe2 4415
d8ae1baa 4416 arg1_rtx = get_memory_rtx (arg1, len);
4417 arg2_rtx = get_memory_rtx (arg2, len);
8ec3c5c2 4418 arg3_rtx = expand_normal (len);
6ac5504b 4419 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4420 GEN_INT (MIN (arg1_align, arg2_align)));
3f8aefe2 4421 if (insn)
4422 {
4423 emit_insn (insn);
4424
4425 /* Return the value in the proper mode for this function. */
4426 mode = TYPE_MODE (TREE_TYPE (exp));
4427 if (GET_MODE (result) == mode)
4428 return result;
4429 if (target == 0)
4430 return convert_to_mode (mode, result, 0);
4431 convert_move (target, result, 0);
4432 return target;
4433 }
7a3f89b5 4434
3f8aefe2 4435 /* Expand the library call ourselves using a stabilized argument
4436 list to avoid re-evaluating the function's arguments twice. */
3f8aefe2 4437 fndecl = get_callee_fndecl (exp);
c2f47e15 4438 fn = build_call_expr (fndecl, 3, arg1, arg2, len);
0b25db21 4439 if (TREE_CODE (fn) == CALL_EXPR)
4440 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4441 return expand_call (fn, target, target == const0_rtx);
7a3f89b5 4442 }
4443#endif
c2f47e15 4444 return NULL_RTX;
ed09096d 4445}
4446
49f0327b 4447/* Expand expression EXP, which is a call to the strcat builtin.
c2f47e15 4448 Return NULL_RTX if we failed the caller should emit a normal call,
49f0327b 4449 otherwise try to get the result in TARGET, if convenient. */
27d0c333 4450
49f0327b 4451static rtx
c2f47e15 4452expand_builtin_strcat (tree fndecl, tree exp, rtx target, enum machine_mode mode)
49f0327b 4453{
c2f47e15 4454 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4455 return NULL_RTX;
49f0327b 4456 else
4457 {
c2f47e15 4458 tree dst = CALL_EXPR_ARG (exp, 0);
4459 tree src = CALL_EXPR_ARG (exp, 1);
49f0327b 4460 const char *p = c_getstr (src);
4461
1d89860b 4462 /* If the string length is zero, return the dst parameter. */
a0c938f0 4463 if (p && *p == '\0')
1d89860b 4464 return expand_expr (dst, target, mode, EXPAND_NORMAL);
a0c938f0 4465
1d89860b 4466 if (!optimize_size)
ca71f89b 4467 {
1d89860b 4468 /* See if we can store by pieces into (dst + strlen(dst)). */
4469 tree newsrc, newdst,
4470 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4471 rtx insns;
4472
4473 /* Stabilize the argument list. */
4474 newsrc = builtin_save_expr (src);
1d89860b 4475 dst = builtin_save_expr (dst);
4476
4477 start_sequence ();
4478
4479 /* Create strlen (dst). */
c2f47e15 4480 newdst = build_call_expr (strlen_fn, 1, dst);
0de36bdb 4481 /* Create (dst p+ strlen (dst)). */
1d89860b 4482
0de36bdb 4483 newdst = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
1d89860b 4484 newdst = builtin_save_expr (newdst);
1d89860b 4485
c2f47e15 4486 if (!expand_builtin_strcpy_args (fndecl, newdst, newsrc, target, mode))
ca71f89b 4487 {
1d89860b 4488 end_sequence (); /* Stop sequence. */
c2f47e15 4489 return NULL_RTX;
ca71f89b 4490 }
a0c938f0 4491
1d89860b 4492 /* Output the entire sequence. */
4493 insns = get_insns ();
4494 end_sequence ();
4495 emit_insn (insns);
a0c938f0 4496
1d89860b 4497 return expand_expr (dst, target, mode, EXPAND_NORMAL);
ca71f89b 4498 }
49f0327b 4499
c2f47e15 4500 return NULL_RTX;
49f0327b 4501 }
4502}
4503
4504/* Expand expression EXP, which is a call to the strncat builtin.
c2f47e15 4505 Return NULL_RTX if we failed the caller should emit a normal call,
49f0327b 4506 otherwise try to get the result in TARGET, if convenient. */
27d0c333 4507
49f0327b 4508static rtx
c2f47e15 4509expand_builtin_strncat (tree exp, rtx target, enum machine_mode mode)
49f0327b 4510{
c2f47e15 4511 if (validate_arglist (exp,
4512 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
49f0327b 4513 {
c2f47e15 4514 tree result = fold_builtin_strncat (CALL_EXPR_ARG (exp, 0),
4515 CALL_EXPR_ARG (exp, 1),
4516 CALL_EXPR_ARG (exp, 2));
2c84ee37 4517 if (result)
4518 return expand_expr (result, target, mode, EXPAND_NORMAL);
49f0327b 4519 }
c2f47e15 4520 return NULL_RTX;
49f0327b 4521}
4522
4523/* Expand expression EXP, which is a call to the strspn builtin.
c2f47e15 4524 Return NULL_RTX if we failed the caller should emit a normal call,
49f0327b 4525 otherwise try to get the result in TARGET, if convenient. */
27d0c333 4526
49f0327b 4527static rtx
c2f47e15 4528expand_builtin_strspn (tree exp, rtx target, enum machine_mode mode)
49f0327b 4529{
c2f47e15 4530 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
49f0327b 4531 {
c2f47e15 4532 tree result = fold_builtin_strspn (CALL_EXPR_ARG (exp, 0),
4533 CALL_EXPR_ARG (exp, 1));
2c84ee37 4534 if (result)
4535 return expand_expr (result, target, mode, EXPAND_NORMAL);
49f0327b 4536 }
c2f47e15 4537 return NULL_RTX;
49f0327b 4538}
4539
4540/* Expand expression EXP, which is a call to the strcspn builtin.
c2f47e15 4541 Return NULL_RTX if we failed the caller should emit a normal call,
49f0327b 4542 otherwise try to get the result in TARGET, if convenient. */
27d0c333 4543
49f0327b 4544static rtx
c2f47e15 4545expand_builtin_strcspn (tree exp, rtx target, enum machine_mode mode)
49f0327b 4546{
c2f47e15 4547 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
49f0327b 4548 {
c2f47e15 4549 tree result = fold_builtin_strcspn (CALL_EXPR_ARG (exp, 0),
4550 CALL_EXPR_ARG (exp, 1));
2c84ee37 4551 if (result)
4552 return expand_expr (result, target, mode, EXPAND_NORMAL);
49f0327b 4553 }
c2f47e15 4554 return NULL_RTX;
49f0327b 4555}
4556
a66c9326 4557/* Expand a call to __builtin_saveregs, generating the result in TARGET,
4558 if that's convenient. */
902de8ed 4559
a66c9326 4560rtx
aecda0d6 4561expand_builtin_saveregs (void)
53800dbe 4562{
a66c9326 4563 rtx val, seq;
53800dbe 4564
4565 /* Don't do __builtin_saveregs more than once in a function.
4566 Save the result of the first call and reuse it. */
4567 if (saveregs_value != 0)
4568 return saveregs_value;
53800dbe 4569
a66c9326 4570 /* When this function is called, it means that registers must be
4571 saved on entry to this function. So we migrate the call to the
4572 first insn of this function. */
4573
4574 start_sequence ();
53800dbe 4575
a66c9326 4576 /* Do whatever the machine needs done in this case. */
45550790 4577 val = targetm.calls.expand_builtin_saveregs ();
53800dbe 4578
a66c9326 4579 seq = get_insns ();
4580 end_sequence ();
53800dbe 4581
a66c9326 4582 saveregs_value = val;
53800dbe 4583
31d3e01c 4584 /* Put the insns after the NOTE that starts the function. If this
4585 is inside a start_sequence, make the outer-level insn chain current, so
a66c9326 4586 the code is placed at the start of the function. */
4587 push_topmost_sequence ();
0ec80471 4588 emit_insn_after (seq, entry_of_function ());
a66c9326 4589 pop_topmost_sequence ();
4590
4591 return val;
53800dbe 4592}
4593
4594/* __builtin_args_info (N) returns word N of the arg space info
4595 for the current function. The number and meanings of words
4596 is controlled by the definition of CUMULATIVE_ARGS. */
f7c44134 4597
53800dbe 4598static rtx
c2f47e15 4599expand_builtin_args_info (tree exp)
53800dbe 4600{
53800dbe 4601 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
abe32cce 4602 int *word_ptr = (int *) &crtl->args.info;
53800dbe 4603
64db345d 4604 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
53800dbe 4605
c2f47e15 4606 if (call_expr_nargs (exp) != 0)
53800dbe 4607 {
c2f47e15 4608 if (!host_integerp (CALL_EXPR_ARG (exp, 0), 0))
eb586f2c 4609 error ("argument of %<__builtin_args_info%> must be constant");
53800dbe 4610 else
4611 {
c2f47e15 4612 HOST_WIDE_INT wordnum = tree_low_cst (CALL_EXPR_ARG (exp, 0), 0);
53800dbe 4613
27d0c333 4614 if (wordnum < 0 || wordnum >= nwords)
eb586f2c 4615 error ("argument of %<__builtin_args_info%> out of range");
53800dbe 4616 else
4617 return GEN_INT (word_ptr[wordnum]);
4618 }
4619 }
4620 else
eb586f2c 4621 error ("missing argument in %<__builtin_args_info%>");
53800dbe 4622
4623 return const0_rtx;
53800dbe 4624}
4625
79012a9d 4626/* Expand a call to __builtin_next_arg. */
27d0c333 4627
53800dbe 4628static rtx
79012a9d 4629expand_builtin_next_arg (void)
53800dbe 4630{
79012a9d 4631 /* Checking arguments is already done in fold_builtin_next_arg
4632 that must be called before this function. */
940ddc5c 4633 return expand_binop (ptr_mode, add_optab,
abe32cce 4634 crtl->args.internal_arg_pointer,
4635 crtl->args.arg_offset_rtx,
53800dbe 4636 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4637}
4638
a66c9326 4639/* Make it easier for the backends by protecting the valist argument
4640 from multiple evaluations. */
4641
4642static tree
aecda0d6 4643stabilize_va_list (tree valist, int needs_lvalue)
a66c9326 4644{
5f57a8b1 4645 tree vatype = targetm.canonical_va_list_type (TREE_TYPE (valist));
4646
4647 gcc_assert (vatype != NULL_TREE);
4648
4649 if (TREE_CODE (vatype) == ARRAY_TYPE)
a66c9326 4650 {
2d47cc32 4651 if (TREE_SIDE_EFFECTS (valist))
4652 valist = save_expr (valist);
11a61dea 4653
2d47cc32 4654 /* For this case, the backends will be expecting a pointer to
5f57a8b1 4655 vatype, but it's possible we've actually been given an array
4656 (an actual TARGET_CANONICAL_VA_LIST_TYPE (valist)).
2d47cc32 4657 So fix it. */
4658 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
8a15c04a 4659 {
5f57a8b1 4660 tree p1 = build_pointer_type (TREE_TYPE (vatype));
fcdd3ab3 4661 valist = build_fold_addr_expr_with_type (valist, p1);
8a15c04a 4662 }
a66c9326 4663 }
11a61dea 4664 else
a66c9326 4665 {
2d47cc32 4666 tree pt;
11a61dea 4667
2d47cc32 4668 if (! needs_lvalue)
4669 {
11a61dea 4670 if (! TREE_SIDE_EFFECTS (valist))
4671 return valist;
bf8e3599 4672
5f57a8b1 4673 pt = build_pointer_type (vatype);
49d00087 4674 valist = fold_build1 (ADDR_EXPR, pt, valist);
a66c9326 4675 TREE_SIDE_EFFECTS (valist) = 1;
a66c9326 4676 }
2d47cc32 4677
11a61dea 4678 if (TREE_SIDE_EFFECTS (valist))
2d47cc32 4679 valist = save_expr (valist);
fcdd3ab3 4680 valist = build_fold_indirect_ref (valist);
a66c9326 4681 }
4682
4683 return valist;
4684}
4685
2e15d750 4686/* The "standard" definition of va_list is void*. */
4687
4688tree
4689std_build_builtin_va_list (void)
4690{
4691 return ptr_type_node;
4692}
4693
5f57a8b1 4694/* The "standard" abi va_list is va_list_type_node. */
4695
4696tree
4697std_fn_abi_va_list (tree fndecl ATTRIBUTE_UNUSED)
4698{
4699 return va_list_type_node;
4700}
4701
4702/* The "standard" type of va_list is va_list_type_node. */
4703
4704tree
4705std_canonical_va_list_type (tree type)
4706{
4707 tree wtype, htype;
4708
4709 if (INDIRECT_REF_P (type))
4710 type = TREE_TYPE (type);
4711 else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE(type)))
4712 type = TREE_TYPE (type);
5f57a8b1 4713 wtype = va_list_type_node;
4714 htype = type;
7b36f9ab 4715 /* Treat structure va_list types. */
4716 if (TREE_CODE (wtype) == RECORD_TYPE && POINTER_TYPE_P (htype))
4717 htype = TREE_TYPE (htype);
4718 else if (TREE_CODE (wtype) == ARRAY_TYPE)
5f57a8b1 4719 {
4720 /* If va_list is an array type, the argument may have decayed
4721 to a pointer type, e.g. by being passed to another function.
4722 In that case, unwrap both types so that we can compare the
4723 underlying records. */
4724 if (TREE_CODE (htype) == ARRAY_TYPE
4725 || POINTER_TYPE_P (htype))
4726 {
4727 wtype = TREE_TYPE (wtype);
4728 htype = TREE_TYPE (htype);
4729 }
4730 }
4731 if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
4732 return va_list_type_node;
4733
4734 return NULL_TREE;
4735}
4736
a66c9326 4737/* The "standard" implementation of va_start: just assign `nextarg' to
4738 the variable. */
27d0c333 4739
a66c9326 4740void
aecda0d6 4741std_expand_builtin_va_start (tree valist, rtx nextarg)
a66c9326 4742{
f03c17bc 4743 rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
4744 convert_move (va_r, nextarg, 0);
a66c9326 4745}
4746
c2f47e15 4747/* Expand EXP, a call to __builtin_va_start. */
27d0c333 4748
a66c9326 4749static rtx
c2f47e15 4750expand_builtin_va_start (tree exp)
a66c9326 4751{
4752 rtx nextarg;
c2f47e15 4753 tree valist;
a66c9326 4754
c2f47e15 4755 if (call_expr_nargs (exp) < 2)
cb166087 4756 {
4757 error ("too few arguments to function %<va_start%>");
4758 return const0_rtx;
4759 }
a66c9326 4760
c2f47e15 4761 if (fold_builtin_next_arg (exp, true))
79012a9d 4762 return const0_rtx;
7c2f0500 4763
79012a9d 4764 nextarg = expand_builtin_next_arg ();
c2f47e15 4765 valist = stabilize_va_list (CALL_EXPR_ARG (exp, 0), 1);
a66c9326 4766
8a58ed0a 4767 if (targetm.expand_builtin_va_start)
4768 targetm.expand_builtin_va_start (valist, nextarg);
4769 else
4770 std_expand_builtin_va_start (valist, nextarg);
a66c9326 4771
4772 return const0_rtx;
4773}
4774
a66c9326 4775/* The "standard" implementation of va_arg: read the value from the
4776 current (padded) address and increment by the (padded) size. */
f7c44134 4777
e0eca1fa 4778tree
75a70cf9 4779std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
4780 gimple_seq *post_p)
fcdd3ab3 4781{
52cc2eeb 4782 tree addr, t, type_size, rounded_size, valist_tmp;
b8e8e485 4783 unsigned HOST_WIDE_INT align, boundary;
bef380a4 4784 bool indirect;
52cc2eeb 4785
4786#ifdef ARGS_GROW_DOWNWARD
4787 /* All of the alignment and movement below is for args-grow-up machines.
4788 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4789 implement their own specialized gimplify_va_arg_expr routines. */
64db345d 4790 gcc_unreachable ();
52cc2eeb 4791#endif
fcdd3ab3 4792
bef380a4 4793 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4794 if (indirect)
4795 type = build_pointer_type (type);
4796
52cc2eeb 4797 align = PARM_BOUNDARY / BITS_PER_UNIT;
c8b779eb 4798 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
4799
4800 /* When we align parameter on stack for caller, if the parameter
befa808c 4801 alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
4802 aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
c8b779eb 4803 here with caller. */
befa808c 4804 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
4805 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
c8b779eb 4806
4807 boundary /= BITS_PER_UNIT;
fcdd3ab3 4808
52cc2eeb 4809 /* Hoist the valist value into a temporary for the moment. */
ecdeeb37 4810 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4811
fcdd3ab3 4812 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4813 requires greater alignment, we must perform dynamic alignment. */
85c1f587 4814 if (boundary > align
4815 && !integer_zerop (TYPE_SIZE (type)))
fcdd3ab3 4816 {
41076ef6 4817 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
0de36bdb 4818 fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (valist),
4819 valist_tmp, size_int (boundary - 1)));
52cc2eeb 4820 gimplify_and_add (t, pre_p);
4821
0de36bdb 4822 t = fold_convert (sizetype, valist_tmp);
41076ef6 4823 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
0de36bdb 4824 fold_convert (TREE_TYPE (valist),
4825 fold_build2 (BIT_AND_EXPR, sizetype, t,
4826 size_int (-boundary))));
ecdeeb37 4827 gimplify_and_add (t, pre_p);
fcdd3ab3 4828 }
c5dc0c32 4829 else
4830 boundary = align;
4831
4832 /* If the actual alignment is less than the alignment of the type,
4833 adjust the type accordingly so that we don't assume strict alignment
f0b5f617 4834 when dereferencing the pointer. */
c5dc0c32 4835 boundary *= BITS_PER_UNIT;
4836 if (boundary < TYPE_ALIGN (type))
4837 {
4838 type = build_variant_type_copy (type);
4839 TYPE_ALIGN (type) = boundary;
4840 }
fcdd3ab3 4841
bcff3604 4842 /* Compute the rounded size of the type. */
52cc2eeb 4843 type_size = size_in_bytes (type);
4844 rounded_size = round_up (type_size, align);
4845
fcdd3ab3 4846 /* Reduce rounded_size so it's sharable with the postqueue. */
4847 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4848
4849 /* Get AP. */
ecdeeb37 4850 addr = valist_tmp;
52cc2eeb 4851 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
fcdd3ab3 4852 {
4853 /* Small args are padded downward. */
49d00087 4854 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4855 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4856 size_binop (MINUS_EXPR, rounded_size, type_size));
0de36bdb 4857 addr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (addr), addr, t);
fcdd3ab3 4858 }
4859
fcdd3ab3 4860 /* Compute new value for AP. */
0de36bdb 4861 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (valist), valist_tmp, rounded_size);
41076ef6 4862 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
ecdeeb37 4863 gimplify_and_add (t, pre_p);
e0eca1fa 4864
4865 addr = fold_convert (build_pointer_type (type), addr);
fcdd3ab3 4866
bef380a4 4867 if (indirect)
f2462d6c 4868 addr = build_va_arg_indirect_ref (addr);
4869
4870 return build_va_arg_indirect_ref (addr);
4871}
a0930a69 4872
f2462d6c 4873/* Build an indirect-ref expression over the given TREE, which represents a
4874 piece of a va_arg() expansion. */
4875tree
4876build_va_arg_indirect_ref (tree addr)
4877{
a0930a69 4878 addr = build_fold_indirect_ref (addr);
f2462d6c 4879
a0930a69 4880 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4881 mf_mark (addr);
bef380a4 4882
a0930a69 4883 return addr;
433006a9 4884}
4885
fcdd3ab3 4886/* Return a dummy expression of type TYPE in order to keep going after an
4887 error. */
4888
4889static tree
4890dummy_object (tree type)
4891{
535664e3 4892 tree t = build_int_cst (build_pointer_type (type), 0);
fcdd3ab3 4893 return build1 (INDIRECT_REF, type, t);
4894}
4895
2799a2b7 4896/* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4897 builtin function, but a very special sort of operator. */
fcdd3ab3 4898
4899enum gimplify_status
75a70cf9 4900gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
fcdd3ab3 4901{
5f57a8b1 4902 tree promoted_type, have_va_type;
fcdd3ab3 4903 tree valist = TREE_OPERAND (*expr_p, 0);
4904 tree type = TREE_TYPE (*expr_p);
4905 tree t;
4906
4907 /* Verify that valist is of the proper type. */
fcdd3ab3 4908 have_va_type = TREE_TYPE (valist);
f43dda35 4909 if (have_va_type == error_mark_node)
4910 return GS_ERROR;
5f57a8b1 4911 have_va_type = targetm.canonical_va_list_type (have_va_type);
f43dda35 4912
5f57a8b1 4913 if (have_va_type == NULL_TREE)
fcdd3ab3 4914 {
eb586f2c 4915 error ("first argument to %<va_arg%> not of type %<va_list%>");
e0eca1fa 4916 return GS_ERROR;
fcdd3ab3 4917 }
4918
4919 /* Generate a diagnostic for requesting data of a type that cannot
4920 be passed through `...' due to type promotion at the call site. */
5f57a8b1 4921 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
fcdd3ab3 4922 != type)
4923 {
4924 static bool gave_help;
4925
4926 /* Unfortunately, this is merely undefined, rather than a constraint
4927 violation, so we cannot make this an error. If this call is never
4928 executed, the program is still strictly conforming. */
c3ceba8e 4929 warning (0, "%qT is promoted to %qT when passed through %<...%>",
fcdd3ab3 4930 type, promoted_type);
4931 if (! gave_help)
4932 {
4933 gave_help = true;
2006d7dc 4934 inform ("(so you should pass %qT not %qT to %<va_arg%>)",
fcdd3ab3 4935 promoted_type, type);
4936 }
4937
4938 /* We can, however, treat "undefined" any way we please.
4939 Call abort to encourage the user to fix the program. */
4940 inform ("if this code is reached, the program will abort");
c2f47e15 4941 t = build_call_expr (implicit_built_in_decls[BUILT_IN_TRAP], 0);
75a70cf9 4942 gimplify_and_add (t, pre_p);
fcdd3ab3 4943
4944 /* This is dead code, but go ahead and finish so that the
4945 mode of the result comes out right. */
4946 *expr_p = dummy_object (type);
4947 return GS_ALL_DONE;
4948 }
4949 else
4950 {
4951 /* Make it easier for the backends by protecting the valist argument
a0c938f0 4952 from multiple evaluations. */
5f57a8b1 4953 if (TREE_CODE (have_va_type) == ARRAY_TYPE)
e0eca1fa 4954 {
4955 /* For this case, the backends will be expecting a pointer to
5f57a8b1 4956 TREE_TYPE (abi), but it's possible we've
4957 actually been given an array (an actual TARGET_FN_ABI_VA_LIST).
e0eca1fa 4958 So fix it. */
4959 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4960 {
5f57a8b1 4961 tree p1 = build_pointer_type (TREE_TYPE (have_va_type));
e0eca1fa 4962 valist = build_fold_addr_expr_with_type (valist, p1);
4963 }
75a70cf9 4964
e0eca1fa 4965 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4966 }
4967 else
4968 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
fcdd3ab3 4969
17a6380d 4970 if (!targetm.gimplify_va_arg_expr)
75a70cf9 4971 /* FIXME: Once most targets are converted we should merely
89f18f73 4972 assert this is non-null. */
fcdd3ab3 4973 return GS_ALL_DONE;
4974
17a6380d 4975 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
fcdd3ab3 4976 return GS_OK;
4977 }
4978}
4979
c2f47e15 4980/* Expand EXP, a call to __builtin_va_end. */
f7c44134 4981
a66c9326 4982static rtx
c2f47e15 4983expand_builtin_va_end (tree exp)
a66c9326 4984{
c2f47e15 4985 tree valist = CALL_EXPR_ARG (exp, 0);
8a15c04a 4986
8a15c04a 4987 /* Evaluate for side effects, if needed. I hate macros that don't
4988 do that. */
4989 if (TREE_SIDE_EFFECTS (valist))
4990 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
a66c9326 4991
4992 return const0_rtx;
4993}
4994
c2f47e15 4995/* Expand EXP, a call to __builtin_va_copy. We do this as a
a66c9326 4996 builtin rather than just as an assignment in stdarg.h because of the
4997 nastiness of array-type va_list types. */
f7c44134 4998
a66c9326 4999static rtx
c2f47e15 5000expand_builtin_va_copy (tree exp)
a66c9326 5001{
5002 tree dst, src, t;
5003
c2f47e15 5004 dst = CALL_EXPR_ARG (exp, 0);
5005 src = CALL_EXPR_ARG (exp, 1);
a66c9326 5006
5007 dst = stabilize_va_list (dst, 1);
5008 src = stabilize_va_list (src, 0);
5009
5f57a8b1 5010 gcc_assert (cfun != NULL && cfun->decl != NULL_TREE);
5011
5012 if (TREE_CODE (targetm.fn_abi_va_list (cfun->decl)) != ARRAY_TYPE)
a66c9326 5013 {
5f57a8b1 5014 t = build2 (MODIFY_EXPR, targetm.fn_abi_va_list (cfun->decl), dst, src);
a66c9326 5015 TREE_SIDE_EFFECTS (t) = 1;
5016 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5017 }
5018 else
5019 {
11a61dea 5020 rtx dstb, srcb, size;
5021
5022 /* Evaluate to pointers. */
5023 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
5024 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
5f57a8b1 5025 size = expand_expr (TYPE_SIZE_UNIT (targetm.fn_abi_va_list (cfun->decl)),
5026 NULL_RTX, VOIDmode, EXPAND_NORMAL);
11a61dea 5027
85d654dd 5028 dstb = convert_memory_address (Pmode, dstb);
5029 srcb = convert_memory_address (Pmode, srcb);
726ec87c 5030
11a61dea 5031 /* "Dereference" to BLKmode memories. */
5032 dstb = gen_rtx_MEM (BLKmode, dstb);
ab6ab77e 5033 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
5f57a8b1 5034 set_mem_align (dstb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
11a61dea 5035 srcb = gen_rtx_MEM (BLKmode, srcb);
ab6ab77e 5036 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
5f57a8b1 5037 set_mem_align (srcb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
11a61dea 5038
5039 /* Copy. */
0378dbdc 5040 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
a66c9326 5041 }
5042
5043 return const0_rtx;
5044}
5045
53800dbe 5046/* Expand a call to one of the builtin functions __builtin_frame_address or
5047 __builtin_return_address. */
27d0c333 5048
53800dbe 5049static rtx
c2f47e15 5050expand_builtin_frame_address (tree fndecl, tree exp)
53800dbe 5051{
53800dbe 5052 /* The argument must be a nonnegative integer constant.
5053 It counts the number of frames to scan up the stack.
5054 The value is the return address saved in that frame. */
c2f47e15 5055 if (call_expr_nargs (exp) == 0)
53800dbe 5056 /* Warning about missing arg was already issued. */
5057 return const0_rtx;
c2f47e15 5058 else if (! host_integerp (CALL_EXPR_ARG (exp, 0), 1))
53800dbe 5059 {
5060 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
07e3a3d2 5061 error ("invalid argument to %<__builtin_frame_address%>");
53800dbe 5062 else
07e3a3d2 5063 error ("invalid argument to %<__builtin_return_address%>");
53800dbe 5064 return const0_rtx;
5065 }
5066 else
5067 {
27d0c333 5068 rtx tem
5069 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
c2f47e15 5070 tree_low_cst (CALL_EXPR_ARG (exp, 0), 1));
53800dbe 5071
5072 /* Some ports cannot access arbitrary stack frames. */
5073 if (tem == NULL)
5074 {
5075 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
c3ceba8e 5076 warning (0, "unsupported argument to %<__builtin_frame_address%>");
53800dbe 5077 else
c3ceba8e 5078 warning (0, "unsupported argument to %<__builtin_return_address%>");
53800dbe 5079 return const0_rtx;
5080 }
5081
5082 /* For __builtin_frame_address, return what we've got. */
5083 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
5084 return tem;
5085
8ad4c111 5086 if (!REG_P (tem)
53800dbe 5087 && ! CONSTANT_P (tem))
5088 tem = copy_to_mode_reg (Pmode, tem);
5089 return tem;
5090 }
5091}
5092
c2f47e15 5093/* Expand EXP, a call to the alloca builtin. Return NULL_RTX if
53800dbe 5094 we failed and the caller should emit a normal call, otherwise try to get
5095 the result in TARGET, if convenient. */
15c6cf6b 5096
53800dbe 5097static rtx
c2f47e15 5098expand_builtin_alloca (tree exp, rtx target)
53800dbe 5099{
5100 rtx op0;
15c6cf6b 5101 rtx result;
53800dbe 5102
4ee9c684 5103 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
5104 should always expand to function calls. These can be intercepted
5105 in libmudflap. */
5106 if (flag_mudflap)
c2f47e15 5107 return NULL_RTX;
4ee9c684 5108
c2f47e15 5109 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5110 return NULL_RTX;
53800dbe 5111
5112 /* Compute the argument. */
c2f47e15 5113 op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
53800dbe 5114
5115 /* Allocate the desired space. */
15c6cf6b 5116 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
85d654dd 5117 result = convert_memory_address (ptr_mode, result);
15c6cf6b 5118
5119 return result;
53800dbe 5120}
5121
c2f47e15 5122/* Expand a call to a bswap builtin with argument ARG0. MODE
42791117 5123 is the mode to expand with. */
5124
5125static rtx
c2f47e15 5126expand_builtin_bswap (tree exp, rtx target, rtx subtarget)
42791117 5127{
5128 enum machine_mode mode;
5129 tree arg;
5130 rtx op0;
5131
c2f47e15 5132 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5133 return NULL_RTX;
42791117 5134
c2f47e15 5135 arg = CALL_EXPR_ARG (exp, 0);
42791117 5136 mode = TYPE_MODE (TREE_TYPE (arg));
1db6d067 5137 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
42791117 5138
5139 target = expand_unop (mode, bswap_optab, op0, target, 1);
5140
5141 gcc_assert (target);
5142
5143 return convert_to_mode (mode, target, 0);
5144}
5145
c2f47e15 5146/* Expand a call to a unary builtin in EXP.
5147 Return NULL_RTX if a normal call should be emitted rather than expanding the
53800dbe 5148 function in-line. If convenient, the result should be placed in TARGET.
5149 SUBTARGET may be used as the target for computing one of EXP's operands. */
15c6cf6b 5150
53800dbe 5151static rtx
c2f47e15 5152expand_builtin_unop (enum machine_mode target_mode, tree exp, rtx target,
aecda0d6 5153 rtx subtarget, optab op_optab)
53800dbe 5154{
5155 rtx op0;
c2f47e15 5156
5157 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5158 return NULL_RTX;
53800dbe 5159
5160 /* Compute the argument. */
1db6d067 5161 op0 = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
5162 VOIDmode, EXPAND_NORMAL);
6a08d0ab 5163 /* Compute op, into TARGET if possible.
53800dbe 5164 Set TARGET to wherever the result comes back. */
c2f47e15 5165 target = expand_unop (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0))),
6a08d0ab 5166 op_optab, op0, target, 1);
64db345d 5167 gcc_assert (target);
7d3f6cc7 5168
efb070c8 5169 return convert_to_mode (target_mode, target, 0);
53800dbe 5170}
89cfe6e5 5171
df94cd3b 5172/* If the string passed to fputs is a constant and is one character
2c0e001b 5173 long, we attempt to transform this call into __builtin_fputc(). */
15c6cf6b 5174
df94cd3b 5175static rtx
c2f47e15 5176expand_builtin_fputs (tree exp, rtx target, bool unlocked)
df94cd3b 5177{
2c0e001b 5178 /* Verify the arguments in the original call. */
c2f47e15 5179 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
ce1b14f4 5180 {
c2f47e15 5181 tree result = fold_builtin_fputs (CALL_EXPR_ARG (exp, 0),
5182 CALL_EXPR_ARG (exp, 1),
5183 (target == const0_rtx),
2c84ee37 5184 unlocked, NULL_TREE);
5185 if (result)
5186 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
ce1b14f4 5187 }
c2f47e15 5188 return NULL_RTX;
3311f67b 5189}
5190
5a74f77e 5191/* Expand a call to __builtin_expect. We just return our argument
5192 as the builtin_expect semantic should've been already executed by
5193 tree branch prediction pass. */
89cfe6e5 5194
5195static rtx
c2f47e15 5196expand_builtin_expect (tree exp, rtx target)
89cfe6e5 5197{
c2f47e15 5198 tree arg, c;
89cfe6e5 5199
c2f47e15 5200 if (call_expr_nargs (exp) < 2)
89cfe6e5 5201 return const0_rtx;
c2f47e15 5202 arg = CALL_EXPR_ARG (exp, 0);
5203 c = CALL_EXPR_ARG (exp, 1);
89cfe6e5 5204
c2f47e15 5205 target = expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5a74f77e 5206 /* When guessing was done, the hints should be already stripped away. */
07311427 5207 gcc_assert (!flag_guess_branch_prob
5208 || optimize == 0 || errorcount || sorrycount);
89cfe6e5 5209 return target;
5210}
689df48e 5211
c22de3f0 5212void
aecda0d6 5213expand_builtin_trap (void)
a0ef1725 5214{
5215#ifdef HAVE_trap
5216 if (HAVE_trap)
5217 emit_insn (gen_trap ());
5218 else
5219#endif
5220 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
5221 emit_barrier ();
5222}
78a74442 5223
c2f47e15 5224/* Expand EXP, a call to fabs, fabsf or fabsl.
5225 Return NULL_RTX if a normal call should be emitted rather than expanding
78a74442 5226 the function inline. If convenient, the result should be placed
5227 in TARGET. SUBTARGET may be used as the target for computing
5228 the operand. */
5229
5230static rtx
c2f47e15 5231expand_builtin_fabs (tree exp, rtx target, rtx subtarget)
78a74442 5232{
5233 enum machine_mode mode;
5234 tree arg;
5235 rtx op0;
5236
c2f47e15 5237 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
5238 return NULL_RTX;
78a74442 5239
c2f47e15 5240 arg = CALL_EXPR_ARG (exp, 0);
c7f617c2 5241 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
78a74442 5242 mode = TYPE_MODE (TREE_TYPE (arg));
1db6d067 5243 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
78a74442 5244 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
5245}
5246
c2f47e15 5247/* Expand EXP, a call to copysign, copysignf, or copysignl.
270436f3 5248 Return NULL is a normal call should be emitted rather than expanding the
5249 function inline. If convenient, the result should be placed in TARGET.
5250 SUBTARGET may be used as the target for computing the operand. */
5251
5252static rtx
c2f47e15 5253expand_builtin_copysign (tree exp, rtx target, rtx subtarget)
270436f3 5254{
5255 rtx op0, op1;
5256 tree arg;
5257
c2f47e15 5258 if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
5259 return NULL_RTX;
270436f3 5260
c2f47e15 5261 arg = CALL_EXPR_ARG (exp, 0);
8ec3c5c2 5262 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
270436f3 5263
c2f47e15 5264 arg = CALL_EXPR_ARG (exp, 1);
8ec3c5c2 5265 op1 = expand_normal (arg);
270436f3 5266
5267 return expand_copysign (op0, op1, target);
5268}
5269
19bf118a 5270/* Create a new constant string literal and return a char* pointer to it.
5271 The STRING_CST value is the LEN characters at STR. */
1e8e9920 5272tree
19bf118a 5273build_string_literal (int len, const char *str)
5274{
5275 tree t, elem, index, type;
5276
5277 t = build_string (len, str);
5278 elem = build_type_variant (char_type_node, 1, 0);
40238f64 5279 index = build_index_type (size_int (len - 1));
19bf118a 5280 type = build_array_type (elem, index);
5281 TREE_TYPE (t) = type;
5282 TREE_CONSTANT (t) = 1;
5283 TREE_READONLY (t) = 1;
5284 TREE_STATIC (t) = 1;
5285
19bf118a 5286 type = build_pointer_type (elem);
40238f64 5287 t = build1 (ADDR_EXPR, type,
5288 build4 (ARRAY_REF, elem,
5289 t, integer_zero_node, NULL_TREE, NULL_TREE));
19bf118a 5290 return t;
5291}
5292
0b25db21 5293/* Expand EXP, a call to printf or printf_unlocked.
c2f47e15 5294 Return NULL_RTX if a normal call should be emitted rather than transforming
19bf118a 5295 the function inline. If convenient, the result should be placed in
0862b7e9 5296 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
19bf118a 5297 call. */
5298static rtx
0b25db21 5299expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
19bf118a 5300 bool unlocked)
5301{
6d77ed92 5302 /* If we're using an unlocked function, assume the other unlocked
5303 functions exist explicitly. */
5304 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
5305 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
5306 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
5307 : implicit_built_in_decls[BUILT_IN_PUTS];
19bf118a 5308 const char *fmt_str;
c2f47e15 5309 tree fn = 0;
5310 tree fmt, arg;
5311 int nargs = call_expr_nargs (exp);
19bf118a 5312
5313 /* If the return value is used, don't do the transformation. */
5314 if (target != const0_rtx)
c2f47e15 5315 return NULL_RTX;
19bf118a 5316
5317 /* Verify the required arguments in the original call. */
c2f47e15 5318 if (nargs == 0)
5319 return NULL_RTX;
5320 fmt = CALL_EXPR_ARG (exp, 0);
552752f7 5321 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
c2f47e15 5322 return NULL_RTX;
19bf118a 5323
5324 /* Check whether the format is a literal string constant. */
5325 fmt_str = c_getstr (fmt);
5326 if (fmt_str == NULL)
c2f47e15 5327 return NULL_RTX;
19bf118a 5328
d4473c84 5329 if (!init_target_chars ())
c2f47e15 5330 return NULL_RTX;
a0c938f0 5331
19bf118a 5332 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
99eabcc1 5333 if (strcmp (fmt_str, target_percent_s_newline) == 0)
19bf118a 5334 {
c2f47e15 5335 if ((nargs != 2)
5336 || ! POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (exp, 1))))
5337 return NULL_RTX;
5338 if (fn_puts)
5339 fn = build_call_expr (fn_puts, 1, CALL_EXPR_ARG (exp, 1));
19bf118a 5340 }
5341 /* If the format specifier was "%c", call __builtin_putchar(arg). */
99eabcc1 5342 else if (strcmp (fmt_str, target_percent_c) == 0)
19bf118a 5343 {
c2f47e15 5344 if ((nargs != 2)
5345 || TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1))) != INTEGER_TYPE)
5346 return NULL_RTX;
5347 if (fn_putchar)
5348 fn = build_call_expr (fn_putchar, 1, CALL_EXPR_ARG (exp, 1));
19bf118a 5349 }
5350 else
5351 {
5352 /* We can't handle anything else with % args or %% ... yet. */
99eabcc1 5353 if (strchr (fmt_str, target_percent))
c2f47e15 5354 return NULL_RTX;
19bf118a 5355
c2f47e15 5356 if (nargs > 1)
5357 return NULL_RTX;
19bf118a 5358
5359 /* If the format specifier was "", printf does nothing. */
5360 if (fmt_str[0] == '\0')
5361 return const0_rtx;
5362 /* If the format specifier has length of 1, call putchar. */
5363 if (fmt_str[1] == '\0')
5364 {
5365 /* Given printf("c"), (where c is any one character,)
5366 convert "c"[0] to an int and pass that to the replacement
5367 function. */
7016c612 5368 arg = build_int_cst (NULL_TREE, fmt_str[0]);
c2f47e15 5369 if (fn_putchar)
5370 fn = build_call_expr (fn_putchar, 1, arg);
19bf118a 5371 }
5372 else
5373 {
5374 /* If the format specifier was "string\n", call puts("string"). */
5375 size_t len = strlen (fmt_str);
99eabcc1 5376 if ((unsigned char)fmt_str[len - 1] == target_newline)
19bf118a 5377 {
91c82c20 5378 /* Create a NUL-terminated string that's one char shorter
19bf118a 5379 than the original, stripping off the trailing '\n'. */
364c0c59 5380 char *newstr = XALLOCAVEC (char, len);
19bf118a 5381 memcpy (newstr, fmt_str, len - 1);
5382 newstr[len - 1] = 0;
19bf118a 5383 arg = build_string_literal (len, newstr);
c2f47e15 5384 if (fn_puts)
5385 fn = build_call_expr (fn_puts, 1, arg);
19bf118a 5386 }
5387 else
5388 /* We'd like to arrange to call fputs(string,stdout) here,
5389 but we need stdout and don't have a way to get it yet. */
c2f47e15 5390 return NULL_RTX;
19bf118a 5391 }
5392 }
5393
5394 if (!fn)
c2f47e15 5395 return NULL_RTX;
0b25db21 5396 if (TREE_CODE (fn) == CALL_EXPR)
5397 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5398 return expand_expr (fn, target, mode, EXPAND_NORMAL);
19bf118a 5399}
5400
0b25db21 5401/* Expand EXP, a call to fprintf or fprintf_unlocked.
c2f47e15 5402 Return NULL_RTX if a normal call should be emitted rather than transforming
19bf118a 5403 the function inline. If convenient, the result should be placed in
0862b7e9 5404 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
19bf118a 5405 call. */
5406static rtx
0b25db21 5407expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
a0c938f0 5408 bool unlocked)
19bf118a 5409{
6d77ed92 5410 /* If we're using an unlocked function, assume the other unlocked
5411 functions exist explicitly. */
5412 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5413 : implicit_built_in_decls[BUILT_IN_FPUTC];
5414 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5415 : implicit_built_in_decls[BUILT_IN_FPUTS];
19bf118a 5416 const char *fmt_str;
c2f47e15 5417 tree fn = 0;
5418 tree fmt, fp, arg;
5419 int nargs = call_expr_nargs (exp);
19bf118a 5420
5421 /* If the return value is used, don't do the transformation. */
5422 if (target != const0_rtx)
c2f47e15 5423 return NULL_RTX;
19bf118a 5424
5425 /* Verify the required arguments in the original call. */
c2f47e15 5426 if (nargs < 2)
5427 return NULL_RTX;
5428 fp = CALL_EXPR_ARG (exp, 0);
552752f7 5429 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
c2f47e15 5430 return NULL_RTX;
5431 fmt = CALL_EXPR_ARG (exp, 1);
552752f7 5432 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
c2f47e15 5433 return NULL_RTX;
19bf118a 5434
5435 /* Check whether the format is a literal string constant. */
5436 fmt_str = c_getstr (fmt);
5437 if (fmt_str == NULL)
c2f47e15 5438 return NULL_RTX;
19bf118a 5439
d4473c84 5440 if (!init_target_chars ())
c2f47e15 5441 return NULL_RTX;
a0c938f0 5442
19bf118a 5443 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
99eabcc1 5444 if (strcmp (fmt_str, target_percent_s) == 0)
19bf118a 5445 {
c2f47e15 5446 if ((nargs != 3)
5447 || ! POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (exp, 2))))
5448 return NULL_RTX;
5449 arg = CALL_EXPR_ARG (exp, 2);
5450 if (fn_fputs)
5451 fn = build_call_expr (fn_fputs, 2, arg, fp);
19bf118a 5452 }
5453 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
99eabcc1 5454 else if (strcmp (fmt_str, target_percent_c) == 0)
19bf118a 5455 {
c2f47e15 5456 if ((nargs != 3)
5457 || TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2))) != INTEGER_TYPE)
5458 return NULL_RTX;
5459 arg = CALL_EXPR_ARG (exp, 2);
5460 if (fn_fputc)
5461 fn = build_call_expr (fn_fputc, 2, arg, fp);
19bf118a 5462 }
5463 else
5464 {
5465 /* We can't handle anything else with % args or %% ... yet. */
99eabcc1 5466 if (strchr (fmt_str, target_percent))
c2f47e15 5467 return NULL_RTX;
19bf118a 5468
c2f47e15 5469 if (nargs > 2)
5470 return NULL_RTX;
19bf118a 5471
5472 /* If the format specifier was "", fprintf does nothing. */
5473 if (fmt_str[0] == '\0')
5474 {
5475 /* Evaluate and ignore FILE* argument for side-effects. */
5476 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5477 return const0_rtx;
5478 }
5479
5480 /* When "string" doesn't contain %, replace all cases of
5481 fprintf(stream,string) with fputs(string,stream). The fputs
5482 builtin will take care of special cases like length == 1. */
c2f47e15 5483 if (fn_fputs)
5484 fn = build_call_expr (fn_fputs, 2, fmt, fp);
19bf118a 5485 }
5486
5487 if (!fn)
c2f47e15 5488 return NULL_RTX;
0b25db21 5489 if (TREE_CODE (fn) == CALL_EXPR)
5490 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5491 return expand_expr (fn, target, mode, EXPAND_NORMAL);
19bf118a 5492}
5493
c2f47e15 5494/* Expand a call EXP to sprintf. Return NULL_RTX if
6411575e 5495 a normal call should be emitted rather than expanding the function
5496 inline. If convenient, the result should be placed in TARGET with
5497 mode MODE. */
5498
5499static rtx
c2f47e15 5500expand_builtin_sprintf (tree exp, rtx target, enum machine_mode mode)
6411575e 5501{
c2f47e15 5502 tree dest, fmt;
a7a723f0 5503 const char *fmt_str;
c2f47e15 5504 int nargs = call_expr_nargs (exp);
6411575e 5505
5506 /* Verify the required arguments in the original call. */
c2f47e15 5507 if (nargs < 2)
5508 return NULL_RTX;
5509 dest = CALL_EXPR_ARG (exp, 0);
552752f7 5510 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
c2f47e15 5511 return NULL_RTX;
5512 fmt = CALL_EXPR_ARG (exp, 0);
552752f7 5513 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
c2f47e15 5514 return NULL_RTX;
6411575e 5515
5516 /* Check whether the format is a literal string constant. */
a7a723f0 5517 fmt_str = c_getstr (fmt);
5518 if (fmt_str == NULL)
c2f47e15 5519 return NULL_RTX;
6411575e 5520
d4473c84 5521 if (!init_target_chars ())
c2f47e15 5522 return NULL_RTX;
99eabcc1 5523
6411575e 5524 /* If the format doesn't contain % args or %%, use strcpy. */
99eabcc1 5525 if (strchr (fmt_str, target_percent) == 0)
6411575e 5526 {
5527 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5528 tree exp;
5529
c2f47e15 5530 if ((nargs > 2) || ! fn)
5531 return NULL_RTX;
5532 expand_expr (build_call_expr (fn, 2, dest, fmt),
6411575e 5533 const0_rtx, VOIDmode, EXPAND_NORMAL);
5534 if (target == const0_rtx)
5535 return const0_rtx;
7016c612 5536 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
6411575e 5537 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5538 }
a7a723f0 5539 /* If the format is "%s", use strcpy if the result isn't used. */
99eabcc1 5540 else if (strcmp (fmt_str, target_percent_s) == 0)
6411575e 5541 {
a7a723f0 5542 tree fn, arg, len;
5543 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
6411575e 5544
a7a723f0 5545 if (! fn)
c2f47e15 5546 return NULL_RTX;
5547 if (nargs != 3)
5548 return NULL_RTX;
5549 arg = CALL_EXPR_ARG (exp, 2);
552752f7 5550 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
c2f47e15 5551 return NULL_RTX;
6411575e 5552
5553 if (target != const0_rtx)
5554 {
681fab1e 5555 len = c_strlen (arg, 1);
a7a723f0 5556 if (! len || TREE_CODE (len) != INTEGER_CST)
c2f47e15 5557 return NULL_RTX;
6411575e 5558 }
5559 else
a7a723f0 5560 len = NULL_TREE;
6411575e 5561
c2f47e15 5562 expand_expr (build_call_expr (fn, 2, dest, arg),
6411575e 5563 const0_rtx, VOIDmode, EXPAND_NORMAL);
5564
5565 if (target == const0_rtx)
5566 return const0_rtx;
a7a723f0 5567 return expand_expr (len, target, mode, EXPAND_NORMAL);
6411575e 5568 }
5569
c2f47e15 5570 return NULL_RTX;
6411575e 5571}
27f261ef 5572
4ee9c684 5573/* Expand a call to either the entry or exit function profiler. */
5574
5575static rtx
5576expand_builtin_profile_func (bool exitp)
5577{
5578 rtx this, which;
5579
5580 this = DECL_RTL (current_function_decl);
64db345d 5581 gcc_assert (MEM_P (this));
5582 this = XEXP (this, 0);
4ee9c684 5583
5584 if (exitp)
5585 which = profile_function_exit_libfunc;
5586 else
5587 which = profile_function_entry_libfunc;
5588
5589 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5590 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
869d0ef0 5591 0),
4ee9c684 5592 Pmode);
5593
5594 return const0_rtx;
5595}
5596
ac8fb6db 5597/* Expand a call to __builtin___clear_cache. */
5598
5599static rtx
5600expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED)
5601{
5602#ifndef HAVE_clear_cache
5603#ifdef CLEAR_INSN_CACHE
5604 /* There is no "clear_cache" insn, and __clear_cache() in libgcc
5605 does something. Just do the default expansion to a call to
5606 __clear_cache(). */
5607 return NULL_RTX;
5608#else
5609 /* There is no "clear_cache" insn, and __clear_cache() in libgcc
5610 does nothing. There is no need to call it. Do nothing. */
5611 return const0_rtx;
5612#endif /* CLEAR_INSN_CACHE */
5613#else
5614 /* We have a "clear_cache" insn, and it will handle everything. */
5615 tree begin, end;
5616 rtx begin_rtx, end_rtx;
5617 enum insn_code icode;
5618
5619 /* We must not expand to a library call. If we did, any
5620 fallback library function in libgcc that might contain a call to
5621 __builtin___clear_cache() would recurse infinitely. */
5622 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
5623 {
5624 error ("both arguments to %<__builtin___clear_cache%> must be pointers");
5625 return const0_rtx;
5626 }
5627
5628 if (HAVE_clear_cache)
5629 {
5630 icode = CODE_FOR_clear_cache;
5631
5632 begin = CALL_EXPR_ARG (exp, 0);
5633 begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL);
5634 begin_rtx = convert_memory_address (Pmode, begin_rtx);
5635 if (!insn_data[icode].operand[0].predicate (begin_rtx, Pmode))
5636 begin_rtx = copy_to_mode_reg (Pmode, begin_rtx);
5637
5638 end = CALL_EXPR_ARG (exp, 1);
5639 end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL);
5640 end_rtx = convert_memory_address (Pmode, end_rtx);
5641 if (!insn_data[icode].operand[1].predicate (end_rtx, Pmode))
5642 end_rtx = copy_to_mode_reg (Pmode, end_rtx);
5643
5644 emit_insn (gen_clear_cache (begin_rtx, end_rtx));
5645 }
5646 return const0_rtx;
5647#endif /* HAVE_clear_cache */
5648}
5649
4ee9c684 5650/* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5651
5652static rtx
5653round_trampoline_addr (rtx tramp)
5654{
5655 rtx temp, addend, mask;
5656
5657 /* If we don't need too much alignment, we'll have been guaranteed
5658 proper alignment by get_trampoline_type. */
5659 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5660 return tramp;
5661
5662 /* Round address up to desired boundary. */
5663 temp = gen_reg_rtx (Pmode);
5664 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5665 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5666
5667 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5668 temp, 0, OPTAB_LIB_WIDEN);
5669 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5670 temp, 0, OPTAB_LIB_WIDEN);
5671
5672 return tramp;
5673}
5674
5675static rtx
c2f47e15 5676expand_builtin_init_trampoline (tree exp)
4ee9c684 5677{
5678 tree t_tramp, t_func, t_chain;
5679 rtx r_tramp, r_func, r_chain;
5680#ifdef TRAMPOLINE_TEMPLATE
5681 rtx blktramp;
5682#endif
5683
c2f47e15 5684 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE,
4ee9c684 5685 POINTER_TYPE, VOID_TYPE))
5686 return NULL_RTX;
5687
c2f47e15 5688 t_tramp = CALL_EXPR_ARG (exp, 0);
5689 t_func = CALL_EXPR_ARG (exp, 1);
5690 t_chain = CALL_EXPR_ARG (exp, 2);
4ee9c684 5691
8ec3c5c2 5692 r_tramp = expand_normal (t_tramp);
5693 r_func = expand_normal (t_func);
5694 r_chain = expand_normal (t_chain);
4ee9c684 5695
5696 /* Generate insns to initialize the trampoline. */
5697 r_tramp = round_trampoline_addr (r_tramp);
5698#ifdef TRAMPOLINE_TEMPLATE
5699 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5700 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5701 emit_block_move (blktramp, assemble_trampoline_template (),
5702 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5703#endif
5704 trampolines_created = 1;
5705 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5706
5707 return const0_rtx;
5708}
5709
5710static rtx
c2f47e15 5711expand_builtin_adjust_trampoline (tree exp)
4ee9c684 5712{
5713 rtx tramp;
5714
c2f47e15 5715 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
4ee9c684 5716 return NULL_RTX;
5717
c2f47e15 5718 tramp = expand_normal (CALL_EXPR_ARG (exp, 0));
4ee9c684 5719 tramp = round_trampoline_addr (tramp);
5720#ifdef TRAMPOLINE_ADJUST_ADDRESS
5721 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5722#endif
5723
5724 return tramp;
5725}
5726
93f564d6 5727/* Expand the call EXP to the built-in signbit, signbitf or signbitl
5728 function. The function first checks whether the back end provides
5729 an insn to implement signbit for the respective mode. If not, it
5730 checks whether the floating point format of the value is such that
5731 the sign bit can be extracted. If that is not the case, the
5732 function returns NULL_RTX to indicate that a normal call should be
5733 emitted rather than expanding the function in-line. EXP is the
5734 expression that is a call to the builtin function; if convenient,
5735 the result should be placed in TARGET. */
27f261ef 5736static rtx
5737expand_builtin_signbit (tree exp, rtx target)
5738{
5739 const struct real_format *fmt;
5740 enum machine_mode fmode, imode, rmode;
5741 HOST_WIDE_INT hi, lo;
c2f47e15 5742 tree arg;
ca4f1f5b 5743 int word, bitpos;
27eda240 5744 enum insn_code icode;
27f261ef 5745 rtx temp;
5746
c2f47e15 5747 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
5748 return NULL_RTX;
27f261ef 5749
c2f47e15 5750 arg = CALL_EXPR_ARG (exp, 0);
27f261ef 5751 fmode = TYPE_MODE (TREE_TYPE (arg));
5752 rmode = TYPE_MODE (TREE_TYPE (exp));
5753 fmt = REAL_MODE_FORMAT (fmode);
5754
93f564d6 5755 arg = builtin_save_expr (arg);
5756
5757 /* Expand the argument yielding a RTX expression. */
5758 temp = expand_normal (arg);
5759
5760 /* Check if the back end provides an insn that handles signbit for the
5761 argument's mode. */
27eda240 5762 icode = signbit_optab->handlers [(int) fmode].insn_code;
5763 if (icode != CODE_FOR_nothing)
93f564d6 5764 {
5765 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
27eda240 5766 emit_unop_insn (icode, target, temp, UNKNOWN);
93f564d6 5767 return target;
5768 }
5769
27f261ef 5770 /* For floating point formats without a sign bit, implement signbit
5771 as "ARG < 0.0". */
8d564692 5772 bitpos = fmt->signbit_ro;
ca4f1f5b 5773 if (bitpos < 0)
27f261ef 5774 {
5775 /* But we can't do this if the format supports signed zero. */
5776 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
c2f47e15 5777 return NULL_RTX;
27f261ef 5778
49d00087 5779 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5780 build_real (TREE_TYPE (arg), dconst0));
27f261ef 5781 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5782 }
5783
ca4f1f5b 5784 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
27f261ef 5785 {
ca4f1f5b 5786 imode = int_mode_for_mode (fmode);
5787 if (imode == BLKmode)
c2f47e15 5788 return NULL_RTX;
ca4f1f5b 5789 temp = gen_lowpart (imode, temp);
24fd4260 5790 }
5791 else
5792 {
ca4f1f5b 5793 imode = word_mode;
5794 /* Handle targets with different FP word orders. */
5795 if (FLOAT_WORDS_BIG_ENDIAN)
a0c938f0 5796 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
ca4f1f5b 5797 else
a0c938f0 5798 word = bitpos / BITS_PER_WORD;
ca4f1f5b 5799 temp = operand_subword_force (temp, word, fmode);
5800 bitpos = bitpos % BITS_PER_WORD;
5801 }
5802
44b0f1d0 5803 /* Force the intermediate word_mode (or narrower) result into a
5804 register. This avoids attempting to create paradoxical SUBREGs
5805 of floating point modes below. */
5806 temp = force_reg (imode, temp);
5807
ca4f1f5b 5808 /* If the bitpos is within the "result mode" lowpart, the operation
5809 can be implement with a single bitwise AND. Otherwise, we need
5810 a right shift and an AND. */
5811
5812 if (bitpos < GET_MODE_BITSIZE (rmode))
5813 {
24fd4260 5814 if (bitpos < HOST_BITS_PER_WIDE_INT)
27f261ef 5815 {
24fd4260 5816 hi = 0;
5817 lo = (HOST_WIDE_INT) 1 << bitpos;
27f261ef 5818 }
5819 else
24fd4260 5820 {
5821 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5822 lo = 0;
5823 }
27f261ef 5824
4a46f016 5825 if (GET_MODE_SIZE (imode) > GET_MODE_SIZE (rmode))
ca4f1f5b 5826 temp = gen_lowpart (rmode, temp);
24fd4260 5827 temp = expand_binop (rmode, and_optab, temp,
5828 immed_double_const (lo, hi, rmode),
ca4f1f5b 5829 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27f261ef 5830 }
ca4f1f5b 5831 else
5832 {
5833 /* Perform a logical right shift to place the signbit in the least
a0c938f0 5834 significant bit, then truncate the result to the desired mode
ca4f1f5b 5835 and mask just this bit. */
5836 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5837 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5838 temp = gen_lowpart (rmode, temp);
5839 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5840 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5841 }
5842
27f261ef 5843 return temp;
5844}
73673831 5845
5846/* Expand fork or exec calls. TARGET is the desired target of the
c2f47e15 5847 call. EXP is the call. FN is the
73673831 5848 identificator of the actual function. IGNORE is nonzero if the
5849 value is to be ignored. */
5850
5851static rtx
c2f47e15 5852expand_builtin_fork_or_exec (tree fn, tree exp, rtx target, int ignore)
73673831 5853{
5854 tree id, decl;
5855 tree call;
5856
5857 /* If we are not profiling, just call the function. */
5858 if (!profile_arc_flag)
5859 return NULL_RTX;
5860
5861 /* Otherwise call the wrapper. This should be equivalent for the rest of
5862 compiler, so the code does not diverge, and the wrapper may run the
9c9bad97 5863 code necessary for keeping the profiling sane. */
73673831 5864
5865 switch (DECL_FUNCTION_CODE (fn))
5866 {
5867 case BUILT_IN_FORK:
5868 id = get_identifier ("__gcov_fork");
5869 break;
5870
5871 case BUILT_IN_EXECL:
5872 id = get_identifier ("__gcov_execl");
5873 break;
5874
5875 case BUILT_IN_EXECV:
5876 id = get_identifier ("__gcov_execv");
5877 break;
5878
5879 case BUILT_IN_EXECLP:
5880 id = get_identifier ("__gcov_execlp");
5881 break;
5882
5883 case BUILT_IN_EXECLE:
5884 id = get_identifier ("__gcov_execle");
5885 break;
5886
5887 case BUILT_IN_EXECVP:
5888 id = get_identifier ("__gcov_execvp");
5889 break;
5890
5891 case BUILT_IN_EXECVE:
5892 id = get_identifier ("__gcov_execve");
5893 break;
5894
5895 default:
64db345d 5896 gcc_unreachable ();
73673831 5897 }
5898
5899 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5900 DECL_EXTERNAL (decl) = 1;
5901 TREE_PUBLIC (decl) = 1;
5902 DECL_ARTIFICIAL (decl) = 1;
5903 TREE_NOTHROW (decl) = 1;
e82d310b 5904 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5905 DECL_VISIBILITY_SPECIFIED (decl) = 1;
c2f47e15 5906 call = rewrite_call_expr (exp, 0, decl, 0);
73673831 5907 return expand_call (call, target, ignore);
c2f47e15 5908 }
5909
b6a5fc45 5910
5911\f
3e272de8 5912/* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5913 the pointer in these functions is void*, the tree optimizers may remove
5914 casts. The mode computed in expand_builtin isn't reliable either, due
5915 to __sync_bool_compare_and_swap.
5916
5917 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5918 group of builtins. This gives us log2 of the mode size. */
5919
5920static inline enum machine_mode
5921get_builtin_sync_mode (int fcode_diff)
5922{
ad3a13b5 5923 /* The size is not negotiable, so ask not to get BLKmode in return
5924 if the target indicates that a smaller size would be better. */
5925 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
3e272de8 5926}
5927
041e0215 5928/* Expand the memory expression LOC and return the appropriate memory operand
5929 for the builtin_sync operations. */
5930
5931static rtx
5932get_builtin_sync_mem (tree loc, enum machine_mode mode)
5933{
5934 rtx addr, mem;
5935
1db6d067 5936 addr = expand_expr (loc, NULL_RTX, Pmode, EXPAND_SUM);
041e0215 5937
5938 /* Note that we explicitly do not want any alias information for this
5939 memory, so that we kill all other live memories. Otherwise we don't
5940 satisfy the full barrier semantics of the intrinsic. */
5941 mem = validize_mem (gen_rtx_MEM (mode, addr));
5942
5943 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
c94cfd1c 5944 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
041e0215 5945 MEM_VOLATILE_P (mem) = 1;
5946
5947 return mem;
5948}
5949
b6a5fc45 5950/* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
c2f47e15 5951 EXP is the CALL_EXPR. CODE is the rtx code
b6a5fc45 5952 that corresponds to the arithmetic or logical operation from the name;
5953 an exception here is that NOT actually means NAND. TARGET is an optional
5954 place for us to store the results; AFTER is true if this is the
5955 fetch_and_xxx form. IGNORE is true if we don't actually care about
5956 the result of the operation at all. */
5957
5958static rtx
c2f47e15 5959expand_builtin_sync_operation (enum machine_mode mode, tree exp,
3e272de8 5960 enum rtx_code code, bool after,
b6a5fc45 5961 rtx target, bool ignore)
5962{
041e0215 5963 rtx val, mem;
a8bb7059 5964 enum machine_mode old_mode;
b6a5fc45 5965
5966 /* Expand the operands. */
c2f47e15 5967 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
b6a5fc45 5968
1db6d067 5969 val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
a8bb7059 5970 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
5971 of CONST_INTs, where we know the old_mode only from the call argument. */
5972 old_mode = GET_MODE (val);
5973 if (old_mode == VOIDmode)
5974 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
5975 val = convert_modes (mode, old_mode, val, 1);
b6a5fc45 5976
b6a5fc45 5977 if (ignore)
5978 return expand_sync_operation (mem, val, code);
5979 else
5980 return expand_sync_fetch_operation (mem, val, code, after, target);
5981}
5982
5983/* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
c2f47e15 5984 intrinsics. EXP is the CALL_EXPR. IS_BOOL is
b6a5fc45 5985 true if this is the boolean form. TARGET is a place for us to store the
5986 results; this is NOT optional if IS_BOOL is true. */
5987
5988static rtx
c2f47e15 5989expand_builtin_compare_and_swap (enum machine_mode mode, tree exp,
3e272de8 5990 bool is_bool, rtx target)
b6a5fc45 5991{
041e0215 5992 rtx old_val, new_val, mem;
a8bb7059 5993 enum machine_mode old_mode;
b6a5fc45 5994
5995 /* Expand the operands. */
c2f47e15 5996 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
b6a5fc45 5997
c2f47e15 5998
1db6d067 5999 old_val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX,
6000 mode, EXPAND_NORMAL);
a8bb7059 6001 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
6002 of CONST_INTs, where we know the old_mode only from the call argument. */
6003 old_mode = GET_MODE (old_val);
6004 if (old_mode == VOIDmode)
6005 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
6006 old_val = convert_modes (mode, old_mode, old_val, 1);
b6a5fc45 6007
1db6d067 6008 new_val = expand_expr (CALL_EXPR_ARG (exp, 2), NULL_RTX,
6009 mode, EXPAND_NORMAL);
a8bb7059 6010 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
6011 of CONST_INTs, where we know the old_mode only from the call argument. */
6012 old_mode = GET_MODE (new_val);
6013 if (old_mode == VOIDmode)
6014 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2)));
6015 new_val = convert_modes (mode, old_mode, new_val, 1);
b6a5fc45 6016
b6a5fc45 6017 if (is_bool)
6018 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
6019 else
6020 return expand_val_compare_and_swap (mem, old_val, new_val, target);
6021}
6022
6023/* Expand the __sync_lock_test_and_set intrinsic. Note that the most
6024 general form is actually an atomic exchange, and some targets only
6025 support a reduced form with the second argument being a constant 1.
c2f47e15 6026 EXP is the CALL_EXPR; TARGET is an optional place for us to store
6027 the results. */
b6a5fc45 6028
6029static rtx
c2f47e15 6030expand_builtin_lock_test_and_set (enum machine_mode mode, tree exp,
3e272de8 6031 rtx target)
b6a5fc45 6032{
041e0215 6033 rtx val, mem;
a8bb7059 6034 enum machine_mode old_mode;
b6a5fc45 6035
6036 /* Expand the operands. */
c2f47e15 6037 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
1db6d067 6038 val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
a8bb7059 6039 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
6040 of CONST_INTs, where we know the old_mode only from the call argument. */
6041 old_mode = GET_MODE (val);
6042 if (old_mode == VOIDmode)
6043 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
6044 val = convert_modes (mode, old_mode, val, 1);
b6a5fc45 6045
b6a5fc45 6046 return expand_sync_lock_test_and_set (mem, val, target);
6047}
6048
6049/* Expand the __sync_synchronize intrinsic. */
6050
6051static void
6052expand_builtin_synchronize (void)
6053{
82e58396 6054 tree x;
b6a5fc45 6055
6056#ifdef HAVE_memory_barrier
6057 if (HAVE_memory_barrier)
6058 {
6059 emit_insn (gen_memory_barrier ());
6060 return;
6061 }
6062#endif
6063
047a7e40 6064 if (synchronize_libfunc != NULL_RTX)
6065 {
6066 emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
6067 return;
6068 }
6069
82e58396 6070 /* If no explicit memory barrier instruction is available, create an
6071 empty asm stmt with a memory clobber. */
6072 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
6073 tree_cons (NULL, build_string (6, "memory"), NULL));
6074 ASM_VOLATILE_P (x) = 1;
6075 expand_asm_expr (x);
b6a5fc45 6076}
6077
c2f47e15 6078/* Expand the __sync_lock_release intrinsic. EXP is the CALL_EXPR. */
b6a5fc45 6079
6080static void
c2f47e15 6081expand_builtin_lock_release (enum machine_mode mode, tree exp)
b6a5fc45 6082{
b6a5fc45 6083 enum insn_code icode;
041e0215 6084 rtx mem, insn;
3e272de8 6085 rtx val = const0_rtx;
b6a5fc45 6086
6087 /* Expand the operands. */
c2f47e15 6088 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
b6a5fc45 6089
6090 /* If there is an explicit operation in the md file, use it. */
6091 icode = sync_lock_release[mode];
6092 if (icode != CODE_FOR_nothing)
6093 {
6094 if (!insn_data[icode].operand[1].predicate (val, mode))
6095 val = force_reg (mode, val);
6096
6097 insn = GEN_FCN (icode) (mem, val);
6098 if (insn)
6099 {
6100 emit_insn (insn);
6101 return;
6102 }
6103 }
6104
6105 /* Otherwise we can implement this operation by emitting a barrier
6106 followed by a store of zero. */
6107 expand_builtin_synchronize ();
6108 emit_move_insn (mem, val);
6109}
53800dbe 6110\f
6111/* Expand an expression EXP that calls a built-in function,
6112 with result going to TARGET if that's convenient
6113 (and in mode MODE if that's convenient).
6114 SUBTARGET may be used as the target for computing one of EXP's operands.
6115 IGNORE is nonzero if the value is to be ignored. */
6116
6117rtx
aecda0d6 6118expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
6119 int ignore)
53800dbe 6120{
c6e6ecb1 6121 tree fndecl = get_callee_fndecl (exp);
53800dbe 6122 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
efb070c8 6123 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
53800dbe 6124
8305149e 6125 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
883b2e73 6126 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
bf8e3599 6127
53800dbe 6128 /* When not optimizing, generate calls to library functions for a certain
6129 set of builtins. */
cd9ff771 6130 if (!optimize
b6a5fc45 6131 && !called_as_built_in (fndecl)
cd9ff771 6132 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
6133 && fcode != BUILT_IN_ALLOCA)
6134 return expand_call (exp, target, ignore);
53800dbe 6135
8d6d7930 6136 /* The built-in function expanders test for target == const0_rtx
6137 to determine whether the function's result will be ignored. */
6138 if (ignore)
6139 target = const0_rtx;
6140
6141 /* If the result of a pure or const built-in function is ignored, and
6142 none of its arguments are volatile, we can avoid expanding the
6143 built-in call and just evaluate the arguments for side-effects. */
6144 if (target == const0_rtx
9c2a0c05 6145 && (DECL_PURE_P (fndecl) || TREE_READONLY (fndecl)))
8d6d7930 6146 {
6147 bool volatilep = false;
6148 tree arg;
c2f47e15 6149 call_expr_arg_iterator iter;
8d6d7930 6150
c2f47e15 6151 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
6152 if (TREE_THIS_VOLATILE (arg))
8d6d7930 6153 {
6154 volatilep = true;
6155 break;
6156 }
6157
6158 if (! volatilep)
6159 {
c2f47e15 6160 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
6161 expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL);
8d6d7930 6162 return const0_rtx;
6163 }
6164 }
6165
53800dbe 6166 switch (fcode)
6167 {
4f35b1fc 6168 CASE_FLT_FN (BUILT_IN_FABS):
c2f47e15 6169 target = expand_builtin_fabs (exp, target, subtarget);
78a74442 6170 if (target)
a0c938f0 6171 return target;
78a74442 6172 break;
6173
4f35b1fc 6174 CASE_FLT_FN (BUILT_IN_COPYSIGN):
c2f47e15 6175 target = expand_builtin_copysign (exp, target, subtarget);
270436f3 6176 if (target)
6177 return target;
6178 break;
6179
7d3f6cc7 6180 /* Just do a normal library call if we were unable to fold
6181 the values. */
4f35b1fc 6182 CASE_FLT_FN (BUILT_IN_CABS):
78a74442 6183 break;
53800dbe 6184
4f35b1fc 6185 CASE_FLT_FN (BUILT_IN_EXP):
6186 CASE_FLT_FN (BUILT_IN_EXP10):
6187 CASE_FLT_FN (BUILT_IN_POW10):
6188 CASE_FLT_FN (BUILT_IN_EXP2):
6189 CASE_FLT_FN (BUILT_IN_EXPM1):
6190 CASE_FLT_FN (BUILT_IN_LOGB):
4f35b1fc 6191 CASE_FLT_FN (BUILT_IN_LOG):
6192 CASE_FLT_FN (BUILT_IN_LOG10):
6193 CASE_FLT_FN (BUILT_IN_LOG2):
6194 CASE_FLT_FN (BUILT_IN_LOG1P):
6195 CASE_FLT_FN (BUILT_IN_TAN):
6196 CASE_FLT_FN (BUILT_IN_ASIN):
6197 CASE_FLT_FN (BUILT_IN_ACOS):
6198 CASE_FLT_FN (BUILT_IN_ATAN):
7f3be425 6199 /* Treat these like sqrt only if unsafe math optimizations are allowed,
6200 because of possible accuracy problems. */
6201 if (! flag_unsafe_math_optimizations)
53800dbe 6202 break;
4f35b1fc 6203 CASE_FLT_FN (BUILT_IN_SQRT):
6204 CASE_FLT_FN (BUILT_IN_FLOOR):
6205 CASE_FLT_FN (BUILT_IN_CEIL):
6206 CASE_FLT_FN (BUILT_IN_TRUNC):
6207 CASE_FLT_FN (BUILT_IN_ROUND):
6208 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6209 CASE_FLT_FN (BUILT_IN_RINT):
53800dbe 6210 target = expand_builtin_mathfn (exp, target, subtarget);
6211 if (target)
6212 return target;
6213 break;
6214
a67a90e5 6215 CASE_FLT_FN (BUILT_IN_ILOGB):
6216 if (! flag_unsafe_math_optimizations)
6217 break;
69b779ea 6218 CASE_FLT_FN (BUILT_IN_ISINF):
cde061c1 6219 CASE_FLT_FN (BUILT_IN_FINITE):
6220 case BUILT_IN_ISFINITE:
8a1a9cb7 6221 case BUILT_IN_ISNORMAL:
a67a90e5 6222 target = expand_builtin_interclass_mathfn (exp, target, subtarget);
6223 if (target)
6224 return target;
6225 break;
6226
4f35b1fc 6227 CASE_FLT_FN (BUILT_IN_LCEIL):
6228 CASE_FLT_FN (BUILT_IN_LLCEIL):
6229 CASE_FLT_FN (BUILT_IN_LFLOOR):
6230 CASE_FLT_FN (BUILT_IN_LLFLOOR):
ff1b14e4 6231 target = expand_builtin_int_roundingfn (exp, target);
ad52b9b7 6232 if (target)
6233 return target;
6234 break;
6235
7d3afc77 6236 CASE_FLT_FN (BUILT_IN_LRINT):
6237 CASE_FLT_FN (BUILT_IN_LLRINT):
ef2f1a10 6238 CASE_FLT_FN (BUILT_IN_LROUND):
6239 CASE_FLT_FN (BUILT_IN_LLROUND):
ff1b14e4 6240 target = expand_builtin_int_roundingfn_2 (exp, target);
7d3afc77 6241 if (target)
6242 return target;
6243 break;
6244
4f35b1fc 6245 CASE_FLT_FN (BUILT_IN_POW):
f1b844c6 6246 target = expand_builtin_pow (exp, target, subtarget);
6247 if (target)
6248 return target;
6249 break;
6250
4f35b1fc 6251 CASE_FLT_FN (BUILT_IN_POWI):
757c219d 6252 target = expand_builtin_powi (exp, target, subtarget);
6253 if (target)
6254 return target;
6255 break;
6256
4f35b1fc 6257 CASE_FLT_FN (BUILT_IN_ATAN2):
6258 CASE_FLT_FN (BUILT_IN_LDEXP):
73a954a1 6259 CASE_FLT_FN (BUILT_IN_SCALB):
6260 CASE_FLT_FN (BUILT_IN_SCALBN):
6261 CASE_FLT_FN (BUILT_IN_SCALBLN):
0fd605a5 6262 if (! flag_unsafe_math_optimizations)
6263 break;
ef722005 6264
6265 CASE_FLT_FN (BUILT_IN_FMOD):
6266 CASE_FLT_FN (BUILT_IN_REMAINDER):
6267 CASE_FLT_FN (BUILT_IN_DREM):
0fd605a5 6268 target = expand_builtin_mathfn_2 (exp, target, subtarget);
6269 if (target)
6270 return target;
6271 break;
6272
d735c391 6273 CASE_FLT_FN (BUILT_IN_CEXPI):
6274 target = expand_builtin_cexpi (exp, target, subtarget);
6275 gcc_assert (target);
6276 return target;
6277
4f35b1fc 6278 CASE_FLT_FN (BUILT_IN_SIN):
6279 CASE_FLT_FN (BUILT_IN_COS):
6b43bae4 6280 if (! flag_unsafe_math_optimizations)
6281 break;
6282 target = expand_builtin_mathfn_3 (exp, target, subtarget);
6283 if (target)
6284 return target;
6285 break;
6286
c3147c1a 6287 CASE_FLT_FN (BUILT_IN_SINCOS):
6288 if (! flag_unsafe_math_optimizations)
6289 break;
6290 target = expand_builtin_sincos (exp);
6291 if (target)
6292 return target;
6293 break;
6294
53800dbe 6295 case BUILT_IN_APPLY_ARGS:
6296 return expand_builtin_apply_args ();
6297
6298 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
6299 FUNCTION with a copy of the parameters described by
6300 ARGUMENTS, and ARGSIZE. It returns a block of memory
6301 allocated on the stack into which is stored all the registers
6302 that might possibly be used for returning the result of a
6303 function. ARGUMENTS is the value returned by
6304 __builtin_apply_args. ARGSIZE is the number of bytes of
6305 arguments that must be copied. ??? How should this value be
6306 computed? We'll also need a safe worst case value for varargs
6307 functions. */
6308 case BUILT_IN_APPLY:
c2f47e15 6309 if (!validate_arglist (exp, POINTER_TYPE,
0eb671f7 6310 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
c2f47e15 6311 && !validate_arglist (exp, REFERENCE_TYPE,
0eb671f7 6312 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
53800dbe 6313 return const0_rtx;
6314 else
6315 {
53800dbe 6316 rtx ops[3];
6317
c2f47e15 6318 ops[0] = expand_normal (CALL_EXPR_ARG (exp, 0));
6319 ops[1] = expand_normal (CALL_EXPR_ARG (exp, 1));
6320 ops[2] = expand_normal (CALL_EXPR_ARG (exp, 2));
53800dbe 6321
6322 return expand_builtin_apply (ops[0], ops[1], ops[2]);
6323 }
6324
6325 /* __builtin_return (RESULT) causes the function to return the
6326 value described by RESULT. RESULT is address of the block of
6327 memory returned by __builtin_apply. */
6328 case BUILT_IN_RETURN:
c2f47e15 6329 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6330 expand_builtin_return (expand_normal (CALL_EXPR_ARG (exp, 0)));
53800dbe 6331 return const0_rtx;
6332
6333 case BUILT_IN_SAVEREGS:
a66c9326 6334 return expand_builtin_saveregs ();
53800dbe 6335
6336 case BUILT_IN_ARGS_INFO:
c2f47e15 6337 return expand_builtin_args_info (exp);
53800dbe 6338
48dc2227 6339 case BUILT_IN_VA_ARG_PACK:
6340 /* All valid uses of __builtin_va_arg_pack () are removed during
6341 inlining. */
b8c23db3 6342 error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp);
48dc2227 6343 return const0_rtx;
6344
4e1d7ea4 6345 case BUILT_IN_VA_ARG_PACK_LEN:
6346 /* All valid uses of __builtin_va_arg_pack_len () are removed during
6347 inlining. */
b8c23db3 6348 error ("%Kinvalid use of %<__builtin_va_arg_pack_len ()%>", exp);
4e1d7ea4 6349 return const0_rtx;
6350
53800dbe 6351 /* Return the address of the first anonymous stack arg. */
6352 case BUILT_IN_NEXT_ARG:
c2f47e15 6353 if (fold_builtin_next_arg (exp, false))
a0c938f0 6354 return const0_rtx;
79012a9d 6355 return expand_builtin_next_arg ();
53800dbe 6356
ac8fb6db 6357 case BUILT_IN_CLEAR_CACHE:
6358 target = expand_builtin___clear_cache (exp);
6359 if (target)
6360 return target;
6361 break;
6362
53800dbe 6363 case BUILT_IN_CLASSIFY_TYPE:
c2f47e15 6364 return expand_builtin_classify_type (exp);
53800dbe 6365
6366 case BUILT_IN_CONSTANT_P:
4ee9c684 6367 return const0_rtx;
53800dbe 6368
6369 case BUILT_IN_FRAME_ADDRESS:
6370 case BUILT_IN_RETURN_ADDRESS:
c2f47e15 6371 return expand_builtin_frame_address (fndecl, exp);
53800dbe 6372
6373 /* Returns the address of the area where the structure is returned.
6374 0 otherwise. */
6375 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
c2f47e15 6376 if (call_expr_nargs (exp) != 0
9342ee68 6377 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
e16ceb8e 6378 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
9342ee68 6379 return const0_rtx;
53800dbe 6380 else
9342ee68 6381 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
53800dbe 6382
6383 case BUILT_IN_ALLOCA:
c2f47e15 6384 target = expand_builtin_alloca (exp, target);
53800dbe 6385 if (target)
6386 return target;
6387 break;
6388
4ee9c684 6389 case BUILT_IN_STACK_SAVE:
6390 return expand_stack_save ();
6391
6392 case BUILT_IN_STACK_RESTORE:
c2f47e15 6393 expand_stack_restore (CALL_EXPR_ARG (exp, 0));
4ee9c684 6394 return const0_rtx;
6395
42791117 6396 case BUILT_IN_BSWAP32:
6397 case BUILT_IN_BSWAP64:
c2f47e15 6398 target = expand_builtin_bswap (exp, target, subtarget);
42791117 6399
6400 if (target)
6401 return target;
6402 break;
6403
4f35b1fc 6404 CASE_INT_FN (BUILT_IN_FFS):
5053259b 6405 case BUILT_IN_FFSIMAX:
c2f47e15 6406 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6407 subtarget, ffs_optab);
6a08d0ab 6408 if (target)
6409 return target;
6410 break;
6411
4f35b1fc 6412 CASE_INT_FN (BUILT_IN_CLZ):
5053259b 6413 case BUILT_IN_CLZIMAX:
c2f47e15 6414 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6415 subtarget, clz_optab);
6a08d0ab 6416 if (target)
6417 return target;
6418 break;
6419
4f35b1fc 6420 CASE_INT_FN (BUILT_IN_CTZ):
5053259b 6421 case BUILT_IN_CTZIMAX:
c2f47e15 6422 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6423 subtarget, ctz_optab);
6a08d0ab 6424 if (target)
6425 return target;
6426 break;
6427
4f35b1fc 6428 CASE_INT_FN (BUILT_IN_POPCOUNT):
5053259b 6429 case BUILT_IN_POPCOUNTIMAX:
c2f47e15 6430 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6431 subtarget, popcount_optab);
6a08d0ab 6432 if (target)
6433 return target;
6434 break;
6435
4f35b1fc 6436 CASE_INT_FN (BUILT_IN_PARITY):
5053259b 6437 case BUILT_IN_PARITYIMAX:
c2f47e15 6438 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6439 subtarget, parity_optab);
53800dbe 6440 if (target)
6441 return target;
6442 break;
6443
6444 case BUILT_IN_STRLEN:
c2f47e15 6445 target = expand_builtin_strlen (exp, target, target_mode);
53800dbe 6446 if (target)
6447 return target;
6448 break;
6449
6450 case BUILT_IN_STRCPY:
c2f47e15 6451 target = expand_builtin_strcpy (fndecl, exp, target, mode);
53800dbe 6452 if (target)
6453 return target;
6454 break;
bf8e3599 6455
ed09096d 6456 case BUILT_IN_STRNCPY:
8ff6a5cd 6457 target = expand_builtin_strncpy (exp, target, mode);
ed09096d 6458 if (target)
6459 return target;
6460 break;
bf8e3599 6461
3b824fa6 6462 case BUILT_IN_STPCPY:
dc369150 6463 target = expand_builtin_stpcpy (exp, target, mode);
3b824fa6 6464 if (target)
6465 return target;
6466 break;
6467
49f0327b 6468 case BUILT_IN_STRCAT:
c2f47e15 6469 target = expand_builtin_strcat (fndecl, exp, target, mode);
49f0327b 6470 if (target)
6471 return target;
6472 break;
bf8e3599 6473
49f0327b 6474 case BUILT_IN_STRNCAT:
c2f47e15 6475 target = expand_builtin_strncat (exp, target, mode);
49f0327b 6476 if (target)
6477 return target;
6478 break;
bf8e3599 6479
49f0327b 6480 case BUILT_IN_STRSPN:
c2f47e15 6481 target = expand_builtin_strspn (exp, target, mode);
49f0327b 6482 if (target)
6483 return target;
6484 break;
bf8e3599 6485
49f0327b 6486 case BUILT_IN_STRCSPN:
c2f47e15 6487 target = expand_builtin_strcspn (exp, target, mode);
49f0327b 6488 if (target)
6489 return target;
6490 break;
bf8e3599 6491
17f5ea87 6492 case BUILT_IN_STRSTR:
c2f47e15 6493 target = expand_builtin_strstr (exp, target, mode);
17f5ea87 6494 if (target)
6495 return target;
6496 break;
bf8e3599 6497
46f3a74a 6498 case BUILT_IN_STRPBRK:
c2f47e15 6499 target = expand_builtin_strpbrk (exp, target, mode);
46f3a74a 6500 if (target)
6501 return target;
6502 break;
bf8e3599 6503
398aae36 6504 case BUILT_IN_INDEX:
83d79705 6505 case BUILT_IN_STRCHR:
c2f47e15 6506 target = expand_builtin_strchr (exp, target, mode);
83d79705 6507 if (target)
6508 return target;
6509 break;
6510
398aae36 6511 case BUILT_IN_RINDEX:
83d79705 6512 case BUILT_IN_STRRCHR:
c2f47e15 6513 target = expand_builtin_strrchr (exp, target, mode);
83d79705 6514 if (target)
6515 return target;
6516 break;
6517
53800dbe 6518 case BUILT_IN_MEMCPY:
5a0de151 6519 target = expand_builtin_memcpy (exp, target, mode);
3b824fa6 6520 if (target)
6521 return target;
6522 break;
6523
6524 case BUILT_IN_MEMPCPY:
c2f47e15 6525 target = expand_builtin_mempcpy (exp, target, mode);
53800dbe 6526 if (target)
6527 return target;
6528 break;
6529
c4950093 6530 case BUILT_IN_MEMMOVE:
c2f47e15 6531 target = expand_builtin_memmove (exp, target, mode, ignore);
c4950093 6532 if (target)
6533 return target;
6534 break;
6535
6536 case BUILT_IN_BCOPY:
c2f47e15 6537 target = expand_builtin_bcopy (exp, ignore);
c4950093 6538 if (target)
6539 return target;
6540 break;
6541
53800dbe 6542 case BUILT_IN_MEMSET:
c2f47e15 6543 target = expand_builtin_memset (exp, target, mode);
53800dbe 6544 if (target)
6545 return target;
6546 break;
6547
ffc83088 6548 case BUILT_IN_BZERO:
0b25db21 6549 target = expand_builtin_bzero (exp);
ffc83088 6550 if (target)
6551 return target;
6552 break;
6553
53800dbe 6554 case BUILT_IN_STRCMP:
83d79705 6555 target = expand_builtin_strcmp (exp, target, mode);
53800dbe 6556 if (target)
6557 return target;
6558 break;
6559
ed09096d 6560 case BUILT_IN_STRNCMP:
6561 target = expand_builtin_strncmp (exp, target, mode);
6562 if (target)
6563 return target;
6564 break;
6565
7959b13b 6566 case BUILT_IN_MEMCHR:
6567 target = expand_builtin_memchr (exp, target, mode);
6568 if (target)
6569 return target;
6570 break;
6571
071f1696 6572 case BUILT_IN_BCMP:
53800dbe 6573 case BUILT_IN_MEMCMP:
c2f47e15 6574 target = expand_builtin_memcmp (exp, target, mode);
53800dbe 6575 if (target)
6576 return target;
6577 break;
53800dbe 6578
6579 case BUILT_IN_SETJMP:
2c8a1497 6580 /* This should have been lowered to the builtins below. */
6581 gcc_unreachable ();
6582
6583 case BUILT_IN_SETJMP_SETUP:
6584 /* __builtin_setjmp_setup is passed a pointer to an array of five words
6585 and the receiver label. */
c2f47e15 6586 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2c8a1497 6587 {
c2f47e15 6588 rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
2c8a1497 6589 VOIDmode, EXPAND_NORMAL);
c2f47e15 6590 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 1), 0);
2c8a1497 6591 rtx label_r = label_rtx (label);
6592
6593 /* This is copied from the handling of non-local gotos. */
6594 expand_builtin_setjmp_setup (buf_addr, label_r);
6595 nonlocal_goto_handler_labels
6596 = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6597 nonlocal_goto_handler_labels);
6598 /* ??? Do not let expand_label treat us as such since we would
6599 not want to be both on the list of non-local labels and on
6600 the list of forced labels. */
6601 FORCED_LABEL (label) = 0;
6602 return const0_rtx;
6603 }
6604 break;
6605
6606 case BUILT_IN_SETJMP_DISPATCHER:
6607 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */
c2f47e15 6608 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
2c8a1497 6609 {
c2f47e15 6610 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
2c8a1497 6611 rtx label_r = label_rtx (label);
6612
6613 /* Remove the dispatcher label from the list of non-local labels
6614 since the receiver labels have been added to it above. */
6615 remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6616 return const0_rtx;
6617 }
6618 break;
6619
6620 case BUILT_IN_SETJMP_RECEIVER:
6621 /* __builtin_setjmp_receiver is passed the receiver label. */
c2f47e15 6622 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
2c8a1497 6623 {
c2f47e15 6624 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
2c8a1497 6625 rtx label_r = label_rtx (label);
6626
6627 expand_builtin_setjmp_receiver (label_r);
6628 return const0_rtx;
6629 }
6b7f6858 6630 break;
53800dbe 6631
6632 /* __builtin_longjmp is passed a pointer to an array of five words.
6633 It's similar to the C library longjmp function but works with
6634 __builtin_setjmp above. */
6635 case BUILT_IN_LONGJMP:
c2f47e15 6636 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
53800dbe 6637 {
c2f47e15 6638 rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
8ec3c5c2 6639 VOIDmode, EXPAND_NORMAL);
c2f47e15 6640 rtx value = expand_normal (CALL_EXPR_ARG (exp, 1));
53800dbe 6641
6642 if (value != const1_rtx)
6643 {
1e5fcbe2 6644 error ("%<__builtin_longjmp%> second argument must be 1");
53800dbe 6645 return const0_rtx;
6646 }
6647
6648 expand_builtin_longjmp (buf_addr, value);
6649 return const0_rtx;
6650 }
2c8a1497 6651 break;
53800dbe 6652
4ee9c684 6653 case BUILT_IN_NONLOCAL_GOTO:
c2f47e15 6654 target = expand_builtin_nonlocal_goto (exp);
4ee9c684 6655 if (target)
6656 return target;
6657 break;
6658
843d08a9 6659 /* This updates the setjmp buffer that is its argument with the value
6660 of the current stack pointer. */
6661 case BUILT_IN_UPDATE_SETJMP_BUF:
c2f47e15 6662 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
843d08a9 6663 {
6664 rtx buf_addr
c2f47e15 6665 = expand_normal (CALL_EXPR_ARG (exp, 0));
843d08a9 6666
6667 expand_builtin_update_setjmp_buf (buf_addr);
6668 return const0_rtx;
6669 }
6670 break;
6671
53800dbe 6672 case BUILT_IN_TRAP:
a0ef1725 6673 expand_builtin_trap ();
53800dbe 6674 return const0_rtx;
6675
19bf118a 6676 case BUILT_IN_PRINTF:
0b25db21 6677 target = expand_builtin_printf (exp, target, mode, false);
19bf118a 6678 if (target)
6679 return target;
6680 break;
6681
6682 case BUILT_IN_PRINTF_UNLOCKED:
0b25db21 6683 target = expand_builtin_printf (exp, target, mode, true);
19bf118a 6684 if (target)
6685 return target;
6686 break;
6687
df94cd3b 6688 case BUILT_IN_FPUTS:
c2f47e15 6689 target = expand_builtin_fputs (exp, target, false);
c013a46e 6690 if (target)
6691 return target;
6692 break;
6693 case BUILT_IN_FPUTS_UNLOCKED:
c2f47e15 6694 target = expand_builtin_fputs (exp, target, true);
19bf118a 6695 if (target)
6696 return target;
6697 break;
6698
6699 case BUILT_IN_FPRINTF:
0b25db21 6700 target = expand_builtin_fprintf (exp, target, mode, false);
19bf118a 6701 if (target)
6702 return target;
6703 break;
6704
6705 case BUILT_IN_FPRINTF_UNLOCKED:
0b25db21 6706 target = expand_builtin_fprintf (exp, target, mode, true);
df94cd3b 6707 if (target)
6708 return target;
6709 break;
bf8e3599 6710
6411575e 6711 case BUILT_IN_SPRINTF:
c2f47e15 6712 target = expand_builtin_sprintf (exp, target, mode);
6411575e 6713 if (target)
6714 return target;
6715 break;
6716
4f35b1fc 6717 CASE_FLT_FN (BUILT_IN_SIGNBIT):
004e23c4 6718 case BUILT_IN_SIGNBITD32:
6719 case BUILT_IN_SIGNBITD64:
6720 case BUILT_IN_SIGNBITD128:
27f261ef 6721 target = expand_builtin_signbit (exp, target);
6722 if (target)
6723 return target;
6724 break;
6725
53800dbe 6726 /* Various hooks for the DWARF 2 __throw routine. */
6727 case BUILT_IN_UNWIND_INIT:
6728 expand_builtin_unwind_init ();
6729 return const0_rtx;
6730 case BUILT_IN_DWARF_CFA:
6731 return virtual_cfa_rtx;
6732#ifdef DWARF2_UNWIND_INFO
f8f023a5 6733 case BUILT_IN_DWARF_SP_COLUMN:
6734 return expand_builtin_dwarf_sp_column ();
695e919b 6735 case BUILT_IN_INIT_DWARF_REG_SIZES:
c2f47e15 6736 expand_builtin_init_dwarf_reg_sizes (CALL_EXPR_ARG (exp, 0));
695e919b 6737 return const0_rtx;
53800dbe 6738#endif
6739 case BUILT_IN_FROB_RETURN_ADDR:
c2f47e15 6740 return expand_builtin_frob_return_addr (CALL_EXPR_ARG (exp, 0));
53800dbe 6741 case BUILT_IN_EXTRACT_RETURN_ADDR:
c2f47e15 6742 return expand_builtin_extract_return_addr (CALL_EXPR_ARG (exp, 0));
53800dbe 6743 case BUILT_IN_EH_RETURN:
c2f47e15 6744 expand_builtin_eh_return (CALL_EXPR_ARG (exp, 0),
6745 CALL_EXPR_ARG (exp, 1));
53800dbe 6746 return const0_rtx;
df4b504c 6747#ifdef EH_RETURN_DATA_REGNO
6748 case BUILT_IN_EH_RETURN_DATA_REGNO:
c2f47e15 6749 return expand_builtin_eh_return_data_regno (exp);
df4b504c 6750#endif
26093bf4 6751 case BUILT_IN_EXTEND_POINTER:
c2f47e15 6752 return expand_builtin_extend_pointer (CALL_EXPR_ARG (exp, 0));
26093bf4 6753
7ccc713a 6754 case BUILT_IN_VA_START:
c2f47e15 6755 return expand_builtin_va_start (exp);
a66c9326 6756 case BUILT_IN_VA_END:
c2f47e15 6757 return expand_builtin_va_end (exp);
a66c9326 6758 case BUILT_IN_VA_COPY:
c2f47e15 6759 return expand_builtin_va_copy (exp);
89cfe6e5 6760 case BUILT_IN_EXPECT:
c2f47e15 6761 return expand_builtin_expect (exp, target);
5e3608d8 6762 case BUILT_IN_PREFETCH:
c2f47e15 6763 expand_builtin_prefetch (exp);
5e3608d8 6764 return const0_rtx;
6765
4ee9c684 6766 case BUILT_IN_PROFILE_FUNC_ENTER:
6767 return expand_builtin_profile_func (false);
6768 case BUILT_IN_PROFILE_FUNC_EXIT:
6769 return expand_builtin_profile_func (true);
6770
6771 case BUILT_IN_INIT_TRAMPOLINE:
c2f47e15 6772 return expand_builtin_init_trampoline (exp);
4ee9c684 6773 case BUILT_IN_ADJUST_TRAMPOLINE:
c2f47e15 6774 return expand_builtin_adjust_trampoline (exp);
4ee9c684 6775
73673831 6776 case BUILT_IN_FORK:
6777 case BUILT_IN_EXECL:
6778 case BUILT_IN_EXECV:
6779 case BUILT_IN_EXECLP:
6780 case BUILT_IN_EXECLE:
6781 case BUILT_IN_EXECVP:
6782 case BUILT_IN_EXECVE:
c2f47e15 6783 target = expand_builtin_fork_or_exec (fndecl, exp, target, ignore);
73673831 6784 if (target)
6785 return target;
6786 break;
53800dbe 6787
b6a5fc45 6788 case BUILT_IN_FETCH_AND_ADD_1:
6789 case BUILT_IN_FETCH_AND_ADD_2:
6790 case BUILT_IN_FETCH_AND_ADD_4:
6791 case BUILT_IN_FETCH_AND_ADD_8:
27213ba3 6792 case BUILT_IN_FETCH_AND_ADD_16:
3e272de8 6793 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
c2f47e15 6794 target = expand_builtin_sync_operation (mode, exp, PLUS,
b6a5fc45 6795 false, target, ignore);
6796 if (target)
6797 return target;
6798 break;
6799
6800 case BUILT_IN_FETCH_AND_SUB_1:
6801 case BUILT_IN_FETCH_AND_SUB_2:
6802 case BUILT_IN_FETCH_AND_SUB_4:
6803 case BUILT_IN_FETCH_AND_SUB_8:
27213ba3 6804 case BUILT_IN_FETCH_AND_SUB_16:
3e272de8 6805 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
c2f47e15 6806 target = expand_builtin_sync_operation (mode, exp, MINUS,
b6a5fc45 6807 false, target, ignore);
6808 if (target)
6809 return target;
6810 break;
6811
6812 case BUILT_IN_FETCH_AND_OR_1:
6813 case BUILT_IN_FETCH_AND_OR_2:
6814 case BUILT_IN_FETCH_AND_OR_4:
6815 case BUILT_IN_FETCH_AND_OR_8:
27213ba3 6816 case BUILT_IN_FETCH_AND_OR_16:
3e272de8 6817 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
c2f47e15 6818 target = expand_builtin_sync_operation (mode, exp, IOR,
b6a5fc45 6819 false, target, ignore);
6820 if (target)
6821 return target;
6822 break;
6823
6824 case BUILT_IN_FETCH_AND_AND_1:
6825 case BUILT_IN_FETCH_AND_AND_2:
6826 case BUILT_IN_FETCH_AND_AND_4:
6827 case BUILT_IN_FETCH_AND_AND_8:
27213ba3 6828 case BUILT_IN_FETCH_AND_AND_16:
3e272de8 6829 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
c2f47e15 6830 target = expand_builtin_sync_operation (mode, exp, AND,
b6a5fc45 6831 false, target, ignore);
6832 if (target)
6833 return target;
6834 break;
6835
6836 case BUILT_IN_FETCH_AND_XOR_1:
6837 case BUILT_IN_FETCH_AND_XOR_2:
6838 case BUILT_IN_FETCH_AND_XOR_4:
6839 case BUILT_IN_FETCH_AND_XOR_8:
27213ba3 6840 case BUILT_IN_FETCH_AND_XOR_16:
3e272de8 6841 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
c2f47e15 6842 target = expand_builtin_sync_operation (mode, exp, XOR,
b6a5fc45 6843 false, target, ignore);
6844 if (target)
6845 return target;
6846 break;
6847
6848 case BUILT_IN_FETCH_AND_NAND_1:
6849 case BUILT_IN_FETCH_AND_NAND_2:
6850 case BUILT_IN_FETCH_AND_NAND_4:
6851 case BUILT_IN_FETCH_AND_NAND_8:
27213ba3 6852 case BUILT_IN_FETCH_AND_NAND_16:
3e272de8 6853 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
c2f47e15 6854 target = expand_builtin_sync_operation (mode, exp, NOT,
b6a5fc45 6855 false, target, ignore);
6856 if (target)
6857 return target;
6858 break;
6859
6860 case BUILT_IN_ADD_AND_FETCH_1:
6861 case BUILT_IN_ADD_AND_FETCH_2:
6862 case BUILT_IN_ADD_AND_FETCH_4:
6863 case BUILT_IN_ADD_AND_FETCH_8:
27213ba3 6864 case BUILT_IN_ADD_AND_FETCH_16:
3e272de8 6865 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
c2f47e15 6866 target = expand_builtin_sync_operation (mode, exp, PLUS,
b6a5fc45 6867 true, target, ignore);
6868 if (target)
6869 return target;
6870 break;
6871
6872 case BUILT_IN_SUB_AND_FETCH_1:
6873 case BUILT_IN_SUB_AND_FETCH_2:
6874 case BUILT_IN_SUB_AND_FETCH_4:
6875 case BUILT_IN_SUB_AND_FETCH_8:
27213ba3 6876 case BUILT_IN_SUB_AND_FETCH_16:
3e272de8 6877 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
c2f47e15 6878 target = expand_builtin_sync_operation (mode, exp, MINUS,
b6a5fc45 6879 true, target, ignore);
6880 if (target)
6881 return target;
6882 break;
6883
6884 case BUILT_IN_OR_AND_FETCH_1:
6885 case BUILT_IN_OR_AND_FETCH_2:
6886 case BUILT_IN_OR_AND_FETCH_4:
6887 case BUILT_IN_OR_AND_FETCH_8:
27213ba3 6888 case BUILT_IN_OR_AND_FETCH_16:
3e272de8 6889 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
c2f47e15 6890 target = expand_builtin_sync_operation (mode, exp, IOR,
b6a5fc45 6891 true, target, ignore);
6892 if (target)
6893 return target;
6894 break;
6895
6896 case BUILT_IN_AND_AND_FETCH_1:
6897 case BUILT_IN_AND_AND_FETCH_2:
6898 case BUILT_IN_AND_AND_FETCH_4:
6899 case BUILT_IN_AND_AND_FETCH_8:
27213ba3 6900 case BUILT_IN_AND_AND_FETCH_16:
3e272de8 6901 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
c2f47e15 6902 target = expand_builtin_sync_operation (mode, exp, AND,
b6a5fc45 6903 true, target, ignore);
6904 if (target)
6905 return target;
6906 break;
6907
6908 case BUILT_IN_XOR_AND_FETCH_1:
6909 case BUILT_IN_XOR_AND_FETCH_2:
6910 case BUILT_IN_XOR_AND_FETCH_4:
6911 case BUILT_IN_XOR_AND_FETCH_8:
27213ba3 6912 case BUILT_IN_XOR_AND_FETCH_16:
3e272de8 6913 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
c2f47e15 6914 target = expand_builtin_sync_operation (mode, exp, XOR,
b6a5fc45 6915 true, target, ignore);
6916 if (target)
6917 return target;
6918 break;
6919
6920 case BUILT_IN_NAND_AND_FETCH_1:
6921 case BUILT_IN_NAND_AND_FETCH_2:
6922 case BUILT_IN_NAND_AND_FETCH_4:
6923 case BUILT_IN_NAND_AND_FETCH_8:
27213ba3 6924 case BUILT_IN_NAND_AND_FETCH_16:
3e272de8 6925 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
c2f47e15 6926 target = expand_builtin_sync_operation (mode, exp, NOT,
b6a5fc45 6927 true, target, ignore);
6928 if (target)
6929 return target;
6930 break;
6931
6932 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6933 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6934 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6935 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
27213ba3 6936 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
a601d32a 6937 if (mode == VOIDmode)
6938 mode = TYPE_MODE (boolean_type_node);
b6a5fc45 6939 if (!target || !register_operand (target, mode))
6940 target = gen_reg_rtx (mode);
3e272de8 6941
6942 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
c2f47e15 6943 target = expand_builtin_compare_and_swap (mode, exp, true, target);
b6a5fc45 6944 if (target)
6945 return target;
6946 break;
6947
6948 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6949 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6950 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6951 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
27213ba3 6952 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
3e272de8 6953 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
c2f47e15 6954 target = expand_builtin_compare_and_swap (mode, exp, false, target);
b6a5fc45 6955 if (target)
6956 return target;
6957 break;
6958
6959 case BUILT_IN_LOCK_TEST_AND_SET_1:
6960 case BUILT_IN_LOCK_TEST_AND_SET_2:
6961 case BUILT_IN_LOCK_TEST_AND_SET_4:
6962 case BUILT_IN_LOCK_TEST_AND_SET_8:
27213ba3 6963 case BUILT_IN_LOCK_TEST_AND_SET_16:
3e272de8 6964 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
c2f47e15 6965 target = expand_builtin_lock_test_and_set (mode, exp, target);
b6a5fc45 6966 if (target)
6967 return target;
6968 break;
6969
6970 case BUILT_IN_LOCK_RELEASE_1:
6971 case BUILT_IN_LOCK_RELEASE_2:
6972 case BUILT_IN_LOCK_RELEASE_4:
6973 case BUILT_IN_LOCK_RELEASE_8:
27213ba3 6974 case BUILT_IN_LOCK_RELEASE_16:
3e272de8 6975 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
c2f47e15 6976 expand_builtin_lock_release (mode, exp);
b6a5fc45 6977 return const0_rtx;
6978
6979 case BUILT_IN_SYNCHRONIZE:
6980 expand_builtin_synchronize ();
6981 return const0_rtx;
6982
0a39fd54 6983 case BUILT_IN_OBJECT_SIZE:
6984 return expand_builtin_object_size (exp);
6985
6986 case BUILT_IN_MEMCPY_CHK:
6987 case BUILT_IN_MEMPCPY_CHK:
6988 case BUILT_IN_MEMMOVE_CHK:
6989 case BUILT_IN_MEMSET_CHK:
6990 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6991 if (target)
6992 return target;
6993 break;
6994
6995 case BUILT_IN_STRCPY_CHK:
6996 case BUILT_IN_STPCPY_CHK:
6997 case BUILT_IN_STRNCPY_CHK:
6998 case BUILT_IN_STRCAT_CHK:
b356dfef 6999 case BUILT_IN_STRNCAT_CHK:
0a39fd54 7000 case BUILT_IN_SNPRINTF_CHK:
7001 case BUILT_IN_VSNPRINTF_CHK:
7002 maybe_emit_chk_warning (exp, fcode);
7003 break;
7004
7005 case BUILT_IN_SPRINTF_CHK:
7006 case BUILT_IN_VSPRINTF_CHK:
7007 maybe_emit_sprintf_chk_warning (exp, fcode);
7008 break;
7009
92482ee0 7010 default: /* just do library call, if unknown builtin */
146c1b4f 7011 break;
53800dbe 7012 }
7013
7014 /* The switch statement above can drop through to cause the function
7015 to be called normally. */
7016 return expand_call (exp, target, ignore);
7017}
650e4c94 7018
805e22b2 7019/* Determine whether a tree node represents a call to a built-in
52203a9d 7020 function. If the tree T is a call to a built-in function with
7021 the right number of arguments of the appropriate types, return
7022 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
7023 Otherwise the return value is END_BUILTINS. */
aecda0d6 7024
805e22b2 7025enum built_in_function
b7bf20db 7026builtin_mathfn_code (const_tree t)
805e22b2 7027{
b7bf20db 7028 const_tree fndecl, arg, parmlist;
7029 const_tree argtype, parmtype;
7030 const_call_expr_arg_iterator iter;
805e22b2 7031
7032 if (TREE_CODE (t) != CALL_EXPR
c2f47e15 7033 || TREE_CODE (CALL_EXPR_FN (t)) != ADDR_EXPR)
805e22b2 7034 return END_BUILTINS;
7035
c6e6ecb1 7036 fndecl = get_callee_fndecl (t);
7037 if (fndecl == NULL_TREE
52203a9d 7038 || TREE_CODE (fndecl) != FUNCTION_DECL
805e22b2 7039 || ! DECL_BUILT_IN (fndecl)
7040 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7041 return END_BUILTINS;
7042
52203a9d 7043 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
b7bf20db 7044 init_const_call_expr_arg_iterator (t, &iter);
52203a9d 7045 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
e9f80ff5 7046 {
52203a9d 7047 /* If a function doesn't take a variable number of arguments,
7048 the last element in the list will have type `void'. */
7049 parmtype = TREE_VALUE (parmlist);
7050 if (VOID_TYPE_P (parmtype))
7051 {
b7bf20db 7052 if (more_const_call_expr_args_p (&iter))
52203a9d 7053 return END_BUILTINS;
7054 return DECL_FUNCTION_CODE (fndecl);
7055 }
7056
b7bf20db 7057 if (! more_const_call_expr_args_p (&iter))
e9f80ff5 7058 return END_BUILTINS;
c2f47e15 7059
b7bf20db 7060 arg = next_const_call_expr_arg (&iter);
c2f47e15 7061 argtype = TREE_TYPE (arg);
52203a9d 7062
7063 if (SCALAR_FLOAT_TYPE_P (parmtype))
7064 {
7065 if (! SCALAR_FLOAT_TYPE_P (argtype))
7066 return END_BUILTINS;
7067 }
7068 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
7069 {
7070 if (! COMPLEX_FLOAT_TYPE_P (argtype))
7071 return END_BUILTINS;
7072 }
7073 else if (POINTER_TYPE_P (parmtype))
7074 {
7075 if (! POINTER_TYPE_P (argtype))
7076 return END_BUILTINS;
7077 }
7078 else if (INTEGRAL_TYPE_P (parmtype))
7079 {
7080 if (! INTEGRAL_TYPE_P (argtype))
7081 return END_BUILTINS;
7082 }
7083 else
e9f80ff5 7084 return END_BUILTINS;
e9f80ff5 7085 }
7086
52203a9d 7087 /* Variable-length argument list. */
805e22b2 7088 return DECL_FUNCTION_CODE (fndecl);
7089}
7090
c2f47e15 7091/* Fold a call to __builtin_constant_p, if we know its argument ARG will
7092 evaluate to a constant. */
650e4c94 7093
7094static tree
c2f47e15 7095fold_builtin_constant_p (tree arg)
650e4c94 7096{
650e4c94 7097 /* We return 1 for a numeric type that's known to be a constant
7098 value at compile-time or for an aggregate type that's a
7099 literal constant. */
c2f47e15 7100 STRIP_NOPS (arg);
650e4c94 7101
7102 /* If we know this is a constant, emit the constant of one. */
c2f47e15 7103 if (CONSTANT_CLASS_P (arg)
7104 || (TREE_CODE (arg) == CONSTRUCTOR
7105 && TREE_CONSTANT (arg)))
650e4c94 7106 return integer_one_node;
c2f47e15 7107 if (TREE_CODE (arg) == ADDR_EXPR)
adcfa3a3 7108 {
c2f47e15 7109 tree op = TREE_OPERAND (arg, 0);
adcfa3a3 7110 if (TREE_CODE (op) == STRING_CST
7111 || (TREE_CODE (op) == ARRAY_REF
7112 && integer_zerop (TREE_OPERAND (op, 1))
7113 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
7114 return integer_one_node;
7115 }
650e4c94 7116
1fb4300c 7117 /* If this expression has side effects, show we don't know it to be a
7118 constant. Likewise if it's a pointer or aggregate type since in
7119 those case we only want literals, since those are only optimized
f97c71a1 7120 when generating RTL, not later.
7121 And finally, if we are compiling an initializer, not code, we
7122 need to return a definite result now; there's not going to be any
7123 more optimization done. */
c2f47e15 7124 if (TREE_SIDE_EFFECTS (arg)
7125 || AGGREGATE_TYPE_P (TREE_TYPE (arg))
7126 || POINTER_TYPE_P (TREE_TYPE (arg))
47be647d 7127 || cfun == 0
7128 || folding_initializer)
650e4c94 7129 return integer_zero_node;
7130
c2f47e15 7131 return NULL_TREE;
650e4c94 7132}
7133
76f5a783 7134/* Create builtin_expect with PRED and EXPECTED as its arguments and
7135 return it as a truthvalue. */
4ee9c684 7136
7137static tree
76f5a783 7138build_builtin_expect_predicate (tree pred, tree expected)
4ee9c684 7139{
76f5a783 7140 tree fn, arg_types, pred_type, expected_type, call_expr, ret_type;
4ee9c684 7141
76f5a783 7142 fn = built_in_decls[BUILT_IN_EXPECT];
7143 arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
7144 ret_type = TREE_TYPE (TREE_TYPE (fn));
7145 pred_type = TREE_VALUE (arg_types);
7146 expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
7147
7148 pred = fold_convert (pred_type, pred);
7149 expected = fold_convert (expected_type, expected);
7150 call_expr = build_call_expr (fn, 2, pred, expected);
7151
7152 return build2 (NE_EXPR, TREE_TYPE (pred), call_expr,
7153 build_int_cst (ret_type, 0));
7154}
7155
7156/* Fold a call to builtin_expect with arguments ARG0 and ARG1. Return
7157 NULL_TREE if no simplification is possible. */
7158
7159static tree
7160fold_builtin_expect (tree arg0, tree arg1)
7161{
7162 tree inner, fndecl;
7163 enum tree_code code;
7164
7165 /* If this is a builtin_expect within a builtin_expect keep the
7166 inner one. See through a comparison against a constant. It
7167 might have been added to create a thruthvalue. */
7168 inner = arg0;
7169 if (COMPARISON_CLASS_P (inner)
7170 && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST)
7171 inner = TREE_OPERAND (inner, 0);
7172
7173 if (TREE_CODE (inner) == CALL_EXPR
7174 && (fndecl = get_callee_fndecl (inner))
7175 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
7176 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT)
7177 return arg0;
7178
7179 /* Distribute the expected value over short-circuiting operators.
7180 See through the cast from truthvalue_type_node to long. */
7181 inner = arg0;
7182 while (TREE_CODE (inner) == NOP_EXPR
7183 && INTEGRAL_TYPE_P (TREE_TYPE (inner))
7184 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (inner, 0))))
7185 inner = TREE_OPERAND (inner, 0);
7186
7187 code = TREE_CODE (inner);
7188 if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
7189 {
7190 tree op0 = TREE_OPERAND (inner, 0);
7191 tree op1 = TREE_OPERAND (inner, 1);
7192
7193 op0 = build_builtin_expect_predicate (op0, arg1);
7194 op1 = build_builtin_expect_predicate (op1, arg1);
7195 inner = build2 (code, TREE_TYPE (inner), op0, op1);
7196
7197 return fold_convert (TREE_TYPE (arg0), inner);
7198 }
7199
7200 /* If the argument isn't invariant then there's nothing else we can do. */
c7d4e749 7201 if (!TREE_CONSTANT (arg0))
c2f47e15 7202 return NULL_TREE;
4ee9c684 7203
76f5a783 7204 /* If we expect that a comparison against the argument will fold to
7205 a constant return the constant. In practice, this means a true
7206 constant or the address of a non-weak symbol. */
7207 inner = arg0;
4ee9c684 7208 STRIP_NOPS (inner);
7209 if (TREE_CODE (inner) == ADDR_EXPR)
7210 {
7211 do
7212 {
7213 inner = TREE_OPERAND (inner, 0);
7214 }
7215 while (TREE_CODE (inner) == COMPONENT_REF
7216 || TREE_CODE (inner) == ARRAY_REF);
7217 if (DECL_P (inner) && DECL_WEAK (inner))
c2f47e15 7218 return NULL_TREE;
4ee9c684 7219 }
7220
76f5a783 7221 /* Otherwise, ARG0 already has the proper type for the return value. */
7222 return arg0;
4ee9c684 7223}
7224
c2f47e15 7225/* Fold a call to __builtin_classify_type with argument ARG. */
27d0c333 7226
539a3a92 7227static tree
c2f47e15 7228fold_builtin_classify_type (tree arg)
539a3a92 7229{
c2f47e15 7230 if (arg == 0)
7016c612 7231 return build_int_cst (NULL_TREE, no_type_class);
539a3a92 7232
c2f47e15 7233 return build_int_cst (NULL_TREE, type_to_class (TREE_TYPE (arg)));
539a3a92 7234}
7235
c2f47e15 7236/* Fold a call to __builtin_strlen with argument ARG. */
e6e27594 7237
7238static tree
c2f47e15 7239fold_builtin_strlen (tree arg)
e6e27594 7240{
c2f47e15 7241 if (!validate_arg (arg, POINTER_TYPE))
e6e27594 7242 return NULL_TREE;
7243 else
7244 {
c2f47e15 7245 tree len = c_strlen (arg, 0);
e6e27594 7246
7247 if (len)
7248 {
7249 /* Convert from the internal "sizetype" type to "size_t". */
7250 if (size_type_node)
7251 len = fold_convert (size_type_node, len);
7252 return len;
7253 }
7254
7255 return NULL_TREE;
7256 }
7257}
7258
92c43e3c 7259/* Fold a call to __builtin_inf or __builtin_huge_val. */
7260
7261static tree
aecda0d6 7262fold_builtin_inf (tree type, int warn)
92c43e3c 7263{
aa870c1b 7264 REAL_VALUE_TYPE real;
7265
40f4dbd5 7266 /* __builtin_inff is intended to be usable to define INFINITY on all
7267 targets. If an infinity is not available, INFINITY expands "to a
7268 positive constant of type float that overflows at translation
7269 time", footnote "In this case, using INFINITY will violate the
7270 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
7271 Thus we pedwarn to ensure this constraint violation is
7272 diagnosed. */
92c43e3c 7273 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
8864917d 7274 pedwarn (0, "target format does not support infinity");
92c43e3c 7275
aa870c1b 7276 real_inf (&real);
7277 return build_real (type, real);
92c43e3c 7278}
7279
c2f47e15 7280/* Fold a call to __builtin_nan or __builtin_nans with argument ARG. */
b0db7939 7281
7282static tree
c2f47e15 7283fold_builtin_nan (tree arg, tree type, int quiet)
b0db7939 7284{
7285 REAL_VALUE_TYPE real;
7286 const char *str;
7287
c2f47e15 7288 if (!validate_arg (arg, POINTER_TYPE))
7289 return NULL_TREE;
7290 str = c_getstr (arg);
b0db7939 7291 if (!str)
c2f47e15 7292 return NULL_TREE;
b0db7939 7293
7294 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
c2f47e15 7295 return NULL_TREE;
b0db7939 7296
7297 return build_real (type, real);
7298}
7299
277f8dd2 7300/* Return true if the floating point expression T has an integer value.
7301 We also allow +Inf, -Inf and NaN to be considered integer values. */
7302
7303static bool
7304integer_valued_real_p (tree t)
7305{
7306 switch (TREE_CODE (t))
7307 {
7308 case FLOAT_EXPR:
7309 return true;
7310
7311 case ABS_EXPR:
7312 case SAVE_EXPR:
277f8dd2 7313 return integer_valued_real_p (TREE_OPERAND (t, 0));
7314
7315 case COMPOUND_EXPR:
41076ef6 7316 case MODIFY_EXPR:
277f8dd2 7317 case BIND_EXPR:
75a70cf9 7318 return integer_valued_real_p (TREE_OPERAND (t, 1));
277f8dd2 7319
7320 case PLUS_EXPR:
7321 case MINUS_EXPR:
7322 case MULT_EXPR:
7323 case MIN_EXPR:
7324 case MAX_EXPR:
7325 return integer_valued_real_p (TREE_OPERAND (t, 0))
7326 && integer_valued_real_p (TREE_OPERAND (t, 1));
7327
7328 case COND_EXPR:
7329 return integer_valued_real_p (TREE_OPERAND (t, 1))
7330 && integer_valued_real_p (TREE_OPERAND (t, 2));
7331
7332 case REAL_CST:
0570334c 7333 return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t)));
277f8dd2 7334
7335 case NOP_EXPR:
7336 {
7337 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
7338 if (TREE_CODE (type) == INTEGER_TYPE)
7339 return true;
7340 if (TREE_CODE (type) == REAL_TYPE)
7341 return integer_valued_real_p (TREE_OPERAND (t, 0));
7342 break;
7343 }
7344
7345 case CALL_EXPR:
7346 switch (builtin_mathfn_code (t))
7347 {
4f35b1fc 7348 CASE_FLT_FN (BUILT_IN_CEIL):
7349 CASE_FLT_FN (BUILT_IN_FLOOR):
7350 CASE_FLT_FN (BUILT_IN_NEARBYINT):
7351 CASE_FLT_FN (BUILT_IN_RINT):
7352 CASE_FLT_FN (BUILT_IN_ROUND):
7353 CASE_FLT_FN (BUILT_IN_TRUNC):
277f8dd2 7354 return true;
7355
d4a43a03 7356 CASE_FLT_FN (BUILT_IN_FMIN):
7357 CASE_FLT_FN (BUILT_IN_FMAX):
c2f47e15 7358 return integer_valued_real_p (CALL_EXPR_ARG (t, 0))
7359 && integer_valued_real_p (CALL_EXPR_ARG (t, 1));
d4a43a03 7360
277f8dd2 7361 default:
7362 break;
7363 }
7364 break;
7365
7366 default:
7367 break;
7368 }
7369 return false;
7370}
7371
c2f47e15 7372/* FNDECL is assumed to be a builtin where truncation can be propagated
6528f4f4 7373 across (for instance floor((double)f) == (double)floorf (f).
c2f47e15 7374 Do the transformation for a call with argument ARG. */
277f8dd2 7375
6528f4f4 7376static tree
c2f47e15 7377fold_trunc_transparent_mathfn (tree fndecl, tree arg)
6528f4f4 7378{
6528f4f4 7379 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
277f8dd2 7380
c2f47e15 7381 if (!validate_arg (arg, REAL_TYPE))
7382 return NULL_TREE;
6528f4f4 7383
277f8dd2 7384 /* Integer rounding functions are idempotent. */
7385 if (fcode == builtin_mathfn_code (arg))
7386 return arg;
7387
7388 /* If argument is already integer valued, and we don't need to worry
7389 about setting errno, there's no need to perform rounding. */
7390 if (! flag_errno_math && integer_valued_real_p (arg))
7391 return arg;
7392
7393 if (optimize)
6528f4f4 7394 {
277f8dd2 7395 tree arg0 = strip_float_extensions (arg);
2426241c 7396 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6528f4f4 7397 tree newtype = TREE_TYPE (arg0);
7398 tree decl;
7399
7400 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7401 && (decl = mathfn_built_in (newtype, fcode)))
c2f47e15 7402 return fold_convert (ftype,
7403 build_call_expr (decl, 1,
7404 fold_convert (newtype, arg0)));
6528f4f4 7405 }
c2f47e15 7406 return NULL_TREE;
6528f4f4 7407}
7408
c2f47e15 7409/* FNDECL is assumed to be builtin which can narrow the FP type of
7410 the argument, for instance lround((double)f) -> lroundf (f).
7411 Do the transformation for a call with argument ARG. */
9ed65c7f 7412
7413static tree
c2f47e15 7414fold_fixed_mathfn (tree fndecl, tree arg)
9ed65c7f 7415{
9ed65c7f 7416 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
9ed65c7f 7417
c2f47e15 7418 if (!validate_arg (arg, REAL_TYPE))
7419 return NULL_TREE;
9ed65c7f 7420
7421 /* If argument is already integer valued, and we don't need to worry
7422 about setting errno, there's no need to perform rounding. */
7423 if (! flag_errno_math && integer_valued_real_p (arg))
49d00087 7424 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
9ed65c7f 7425
7426 if (optimize)
7427 {
7428 tree ftype = TREE_TYPE (arg);
7429 tree arg0 = strip_float_extensions (arg);
7430 tree newtype = TREE_TYPE (arg0);
7431 tree decl;
7432
7433 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7434 && (decl = mathfn_built_in (newtype, fcode)))
c2f47e15 7435 return build_call_expr (decl, 1, fold_convert (newtype, arg0));
9ed65c7f 7436 }
73a0da56 7437
7438 /* Canonicalize llround (x) to lround (x) on LP64 targets where
7439 sizeof (long long) == sizeof (long). */
7440 if (TYPE_PRECISION (long_long_integer_type_node)
7441 == TYPE_PRECISION (long_integer_type_node))
7442 {
7443 tree newfn = NULL_TREE;
7444 switch (fcode)
7445 {
7446 CASE_FLT_FN (BUILT_IN_LLCEIL):
7447 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7448 break;
7449
7450 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7451 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7452 break;
7453
7454 CASE_FLT_FN (BUILT_IN_LLROUND):
7455 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7456 break;
7457
7458 CASE_FLT_FN (BUILT_IN_LLRINT):
7459 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7460 break;
7461
7462 default:
7463 break;
7464 }
7465
7466 if (newfn)
7467 {
c2f47e15 7468 tree newcall = build_call_expr(newfn, 1, arg);
73a0da56 7469 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
7470 }
7471 }
7472
c2f47e15 7473 return NULL_TREE;
9ed65c7f 7474}
7475
c2f47e15 7476/* Fold call to builtin cabs, cabsf or cabsl with argument ARG. TYPE is the
7477 return type. Return NULL_TREE if no simplification can be made. */
c63f4ad3 7478
7479static tree
c2f47e15 7480fold_builtin_cabs (tree arg, tree type, tree fndecl)
c63f4ad3 7481{
c2f47e15 7482 tree res;
c63f4ad3 7483
c63f4ad3 7484 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
7485 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7486 return NULL_TREE;
7487
b4725390 7488 /* Calculate the result when the argument is a constant. */
7489 if (TREE_CODE (arg) == COMPLEX_CST
7490 && (res = do_mpfr_arg2 (TREE_REALPART (arg), TREE_IMAGPART (arg),
7491 type, mpfr_hypot)))
7492 return res;
7493
1af0d139 7494 if (TREE_CODE (arg) == COMPLEX_EXPR)
7495 {
7496 tree real = TREE_OPERAND (arg, 0);
7497 tree imag = TREE_OPERAND (arg, 1);
7498
7499 /* If either part is zero, cabs is fabs of the other. */
7500 if (real_zerop (real))
7501 return fold_build1 (ABS_EXPR, type, imag);
7502 if (real_zerop (imag))
7503 return fold_build1 (ABS_EXPR, type, real);
7504
7505 /* cabs(x+xi) -> fabs(x)*sqrt(2). */
7506 if (flag_unsafe_math_optimizations
7507 && operand_equal_p (real, imag, OEP_PURE_SAME))
7508 {
2e7ca27b 7509 const REAL_VALUE_TYPE sqrt2_trunc
3fa759a9 7510 = real_value_truncate (TYPE_MODE (type),
7511 *get_real_const (rv_sqrt2));
1af0d139 7512 STRIP_NOPS (real);
7513 return fold_build2 (MULT_EXPR, type,
7514 fold_build1 (ABS_EXPR, type, real),
2e7ca27b 7515 build_real (type, sqrt2_trunc));
1af0d139 7516 }
7517 }
c63f4ad3 7518
749891b2 7519 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
7520 if (TREE_CODE (arg) == NEGATE_EXPR
7521 || TREE_CODE (arg) == CONJ_EXPR)
c2f47e15 7522 return build_call_expr (fndecl, 1, TREE_OPERAND (arg, 0));
749891b2 7523
7d3f6cc7 7524 /* Don't do this when optimizing for size. */
7525 if (flag_unsafe_math_optimizations
7526 && optimize && !optimize_size)
c63f4ad3 7527 {
0da0dbfa 7528 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
c63f4ad3 7529
7530 if (sqrtfn != NULL_TREE)
7531 {
c2f47e15 7532 tree rpart, ipart, result;
c63f4ad3 7533
4ee9c684 7534 arg = builtin_save_expr (arg);
29a6518e 7535
49d00087 7536 rpart = fold_build1 (REALPART_EXPR, type, arg);
7537 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
c63f4ad3 7538
4ee9c684 7539 rpart = builtin_save_expr (rpart);
7540 ipart = builtin_save_expr (ipart);
c63f4ad3 7541
49d00087 7542 result = fold_build2 (PLUS_EXPR, type,
7543 fold_build2 (MULT_EXPR, type,
7544 rpart, rpart),
7545 fold_build2 (MULT_EXPR, type,
7546 ipart, ipart));
c63f4ad3 7547
c2f47e15 7548 return build_call_expr (sqrtfn, 1, result);
c63f4ad3 7549 }
7550 }
7551
7552 return NULL_TREE;
7553}
7554
c2f47e15 7555/* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG.
7556 Return NULL_TREE if no simplification can be made. */
e6e27594 7557
7558static tree
c2f47e15 7559fold_builtin_sqrt (tree arg, tree type)
e6e27594 7560{
7561
7562 enum built_in_function fcode;
b4e8ab0c 7563 tree res;
c2f47e15 7564
7565 if (!validate_arg (arg, REAL_TYPE))
e6e27594 7566 return NULL_TREE;
7567
b4e8ab0c 7568 /* Calculate the result when the argument is a constant. */
7569 if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst0, NULL, true)))
7570 return res;
7571
e6e27594 7572 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7573 fcode = builtin_mathfn_code (arg);
7574 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7575 {
c2f47e15 7576 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
49d00087 7577 arg = fold_build2 (MULT_EXPR, type,
c2f47e15 7578 CALL_EXPR_ARG (arg, 0),
49d00087 7579 build_real (type, dconsthalf));
c2f47e15 7580 return build_call_expr (expfn, 1, arg);
e6e27594 7581 }
7582
7583 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7584 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7585 {
7586 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7587
7588 if (powfn)
7589 {
c2f47e15 7590 tree arg0 = CALL_EXPR_ARG (arg, 0);
e6e27594 7591 tree tree_root;
7592 /* The inner root was either sqrt or cbrt. */
7593 REAL_VALUE_TYPE dconstroot =
3fa759a9 7594 BUILTIN_SQRT_P (fcode) ? dconsthalf : *get_real_const (rv_third);
e6e27594 7595
7596 /* Adjust for the outer root. */
7597 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7598 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7599 tree_root = build_real (type, dconstroot);
c2f47e15 7600 return build_call_expr (powfn, 2, arg0, tree_root);
e6e27594 7601 }
7602 }
7603
bc33117f 7604 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
e6e27594 7605 if (flag_unsafe_math_optimizations
7606 && (fcode == BUILT_IN_POW
7607 || fcode == BUILT_IN_POWF
7608 || fcode == BUILT_IN_POWL))
7609 {
c2f47e15 7610 tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7611 tree arg0 = CALL_EXPR_ARG (arg, 0);
7612 tree arg1 = CALL_EXPR_ARG (arg, 1);
bc33117f 7613 tree narg1;
7614 if (!tree_expr_nonnegative_p (arg0))
7615 arg0 = build1 (ABS_EXPR, type, arg0);
49d00087 7616 narg1 = fold_build2 (MULT_EXPR, type, arg1,
7617 build_real (type, dconsthalf));
c2f47e15 7618 return build_call_expr (powfn, 2, arg0, narg1);
e6e27594 7619 }
7620
7621 return NULL_TREE;
7622}
7623
c2f47e15 7624/* Fold a builtin function call to cbrt, cbrtf, or cbrtl with argument ARG.
7625 Return NULL_TREE if no simplification can be made. */
7626
e6e27594 7627static tree
c2f47e15 7628fold_builtin_cbrt (tree arg, tree type)
e6e27594 7629{
e6e27594 7630 const enum built_in_function fcode = builtin_mathfn_code (arg);
29f4cd78 7631 tree res;
e6e27594 7632
c2f47e15 7633 if (!validate_arg (arg, REAL_TYPE))
e6e27594 7634 return NULL_TREE;
7635
29f4cd78 7636 /* Calculate the result when the argument is a constant. */
7637 if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7638 return res;
e6e27594 7639
cdfeb715 7640 if (flag_unsafe_math_optimizations)
e6e27594 7641 {
cdfeb715 7642 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7643 if (BUILTIN_EXPONENT_P (fcode))
a0c938f0 7644 {
c2f47e15 7645 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
cdfeb715 7646 const REAL_VALUE_TYPE third_trunc =
3fa759a9 7647 real_value_truncate (TYPE_MODE (type), *get_real_const (rv_third));
49d00087 7648 arg = fold_build2 (MULT_EXPR, type,
c2f47e15 7649 CALL_EXPR_ARG (arg, 0),
49d00087 7650 build_real (type, third_trunc));
c2f47e15 7651 return build_call_expr (expfn, 1, arg);
cdfeb715 7652 }
e6e27594 7653
cdfeb715 7654 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7655 if (BUILTIN_SQRT_P (fcode))
a0c938f0 7656 {
cdfeb715 7657 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
e6e27594 7658
cdfeb715 7659 if (powfn)
7660 {
c2f47e15 7661 tree arg0 = CALL_EXPR_ARG (arg, 0);
cdfeb715 7662 tree tree_root;
3fa759a9 7663 REAL_VALUE_TYPE dconstroot = *get_real_const (rv_third);
cdfeb715 7664
7665 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7666 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7667 tree_root = build_real (type, dconstroot);
c2f47e15 7668 return build_call_expr (powfn, 2, arg0, tree_root);
cdfeb715 7669 }
e6e27594 7670 }
7671
cdfeb715 7672 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7673 if (BUILTIN_CBRT_P (fcode))
a0c938f0 7674 {
c2f47e15 7675 tree arg0 = CALL_EXPR_ARG (arg, 0);
cdfeb715 7676 if (tree_expr_nonnegative_p (arg0))
7677 {
7678 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7679
7680 if (powfn)
a0c938f0 7681 {
cdfeb715 7682 tree tree_root;
7683 REAL_VALUE_TYPE dconstroot;
a0c938f0 7684
3fa759a9 7685 real_arithmetic (&dconstroot, MULT_EXPR,
7686 get_real_const (rv_third),
7687 get_real_const (rv_third));
cdfeb715 7688 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7689 tree_root = build_real (type, dconstroot);
c2f47e15 7690 return build_call_expr (powfn, 2, arg0, tree_root);
cdfeb715 7691 }
7692 }
7693 }
a0c938f0 7694
cdfeb715 7695 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
c2f47e15 7696 if (fcode == BUILT_IN_POW
7697 || fcode == BUILT_IN_POWF
cdfeb715 7698 || fcode == BUILT_IN_POWL)
a0c938f0 7699 {
c2f47e15 7700 tree arg00 = CALL_EXPR_ARG (arg, 0);
7701 tree arg01 = CALL_EXPR_ARG (arg, 1);
cdfeb715 7702 if (tree_expr_nonnegative_p (arg00))
7703 {
c2f47e15 7704 tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
cdfeb715 7705 const REAL_VALUE_TYPE dconstroot
3fa759a9 7706 = real_value_truncate (TYPE_MODE (type),
7707 *get_real_const (rv_third));
49d00087 7708 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7709 build_real (type, dconstroot));
c2f47e15 7710 return build_call_expr (powfn, 2, arg00, narg01);
cdfeb715 7711 }
7712 }
e6e27594 7713 }
7714 return NULL_TREE;
7715}
7716
c2f47e15 7717/* Fold function call to builtin cos, cosf, or cosl with argument ARG.
7718 TYPE is the type of the return value. Return NULL_TREE if no
7719 simplification can be made. */
7720
e6e27594 7721static tree
c2f47e15 7722fold_builtin_cos (tree arg, tree type, tree fndecl)
e6e27594 7723{
e6ab33d8 7724 tree res, narg;
e6e27594 7725
c2f47e15 7726 if (!validate_arg (arg, REAL_TYPE))
e6e27594 7727 return NULL_TREE;
7728
bffb7645 7729 /* Calculate the result when the argument is a constant. */
728bac60 7730 if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
bffb7645 7731 return res;
7732
e6e27594 7733 /* Optimize cos(-x) into cos (x). */
e6ab33d8 7734 if ((narg = fold_strip_sign_ops (arg)))
c2f47e15 7735 return build_call_expr (fndecl, 1, narg);
e6e27594 7736
7737 return NULL_TREE;
7738}
7739
c2f47e15 7740/* Fold function call to builtin cosh, coshf, or coshl with argument ARG.
7741 Return NULL_TREE if no simplification can be made. */
7742
cacdc1af 7743static tree
c2f47e15 7744fold_builtin_cosh (tree arg, tree type, tree fndecl)
cacdc1af 7745{
c2f47e15 7746 if (validate_arg (arg, REAL_TYPE))
cacdc1af 7747 {
cacdc1af 7748 tree res, narg;
7749
7750 /* Calculate the result when the argument is a constant. */
7751 if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0)))
7752 return res;
7753
7754 /* Optimize cosh(-x) into cosh (x). */
7755 if ((narg = fold_strip_sign_ops (arg)))
c2f47e15 7756 return build_call_expr (fndecl, 1, narg);
cacdc1af 7757 }
7758
7759 return NULL_TREE;
7760}
7761
c2f47e15 7762/* Fold function call to builtin tan, tanf, or tanl with argument ARG.
7763 Return NULL_TREE if no simplification can be made. */
7764
e6e27594 7765static tree
c2f47e15 7766fold_builtin_tan (tree arg, tree type)
e6e27594 7767{
7768 enum built_in_function fcode;
29f4cd78 7769 tree res;
e6e27594 7770
c2f47e15 7771 if (!validate_arg (arg, REAL_TYPE))
e6e27594 7772 return NULL_TREE;
7773
bffb7645 7774 /* Calculate the result when the argument is a constant. */
728bac60 7775 if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0)))
bffb7645 7776 return res;
7777
e6e27594 7778 /* Optimize tan(atan(x)) = x. */
7779 fcode = builtin_mathfn_code (arg);
7780 if (flag_unsafe_math_optimizations
7781 && (fcode == BUILT_IN_ATAN
7782 || fcode == BUILT_IN_ATANF
7783 || fcode == BUILT_IN_ATANL))
c2f47e15 7784 return CALL_EXPR_ARG (arg, 0);
e6e27594 7785
7786 return NULL_TREE;
7787}
7788
d735c391 7789/* Fold function call to builtin sincos, sincosf, or sincosl. Return
7790 NULL_TREE if no simplification can be made. */
7791
7792static tree
c2f47e15 7793fold_builtin_sincos (tree arg0, tree arg1, tree arg2)
d735c391 7794{
c2f47e15 7795 tree type;
d735c391 7796 tree res, fn, call;
7797
c2f47e15 7798 if (!validate_arg (arg0, REAL_TYPE)
7799 || !validate_arg (arg1, POINTER_TYPE)
7800 || !validate_arg (arg2, POINTER_TYPE))
d735c391 7801 return NULL_TREE;
7802
d735c391 7803 type = TREE_TYPE (arg0);
d735c391 7804
7805 /* Calculate the result when the argument is a constant. */
7806 if ((res = do_mpfr_sincos (arg0, arg1, arg2)))
7807 return res;
7808
7809 /* Canonicalize sincos to cexpi. */
2a6b4c77 7810 if (!TARGET_C99_FUNCTIONS)
7811 return NULL_TREE;
d735c391 7812 fn = mathfn_built_in (type, BUILT_IN_CEXPI);
7813 if (!fn)
7814 return NULL_TREE;
7815
c2f47e15 7816 call = build_call_expr (fn, 1, arg0);
d735c391 7817 call = builtin_save_expr (call);
7818
7819 return build2 (COMPOUND_EXPR, type,
7820 build2 (MODIFY_EXPR, void_type_node,
7821 build_fold_indirect_ref (arg1),
7822 build1 (IMAGPART_EXPR, type, call)),
7823 build2 (MODIFY_EXPR, void_type_node,
7824 build_fold_indirect_ref (arg2),
7825 build1 (REALPART_EXPR, type, call)));
7826}
7827
c5bb2c4b 7828/* Fold function call to builtin cexp, cexpf, or cexpl. Return
7829 NULL_TREE if no simplification can be made. */
7830
7831static tree
c2f47e15 7832fold_builtin_cexp (tree arg0, tree type)
c5bb2c4b 7833{
c2f47e15 7834 tree rtype;
c5bb2c4b 7835 tree realp, imagp, ifn;
7836
c2f47e15 7837 if (!validate_arg (arg0, COMPLEX_TYPE))
c5bb2c4b 7838 return NULL_TREE;
7839
c5bb2c4b 7840 rtype = TREE_TYPE (TREE_TYPE (arg0));
7841
7842 /* In case we can figure out the real part of arg0 and it is constant zero
7843 fold to cexpi. */
2a6b4c77 7844 if (!TARGET_C99_FUNCTIONS)
7845 return NULL_TREE;
c5bb2c4b 7846 ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
7847 if (!ifn)
7848 return NULL_TREE;
7849
7850 if ((realp = fold_unary (REALPART_EXPR, rtype, arg0))
7851 && real_zerop (realp))
7852 {
7853 tree narg = fold_build1 (IMAGPART_EXPR, rtype, arg0);
c2f47e15 7854 return build_call_expr (ifn, 1, narg);
c5bb2c4b 7855 }
7856
7857 /* In case we can easily decompose real and imaginary parts split cexp
7858 to exp (r) * cexpi (i). */
7859 if (flag_unsafe_math_optimizations
7860 && realp)
7861 {
7862 tree rfn, rcall, icall;
7863
7864 rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
7865 if (!rfn)
7866 return NULL_TREE;
7867
7868 imagp = fold_unary (IMAGPART_EXPR, rtype, arg0);
7869 if (!imagp)
7870 return NULL_TREE;
7871
c2f47e15 7872 icall = build_call_expr (ifn, 1, imagp);
c5bb2c4b 7873 icall = builtin_save_expr (icall);
c2f47e15 7874 rcall = build_call_expr (rfn, 1, realp);
c5bb2c4b 7875 rcall = builtin_save_expr (rcall);
71bf42bb 7876 return fold_build2 (COMPLEX_EXPR, type,
7877 fold_build2 (MULT_EXPR, rtype,
7878 rcall,
7879 fold_build1 (REALPART_EXPR, rtype, icall)),
7880 fold_build2 (MULT_EXPR, rtype,
7881 rcall,
7882 fold_build1 (IMAGPART_EXPR, rtype, icall)));
c5bb2c4b 7883 }
7884
7885 return NULL_TREE;
7886}
7887
c2f47e15 7888/* Fold function call to builtin trunc, truncf or truncl with argument ARG.
7889 Return NULL_TREE if no simplification can be made. */
277f8dd2 7890
7891static tree
c2f47e15 7892fold_builtin_trunc (tree fndecl, tree arg)
277f8dd2 7893{
c2f47e15 7894 if (!validate_arg (arg, REAL_TYPE))
7895 return NULL_TREE;
277f8dd2 7896
7897 /* Optimize trunc of constant value. */
f96bd2bf 7898 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
277f8dd2 7899 {
7900 REAL_VALUE_TYPE r, x;
2426241c 7901 tree type = TREE_TYPE (TREE_TYPE (fndecl));
277f8dd2 7902
7903 x = TREE_REAL_CST (arg);
7904 real_trunc (&r, TYPE_MODE (type), &x);
7905 return build_real (type, r);
7906 }
7907
c2f47e15 7908 return fold_trunc_transparent_mathfn (fndecl, arg);
277f8dd2 7909}
7910
c2f47e15 7911/* Fold function call to builtin floor, floorf or floorl with argument ARG.
7912 Return NULL_TREE if no simplification can be made. */
277f8dd2 7913
7914static tree
c2f47e15 7915fold_builtin_floor (tree fndecl, tree arg)
277f8dd2 7916{
c2f47e15 7917 if (!validate_arg (arg, REAL_TYPE))
7918 return NULL_TREE;
277f8dd2 7919
7920 /* Optimize floor of constant value. */
f96bd2bf 7921 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
277f8dd2 7922 {
7923 REAL_VALUE_TYPE x;
7924
7925 x = TREE_REAL_CST (arg);
7926 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7927 {
2426241c 7928 tree type = TREE_TYPE (TREE_TYPE (fndecl));
277f8dd2 7929 REAL_VALUE_TYPE r;
7930
7931 real_floor (&r, TYPE_MODE (type), &x);
7932 return build_real (type, r);
7933 }
7934 }
7935
acc2b92e 7936 /* Fold floor (x) where x is nonnegative to trunc (x). */
7937 if (tree_expr_nonnegative_p (arg))
30fe8286 7938 {
7939 tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
7940 if (truncfn)
c2f47e15 7941 return build_call_expr (truncfn, 1, arg);
30fe8286 7942 }
acc2b92e 7943
c2f47e15 7944 return fold_trunc_transparent_mathfn (fndecl, arg);
277f8dd2 7945}
7946
c2f47e15 7947/* Fold function call to builtin ceil, ceilf or ceill with argument ARG.
7948 Return NULL_TREE if no simplification can be made. */
277f8dd2 7949
7950static tree
c2f47e15 7951fold_builtin_ceil (tree fndecl, tree arg)
277f8dd2 7952{
c2f47e15 7953 if (!validate_arg (arg, REAL_TYPE))
7954 return NULL_TREE;
277f8dd2 7955
7956 /* Optimize ceil of constant value. */
f96bd2bf 7957 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
277f8dd2 7958 {
7959 REAL_VALUE_TYPE x;
7960
7961 x = TREE_REAL_CST (arg);
7962 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7963 {
2426241c 7964 tree type = TREE_TYPE (TREE_TYPE (fndecl));
277f8dd2 7965 REAL_VALUE_TYPE r;
7966
7967 real_ceil (&r, TYPE_MODE (type), &x);
7968 return build_real (type, r);
7969 }
7970 }
7971
c2f47e15 7972 return fold_trunc_transparent_mathfn (fndecl, arg);
277f8dd2 7973}
7974
c2f47e15 7975/* Fold function call to builtin round, roundf or roundl with argument ARG.
7976 Return NULL_TREE if no simplification can be made. */
89ab3887 7977
7978static tree
c2f47e15 7979fold_builtin_round (tree fndecl, tree arg)
89ab3887 7980{
c2f47e15 7981 if (!validate_arg (arg, REAL_TYPE))
7982 return NULL_TREE;
89ab3887 7983
34f17811 7984 /* Optimize round of constant value. */
f96bd2bf 7985 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
89ab3887 7986 {
7987 REAL_VALUE_TYPE x;
7988
7989 x = TREE_REAL_CST (arg);
7990 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7991 {
2426241c 7992 tree type = TREE_TYPE (TREE_TYPE (fndecl));
89ab3887 7993 REAL_VALUE_TYPE r;
7994
7995 real_round (&r, TYPE_MODE (type), &x);
7996 return build_real (type, r);
7997 }
7998 }
7999
c2f47e15 8000 return fold_trunc_transparent_mathfn (fndecl, arg);
89ab3887 8001}
8002
34f17811 8003/* Fold function call to builtin lround, lroundf or lroundl (or the
c2f47e15 8004 corresponding long long versions) and other rounding functions. ARG
8005 is the argument to the call. Return NULL_TREE if no simplification
8006 can be made. */
34f17811 8007
8008static tree
c2f47e15 8009fold_builtin_int_roundingfn (tree fndecl, tree arg)
34f17811 8010{
c2f47e15 8011 if (!validate_arg (arg, REAL_TYPE))
8012 return NULL_TREE;
34f17811 8013
8014 /* Optimize lround of constant value. */
f96bd2bf 8015 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
34f17811 8016 {
8017 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
8018
776a7bab 8019 if (real_isfinite (&x))
34f17811 8020 {
2426241c 8021 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
ca9b061d 8022 tree ftype = TREE_TYPE (arg);
8023 unsigned HOST_WIDE_INT lo2;
34f17811 8024 HOST_WIDE_INT hi, lo;
8025 REAL_VALUE_TYPE r;
8026
ad52b9b7 8027 switch (DECL_FUNCTION_CODE (fndecl))
8028 {
4f35b1fc 8029 CASE_FLT_FN (BUILT_IN_LFLOOR):
8030 CASE_FLT_FN (BUILT_IN_LLFLOOR):
ad52b9b7 8031 real_floor (&r, TYPE_MODE (ftype), &x);
8032 break;
8033
4f35b1fc 8034 CASE_FLT_FN (BUILT_IN_LCEIL):
8035 CASE_FLT_FN (BUILT_IN_LLCEIL):
ac148751 8036 real_ceil (&r, TYPE_MODE (ftype), &x);
8037 break;
8038
4f35b1fc 8039 CASE_FLT_FN (BUILT_IN_LROUND):
8040 CASE_FLT_FN (BUILT_IN_LLROUND):
ad52b9b7 8041 real_round (&r, TYPE_MODE (ftype), &x);
8042 break;
8043
8044 default:
8045 gcc_unreachable ();
8046 }
8047
34f17811 8048 REAL_VALUE_TO_INT (&lo, &hi, r);
ca9b061d 8049 if (!fit_double_type (lo, hi, &lo2, &hi, itype))
8050 return build_int_cst_wide (itype, lo2, hi);
34f17811 8051 }
8052 }
8053
acc2b92e 8054 switch (DECL_FUNCTION_CODE (fndecl))
8055 {
8056 CASE_FLT_FN (BUILT_IN_LFLOOR):
8057 CASE_FLT_FN (BUILT_IN_LLFLOOR):
8058 /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x). */
8059 if (tree_expr_nonnegative_p (arg))
8060 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)),
8061 arg);
8062 break;
8063 default:;
8064 }
8065
c2f47e15 8066 return fold_fixed_mathfn (fndecl, arg);
34f17811 8067}
8068
70fb4c07 8069/* Fold function call to builtin ffs, clz, ctz, popcount and parity
c2f47e15 8070 and their long and long long variants (i.e. ffsl and ffsll). ARG is
8071 the argument to the call. Return NULL_TREE if no simplification can
8072 be made. */
70fb4c07 8073
8074static tree
c2f47e15 8075fold_builtin_bitop (tree fndecl, tree arg)
70fb4c07 8076{
c2f47e15 8077 if (!validate_arg (arg, INTEGER_TYPE))
70fb4c07 8078 return NULL_TREE;
8079
8080 /* Optimize for constant argument. */
f96bd2bf 8081 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
70fb4c07 8082 {
8083 HOST_WIDE_INT hi, width, result;
8084 unsigned HOST_WIDE_INT lo;
7c446c95 8085 tree type;
70fb4c07 8086
8087 type = TREE_TYPE (arg);
8088 width = TYPE_PRECISION (type);
8089 lo = TREE_INT_CST_LOW (arg);
8090
8091 /* Clear all the bits that are beyond the type's precision. */
8092 if (width > HOST_BITS_PER_WIDE_INT)
8093 {
8094 hi = TREE_INT_CST_HIGH (arg);
8095 if (width < 2 * HOST_BITS_PER_WIDE_INT)
8096 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
8097 }
8098 else
8099 {
8100 hi = 0;
8101 if (width < HOST_BITS_PER_WIDE_INT)
8102 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
8103 }
8104
8105 switch (DECL_FUNCTION_CODE (fndecl))
8106 {
4f35b1fc 8107 CASE_INT_FN (BUILT_IN_FFS):
70fb4c07 8108 if (lo != 0)
8109 result = exact_log2 (lo & -lo) + 1;
8110 else if (hi != 0)
8111 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
8112 else
8113 result = 0;
8114 break;
8115
4f35b1fc 8116 CASE_INT_FN (BUILT_IN_CLZ):
70fb4c07 8117 if (hi != 0)
8118 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
8119 else if (lo != 0)
8120 result = width - floor_log2 (lo) - 1;
8121 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8122 result = width;
8123 break;
8124
4f35b1fc 8125 CASE_INT_FN (BUILT_IN_CTZ):
70fb4c07 8126 if (lo != 0)
8127 result = exact_log2 (lo & -lo);
8128 else if (hi != 0)
8129 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
8130 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8131 result = width;
8132 break;
8133
4f35b1fc 8134 CASE_INT_FN (BUILT_IN_POPCOUNT):
70fb4c07 8135 result = 0;
8136 while (lo)
8137 result++, lo &= lo - 1;
8138 while (hi)
8139 result++, hi &= hi - 1;
8140 break;
8141
4f35b1fc 8142 CASE_INT_FN (BUILT_IN_PARITY):
70fb4c07 8143 result = 0;
8144 while (lo)
8145 result++, lo &= lo - 1;
8146 while (hi)
8147 result++, hi &= hi - 1;
8148 result &= 1;
8149 break;
8150
8151 default:
64db345d 8152 gcc_unreachable ();
70fb4c07 8153 }
8154
2426241c 8155 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
70fb4c07 8156 }
8157
8158 return NULL_TREE;
8159}
8160
42791117 8161/* Fold function call to builtin_bswap and the long and long long
8162 variants. Return NULL_TREE if no simplification can be made. */
8163static tree
c2f47e15 8164fold_builtin_bswap (tree fndecl, tree arg)
42791117 8165{
c2f47e15 8166 if (! validate_arg (arg, INTEGER_TYPE))
8167 return NULL_TREE;
42791117 8168
8169 /* Optimize constant value. */
f96bd2bf 8170 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
42791117 8171 {
8172 HOST_WIDE_INT hi, width, r_hi = 0;
8173 unsigned HOST_WIDE_INT lo, r_lo = 0;
8174 tree type;
8175
8176 type = TREE_TYPE (arg);
8177 width = TYPE_PRECISION (type);
8178 lo = TREE_INT_CST_LOW (arg);
8179 hi = TREE_INT_CST_HIGH (arg);
8180
8181 switch (DECL_FUNCTION_CODE (fndecl))
8182 {
8183 case BUILT_IN_BSWAP32:
8184 case BUILT_IN_BSWAP64:
8185 {
8186 int s;
8187
8188 for (s = 0; s < width; s += 8)
8189 {
8190 int d = width - s - 8;
8191 unsigned HOST_WIDE_INT byte;
8192
8193 if (s < HOST_BITS_PER_WIDE_INT)
8194 byte = (lo >> s) & 0xff;
8195 else
8196 byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
8197
8198 if (d < HOST_BITS_PER_WIDE_INT)
8199 r_lo |= byte << d;
8200 else
8201 r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
8202 }
8203 }
8204
8205 break;
8206
8207 default:
8208 gcc_unreachable ();
8209 }
8210
8211 if (width < HOST_BITS_PER_WIDE_INT)
8212 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo);
8213 else
8214 return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi);
8215 }
8216
8217 return NULL_TREE;
8218}
c2f47e15 8219
8918c507 8220/* Return true if EXPR is the real constant contained in VALUE. */
8221
8222static bool
8223real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
8224{
8225 STRIP_NOPS (expr);
8226
8227 return ((TREE_CODE (expr) == REAL_CST
f96bd2bf 8228 && !TREE_OVERFLOW (expr)
a0c938f0 8229 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
8230 || (TREE_CODE (expr) == COMPLEX_CST
8231 && real_dconstp (TREE_REALPART (expr), value)
8232 && real_zerop (TREE_IMAGPART (expr))));
8918c507 8233}
8234
8235/* A subroutine of fold_builtin to fold the various logarithmic
29f4cd78 8236 functions. Return NULL_TREE if no simplification can me made.
8237 FUNC is the corresponding MPFR logarithm function. */
8918c507 8238
8239static tree
c2f47e15 8240fold_builtin_logarithm (tree fndecl, tree arg,
29f4cd78 8241 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8918c507 8242{
c2f47e15 8243 if (validate_arg (arg, REAL_TYPE))
8918c507 8244 {
8918c507 8245 tree type = TREE_TYPE (TREE_TYPE (fndecl));
29f4cd78 8246 tree res;
8918c507 8247 const enum built_in_function fcode = builtin_mathfn_code (arg);
0862b7e9 8248
29f4cd78 8249 /* Optimize log(e) = 1.0. We're never passed an exact 'e',
8250 instead we'll look for 'e' truncated to MODE. So only do
8251 this if flag_unsafe_math_optimizations is set. */
8252 if (flag_unsafe_math_optimizations && func == mpfr_log)
8253 {
8254 const REAL_VALUE_TYPE e_truncated =
3fa759a9 8255 real_value_truncate (TYPE_MODE (type), *get_real_const (rv_e));
29f4cd78 8256 if (real_dconstp (arg, &e_truncated))
1f5cb383 8257 return build_real (type, dconst1);
8258 }
0862b7e9 8259
29f4cd78 8260 /* Calculate the result when the argument is a constant. */
8261 if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
8262 return res;
8263
8918c507 8264 /* Special case, optimize logN(expN(x)) = x. */
8265 if (flag_unsafe_math_optimizations
29f4cd78 8266 && ((func == mpfr_log
8918c507 8267 && (fcode == BUILT_IN_EXP
8268 || fcode == BUILT_IN_EXPF
8269 || fcode == BUILT_IN_EXPL))
29f4cd78 8270 || (func == mpfr_log2
8918c507 8271 && (fcode == BUILT_IN_EXP2
8272 || fcode == BUILT_IN_EXP2F
8273 || fcode == BUILT_IN_EXP2L))
29f4cd78 8274 || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
c2f47e15 8275 return fold_convert (type, CALL_EXPR_ARG (arg, 0));
8918c507 8276
ca273d4a 8277 /* Optimize logN(func()) for various exponential functions. We
a0c938f0 8278 want to determine the value "x" and the power "exponent" in
8279 order to transform logN(x**exponent) into exponent*logN(x). */
8918c507 8280 if (flag_unsafe_math_optimizations)
a0c938f0 8281 {
8918c507 8282 tree exponent = 0, x = 0;
0862b7e9 8283
8918c507 8284 switch (fcode)
8285 {
4f35b1fc 8286 CASE_FLT_FN (BUILT_IN_EXP):
8918c507 8287 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
8918c507 8288 x = build_real (type,
3fa759a9 8289 real_value_truncate (TYPE_MODE (type),
8290 *get_real_const (rv_e)));
c2f47e15 8291 exponent = CALL_EXPR_ARG (arg, 0);
8918c507 8292 break;
4f35b1fc 8293 CASE_FLT_FN (BUILT_IN_EXP2):
8918c507 8294 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
8295 x = build_real (type, dconst2);
c2f47e15 8296 exponent = CALL_EXPR_ARG (arg, 0);
8918c507 8297 break;
4f35b1fc 8298 CASE_FLT_FN (BUILT_IN_EXP10):
8299 CASE_FLT_FN (BUILT_IN_POW10):
8918c507 8300 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
3fa759a9 8301 {
8302 REAL_VALUE_TYPE dconst10;
8303 real_from_integer (&dconst10, VOIDmode, 10, 0, 0);
8304 x = build_real (type, dconst10);
8305 }
c2f47e15 8306 exponent = CALL_EXPR_ARG (arg, 0);
8918c507 8307 break;
4f35b1fc 8308 CASE_FLT_FN (BUILT_IN_SQRT):
8918c507 8309 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
c2f47e15 8310 x = CALL_EXPR_ARG (arg, 0);
8918c507 8311 exponent = build_real (type, dconsthalf);
8312 break;
4f35b1fc 8313 CASE_FLT_FN (BUILT_IN_CBRT):
8918c507 8314 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
c2f47e15 8315 x = CALL_EXPR_ARG (arg, 0);
8918c507 8316 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
3fa759a9 8317 *get_real_const (rv_third)));
8918c507 8318 break;
4f35b1fc 8319 CASE_FLT_FN (BUILT_IN_POW):
8918c507 8320 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
c2f47e15 8321 x = CALL_EXPR_ARG (arg, 0);
8322 exponent = CALL_EXPR_ARG (arg, 1);
8918c507 8323 break;
8324 default:
8325 break;
8326 }
8327
8328 /* Now perform the optimization. */
8329 if (x && exponent)
8330 {
c2f47e15 8331 tree logfn = build_call_expr (fndecl, 1, x);
49d00087 8332 return fold_build2 (MULT_EXPR, type, exponent, logfn);
8918c507 8333 }
8334 }
8335 }
8336
c2f47e15 8337 return NULL_TREE;
8918c507 8338}
0862b7e9 8339
f0c477f2 8340/* Fold a builtin function call to hypot, hypotf, or hypotl. Return
8341 NULL_TREE if no simplification can be made. */
8342
8343static tree
c2f47e15 8344fold_builtin_hypot (tree fndecl, tree arg0, tree arg1, tree type)
f0c477f2 8345{
e6ab33d8 8346 tree res, narg0, narg1;
f0c477f2 8347
c2f47e15 8348 if (!validate_arg (arg0, REAL_TYPE)
8349 || !validate_arg (arg1, REAL_TYPE))
f0c477f2 8350 return NULL_TREE;
8351
8352 /* Calculate the result when the argument is a constant. */
8353 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
8354 return res;
8355
6c95f21c 8356 /* If either argument to hypot has a negate or abs, strip that off.
8357 E.g. hypot(-x,fabs(y)) -> hypot(x,y). */
e6ab33d8 8358 narg0 = fold_strip_sign_ops (arg0);
8359 narg1 = fold_strip_sign_ops (arg1);
8360 if (narg0 || narg1)
8361 {
c2f47e15 8362 return build_call_expr (fndecl, 2, narg0 ? narg0 : arg0,
8363 narg1 ? narg1 : arg1);
6c95f21c 8364 }
8365
f0c477f2 8366 /* If either argument is zero, hypot is fabs of the other. */
8367 if (real_zerop (arg0))
8368 return fold_build1 (ABS_EXPR, type, arg1);
8369 else if (real_zerop (arg1))
8370 return fold_build1 (ABS_EXPR, type, arg0);
8371
6c95f21c 8372 /* hypot(x,x) -> fabs(x)*sqrt(2). */
8373 if (flag_unsafe_math_optimizations
8374 && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
f0c477f2 8375 {
2e7ca27b 8376 const REAL_VALUE_TYPE sqrt2_trunc
3fa759a9 8377 = real_value_truncate (TYPE_MODE (type), *get_real_const (rv_sqrt2));
6c95f21c 8378 return fold_build2 (MULT_EXPR, type,
8379 fold_build1 (ABS_EXPR, type, arg0),
2e7ca27b 8380 build_real (type, sqrt2_trunc));
f0c477f2 8381 }
8382
f0c477f2 8383 return NULL_TREE;
8384}
8385
8386
e6e27594 8387/* Fold a builtin function call to pow, powf, or powl. Return
8388 NULL_TREE if no simplification can be made. */
8389static tree
c2f47e15 8390fold_builtin_pow (tree fndecl, tree arg0, tree arg1, tree type)
e6e27594 8391{
f0c477f2 8392 tree res;
e6e27594 8393
c2f47e15 8394 if (!validate_arg (arg0, REAL_TYPE)
8395 || !validate_arg (arg1, REAL_TYPE))
e6e27594 8396 return NULL_TREE;
8397
f0c477f2 8398 /* Calculate the result when the argument is a constant. */
8399 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
8400 return res;
8401
e6e27594 8402 /* Optimize pow(1.0,y) = 1.0. */
8403 if (real_onep (arg0))
8404 return omit_one_operand (type, build_real (type, dconst1), arg1);
8405
8406 if (TREE_CODE (arg1) == REAL_CST
f96bd2bf 8407 && !TREE_OVERFLOW (arg1))
e6e27594 8408 {
198d9bbe 8409 REAL_VALUE_TYPE cint;
e6e27594 8410 REAL_VALUE_TYPE c;
198d9bbe 8411 HOST_WIDE_INT n;
8412
e6e27594 8413 c = TREE_REAL_CST (arg1);
8414
8415 /* Optimize pow(x,0.0) = 1.0. */
8416 if (REAL_VALUES_EQUAL (c, dconst0))
8417 return omit_one_operand (type, build_real (type, dconst1),
8418 arg0);
8419
8420 /* Optimize pow(x,1.0) = x. */
8421 if (REAL_VALUES_EQUAL (c, dconst1))
8422 return arg0;
8423
8424 /* Optimize pow(x,-1.0) = 1.0/x. */
8425 if (REAL_VALUES_EQUAL (c, dconstm1))
49d00087 8426 return fold_build2 (RDIV_EXPR, type,
8427 build_real (type, dconst1), arg0);
e6e27594 8428
8429 /* Optimize pow(x,0.5) = sqrt(x). */
8430 if (flag_unsafe_math_optimizations
8431 && REAL_VALUES_EQUAL (c, dconsthalf))
8432 {
8433 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8434
8435 if (sqrtfn != NULL_TREE)
c2f47e15 8436 return build_call_expr (sqrtfn, 1, arg0);
e6e27594 8437 }
8438
feb5b3eb 8439 /* Optimize pow(x,1.0/3.0) = cbrt(x). */
8440 if (flag_unsafe_math_optimizations)
8441 {
8442 const REAL_VALUE_TYPE dconstroot
3fa759a9 8443 = real_value_truncate (TYPE_MODE (type),
8444 *get_real_const (rv_third));
feb5b3eb 8445
8446 if (REAL_VALUES_EQUAL (c, dconstroot))
8447 {
8448 tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
8449 if (cbrtfn != NULL_TREE)
c2f47e15 8450 return build_call_expr (cbrtfn, 1, arg0);
feb5b3eb 8451 }
8452 }
8453
198d9bbe 8454 /* Check for an integer exponent. */
8455 n = real_to_integer (&c);
8456 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
8457 if (real_identical (&c, &cint))
e6e27594 8458 {
198d9bbe 8459 /* Attempt to evaluate pow at compile-time. */
8460 if (TREE_CODE (arg0) == REAL_CST
f96bd2bf 8461 && !TREE_OVERFLOW (arg0))
e6e27594 8462 {
8463 REAL_VALUE_TYPE x;
8464 bool inexact;
8465
8466 x = TREE_REAL_CST (arg0);
8467 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8468 if (flag_unsafe_math_optimizations || !inexact)
8469 return build_real (type, x);
8470 }
198d9bbe 8471
8472 /* Strip sign ops from even integer powers. */
8473 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
8474 {
8475 tree narg0 = fold_strip_sign_ops (arg0);
8476 if (narg0)
c2f47e15 8477 return build_call_expr (fndecl, 2, narg0, arg1);
198d9bbe 8478 }
e6e27594 8479 }
8480 }
8481
cdfeb715 8482 if (flag_unsafe_math_optimizations)
e6e27594 8483 {
cdfeb715 8484 const enum built_in_function fcode = builtin_mathfn_code (arg0);
e6e27594 8485
cdfeb715 8486 /* Optimize pow(expN(x),y) = expN(x*y). */
8487 if (BUILTIN_EXPONENT_P (fcode))
a0c938f0 8488 {
c2f47e15 8489 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0);
8490 tree arg = CALL_EXPR_ARG (arg0, 0);
49d00087 8491 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
c2f47e15 8492 return build_call_expr (expfn, 1, arg);
cdfeb715 8493 }
e6e27594 8494
cdfeb715 8495 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
8496 if (BUILTIN_SQRT_P (fcode))
a0c938f0 8497 {
c2f47e15 8498 tree narg0 = CALL_EXPR_ARG (arg0, 0);
49d00087 8499 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
8500 build_real (type, dconsthalf));
c2f47e15 8501 return build_call_expr (fndecl, 2, narg0, narg1);
cdfeb715 8502 }
8503
8504 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
8505 if (BUILTIN_CBRT_P (fcode))
a0c938f0 8506 {
c2f47e15 8507 tree arg = CALL_EXPR_ARG (arg0, 0);
cdfeb715 8508 if (tree_expr_nonnegative_p (arg))
8509 {
8510 const REAL_VALUE_TYPE dconstroot
3fa759a9 8511 = real_value_truncate (TYPE_MODE (type),
8512 *get_real_const (rv_third));
49d00087 8513 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
8514 build_real (type, dconstroot));
c2f47e15 8515 return build_call_expr (fndecl, 2, arg, narg1);
cdfeb715 8516 }
8517 }
a0c938f0 8518
cdfeb715 8519 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
c2f47e15 8520 if (fcode == BUILT_IN_POW
8521 || fcode == BUILT_IN_POWF
8522 || fcode == BUILT_IN_POWL)
a0c938f0 8523 {
c2f47e15 8524 tree arg00 = CALL_EXPR_ARG (arg0, 0);
8525 tree arg01 = CALL_EXPR_ARG (arg0, 1);
49d00087 8526 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
c2f47e15 8527 return build_call_expr (fndecl, 2, arg00, narg1);
cdfeb715 8528 }
e6e27594 8529 }
cdfeb715 8530
e6e27594 8531 return NULL_TREE;
8532}
8533
c2f47e15 8534/* Fold a builtin function call to powi, powif, or powil with argument ARG.
8535 Return NULL_TREE if no simplification can be made. */
b4d0c20c 8536static tree
c2f47e15 8537fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED,
8538 tree arg0, tree arg1, tree type)
b4d0c20c 8539{
c2f47e15 8540 if (!validate_arg (arg0, REAL_TYPE)
8541 || !validate_arg (arg1, INTEGER_TYPE))
b4d0c20c 8542 return NULL_TREE;
8543
8544 /* Optimize pow(1.0,y) = 1.0. */
8545 if (real_onep (arg0))
8546 return omit_one_operand (type, build_real (type, dconst1), arg1);
8547
8548 if (host_integerp (arg1, 0))
8549 {
8550 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
8551
8552 /* Evaluate powi at compile-time. */
8553 if (TREE_CODE (arg0) == REAL_CST
f96bd2bf 8554 && !TREE_OVERFLOW (arg0))
b4d0c20c 8555 {
8556 REAL_VALUE_TYPE x;
8557 x = TREE_REAL_CST (arg0);
8558 real_powi (&x, TYPE_MODE (type), &x, c);
8559 return build_real (type, x);
8560 }
8561
8562 /* Optimize pow(x,0) = 1.0. */
8563 if (c == 0)
8564 return omit_one_operand (type, build_real (type, dconst1),
8565 arg0);
8566
8567 /* Optimize pow(x,1) = x. */
8568 if (c == 1)
8569 return arg0;
8570
8571 /* Optimize pow(x,-1) = 1.0/x. */
8572 if (c == -1)
49d00087 8573 return fold_build2 (RDIV_EXPR, type,
8574 build_real (type, dconst1), arg0);
b4d0c20c 8575 }
8576
8577 return NULL_TREE;
8578}
8579
8918c507 8580/* A subroutine of fold_builtin to fold the various exponent
c2f47e15 8581 functions. Return NULL_TREE if no simplification can be made.
debf9994 8582 FUNC is the corresponding MPFR exponent function. */
8918c507 8583
8584static tree
c2f47e15 8585fold_builtin_exponent (tree fndecl, tree arg,
debf9994 8586 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8918c507 8587{
c2f47e15 8588 if (validate_arg (arg, REAL_TYPE))
8918c507 8589 {
8918c507 8590 tree type = TREE_TYPE (TREE_TYPE (fndecl));
29f4cd78 8591 tree res;
debf9994 8592
8593 /* Calculate the result when the argument is a constant. */
728bac60 8594 if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
debf9994 8595 return res;
8918c507 8596
8597 /* Optimize expN(logN(x)) = x. */
8598 if (flag_unsafe_math_optimizations)
a0c938f0 8599 {
8918c507 8600 const enum built_in_function fcode = builtin_mathfn_code (arg);
8601
debf9994 8602 if ((func == mpfr_exp
8918c507 8603 && (fcode == BUILT_IN_LOG
8604 || fcode == BUILT_IN_LOGF
8605 || fcode == BUILT_IN_LOGL))
debf9994 8606 || (func == mpfr_exp2
8918c507 8607 && (fcode == BUILT_IN_LOG2
8608 || fcode == BUILT_IN_LOG2F
8609 || fcode == BUILT_IN_LOG2L))
debf9994 8610 || (func == mpfr_exp10
8918c507 8611 && (fcode == BUILT_IN_LOG10
8612 || fcode == BUILT_IN_LOG10F
8613 || fcode == BUILT_IN_LOG10L)))
c2f47e15 8614 return fold_convert (type, CALL_EXPR_ARG (arg, 0));
8918c507 8615 }
8616 }
8617
c2f47e15 8618 return NULL_TREE;
8918c507 8619}
8620
e973ffcc 8621/* Return true if VAR is a VAR_DECL or a component thereof. */
8622
8623static bool
8624var_decl_component_p (tree var)
8625{
8626 tree inner = var;
8627 while (handled_component_p (inner))
8628 inner = TREE_OPERAND (inner, 0);
8629 return SSA_VAR_P (inner);
8630}
8631
4f46f2b9 8632/* Fold function call to builtin memset. Return
9c8a1629 8633 NULL_TREE if no simplification can be made. */
8634
8635static tree
c2f47e15 8636fold_builtin_memset (tree dest, tree c, tree len, tree type, bool ignore)
9c8a1629 8637{
c2f47e15 8638 tree var, ret;
4f46f2b9 8639 unsigned HOST_WIDE_INT length, cval;
9c8a1629 8640
c2f47e15 8641 if (! validate_arg (dest, POINTER_TYPE)
8642 || ! validate_arg (c, INTEGER_TYPE)
8643 || ! validate_arg (len, INTEGER_TYPE))
8644 return NULL_TREE;
9c8a1629 8645
4f46f2b9 8646 if (! host_integerp (len, 1))
c2f47e15 8647 return NULL_TREE;
4f46f2b9 8648
9c8a1629 8649 /* If the LEN parameter is zero, return DEST. */
8650 if (integer_zerop (len))
4f46f2b9 8651 return omit_one_operand (type, dest, c);
9c8a1629 8652
4f46f2b9 8653 if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
c2f47e15 8654 return NULL_TREE;
9c8a1629 8655
4f46f2b9 8656 var = dest;
8657 STRIP_NOPS (var);
8658 if (TREE_CODE (var) != ADDR_EXPR)
c2f47e15 8659 return NULL_TREE;
4f46f2b9 8660
8661 var = TREE_OPERAND (var, 0);
8662 if (TREE_THIS_VOLATILE (var))
c2f47e15 8663 return NULL_TREE;
4f46f2b9 8664
8665 if (!INTEGRAL_TYPE_P (TREE_TYPE (var))
8666 && !POINTER_TYPE_P (TREE_TYPE (var)))
c2f47e15 8667 return NULL_TREE;
4f46f2b9 8668
e973ffcc 8669 if (! var_decl_component_p (var))
c2f47e15 8670 return NULL_TREE;
e973ffcc 8671
4f46f2b9 8672 length = tree_low_cst (len, 1);
8673 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length
8674 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8675 < (int) length)
c2f47e15 8676 return NULL_TREE;
4f46f2b9 8677
8678 if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
c2f47e15 8679 return NULL_TREE;
4f46f2b9 8680
8681 if (integer_zerop (c))
8682 cval = 0;
8683 else
8684 {
8685 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
c2f47e15 8686 return NULL_TREE;
4f46f2b9 8687
8688 cval = tree_low_cst (c, 1);
8689 cval &= 0xff;
8690 cval |= cval << 8;
8691 cval |= cval << 16;
8692 cval |= (cval << 31) << 1;
8693 }
8694
8695 ret = build_int_cst_type (TREE_TYPE (var), cval);
41076ef6 8696 ret = build2 (MODIFY_EXPR, TREE_TYPE (var), var, ret);
4f46f2b9 8697 if (ignore)
8698 return ret;
8699
8700 return omit_one_operand (type, dest, ret);
9c8a1629 8701}
8702
4f46f2b9 8703/* Fold function call to builtin memset. Return
9c8a1629 8704 NULL_TREE if no simplification can be made. */
8705
8706static tree
c2f47e15 8707fold_builtin_bzero (tree dest, tree size, bool ignore)
9c8a1629 8708{
c2f47e15 8709 if (! validate_arg (dest, POINTER_TYPE)
8710 || ! validate_arg (size, INTEGER_TYPE))
8711 return NULL_TREE;
9c8a1629 8712
4f46f2b9 8713 if (!ignore)
c2f47e15 8714 return NULL_TREE;
a0c938f0 8715
4f46f2b9 8716 /* New argument list transforming bzero(ptr x, int y) to
8717 memset(ptr x, int 0, size_t y). This is done this way
8718 so that if it isn't expanded inline, we fallback to
8719 calling bzero instead of memset. */
8720
c2f47e15 8721 return fold_builtin_memset (dest, integer_zero_node,
8722 fold_convert (sizetype, size),
8723 void_type_node, ignore);
9c8a1629 8724}
8725
4f46f2b9 8726/* Fold function call to builtin mem{{,p}cpy,move}. Return
8727 NULL_TREE if no simplification can be made.
8728 If ENDP is 0, return DEST (like memcpy).
8729 If ENDP is 1, return DEST+LEN (like mempcpy).
8730 If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8731 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8732 (memmove). */
9c8a1629 8733
8734static tree
c2f47e15 8735fold_builtin_memory_op (tree dest, tree src, tree len, tree type, bool ignore, int endp)
9c8a1629 8736{
c2f47e15 8737 tree destvar, srcvar, expr;
9c8a1629 8738
c2f47e15 8739 if (! validate_arg (dest, POINTER_TYPE)
8740 || ! validate_arg (src, POINTER_TYPE)
8741 || ! validate_arg (len, INTEGER_TYPE))
8742 return NULL_TREE;
9c8a1629 8743
8744 /* If the LEN parameter is zero, return DEST. */
8745 if (integer_zerop (len))
7e72af53 8746 return omit_one_operand (type, dest, src);
9c8a1629 8747
4f46f2b9 8748 /* If SRC and DEST are the same (and not volatile), return
8749 DEST{,+LEN,+LEN-1}. */
9c8a1629 8750 if (operand_equal_p (src, dest, 0))
4f46f2b9 8751 expr = len;
8752 else
8753 {
5a84fdd6 8754 tree srctype, desttype;
3b1757a2 8755 if (endp == 3)
8756 {
5a84fdd6 8757 int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
8758 int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
8759
3b1757a2 8760 /* Both DEST and SRC must be pointer types.
8761 ??? This is what old code did. Is the testing for pointer types
8762 really mandatory?
8763
8764 If either SRC is readonly or length is 1, we can use memcpy. */
8765 if (dest_align && src_align
8766 && (readonly_data_expr (src)
5a84fdd6 8767 || (host_integerp (len, 1)
b4fc673b 8768 && (MIN (src_align, dest_align) / BITS_PER_UNIT >=
5a84fdd6 8769 tree_low_cst (len, 1)))))
3b1757a2 8770 {
8771 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8772 if (!fn)
c2f47e15 8773 return NULL_TREE;
8774 return build_call_expr (fn, 3, dest, src, len);
3b1757a2 8775 }
c2f47e15 8776 return NULL_TREE;
3b1757a2 8777 }
4f46f2b9 8778
5a84fdd6 8779 if (!host_integerp (len, 0))
c2f47e15 8780 return NULL_TREE;
5a84fdd6 8781 /* FIXME:
8782 This logic lose for arguments like (type *)malloc (sizeof (type)),
8783 since we strip the casts of up to VOID return value from malloc.
8784 Perhaps we ought to inherit type from non-VOID argument here? */
8785 STRIP_NOPS (src);
8786 STRIP_NOPS (dest);
8787 srctype = TREE_TYPE (TREE_TYPE (src));
8788 desttype = TREE_TYPE (TREE_TYPE (dest));
8789 if (!srctype || !desttype
8790 || !TYPE_SIZE_UNIT (srctype)
8791 || !TYPE_SIZE_UNIT (desttype)
8792 || TREE_CODE (TYPE_SIZE_UNIT (srctype)) != INTEGER_CST
8793 || TREE_CODE (TYPE_SIZE_UNIT (desttype)) != INTEGER_CST
92552a26 8794 || !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)
8795 || !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
c2f47e15 8796 return NULL_TREE;
4f46f2b9 8797
5a84fdd6 8798 if (get_pointer_alignment (dest, BIGGEST_ALIGNMENT)
8799 < (int) TYPE_ALIGN (desttype)
8800 || (get_pointer_alignment (src, BIGGEST_ALIGNMENT)
8801 < (int) TYPE_ALIGN (srctype)))
c2f47e15 8802 return NULL_TREE;
e973ffcc 8803
5a84fdd6 8804 if (!ignore)
8805 dest = builtin_save_expr (dest);
4f46f2b9 8806
5a84fdd6 8807 srcvar = build_fold_indirect_ref (src);
4f46f2b9 8808 if (TREE_THIS_VOLATILE (srcvar))
c2f47e15 8809 return NULL_TREE;
92552a26 8810 if (!tree_int_cst_equal (lang_hooks.expr_size (srcvar), len))
c2f47e15 8811 return NULL_TREE;
5a84fdd6 8812 /* With memcpy, it is possible to bypass aliasing rules, so without
f0b5f617 8813 this check i.e. execute/20060930-2.c would be misoptimized, because
5a84fdd6 8814 it use conflicting alias set to hold argument for the memcpy call.
f0b5f617 8815 This check is probably unnecessary with -fno-strict-aliasing.
5a84fdd6 8816 Similarly for destvar. See also PR29286. */
8817 if (!var_decl_component_p (srcvar)
8818 /* Accept: memcpy (*char_var, "test", 1); that simplify
8819 to char_var='t'; */
8820 || is_gimple_min_invariant (srcvar)
8821 || readonly_data_expr (src))
c2f47e15 8822 return NULL_TREE;
4f46f2b9 8823
5a84fdd6 8824 destvar = build_fold_indirect_ref (dest);
8825 if (TREE_THIS_VOLATILE (destvar))
c2f47e15 8826 return NULL_TREE;
92552a26 8827 if (!tree_int_cst_equal (lang_hooks.expr_size (destvar), len))
c2f47e15 8828 return NULL_TREE;
5a84fdd6 8829 if (!var_decl_component_p (destvar))
c2f47e15 8830 return NULL_TREE;
4f46f2b9 8831
5a84fdd6 8832 if (srctype == desttype
2d04fd8d 8833 || (gimple_in_ssa_p (cfun)
548044d8 8834 && useless_type_conversion_p (desttype, srctype)))
5a84fdd6 8835 expr = srcvar;
8836 else if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
4f46f2b9 8837 || POINTER_TYPE_P (TREE_TYPE (srcvar)))
8838 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8839 || POINTER_TYPE_P (TREE_TYPE (destvar))))
8840 expr = fold_convert (TREE_TYPE (destvar), srcvar);
8841 else
8842 expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar);
41076ef6 8843 expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, expr);
4f46f2b9 8844 }
8845
8846 if (ignore)
8847 return expr;
8848
8849 if (endp == 0 || endp == 3)
8850 return omit_one_operand (type, dest, expr);
8851
8852 if (expr == len)
c2f47e15 8853 expr = NULL_TREE;
4f46f2b9 8854
8855 if (endp == 2)
8856 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
8857 ssize_int (1));
8858
0de36bdb 8859 dest = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
4f46f2b9 8860 dest = fold_convert (type, dest);
8861 if (expr)
8862 dest = omit_one_operand (type, dest, expr);
8863 return dest;
8864}
8865
c2f47e15 8866/* Fold function call to builtin strcpy with arguments DEST and SRC.
8867 If LEN is not NULL, it represents the length of the string to be
8868 copied. Return NULL_TREE if no simplification can be made. */
9c8a1629 8869
f0613857 8870tree
c2f47e15 8871fold_builtin_strcpy (tree fndecl, tree dest, tree src, tree len)
9c8a1629 8872{
c2f47e15 8873 tree fn;
9c8a1629 8874
c2f47e15 8875 if (!validate_arg (dest, POINTER_TYPE)
8876 || !validate_arg (src, POINTER_TYPE))
8877 return NULL_TREE;
9c8a1629 8878
8879 /* If SRC and DEST are the same (and not volatile), return DEST. */
8880 if (operand_equal_p (src, dest, 0))
2426241c 8881 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
9c8a1629 8882
f0613857 8883 if (optimize_size)
c2f47e15 8884 return NULL_TREE;
f0613857 8885
8886 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8887 if (!fn)
c2f47e15 8888 return NULL_TREE;
f0613857 8889
8890 if (!len)
8891 {
8892 len = c_strlen (src, 1);
8893 if (! len || TREE_SIDE_EFFECTS (len))
c2f47e15 8894 return NULL_TREE;
f0613857 8895 }
8896
8897 len = size_binop (PLUS_EXPR, len, ssize_int (1));
2426241c 8898 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
c2f47e15 8899 build_call_expr (fn, 3, dest, src, len));
9c8a1629 8900}
8901
c2f47e15 8902/* Fold function call to builtin strncpy with arguments DEST, SRC, and LEN.
8903 If SLEN is not NULL, it represents the length of the source string.
8904 Return NULL_TREE if no simplification can be made. */
9c8a1629 8905
f0613857 8906tree
c2f47e15 8907fold_builtin_strncpy (tree fndecl, tree dest, tree src, tree len, tree slen)
9c8a1629 8908{
c2f47e15 8909 tree fn;
9c8a1629 8910
c2f47e15 8911 if (!validate_arg (dest, POINTER_TYPE)
8912 || !validate_arg (src, POINTER_TYPE)
8913 || !validate_arg (len, INTEGER_TYPE))
8914 return NULL_TREE;
9c8a1629 8915
8916 /* If the LEN parameter is zero, return DEST. */
8917 if (integer_zerop (len))
2426241c 8918 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
9c8a1629 8919
19226313 8920 /* We can't compare slen with len as constants below if len is not a
8921 constant. */
8922 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
c2f47e15 8923 return NULL_TREE;
19226313 8924
f0613857 8925 if (!slen)
8926 slen = c_strlen (src, 1);
8927
8928 /* Now, we must be passed a constant src ptr parameter. */
8929 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
c2f47e15 8930 return NULL_TREE;
f0613857 8931
8932 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8933
8934 /* We do not support simplification of this case, though we do
8935 support it when expanding trees into RTL. */
8936 /* FIXME: generate a call to __builtin_memset. */
8937 if (tree_int_cst_lt (slen, len))
c2f47e15 8938 return NULL_TREE;
f0613857 8939
8940 /* OK transform into builtin memcpy. */
8941 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8942 if (!fn)
c2f47e15 8943 return NULL_TREE;
2426241c 8944 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
c2f47e15 8945 build_call_expr (fn, 3, dest, src, len));
9c8a1629 8946}
8947
7959b13b 8948/* Fold function call to builtin memchr. ARG1, ARG2 and LEN are the
8949 arguments to the call, and TYPE is its return type.
8950 Return NULL_TREE if no simplification can be made. */
8951
8952static tree
8953fold_builtin_memchr (tree arg1, tree arg2, tree len, tree type)
8954{
8955 if (!validate_arg (arg1, POINTER_TYPE)
8956 || !validate_arg (arg2, INTEGER_TYPE)
8957 || !validate_arg (len, INTEGER_TYPE))
8958 return NULL_TREE;
8959 else
8960 {
8961 const char *p1;
8962
8963 if (TREE_CODE (arg2) != INTEGER_CST
8964 || !host_integerp (len, 1))
8965 return NULL_TREE;
8966
8967 p1 = c_getstr (arg1);
8968 if (p1 && compare_tree_int (len, strlen (p1) + 1) <= 0)
8969 {
8970 char c;
8971 const char *r;
8972 tree tem;
8973
8974 if (target_char_cast (arg2, &c))
8975 return NULL_TREE;
8976
364c0c59 8977 r = (char *) memchr (p1, c, tree_low_cst (len, 1));
7959b13b 8978
8979 if (r == NULL)
8980 return build_int_cst (TREE_TYPE (arg1), 0);
8981
0de36bdb 8982 tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (arg1), arg1,
8983 size_int (r - p1));
7959b13b 8984 return fold_convert (type, tem);
8985 }
8986 return NULL_TREE;
8987 }
8988}
8989
c2f47e15 8990/* Fold function call to builtin memcmp with arguments ARG1 and ARG2.
8991 Return NULL_TREE if no simplification can be made. */
9c8a1629 8992
8993static tree
c2f47e15 8994fold_builtin_memcmp (tree arg1, tree arg2, tree len)
9c8a1629 8995{
c4fef134 8996 const char *p1, *p2;
9c8a1629 8997
c2f47e15 8998 if (!validate_arg (arg1, POINTER_TYPE)
8999 || !validate_arg (arg2, POINTER_TYPE)
9000 || !validate_arg (len, INTEGER_TYPE))
9001 return NULL_TREE;
9c8a1629 9002
9003 /* If the LEN parameter is zero, return zero. */
9004 if (integer_zerop (len))
c4fef134 9005 return omit_two_operands (integer_type_node, integer_zero_node,
9006 arg1, arg2);
9c8a1629 9007
9008 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
9009 if (operand_equal_p (arg1, arg2, 0))
c4fef134 9010 return omit_one_operand (integer_type_node, integer_zero_node, len);
9011
9012 p1 = c_getstr (arg1);
9013 p2 = c_getstr (arg2);
9014
9015 /* If all arguments are constant, and the value of len is not greater
9016 than the lengths of arg1 and arg2, evaluate at compile-time. */
9017 if (host_integerp (len, 1) && p1 && p2
9018 && compare_tree_int (len, strlen (p1) + 1) <= 0
9019 && compare_tree_int (len, strlen (p2) + 1) <= 0)
9020 {
9021 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
9022
9023 if (r > 0)
9024 return integer_one_node;
9025 else if (r < 0)
9026 return integer_minus_one_node;
9027 else
9028 return integer_zero_node;
9029 }
9030
9031 /* If len parameter is one, return an expression corresponding to
9032 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
9033 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9034 {
9035 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9036 tree cst_uchar_ptr_node
9037 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9038
c4fef134 9039 tree ind1 = fold_convert (integer_type_node,
9040 build1 (INDIRECT_REF, cst_uchar_node,
9041 fold_convert (cst_uchar_ptr_node,
9042 arg1)));
9043 tree ind2 = fold_convert (integer_type_node,
9044 build1 (INDIRECT_REF, cst_uchar_node,
9045 fold_convert (cst_uchar_ptr_node,
9046 arg2)));
49d00087 9047 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
c4fef134 9048 }
9c8a1629 9049
c2f47e15 9050 return NULL_TREE;
9c8a1629 9051}
9052
c2f47e15 9053/* Fold function call to builtin strcmp with arguments ARG1 and ARG2.
9054 Return NULL_TREE if no simplification can be made. */
9c8a1629 9055
9056static tree
c2f47e15 9057fold_builtin_strcmp (tree arg1, tree arg2)
9c8a1629 9058{
9c8a1629 9059 const char *p1, *p2;
9060
c2f47e15 9061 if (!validate_arg (arg1, POINTER_TYPE)
9062 || !validate_arg (arg2, POINTER_TYPE))
9063 return NULL_TREE;
9c8a1629 9064
9065 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
9066 if (operand_equal_p (arg1, arg2, 0))
c4fef134 9067 return integer_zero_node;
9c8a1629 9068
9069 p1 = c_getstr (arg1);
9070 p2 = c_getstr (arg2);
9071
9072 if (p1 && p2)
9073 {
9c8a1629 9074 const int i = strcmp (p1, p2);
9075 if (i < 0)
c4fef134 9076 return integer_minus_one_node;
9c8a1629 9077 else if (i > 0)
c4fef134 9078 return integer_one_node;
9c8a1629 9079 else
c4fef134 9080 return integer_zero_node;
9081 }
9082
9083 /* If the second arg is "", return *(const unsigned char*)arg1. */
9084 if (p2 && *p2 == '\0')
9085 {
9086 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9087 tree cst_uchar_ptr_node
9088 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9089
c4fef134 9090 return fold_convert (integer_type_node,
9091 build1 (INDIRECT_REF, cst_uchar_node,
9092 fold_convert (cst_uchar_ptr_node,
9093 arg1)));
9094 }
9095
9096 /* If the first arg is "", return -*(const unsigned char*)arg2. */
9097 if (p1 && *p1 == '\0')
9098 {
9099 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9100 tree cst_uchar_ptr_node
9101 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9102
c4fef134 9103 tree temp = fold_convert (integer_type_node,
9104 build1 (INDIRECT_REF, cst_uchar_node,
9105 fold_convert (cst_uchar_ptr_node,
9106 arg2)));
49d00087 9107 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
9c8a1629 9108 }
9109
c2f47e15 9110 return NULL_TREE;
9c8a1629 9111}
9112
c2f47e15 9113/* Fold function call to builtin strncmp with arguments ARG1, ARG2, and LEN.
9114 Return NULL_TREE if no simplification can be made. */
9c8a1629 9115
9116static tree
c2f47e15 9117fold_builtin_strncmp (tree arg1, tree arg2, tree len)
9c8a1629 9118{
9c8a1629 9119 const char *p1, *p2;
9120
c2f47e15 9121 if (!validate_arg (arg1, POINTER_TYPE)
9122 || !validate_arg (arg2, POINTER_TYPE)
9123 || !validate_arg (len, INTEGER_TYPE))
9124 return NULL_TREE;
9c8a1629 9125
9126 /* If the LEN parameter is zero, return zero. */
9127 if (integer_zerop (len))
c4fef134 9128 return omit_two_operands (integer_type_node, integer_zero_node,
9129 arg1, arg2);
9c8a1629 9130
9131 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
9132 if (operand_equal_p (arg1, arg2, 0))
c4fef134 9133 return omit_one_operand (integer_type_node, integer_zero_node, len);
9c8a1629 9134
9135 p1 = c_getstr (arg1);
9136 p2 = c_getstr (arg2);
9137
9138 if (host_integerp (len, 1) && p1 && p2)
9139 {
9c8a1629 9140 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
c4fef134 9141 if (i > 0)
9142 return integer_one_node;
9143 else if (i < 0)
9144 return integer_minus_one_node;
9c8a1629 9145 else
c4fef134 9146 return integer_zero_node;
9147 }
9148
9149 /* If the second arg is "", and the length is greater than zero,
9150 return *(const unsigned char*)arg1. */
9151 if (p2 && *p2 == '\0'
9152 && TREE_CODE (len) == INTEGER_CST
9153 && tree_int_cst_sgn (len) == 1)
9154 {
9155 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9156 tree cst_uchar_ptr_node
9157 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9158
c4fef134 9159 return fold_convert (integer_type_node,
9160 build1 (INDIRECT_REF, cst_uchar_node,
9161 fold_convert (cst_uchar_ptr_node,
9162 arg1)));
9163 }
9164
9165 /* If the first arg is "", and the length is greater than zero,
9166 return -*(const unsigned char*)arg2. */
9167 if (p1 && *p1 == '\0'
9168 && TREE_CODE (len) == INTEGER_CST
9169 && tree_int_cst_sgn (len) == 1)
9170 {
9171 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9172 tree cst_uchar_ptr_node
9173 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9174
c4fef134 9175 tree temp = fold_convert (integer_type_node,
9176 build1 (INDIRECT_REF, cst_uchar_node,
9177 fold_convert (cst_uchar_ptr_node,
9178 arg2)));
49d00087 9179 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
c4fef134 9180 }
9181
9182 /* If len parameter is one, return an expression corresponding to
9183 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
9184 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9185 {
9186 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9187 tree cst_uchar_ptr_node
9188 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9189
c4fef134 9190 tree ind1 = fold_convert (integer_type_node,
9191 build1 (INDIRECT_REF, cst_uchar_node,
9192 fold_convert (cst_uchar_ptr_node,
9193 arg1)));
9194 tree ind2 = fold_convert (integer_type_node,
9195 build1 (INDIRECT_REF, cst_uchar_node,
9196 fold_convert (cst_uchar_ptr_node,
9197 arg2)));
49d00087 9198 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
9c8a1629 9199 }
9200
c2f47e15 9201 return NULL_TREE;
9c8a1629 9202}
9203
c2f47e15 9204/* Fold function call to builtin signbit, signbitf or signbitl with argument
9205 ARG. Return NULL_TREE if no simplification can be made. */
27f261ef 9206
9207static tree
c2f47e15 9208fold_builtin_signbit (tree arg, tree type)
27f261ef 9209{
c2f47e15 9210 tree temp;
27f261ef 9211
c2f47e15 9212 if (!validate_arg (arg, REAL_TYPE))
27f261ef 9213 return NULL_TREE;
9214
27f261ef 9215 /* If ARG is a compile-time constant, determine the result. */
9216 if (TREE_CODE (arg) == REAL_CST
f96bd2bf 9217 && !TREE_OVERFLOW (arg))
27f261ef 9218 {
9219 REAL_VALUE_TYPE c;
9220
9221 c = TREE_REAL_CST (arg);
9222 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
2426241c 9223 return fold_convert (type, temp);
27f261ef 9224 }
9225
9226 /* If ARG is non-negative, the result is always zero. */
9227 if (tree_expr_nonnegative_p (arg))
2426241c 9228 return omit_one_operand (type, integer_zero_node, arg);
27f261ef 9229
9230 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
9231 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
49d00087 9232 return fold_build2 (LT_EXPR, type, arg,
9233 build_real (TREE_TYPE (arg), dconst0));
27f261ef 9234
9235 return NULL_TREE;
9236}
9237
c2f47e15 9238/* Fold function call to builtin copysign, copysignf or copysignl with
9239 arguments ARG1 and ARG2. Return NULL_TREE if no simplification can
9240 be made. */
467214fd 9241
9242static tree
c2f47e15 9243fold_builtin_copysign (tree fndecl, tree arg1, tree arg2, tree type)
467214fd 9244{
c2f47e15 9245 tree tem;
467214fd 9246
c2f47e15 9247 if (!validate_arg (arg1, REAL_TYPE)
9248 || !validate_arg (arg2, REAL_TYPE))
467214fd 9249 return NULL_TREE;
9250
467214fd 9251 /* copysign(X,X) is X. */
9252 if (operand_equal_p (arg1, arg2, 0))
9253 return fold_convert (type, arg1);
9254
9255 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
9256 if (TREE_CODE (arg1) == REAL_CST
9257 && TREE_CODE (arg2) == REAL_CST
f96bd2bf 9258 && !TREE_OVERFLOW (arg1)
9259 && !TREE_OVERFLOW (arg2))
467214fd 9260 {
9261 REAL_VALUE_TYPE c1, c2;
9262
9263 c1 = TREE_REAL_CST (arg1);
9264 c2 = TREE_REAL_CST (arg2);
749680e2 9265 /* c1.sign := c2.sign. */
467214fd 9266 real_copysign (&c1, &c2);
9267 return build_real (type, c1);
467214fd 9268 }
9269
9270 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
9271 Remember to evaluate Y for side-effects. */
9272 if (tree_expr_nonnegative_p (arg2))
9273 return omit_one_operand (type,
49d00087 9274 fold_build1 (ABS_EXPR, type, arg1),
467214fd 9275 arg2);
9276
198d9bbe 9277 /* Strip sign changing operations for the first argument. */
9278 tem = fold_strip_sign_ops (arg1);
9279 if (tem)
c2f47e15 9280 return build_call_expr (fndecl, 2, tem, arg2);
198d9bbe 9281
467214fd 9282 return NULL_TREE;
9283}
9284
c2f47e15 9285/* Fold a call to builtin isascii with argument ARG. */
d49367d4 9286
9287static tree
c2f47e15 9288fold_builtin_isascii (tree arg)
d49367d4 9289{
c2f47e15 9290 if (!validate_arg (arg, INTEGER_TYPE))
9291 return NULL_TREE;
d49367d4 9292 else
9293 {
9294 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
7c446c95 9295 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
9296 build_int_cst (NULL_TREE,
7016c612 9297 ~ (unsigned HOST_WIDE_INT) 0x7f));
f2532264 9298 return fold_build2 (EQ_EXPR, integer_type_node,
9299 arg, integer_zero_node);
d49367d4 9300 }
9301}
9302
c2f47e15 9303/* Fold a call to builtin toascii with argument ARG. */
d49367d4 9304
9305static tree
c2f47e15 9306fold_builtin_toascii (tree arg)
d49367d4 9307{
c2f47e15 9308 if (!validate_arg (arg, INTEGER_TYPE))
9309 return NULL_TREE;
9310
9311 /* Transform toascii(c) -> (c & 0x7f). */
9312 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
9313 build_int_cst (NULL_TREE, 0x7f));
d49367d4 9314}
9315
c2f47e15 9316/* Fold a call to builtin isdigit with argument ARG. */
df1cf42e 9317
9318static tree
c2f47e15 9319fold_builtin_isdigit (tree arg)
df1cf42e 9320{
c2f47e15 9321 if (!validate_arg (arg, INTEGER_TYPE))
9322 return NULL_TREE;
df1cf42e 9323 else
9324 {
9325 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
624d37a6 9326 /* According to the C standard, isdigit is unaffected by locale.
9327 However, it definitely is affected by the target character set. */
624d37a6 9328 unsigned HOST_WIDE_INT target_digit0
9329 = lang_hooks.to_target_charset ('0');
9330
9331 if (target_digit0 == 0)
9332 return NULL_TREE;
9333
c2f47e15 9334 arg = fold_convert (unsigned_type_node, arg);
05abc81b 9335 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
624d37a6 9336 build_int_cst (unsigned_type_node, target_digit0));
f2532264 9337 return fold_build2 (LE_EXPR, integer_type_node, arg,
9338 build_int_cst (unsigned_type_node, 9));
df1cf42e 9339 }
9340}
27f261ef 9341
c2f47e15 9342/* Fold a call to fabs, fabsf or fabsl with argument ARG. */
d1aade50 9343
9344static tree
c2f47e15 9345fold_builtin_fabs (tree arg, tree type)
d1aade50 9346{
c2f47e15 9347 if (!validate_arg (arg, REAL_TYPE))
9348 return NULL_TREE;
d1aade50 9349
9829e110 9350 arg = fold_convert (type, arg);
d1aade50 9351 if (TREE_CODE (arg) == REAL_CST)
9352 return fold_abs_const (arg, type);
49d00087 9353 return fold_build1 (ABS_EXPR, type, arg);
d1aade50 9354}
9355
c2f47e15 9356/* Fold a call to abs, labs, llabs or imaxabs with argument ARG. */
d1aade50 9357
9358static tree
c2f47e15 9359fold_builtin_abs (tree arg, tree type)
d1aade50 9360{
c2f47e15 9361 if (!validate_arg (arg, INTEGER_TYPE))
9362 return NULL_TREE;
d1aade50 9363
9829e110 9364 arg = fold_convert (type, arg);
d1aade50 9365 if (TREE_CODE (arg) == INTEGER_CST)
9366 return fold_abs_const (arg, type);
49d00087 9367 return fold_build1 (ABS_EXPR, type, arg);
d1aade50 9368}
9369
d4a43a03 9370/* Fold a call to builtin fmin or fmax. */
9371
9372static tree
c2f47e15 9373fold_builtin_fmin_fmax (tree arg0, tree arg1, tree type, bool max)
d4a43a03 9374{
c2f47e15 9375 if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, REAL_TYPE))
d4a43a03 9376 {
d4a43a03 9377 /* Calculate the result when the argument is a constant. */
9378 tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
9379
9380 if (res)
9381 return res;
9382
61fe3555 9383 /* If either argument is NaN, return the other one. Avoid the
9384 transformation if we get (and honor) a signalling NaN. Using
9385 omit_one_operand() ensures we create a non-lvalue. */
9386 if (TREE_CODE (arg0) == REAL_CST
9387 && real_isnan (&TREE_REAL_CST (arg0))
9388 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
9389 || ! TREE_REAL_CST (arg0).signalling))
9390 return omit_one_operand (type, arg1, arg0);
9391 if (TREE_CODE (arg1) == REAL_CST
9392 && real_isnan (&TREE_REAL_CST (arg1))
9393 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
9394 || ! TREE_REAL_CST (arg1).signalling))
9395 return omit_one_operand (type, arg0, arg1);
9396
d4a43a03 9397 /* Transform fmin/fmax(x,x) -> x. */
9398 if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
9399 return omit_one_operand (type, arg0, arg1);
9400
9401 /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR. C99 requires these
9402 functions to return the numeric arg if the other one is NaN.
9403 These tree codes don't honor that, so only transform if
9404 -ffinite-math-only is set. C99 doesn't require -0.0 to be
9405 handled, so we don't have to worry about it either. */
9406 if (flag_finite_math_only)
9407 return fold_build2 ((max ? MAX_EXPR : MIN_EXPR), type,
9408 fold_convert (type, arg0),
9409 fold_convert (type, arg1));
9410 }
9411 return NULL_TREE;
9412}
9413
abe4dcf6 9414/* Fold a call to builtin carg(a+bi) -> atan2(b,a). */
9415
9416static tree
c2f47e15 9417fold_builtin_carg (tree arg, tree type)
abe4dcf6 9418{
c2f47e15 9419 if (validate_arg (arg, COMPLEX_TYPE))
abe4dcf6 9420 {
9421 tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2);
9422
9423 if (atan2_fn)
9424 {
c2f47e15 9425 tree new_arg = builtin_save_expr (arg);
9426 tree r_arg = fold_build1 (REALPART_EXPR, type, new_arg);
9427 tree i_arg = fold_build1 (IMAGPART_EXPR, type, new_arg);
9428 return build_call_expr (atan2_fn, 2, i_arg, r_arg);
abe4dcf6 9429 }
9430 }
9431
9432 return NULL_TREE;
9433}
9434
cb2b9385 9435/* Fold a call to builtin logb/ilogb. */
9436
9437static tree
9438fold_builtin_logb (tree arg, tree rettype)
9439{
9440 if (! validate_arg (arg, REAL_TYPE))
9441 return NULL_TREE;
9442
9443 STRIP_NOPS (arg);
9444
9445 if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9446 {
9447 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9448
9449 switch (value->cl)
9450 {
9451 case rvc_nan:
9452 case rvc_inf:
9453 /* If arg is Inf or NaN and we're logb, return it. */
9454 if (TREE_CODE (rettype) == REAL_TYPE)
9455 return fold_convert (rettype, arg);
9456 /* Fall through... */
9457 case rvc_zero:
9458 /* Zero may set errno and/or raise an exception for logb, also
9459 for ilogb we don't know FP_ILOGB0. */
9460 return NULL_TREE;
9461 case rvc_normal:
9462 /* For normal numbers, proceed iff radix == 2. In GCC,
9463 normalized significands are in the range [0.5, 1.0). We
9464 want the exponent as if they were [1.0, 2.0) so get the
9465 exponent and subtract 1. */
9466 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9467 return fold_convert (rettype, build_int_cst (NULL_TREE,
9468 REAL_EXP (value)-1));
9469 break;
9470 }
9471 }
9472
9473 return NULL_TREE;
9474}
9475
9476/* Fold a call to builtin significand, if radix == 2. */
9477
9478static tree
9479fold_builtin_significand (tree arg, tree rettype)
9480{
9481 if (! validate_arg (arg, REAL_TYPE))
9482 return NULL_TREE;
9483
9484 STRIP_NOPS (arg);
9485
9486 if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9487 {
9488 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9489
9490 switch (value->cl)
9491 {
9492 case rvc_zero:
9493 case rvc_nan:
9494 case rvc_inf:
9495 /* If arg is +-0, +-Inf or +-NaN, then return it. */
9496 return fold_convert (rettype, arg);
9497 case rvc_normal:
9498 /* For normal numbers, proceed iff radix == 2. */
9499 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9500 {
9501 REAL_VALUE_TYPE result = *value;
9502 /* In GCC, normalized significands are in the range [0.5,
9503 1.0). We want them to be [1.0, 2.0) so set the
9504 exponent to 1. */
9505 SET_REAL_EXP (&result, 1);
9506 return build_real (rettype, result);
9507 }
9508 break;
9509 }
9510 }
9511
9512 return NULL_TREE;
9513}
9514
3838b9ae 9515/* Fold a call to builtin frexp, we can assume the base is 2. */
9516
9517static tree
9518fold_builtin_frexp (tree arg0, tree arg1, tree rettype)
9519{
9520 if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9521 return NULL_TREE;
9522
9523 STRIP_NOPS (arg0);
9524
9525 if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9526 return NULL_TREE;
9527
9528 arg1 = build_fold_indirect_ref (arg1);
9529
9530 /* Proceed if a valid pointer type was passed in. */
9531 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == integer_type_node)
9532 {
9533 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9534 tree frac, exp;
9535
9536 switch (value->cl)
9537 {
9538 case rvc_zero:
9539 /* For +-0, return (*exp = 0, +-0). */
9540 exp = integer_zero_node;
9541 frac = arg0;
9542 break;
9543 case rvc_nan:
9544 case rvc_inf:
9545 /* For +-NaN or +-Inf, *exp is unspecified, return arg0. */
9546 return omit_one_operand (rettype, arg0, arg1);
9547 case rvc_normal:
9548 {
9549 /* Since the frexp function always expects base 2, and in
9550 GCC normalized significands are already in the range
9551 [0.5, 1.0), we have exactly what frexp wants. */
9552 REAL_VALUE_TYPE frac_rvt = *value;
9553 SET_REAL_EXP (&frac_rvt, 0);
9554 frac = build_real (rettype, frac_rvt);
9555 exp = build_int_cst (NULL_TREE, REAL_EXP (value));
9556 }
9557 break;
9558 default:
9559 gcc_unreachable ();
9560 }
9561
9562 /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9563 arg1 = fold_build2 (MODIFY_EXPR, rettype, arg1, exp);
9564 TREE_SIDE_EFFECTS (arg1) = 1;
9565 return fold_build2 (COMPOUND_EXPR, rettype, arg1, frac);
9566 }
9567
9568 return NULL_TREE;
9569}
9570
7587301b 9571/* Fold a call to builtin ldexp or scalbn/scalbln. If LDEXP is true
9572 then we can assume the base is two. If it's false, then we have to
9573 check the mode of the TYPE parameter in certain cases. */
9574
9575static tree
9576fold_builtin_load_exponent (tree arg0, tree arg1, tree type, bool ldexp)
9577{
9578 if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, INTEGER_TYPE))
9579 {
9580 STRIP_NOPS (arg0);
9581 STRIP_NOPS (arg1);
9582
9583 /* If arg0 is 0, Inf or NaN, or if arg1 is 0, then return arg0. */
9584 if (real_zerop (arg0) || integer_zerop (arg1)
9585 || (TREE_CODE (arg0) == REAL_CST
776a7bab 9586 && !real_isfinite (&TREE_REAL_CST (arg0))))
7587301b 9587 return omit_one_operand (type, arg0, arg1);
9588
9589 /* If both arguments are constant, then try to evaluate it. */
9590 if ((ldexp || REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2)
9591 && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
9592 && host_integerp (arg1, 0))
9593 {
9594 /* Bound the maximum adjustment to twice the range of the
9595 mode's valid exponents. Use abs to ensure the range is
9596 positive as a sanity check. */
9597 const long max_exp_adj = 2 *
9598 labs (REAL_MODE_FORMAT (TYPE_MODE (type))->emax
9599 - REAL_MODE_FORMAT (TYPE_MODE (type))->emin);
9600
9601 /* Get the user-requested adjustment. */
9602 const HOST_WIDE_INT req_exp_adj = tree_low_cst (arg1, 0);
9603
9604 /* The requested adjustment must be inside this range. This
9605 is a preliminary cap to avoid things like overflow, we
9606 may still fail to compute the result for other reasons. */
9607 if (-max_exp_adj < req_exp_adj && req_exp_adj < max_exp_adj)
9608 {
9609 REAL_VALUE_TYPE initial_result;
9610
9611 real_ldexp (&initial_result, &TREE_REAL_CST (arg0), req_exp_adj);
9612
9613 /* Ensure we didn't overflow. */
9614 if (! real_isinf (&initial_result))
9615 {
9616 const REAL_VALUE_TYPE trunc_result
9617 = real_value_truncate (TYPE_MODE (type), initial_result);
9618
9619 /* Only proceed if the target mode can hold the
9620 resulting value. */
9621 if (REAL_VALUES_EQUAL (initial_result, trunc_result))
9622 return build_real (type, trunc_result);
9623 }
9624 }
9625 }
9626 }
9627
9628 return NULL_TREE;
9629}
9630
ebf8b4f5 9631/* Fold a call to builtin modf. */
9632
9633static tree
9634fold_builtin_modf (tree arg0, tree arg1, tree rettype)
9635{
9636 if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9637 return NULL_TREE;
9638
9639 STRIP_NOPS (arg0);
9640
9641 if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9642 return NULL_TREE;
9643
9644 arg1 = build_fold_indirect_ref (arg1);
9645
9646 /* Proceed if a valid pointer type was passed in. */
9647 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == TYPE_MAIN_VARIANT (rettype))
9648 {
9649 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9650 REAL_VALUE_TYPE trunc, frac;
9651
9652 switch (value->cl)
9653 {
9654 case rvc_nan:
9655 case rvc_zero:
9656 /* For +-NaN or +-0, return (*arg1 = arg0, arg0). */
9657 trunc = frac = *value;
9658 break;
9659 case rvc_inf:
9660 /* For +-Inf, return (*arg1 = arg0, +-0). */
9661 frac = dconst0;
9662 frac.sign = value->sign;
9663 trunc = *value;
9664 break;
9665 case rvc_normal:
9666 /* Return (*arg1 = trunc(arg0), arg0-trunc(arg0)). */
9667 real_trunc (&trunc, VOIDmode, value);
9668 real_arithmetic (&frac, MINUS_EXPR, value, &trunc);
9669 /* If the original number was negative and already
9670 integral, then the fractional part is -0.0. */
9671 if (value->sign && frac.cl == rvc_zero)
9672 frac.sign = value->sign;
9673 break;
9674 }
9675
9676 /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9677 arg1 = fold_build2 (MODIFY_EXPR, rettype, arg1,
9678 build_real (rettype, trunc));
9679 TREE_SIDE_EFFECTS (arg1) = 1;
9680 return fold_build2 (COMPOUND_EXPR, rettype, arg1,
9681 build_real (rettype, frac));
9682 }
9683
9684 return NULL_TREE;
9685}
9686
726069ba 9687/* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
c2f47e15 9688 ARG is the argument for the call. */
726069ba 9689
9690static tree
c2f47e15 9691fold_builtin_classify (tree fndecl, tree arg, int builtin_index)
726069ba 9692{
726069ba 9693 tree type = TREE_TYPE (TREE_TYPE (fndecl));
726069ba 9694 REAL_VALUE_TYPE r;
9695
c2f47e15 9696 if (!validate_arg (arg, REAL_TYPE))
d43cee80 9697 return NULL_TREE;
726069ba 9698
726069ba 9699 switch (builtin_index)
9700 {
9701 case BUILT_IN_ISINF:
b70bfd00 9702 if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
a0c938f0 9703 return omit_one_operand (type, integer_zero_node, arg);
726069ba 9704
9705 if (TREE_CODE (arg) == REAL_CST)
9706 {
9707 r = TREE_REAL_CST (arg);
9708 if (real_isinf (&r))
9709 return real_compare (GT_EXPR, &r, &dconst0)
9710 ? integer_one_node : integer_minus_one_node;
9711 else
9712 return integer_zero_node;
9713 }
9714
9715 return NULL_TREE;
9716
c319d56a 9717 case BUILT_IN_ISINF_SIGN:
9718 {
9719 /* isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 */
9720 /* In a boolean context, GCC will fold the inner COND_EXPR to
9721 1. So e.g. "if (isinf_sign(x))" would be folded to just
9722 "if (isinf(x) ? 1 : 0)" which becomes "if (isinf(x))". */
9723 tree signbit_fn = mathfn_built_in_1 (TREE_TYPE (arg), BUILT_IN_SIGNBIT, 0);
9724 tree isinf_fn = built_in_decls[BUILT_IN_ISINF];
9725 tree tmp = NULL_TREE;
9726
9727 arg = builtin_save_expr (arg);
9728
9729 if (signbit_fn && isinf_fn)
9730 {
9731 tree signbit_call = build_call_expr (signbit_fn, 1, arg);
9732 tree isinf_call = build_call_expr (isinf_fn, 1, arg);
9733
9734 signbit_call = fold_build2 (NE_EXPR, integer_type_node,
9735 signbit_call, integer_zero_node);
9736 isinf_call = fold_build2 (NE_EXPR, integer_type_node,
9737 isinf_call, integer_zero_node);
9738
9739 tmp = fold_build3 (COND_EXPR, integer_type_node, signbit_call,
9740 integer_minus_one_node, integer_one_node);
9741 tmp = fold_build3 (COND_EXPR, integer_type_node, isinf_call, tmp,
9742 integer_zero_node);
9743 }
9744
9745 return tmp;
9746 }
9747
cde061c1 9748 case BUILT_IN_ISFINITE:
b70bfd00 9749 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
9750 && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
34709e02 9751 return omit_one_operand (type, integer_one_node, arg);
726069ba 9752
9753 if (TREE_CODE (arg) == REAL_CST)
9754 {
9755 r = TREE_REAL_CST (arg);
776a7bab 9756 return real_isfinite (&r) ? integer_one_node : integer_zero_node;
726069ba 9757 }
9758
9759 return NULL_TREE;
9760
9761 case BUILT_IN_ISNAN:
b70bfd00 9762 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
a0c938f0 9763 return omit_one_operand (type, integer_zero_node, arg);
726069ba 9764
9765 if (TREE_CODE (arg) == REAL_CST)
9766 {
9767 r = TREE_REAL_CST (arg);
9768 return real_isnan (&r) ? integer_one_node : integer_zero_node;
9769 }
9770
9771 arg = builtin_save_expr (arg);
49d00087 9772 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
726069ba 9773
9774 default:
64db345d 9775 gcc_unreachable ();
726069ba 9776 }
9777}
9778
19fbe3a4 9779/* Fold a call to __builtin_fpclassify(int, int, int, int, int, ...).
9780 This builtin will generate code to return the appropriate floating
9781 point classification depending on the value of the floating point
9782 number passed in. The possible return values must be supplied as
921b27c0 9783 int arguments to the call in the following order: FP_NAN, FP_INFINITE,
19fbe3a4 9784 FP_NORMAL, FP_SUBNORMAL and FP_ZERO. The ellipses is for exactly
9785 one floating point argument which is "type generic". */
9786
9787static tree
9788fold_builtin_fpclassify (tree exp)
9789{
921b27c0 9790 tree fp_nan, fp_infinite, fp_normal, fp_subnormal, fp_zero,
9791 arg, type, res, tmp;
19fbe3a4 9792 enum machine_mode mode;
9793 REAL_VALUE_TYPE r;
9794 char buf[128];
9795
9796 /* Verify the required arguments in the original call. */
9797 if (!validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE,
9798 INTEGER_TYPE, INTEGER_TYPE,
9799 INTEGER_TYPE, REAL_TYPE, VOID_TYPE))
9800 return NULL_TREE;
9801
9802 fp_nan = CALL_EXPR_ARG (exp, 0);
921b27c0 9803 fp_infinite = CALL_EXPR_ARG (exp, 1);
19fbe3a4 9804 fp_normal = CALL_EXPR_ARG (exp, 2);
9805 fp_subnormal = CALL_EXPR_ARG (exp, 3);
9806 fp_zero = CALL_EXPR_ARG (exp, 4);
9807 arg = CALL_EXPR_ARG (exp, 5);
9808 type = TREE_TYPE (arg);
9809 mode = TYPE_MODE (type);
9810 arg = builtin_save_expr (fold_build1 (ABS_EXPR, type, arg));
9811
9812 /* fpclassify(x) ->
9813 isnan(x) ? FP_NAN :
921b27c0 9814 (fabs(x) == Inf ? FP_INFINITE :
19fbe3a4 9815 (fabs(x) >= DBL_MIN ? FP_NORMAL :
9816 (x == 0 ? FP_ZERO : FP_SUBNORMAL))). */
9817
9818 tmp = fold_build2 (EQ_EXPR, integer_type_node, arg,
9819 build_real (type, dconst0));
9820 res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_zero, fp_subnormal);
9821
9822 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
9823 real_from_string (&r, buf);
9824 tmp = fold_build2 (GE_EXPR, integer_type_node, arg, build_real (type, r));
9825 res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_normal, res);
9826
9827 if (HONOR_INFINITIES (mode))
9828 {
9829 real_inf (&r);
9830 tmp = fold_build2 (EQ_EXPR, integer_type_node, arg,
9831 build_real (type, r));
921b27c0 9832 res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_infinite, res);
19fbe3a4 9833 }
9834
9835 if (HONOR_NANS (mode))
9836 {
9837 tmp = fold_build2 (ORDERED_EXPR, integer_type_node, arg, arg);
9838 res = fold_build3 (COND_EXPR, integer_type_node, tmp, res, fp_nan);
9839 }
9840
9841 return res;
9842}
9843
9bc9f15f 9844/* Fold a call to an unordered comparison function such as
d5019fe8 9845 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
c2f47e15 9846 being called and ARG0 and ARG1 are the arguments for the call.
726069ba 9847 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
9848 the opposite of the desired result. UNORDERED_CODE is used
9849 for modes that can hold NaNs and ORDERED_CODE is used for
9850 the rest. */
9bc9f15f 9851
9852static tree
c2f47e15 9853fold_builtin_unordered_cmp (tree fndecl, tree arg0, tree arg1,
9bc9f15f 9854 enum tree_code unordered_code,
9855 enum tree_code ordered_code)
9856{
859f903a 9857 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9bc9f15f 9858 enum tree_code code;
6978db0d 9859 tree type0, type1;
9860 enum tree_code code0, code1;
9861 tree cmp_type = NULL_TREE;
9bc9f15f 9862
6978db0d 9863 type0 = TREE_TYPE (arg0);
9864 type1 = TREE_TYPE (arg1);
a0c938f0 9865
6978db0d 9866 code0 = TREE_CODE (type0);
9867 code1 = TREE_CODE (type1);
a0c938f0 9868
6978db0d 9869 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
9870 /* Choose the wider of two real types. */
9871 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
9872 ? type0 : type1;
9873 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
9874 cmp_type = type0;
9875 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
9876 cmp_type = type1;
a0c938f0 9877
6978db0d 9878 arg0 = fold_convert (cmp_type, arg0);
9879 arg1 = fold_convert (cmp_type, arg1);
859f903a 9880
9881 if (unordered_code == UNORDERED_EXPR)
9882 {
b70bfd00 9883 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
859f903a 9884 return omit_two_operands (type, integer_zero_node, arg0, arg1);
49d00087 9885 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
859f903a 9886 }
9bc9f15f 9887
b70bfd00 9888 code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
9889 : ordered_code;
49d00087 9890 return fold_build1 (TRUTH_NOT_EXPR, type,
9891 fold_build2 (code, type, arg0, arg1));
9bc9f15f 9892}
9893
c2f47e15 9894/* Fold a call to built-in function FNDECL with 0 arguments.
9895 IGNORE is true if the result of the function call is ignored. This
9896 function returns NULL_TREE if no simplification was possible. */
650e4c94 9897
4ee9c684 9898static tree
c2f47e15 9899fold_builtin_0 (tree fndecl, bool ignore ATTRIBUTE_UNUSED)
650e4c94 9900{
e9f80ff5 9901 tree type = TREE_TYPE (TREE_TYPE (fndecl));
c2f47e15 9902 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
189b3398 9903 switch (fcode)
650e4c94 9904 {
c2f47e15 9905 CASE_FLT_FN (BUILT_IN_INF):
9906 case BUILT_IN_INFD32:
9907 case BUILT_IN_INFD64:
9908 case BUILT_IN_INFD128:
9909 return fold_builtin_inf (type, true);
7c2f0500 9910
c2f47e15 9911 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
9912 return fold_builtin_inf (type, false);
7c2f0500 9913
c2f47e15 9914 case BUILT_IN_CLASSIFY_TYPE:
9915 return fold_builtin_classify_type (NULL_TREE);
7c2f0500 9916
c2f47e15 9917 default:
9918 break;
9919 }
9920 return NULL_TREE;
9921}
7c2f0500 9922
c2f47e15 9923/* Fold a call to built-in function FNDECL with 1 argument, ARG0.
9924 IGNORE is true if the result of the function call is ignored. This
9925 function returns NULL_TREE if no simplification was possible. */
7c2f0500 9926
c2f47e15 9927static tree
9928fold_builtin_1 (tree fndecl, tree arg0, bool ignore)
9929{
9930 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9931 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
9932 switch (fcode)
9933 {
7c2f0500 9934
650e4c94 9935 case BUILT_IN_CONSTANT_P:
7c2f0500 9936 {
c2f47e15 9937 tree val = fold_builtin_constant_p (arg0);
7c2f0500 9938
7c2f0500 9939 /* Gimplification will pull the CALL_EXPR for the builtin out of
9940 an if condition. When not optimizing, we'll not CSE it back.
9941 To avoid link error types of regressions, return false now. */
9942 if (!val && !optimize)
9943 val = integer_zero_node;
9944
9945 return val;
9946 }
650e4c94 9947
539a3a92 9948 case BUILT_IN_CLASSIFY_TYPE:
c2f47e15 9949 return fold_builtin_classify_type (arg0);
539a3a92 9950
650e4c94 9951 case BUILT_IN_STRLEN:
c2f47e15 9952 return fold_builtin_strlen (arg0);
650e4c94 9953
4f35b1fc 9954 CASE_FLT_FN (BUILT_IN_FABS):
c2f47e15 9955 return fold_builtin_fabs (arg0, type);
d1aade50 9956
9957 case BUILT_IN_ABS:
9958 case BUILT_IN_LABS:
9959 case BUILT_IN_LLABS:
9960 case BUILT_IN_IMAXABS:
c2f47e15 9961 return fold_builtin_abs (arg0, type);
c63f4ad3 9962
4f35b1fc 9963 CASE_FLT_FN (BUILT_IN_CONJ):
c2f47e15 9964 if (validate_arg (arg0, COMPLEX_TYPE))
9965 return fold_build1 (CONJ_EXPR, type, arg0);
9966 break;
36d3581d 9967
4f35b1fc 9968 CASE_FLT_FN (BUILT_IN_CREAL):
c2f47e15 9969 if (validate_arg (arg0, COMPLEX_TYPE))
9970 return non_lvalue (fold_build1 (REALPART_EXPR, type, arg0));;
9971 break;
36d3581d 9972
4f35b1fc 9973 CASE_FLT_FN (BUILT_IN_CIMAG):
c2f47e15 9974 if (validate_arg (arg0, COMPLEX_TYPE))
9975 return non_lvalue (fold_build1 (IMAGPART_EXPR, type, arg0));
9976 break;
36d3581d 9977
503733d5 9978 CASE_FLT_FN (BUILT_IN_CCOS):
9979 CASE_FLT_FN (BUILT_IN_CCOSH):
9980 /* These functions are "even", i.e. f(x) == f(-x). */
c2f47e15 9981 if (validate_arg (arg0, COMPLEX_TYPE))
9982 {
9983 tree narg = fold_strip_sign_ops (arg0);
503733d5 9984 if (narg)
c2f47e15 9985 return build_call_expr (fndecl, 1, narg);
503733d5 9986 }
c2f47e15 9987 break;
503733d5 9988
4f35b1fc 9989 CASE_FLT_FN (BUILT_IN_CABS):
c2f47e15 9990 return fold_builtin_cabs (arg0, type, fndecl);
c63f4ad3 9991
abe4dcf6 9992 CASE_FLT_FN (BUILT_IN_CARG):
c2f47e15 9993 return fold_builtin_carg (arg0, type);
abe4dcf6 9994
4f35b1fc 9995 CASE_FLT_FN (BUILT_IN_SQRT):
c2f47e15 9996 return fold_builtin_sqrt (arg0, type);
805e22b2 9997
4f35b1fc 9998 CASE_FLT_FN (BUILT_IN_CBRT):
c2f47e15 9999 return fold_builtin_cbrt (arg0, type);
3bc5c41b 10000
728bac60 10001 CASE_FLT_FN (BUILT_IN_ASIN):
c2f47e15 10002 if (validate_arg (arg0, REAL_TYPE))
10003 return do_mpfr_arg1 (arg0, type, mpfr_asin,
728bac60 10004 &dconstm1, &dconst1, true);
10005 break;
10006
10007 CASE_FLT_FN (BUILT_IN_ACOS):
c2f47e15 10008 if (validate_arg (arg0, REAL_TYPE))
10009 return do_mpfr_arg1 (arg0, type, mpfr_acos,
728bac60 10010 &dconstm1, &dconst1, true);
10011 break;
10012
10013 CASE_FLT_FN (BUILT_IN_ATAN):
c2f47e15 10014 if (validate_arg (arg0, REAL_TYPE))
10015 return do_mpfr_arg1 (arg0, type, mpfr_atan, NULL, NULL, 0);
728bac60 10016 break;
10017
10018 CASE_FLT_FN (BUILT_IN_ASINH):
c2f47e15 10019 if (validate_arg (arg0, REAL_TYPE))
10020 return do_mpfr_arg1 (arg0, type, mpfr_asinh, NULL, NULL, 0);
728bac60 10021 break;
10022
10023 CASE_FLT_FN (BUILT_IN_ACOSH):
c2f47e15 10024 if (validate_arg (arg0, REAL_TYPE))
10025 return do_mpfr_arg1 (arg0, type, mpfr_acosh,
728bac60 10026 &dconst1, NULL, true);
10027 break;
10028
10029 CASE_FLT_FN (BUILT_IN_ATANH):
c2f47e15 10030 if (validate_arg (arg0, REAL_TYPE))
10031 return do_mpfr_arg1 (arg0, type, mpfr_atanh,
728bac60 10032 &dconstm1, &dconst1, false);
10033 break;
10034
4f35b1fc 10035 CASE_FLT_FN (BUILT_IN_SIN):
c2f47e15 10036 if (validate_arg (arg0, REAL_TYPE))
10037 return do_mpfr_arg1 (arg0, type, mpfr_sin, NULL, NULL, 0);
728bac60 10038 break;
77e89269 10039
4f35b1fc 10040 CASE_FLT_FN (BUILT_IN_COS):
c2f47e15 10041 return fold_builtin_cos (arg0, type, fndecl);
10042 break;
77e89269 10043
728bac60 10044 CASE_FLT_FN (BUILT_IN_TAN):
c2f47e15 10045 return fold_builtin_tan (arg0, type);
d735c391 10046
c5bb2c4b 10047 CASE_FLT_FN (BUILT_IN_CEXP):
c2f47e15 10048 return fold_builtin_cexp (arg0, type);
c5bb2c4b 10049
d735c391 10050 CASE_FLT_FN (BUILT_IN_CEXPI):
c2f47e15 10051 if (validate_arg (arg0, REAL_TYPE))
10052 return do_mpfr_sincos (arg0, NULL_TREE, NULL_TREE);
10053 break;
d92f994c 10054
728bac60 10055 CASE_FLT_FN (BUILT_IN_SINH):
c2f47e15 10056 if (validate_arg (arg0, REAL_TYPE))
10057 return do_mpfr_arg1 (arg0, type, mpfr_sinh, NULL, NULL, 0);
728bac60 10058 break;
10059
10060 CASE_FLT_FN (BUILT_IN_COSH):
c2f47e15 10061 return fold_builtin_cosh (arg0, type, fndecl);
728bac60 10062
10063 CASE_FLT_FN (BUILT_IN_TANH):
c2f47e15 10064 if (validate_arg (arg0, REAL_TYPE))
10065 return do_mpfr_arg1 (arg0, type, mpfr_tanh, NULL, NULL, 0);
728bac60 10066 break;
10067
29f4cd78 10068 CASE_FLT_FN (BUILT_IN_ERF):
c2f47e15 10069 if (validate_arg (arg0, REAL_TYPE))
10070 return do_mpfr_arg1 (arg0, type, mpfr_erf, NULL, NULL, 0);
29f4cd78 10071 break;
10072
10073 CASE_FLT_FN (BUILT_IN_ERFC):
c2f47e15 10074 if (validate_arg (arg0, REAL_TYPE))
10075 return do_mpfr_arg1 (arg0, type, mpfr_erfc, NULL, NULL, 0);
29f4cd78 10076 break;
10077
32dba52b 10078 CASE_FLT_FN (BUILT_IN_TGAMMA):
c2f47e15 10079 if (validate_arg (arg0, REAL_TYPE))
10080 return do_mpfr_arg1 (arg0, type, mpfr_gamma, NULL, NULL, 0);
32dba52b 10081 break;
10082
4f35b1fc 10083 CASE_FLT_FN (BUILT_IN_EXP):
c2f47e15 10084 return fold_builtin_exponent (fndecl, arg0, mpfr_exp);
467214fd 10085
4f35b1fc 10086 CASE_FLT_FN (BUILT_IN_EXP2):
c2f47e15 10087 return fold_builtin_exponent (fndecl, arg0, mpfr_exp2);
467214fd 10088
4f35b1fc 10089 CASE_FLT_FN (BUILT_IN_EXP10):
10090 CASE_FLT_FN (BUILT_IN_POW10):
c2f47e15 10091 return fold_builtin_exponent (fndecl, arg0, mpfr_exp10);
467214fd 10092
29f4cd78 10093 CASE_FLT_FN (BUILT_IN_EXPM1):
c2f47e15 10094 if (validate_arg (arg0, REAL_TYPE))
10095 return do_mpfr_arg1 (arg0, type, mpfr_expm1, NULL, NULL, 0);
29f4cd78 10096 break;
10097
4f35b1fc 10098 CASE_FLT_FN (BUILT_IN_LOG):
c2f47e15 10099 return fold_builtin_logarithm (fndecl, arg0, mpfr_log);
467214fd 10100
4f35b1fc 10101 CASE_FLT_FN (BUILT_IN_LOG2):
c2f47e15 10102 return fold_builtin_logarithm (fndecl, arg0, mpfr_log2);
467214fd 10103
4f35b1fc 10104 CASE_FLT_FN (BUILT_IN_LOG10):
c2f47e15 10105 return fold_builtin_logarithm (fndecl, arg0, mpfr_log10);
29f4cd78 10106
10107 CASE_FLT_FN (BUILT_IN_LOG1P):
c2f47e15 10108 if (validate_arg (arg0, REAL_TYPE))
10109 return do_mpfr_arg1 (arg0, type, mpfr_log1p,
29f4cd78 10110 &dconstm1, NULL, false);
10111 break;
805e22b2 10112
65dd1378 10113#if MPFR_VERSION >= MPFR_VERSION_NUM(2,3,0)
10114 CASE_FLT_FN (BUILT_IN_J0):
10115 if (validate_arg (arg0, REAL_TYPE))
10116 return do_mpfr_arg1 (arg0, type, mpfr_j0,
10117 NULL, NULL, 0);
10118 break;
10119
10120 CASE_FLT_FN (BUILT_IN_J1):
10121 if (validate_arg (arg0, REAL_TYPE))
10122 return do_mpfr_arg1 (arg0, type, mpfr_j1,
10123 NULL, NULL, 0);
10124 break;
6ff9eeff 10125
10126 CASE_FLT_FN (BUILT_IN_Y0):
10127 if (validate_arg (arg0, REAL_TYPE))
10128 return do_mpfr_arg1 (arg0, type, mpfr_y0,
10129 &dconst0, NULL, false);
10130 break;
10131
10132 CASE_FLT_FN (BUILT_IN_Y1):
10133 if (validate_arg (arg0, REAL_TYPE))
10134 return do_mpfr_arg1 (arg0, type, mpfr_y1,
10135 &dconst0, NULL, false);
10136 break;
65dd1378 10137#endif
10138
4f35b1fc 10139 CASE_FLT_FN (BUILT_IN_NAN):
c4503c0a 10140 case BUILT_IN_NAND32:
10141 case BUILT_IN_NAND64:
10142 case BUILT_IN_NAND128:
c2f47e15 10143 return fold_builtin_nan (arg0, type, true);
b0db7939 10144
4f35b1fc 10145 CASE_FLT_FN (BUILT_IN_NANS):
c2f47e15 10146 return fold_builtin_nan (arg0, type, false);
b0db7939 10147
4f35b1fc 10148 CASE_FLT_FN (BUILT_IN_FLOOR):
c2f47e15 10149 return fold_builtin_floor (fndecl, arg0);
277f8dd2 10150
4f35b1fc 10151 CASE_FLT_FN (BUILT_IN_CEIL):
c2f47e15 10152 return fold_builtin_ceil (fndecl, arg0);
277f8dd2 10153
4f35b1fc 10154 CASE_FLT_FN (BUILT_IN_TRUNC):
c2f47e15 10155 return fold_builtin_trunc (fndecl, arg0);
277f8dd2 10156
4f35b1fc 10157 CASE_FLT_FN (BUILT_IN_ROUND):
c2f47e15 10158 return fold_builtin_round (fndecl, arg0);
89ab3887 10159
4f35b1fc 10160 CASE_FLT_FN (BUILT_IN_NEARBYINT):
10161 CASE_FLT_FN (BUILT_IN_RINT):
c2f47e15 10162 return fold_trunc_transparent_mathfn (fndecl, arg0);
6528f4f4 10163
4f35b1fc 10164 CASE_FLT_FN (BUILT_IN_LCEIL):
10165 CASE_FLT_FN (BUILT_IN_LLCEIL):
10166 CASE_FLT_FN (BUILT_IN_LFLOOR):
10167 CASE_FLT_FN (BUILT_IN_LLFLOOR):
a0c938f0 10168 CASE_FLT_FN (BUILT_IN_LROUND):
4f35b1fc 10169 CASE_FLT_FN (BUILT_IN_LLROUND):
c2f47e15 10170 return fold_builtin_int_roundingfn (fndecl, arg0);
34f17811 10171
4f35b1fc 10172 CASE_FLT_FN (BUILT_IN_LRINT):
10173 CASE_FLT_FN (BUILT_IN_LLRINT):
c2f47e15 10174 return fold_fixed_mathfn (fndecl, arg0);
9ed65c7f 10175
42791117 10176 case BUILT_IN_BSWAP32:
10177 case BUILT_IN_BSWAP64:
c2f47e15 10178 return fold_builtin_bswap (fndecl, arg0);
42791117 10179
4f35b1fc 10180 CASE_INT_FN (BUILT_IN_FFS):
10181 CASE_INT_FN (BUILT_IN_CLZ):
10182 CASE_INT_FN (BUILT_IN_CTZ):
10183 CASE_INT_FN (BUILT_IN_POPCOUNT):
10184 CASE_INT_FN (BUILT_IN_PARITY):
c2f47e15 10185 return fold_builtin_bitop (fndecl, arg0);
9c8a1629 10186
4f35b1fc 10187 CASE_FLT_FN (BUILT_IN_SIGNBIT):
c2f47e15 10188 return fold_builtin_signbit (arg0, type);
27f261ef 10189
cb2b9385 10190 CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
10191 return fold_builtin_significand (arg0, type);
10192
10193 CASE_FLT_FN (BUILT_IN_ILOGB):
10194 CASE_FLT_FN (BUILT_IN_LOGB):
10195 return fold_builtin_logb (arg0, type);
10196
d49367d4 10197 case BUILT_IN_ISASCII:
c2f47e15 10198 return fold_builtin_isascii (arg0);
d49367d4 10199
10200 case BUILT_IN_TOASCII:
c2f47e15 10201 return fold_builtin_toascii (arg0);
d49367d4 10202
df1cf42e 10203 case BUILT_IN_ISDIGIT:
c2f47e15 10204 return fold_builtin_isdigit (arg0);
467214fd 10205
4f35b1fc 10206 CASE_FLT_FN (BUILT_IN_FINITE):
c4503c0a 10207 case BUILT_IN_FINITED32:
10208 case BUILT_IN_FINITED64:
10209 case BUILT_IN_FINITED128:
cde061c1 10210 case BUILT_IN_ISFINITE:
10211 return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISFINITE);
726069ba 10212
4f35b1fc 10213 CASE_FLT_FN (BUILT_IN_ISINF):
c4503c0a 10214 case BUILT_IN_ISINFD32:
10215 case BUILT_IN_ISINFD64:
10216 case BUILT_IN_ISINFD128:
c2f47e15 10217 return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISINF);
726069ba 10218
c319d56a 10219 case BUILT_IN_ISINF_SIGN:
10220 return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISINF_SIGN);
10221
4f35b1fc 10222 CASE_FLT_FN (BUILT_IN_ISNAN):
c4503c0a 10223 case BUILT_IN_ISNAND32:
10224 case BUILT_IN_ISNAND64:
10225 case BUILT_IN_ISNAND128:
c2f47e15 10226 return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISNAN);
10227
10228 case BUILT_IN_PRINTF:
10229 case BUILT_IN_PRINTF_UNLOCKED:
10230 case BUILT_IN_VPRINTF:
10231 return fold_builtin_printf (fndecl, arg0, NULL_TREE, ignore, fcode);
10232
10233 default:
10234 break;
10235 }
10236
10237 return NULL_TREE;
10238
10239}
10240
10241/* Fold a call to built-in function FNDECL with 2 arguments, ARG0 and ARG1.
10242 IGNORE is true if the result of the function call is ignored. This
10243 function returns NULL_TREE if no simplification was possible. */
10244
10245static tree
10246fold_builtin_2 (tree fndecl, tree arg0, tree arg1, bool ignore)
10247{
10248 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10249 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10250
10251 switch (fcode)
10252 {
65dd1378 10253#if MPFR_VERSION >= MPFR_VERSION_NUM(2,3,0)
10254 CASE_FLT_FN (BUILT_IN_JN):
10255 if (validate_arg (arg0, INTEGER_TYPE)
10256 && validate_arg (arg1, REAL_TYPE))
10257 return do_mpfr_bessel_n (arg0, arg1, type, mpfr_jn, NULL, 0);
10258 break;
6ff9eeff 10259
10260 CASE_FLT_FN (BUILT_IN_YN):
10261 if (validate_arg (arg0, INTEGER_TYPE)
10262 && validate_arg (arg1, REAL_TYPE))
10263 return do_mpfr_bessel_n (arg0, arg1, type, mpfr_yn,
10264 &dconst0, false);
10265 break;
e5407ca6 10266
10267 CASE_FLT_FN (BUILT_IN_DREM):
10268 CASE_FLT_FN (BUILT_IN_REMAINDER):
10269 if (validate_arg (arg0, REAL_TYPE)
10270 && validate_arg(arg1, REAL_TYPE))
10271 return do_mpfr_arg2 (arg0, arg1, type, mpfr_remainder);
10272 break;
e84da7c1 10273
10274 CASE_FLT_FN_REENT (BUILT_IN_GAMMA): /* GAMMA_R */
10275 CASE_FLT_FN_REENT (BUILT_IN_LGAMMA): /* LGAMMA_R */
10276 if (validate_arg (arg0, REAL_TYPE)
10277 && validate_arg(arg1, POINTER_TYPE))
10278 return do_mpfr_lgamma_r (arg0, arg1, type);
10279 break;
65dd1378 10280#endif
c2f47e15 10281
10282 CASE_FLT_FN (BUILT_IN_ATAN2):
10283 if (validate_arg (arg0, REAL_TYPE)
10284 && validate_arg(arg1, REAL_TYPE))
10285 return do_mpfr_arg2 (arg0, arg1, type, mpfr_atan2);
10286 break;
10287
10288 CASE_FLT_FN (BUILT_IN_FDIM):
10289 if (validate_arg (arg0, REAL_TYPE)
10290 && validate_arg(arg1, REAL_TYPE))
10291 return do_mpfr_arg2 (arg0, arg1, type, mpfr_dim);
10292 break;
10293
10294 CASE_FLT_FN (BUILT_IN_HYPOT):
10295 return fold_builtin_hypot (fndecl, arg0, arg1, type);
10296
7587301b 10297 CASE_FLT_FN (BUILT_IN_LDEXP):
10298 return fold_builtin_load_exponent (arg0, arg1, type, /*ldexp=*/true);
10299 CASE_FLT_FN (BUILT_IN_SCALBN):
10300 CASE_FLT_FN (BUILT_IN_SCALBLN):
10301 return fold_builtin_load_exponent (arg0, arg1, type, /*ldexp=*/false);
10302
3838b9ae 10303 CASE_FLT_FN (BUILT_IN_FREXP):
10304 return fold_builtin_frexp (arg0, arg1, type);
10305
ebf8b4f5 10306 CASE_FLT_FN (BUILT_IN_MODF):
10307 return fold_builtin_modf (arg0, arg1, type);
10308
c2f47e15 10309 case BUILT_IN_BZERO:
10310 return fold_builtin_bzero (arg0, arg1, ignore);
10311
10312 case BUILT_IN_FPUTS:
10313 return fold_builtin_fputs (arg0, arg1, ignore, false, NULL_TREE);
10314
10315 case BUILT_IN_FPUTS_UNLOCKED:
10316 return fold_builtin_fputs (arg0, arg1, ignore, true, NULL_TREE);
10317
10318 case BUILT_IN_STRSTR:
10319 return fold_builtin_strstr (arg0, arg1, type);
10320
10321 case BUILT_IN_STRCAT:
10322 return fold_builtin_strcat (arg0, arg1);
10323
10324 case BUILT_IN_STRSPN:
10325 return fold_builtin_strspn (arg0, arg1);
10326
10327 case BUILT_IN_STRCSPN:
10328 return fold_builtin_strcspn (arg0, arg1);
10329
10330 case BUILT_IN_STRCHR:
10331 case BUILT_IN_INDEX:
10332 return fold_builtin_strchr (arg0, arg1, type);
10333
10334 case BUILT_IN_STRRCHR:
10335 case BUILT_IN_RINDEX:
10336 return fold_builtin_strrchr (arg0, arg1, type);
10337
10338 case BUILT_IN_STRCPY:
10339 return fold_builtin_strcpy (fndecl, arg0, arg1, NULL_TREE);
10340
10341 case BUILT_IN_STRCMP:
10342 return fold_builtin_strcmp (arg0, arg1);
10343
10344 case BUILT_IN_STRPBRK:
10345 return fold_builtin_strpbrk (arg0, arg1, type);
10346
10347 case BUILT_IN_EXPECT:
76f5a783 10348 return fold_builtin_expect (arg0, arg1);
c2f47e15 10349
10350 CASE_FLT_FN (BUILT_IN_POW):
10351 return fold_builtin_pow (fndecl, arg0, arg1, type);
10352
10353 CASE_FLT_FN (BUILT_IN_POWI):
10354 return fold_builtin_powi (fndecl, arg0, arg1, type);
10355
10356 CASE_FLT_FN (BUILT_IN_COPYSIGN):
10357 return fold_builtin_copysign (fndecl, arg0, arg1, type);
10358
10359 CASE_FLT_FN (BUILT_IN_FMIN):
10360 return fold_builtin_fmin_fmax (arg0, arg1, type, /*max=*/false);
10361
10362 CASE_FLT_FN (BUILT_IN_FMAX):
10363 return fold_builtin_fmin_fmax (arg0, arg1, type, /*max=*/true);
726069ba 10364
9bc9f15f 10365 case BUILT_IN_ISGREATER:
c2f47e15 10366 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNLE_EXPR, LE_EXPR);
9bc9f15f 10367 case BUILT_IN_ISGREATEREQUAL:
c2f47e15 10368 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNLT_EXPR, LT_EXPR);
9bc9f15f 10369 case BUILT_IN_ISLESS:
c2f47e15 10370 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNGE_EXPR, GE_EXPR);
9bc9f15f 10371 case BUILT_IN_ISLESSEQUAL:
c2f47e15 10372 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNGT_EXPR, GT_EXPR);
9bc9f15f 10373 case BUILT_IN_ISLESSGREATER:
c2f47e15 10374 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNEQ_EXPR, EQ_EXPR);
9bc9f15f 10375 case BUILT_IN_ISUNORDERED:
c2f47e15 10376 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNORDERED_EXPR,
d5019fe8 10377 NOP_EXPR);
9bc9f15f 10378
7c2f0500 10379 /* We do the folding for va_start in the expander. */
10380 case BUILT_IN_VA_START:
10381 break;
f0613857 10382
c2f47e15 10383 case BUILT_IN_SPRINTF:
10384 return fold_builtin_sprintf (arg0, arg1, NULL_TREE, ignore);
10385
0a39fd54 10386 case BUILT_IN_OBJECT_SIZE:
c2f47e15 10387 return fold_builtin_object_size (arg0, arg1);
0a39fd54 10388
10389 case BUILT_IN_PRINTF:
10390 case BUILT_IN_PRINTF_UNLOCKED:
10391 case BUILT_IN_VPRINTF:
c2f47e15 10392 return fold_builtin_printf (fndecl, arg0, arg1, ignore, fcode);
10393
0a39fd54 10394 case BUILT_IN_PRINTF_CHK:
10395 case BUILT_IN_VPRINTF_CHK:
c2f47e15 10396 if (!validate_arg (arg0, INTEGER_TYPE)
10397 || TREE_SIDE_EFFECTS (arg0))
10398 return NULL_TREE;
10399 else
10400 return fold_builtin_printf (fndecl, arg1, NULL_TREE, ignore, fcode);
10401 break;
0a39fd54 10402
10403 case BUILT_IN_FPRINTF:
10404 case BUILT_IN_FPRINTF_UNLOCKED:
10405 case BUILT_IN_VFPRINTF:
c2f47e15 10406 return fold_builtin_fprintf (fndecl, arg0, arg1, NULL_TREE,
10407 ignore, fcode);
10408
10409 default:
10410 break;
10411 }
10412 return NULL_TREE;
10413}
10414
10415/* Fold a call to built-in function FNDECL with 3 arguments, ARG0, ARG1,
10416 and ARG2. IGNORE is true if the result of the function call is ignored.
10417 This function returns NULL_TREE if no simplification was possible. */
10418
10419static tree
10420fold_builtin_3 (tree fndecl, tree arg0, tree arg1, tree arg2, bool ignore)
10421{
10422 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10423 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10424 switch (fcode)
10425 {
10426
10427 CASE_FLT_FN (BUILT_IN_SINCOS):
10428 return fold_builtin_sincos (arg0, arg1, arg2);
10429
10430 CASE_FLT_FN (BUILT_IN_FMA):
10431 if (validate_arg (arg0, REAL_TYPE)
10432 && validate_arg(arg1, REAL_TYPE)
10433 && validate_arg(arg2, REAL_TYPE))
10434 return do_mpfr_arg3 (arg0, arg1, arg2, type, mpfr_fma);
10435 break;
10436
e5407ca6 10437#if MPFR_VERSION >= MPFR_VERSION_NUM(2,3,0)
10438 CASE_FLT_FN (BUILT_IN_REMQUO):
10439 if (validate_arg (arg0, REAL_TYPE)
10440 && validate_arg(arg1, REAL_TYPE)
10441 && validate_arg(arg2, POINTER_TYPE))
10442 return do_mpfr_remquo (arg0, arg1, arg2);
10443 break;
10444#endif
10445
c2f47e15 10446 case BUILT_IN_MEMSET:
10447 return fold_builtin_memset (arg0, arg1, arg2, type, ignore);
10448
10449 case BUILT_IN_BCOPY:
10450 return fold_builtin_memory_op (arg1, arg0, arg2, void_type_node, true, /*endp=*/3);
10451
10452 case BUILT_IN_MEMCPY:
10453 return fold_builtin_memory_op (arg0, arg1, arg2, type, ignore, /*endp=*/0);
10454
10455 case BUILT_IN_MEMPCPY:
10456 return fold_builtin_memory_op (arg0, arg1, arg2, type, ignore, /*endp=*/1);
10457
10458 case BUILT_IN_MEMMOVE:
10459 return fold_builtin_memory_op (arg0, arg1, arg2, type, ignore, /*endp=*/3);
10460
10461 case BUILT_IN_STRNCAT:
10462 return fold_builtin_strncat (arg0, arg1, arg2);
10463
10464 case BUILT_IN_STRNCPY:
10465 return fold_builtin_strncpy (fndecl, arg0, arg1, arg2, NULL_TREE);
10466
10467 case BUILT_IN_STRNCMP:
10468 return fold_builtin_strncmp (arg0, arg1, arg2);
10469
7959b13b 10470 case BUILT_IN_MEMCHR:
10471 return fold_builtin_memchr (arg0, arg1, arg2, type);
10472
c2f47e15 10473 case BUILT_IN_BCMP:
10474 case BUILT_IN_MEMCMP:
10475 return fold_builtin_memcmp (arg0, arg1, arg2);;
10476
10477 case BUILT_IN_SPRINTF:
10478 return fold_builtin_sprintf (arg0, arg1, arg2, ignore);
10479
10480 case BUILT_IN_STRCPY_CHK:
10481 case BUILT_IN_STPCPY_CHK:
10482 return fold_builtin_stxcpy_chk (fndecl, arg0, arg1, arg2, NULL_TREE,
10483 ignore, fcode);
10484
10485 case BUILT_IN_STRCAT_CHK:
10486 return fold_builtin_strcat_chk (fndecl, arg0, arg1, arg2);
10487
10488 case BUILT_IN_PRINTF_CHK:
10489 case BUILT_IN_VPRINTF_CHK:
10490 if (!validate_arg (arg0, INTEGER_TYPE)
10491 || TREE_SIDE_EFFECTS (arg0))
10492 return NULL_TREE;
10493 else
10494 return fold_builtin_printf (fndecl, arg1, arg2, ignore, fcode);
10495 break;
10496
10497 case BUILT_IN_FPRINTF:
10498 case BUILT_IN_FPRINTF_UNLOCKED:
10499 case BUILT_IN_VFPRINTF:
10500 return fold_builtin_fprintf (fndecl, arg0, arg1, arg2, ignore, fcode);
10501
0a39fd54 10502 case BUILT_IN_FPRINTF_CHK:
10503 case BUILT_IN_VFPRINTF_CHK:
c2f47e15 10504 if (!validate_arg (arg1, INTEGER_TYPE)
10505 || TREE_SIDE_EFFECTS (arg1))
10506 return NULL_TREE;
10507 else
10508 return fold_builtin_fprintf (fndecl, arg0, arg2, NULL_TREE,
10509 ignore, fcode);
0a39fd54 10510
650e4c94 10511 default:
10512 break;
10513 }
c2f47e15 10514 return NULL_TREE;
10515}
650e4c94 10516
c2f47e15 10517/* Fold a call to built-in function FNDECL with 4 arguments, ARG0, ARG1,
10518 ARG2, and ARG3. IGNORE is true if the result of the function call is
10519 ignored. This function returns NULL_TREE if no simplification was
10520 possible. */
10521
10522static tree
10523fold_builtin_4 (tree fndecl, tree arg0, tree arg1, tree arg2, tree arg3,
10524 bool ignore)
10525{
10526 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10527
10528 switch (fcode)
10529 {
10530 case BUILT_IN_MEMCPY_CHK:
10531 case BUILT_IN_MEMPCPY_CHK:
10532 case BUILT_IN_MEMMOVE_CHK:
10533 case BUILT_IN_MEMSET_CHK:
10534 return fold_builtin_memory_chk (fndecl, arg0, arg1, arg2, arg3,
10535 NULL_TREE, ignore,
10536 DECL_FUNCTION_CODE (fndecl));
10537
10538 case BUILT_IN_STRNCPY_CHK:
10539 return fold_builtin_strncpy_chk (arg0, arg1, arg2, arg3, NULL_TREE);
10540
10541 case BUILT_IN_STRNCAT_CHK:
10542 return fold_builtin_strncat_chk (fndecl, arg0, arg1, arg2, arg3);
10543
10544 case BUILT_IN_FPRINTF_CHK:
10545 case BUILT_IN_VFPRINTF_CHK:
10546 if (!validate_arg (arg1, INTEGER_TYPE)
10547 || TREE_SIDE_EFFECTS (arg1))
10548 return NULL_TREE;
10549 else
10550 return fold_builtin_fprintf (fndecl, arg0, arg2, arg3,
10551 ignore, fcode);
10552 break;
10553
10554 default:
10555 break;
10556 }
10557 return NULL_TREE;
10558}
10559
10560/* Fold a call to built-in function FNDECL. ARGS is an array of NARGS
10561 arguments, where NARGS <= 4. IGNORE is true if the result of the
10562 function call is ignored. This function returns NULL_TREE if no
10563 simplification was possible. Note that this only folds builtins with
10564 fixed argument patterns. Foldings that do varargs-to-varargs
10565 transformations, or that match calls with more than 4 arguments,
10566 need to be handled with fold_builtin_varargs instead. */
10567
10568#define MAX_ARGS_TO_FOLD_BUILTIN 4
10569
10570static tree
10571fold_builtin_n (tree fndecl, tree *args, int nargs, bool ignore)
10572{
10573 tree ret = NULL_TREE;
a7f5bb2d 10574
c2f47e15 10575 switch (nargs)
10576 {
10577 case 0:
10578 ret = fold_builtin_0 (fndecl, ignore);
10579 break;
10580 case 1:
10581 ret = fold_builtin_1 (fndecl, args[0], ignore);
10582 break;
10583 case 2:
10584 ret = fold_builtin_2 (fndecl, args[0], args[1], ignore);
10585 break;
10586 case 3:
10587 ret = fold_builtin_3 (fndecl, args[0], args[1], args[2], ignore);
10588 break;
10589 case 4:
10590 ret = fold_builtin_4 (fndecl, args[0], args[1], args[2], args[3],
10591 ignore);
10592 break;
10593 default:
10594 break;
10595 }
10596 if (ret)
10597 {
75a70cf9 10598 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
c2f47e15 10599 TREE_NO_WARNING (ret) = 1;
10600 return ret;
10601 }
10602 return NULL_TREE;
10603}
10604
10605/* Builtins with folding operations that operate on "..." arguments
10606 need special handling; we need to store the arguments in a convenient
10607 data structure before attempting any folding. Fortunately there are
10608 only a few builtins that fall into this category. FNDECL is the
10609 function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
10610 result of the function call is ignored. */
10611
10612static tree
10613fold_builtin_varargs (tree fndecl, tree exp, bool ignore ATTRIBUTE_UNUSED)
10614{
10615 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10616 tree ret = NULL_TREE;
10617
10618 switch (fcode)
10619 {
10620 case BUILT_IN_SPRINTF_CHK:
10621 case BUILT_IN_VSPRINTF_CHK:
10622 ret = fold_builtin_sprintf_chk (exp, fcode);
10623 break;
10624
10625 case BUILT_IN_SNPRINTF_CHK:
10626 case BUILT_IN_VSNPRINTF_CHK:
10627 ret = fold_builtin_snprintf_chk (exp, NULL_TREE, fcode);
19fbe3a4 10628 break;
10629
10630 case BUILT_IN_FPCLASSIFY:
10631 ret = fold_builtin_fpclassify (exp);
10632 break;
c2f47e15 10633
10634 default:
10635 break;
10636 }
10637 if (ret)
10638 {
10639 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
10640 TREE_NO_WARNING (ret) = 1;
10641 return ret;
10642 }
10643 return NULL_TREE;
650e4c94 10644}
7e15618b 10645
4ee9c684 10646/* A wrapper function for builtin folding that prevents warnings for
491e04ef 10647 "statement without effect" and the like, caused by removing the
4ee9c684 10648 call node earlier than the warning is generated. */
10649
10650tree
c2f47e15 10651fold_call_expr (tree exp, bool ignore)
4ee9c684 10652{
c2f47e15 10653 tree ret = NULL_TREE;
10654 tree fndecl = get_callee_fndecl (exp);
10655 if (fndecl
10656 && TREE_CODE (fndecl) == FUNCTION_DECL
48dc2227 10657 && DECL_BUILT_IN (fndecl)
10658 /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized
10659 yet. Defer folding until we see all the arguments
10660 (after inlining). */
10661 && !CALL_EXPR_VA_ARG_PACK (exp))
10662 {
10663 int nargs = call_expr_nargs (exp);
10664
10665 /* Before gimplification CALL_EXPR_VA_ARG_PACK is not set, but
10666 instead last argument is __builtin_va_arg_pack (). Defer folding
10667 even in that case, until arguments are finalized. */
10668 if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR)
10669 {
10670 tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1));
10671 if (fndecl2
10672 && TREE_CODE (fndecl2) == FUNCTION_DECL
10673 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
10674 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
10675 return NULL_TREE;
10676 }
10677
c2f47e15 10678 /* FIXME: Don't use a list in this interface. */
10679 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
10680 return targetm.fold_builtin (fndecl, CALL_EXPR_ARGS (exp), ignore);
10681 else
10682 {
c2f47e15 10683 if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
10684 {
10685 tree *args = CALL_EXPR_ARGP (exp);
10686 ret = fold_builtin_n (fndecl, args, nargs, ignore);
10687 }
10688 if (!ret)
10689 ret = fold_builtin_varargs (fndecl, exp, ignore);
10690 if (ret)
10691 {
10692 /* Propagate location information from original call to
10693 expansion of builtin. Otherwise things like
10694 maybe_emit_chk_warning, that operate on the expansion
10695 of a builtin, will use the wrong location information. */
10696 if (CAN_HAVE_LOCATION_P (exp) && EXPR_HAS_LOCATION (exp))
10697 {
10698 tree realret = ret;
10699 if (TREE_CODE (ret) == NOP_EXPR)
10700 realret = TREE_OPERAND (ret, 0);
10701 if (CAN_HAVE_LOCATION_P (realret)
10702 && !EXPR_HAS_LOCATION (realret))
10703 SET_EXPR_LOCATION (realret, EXPR_LOCATION (exp));
55c10931 10704 return realret;
c2f47e15 10705 }
10706 return ret;
10707 }
10708 }
4ee9c684 10709 }
c2f47e15 10710 return NULL_TREE;
10711}
10712
10713/* Conveniently construct a function call expression. FNDECL names the
10714 function to be called and ARGLIST is a TREE_LIST of arguments. */
10715
10716tree
10717build_function_call_expr (tree fndecl, tree arglist)
10718{
10719 tree fntype = TREE_TYPE (fndecl);
10720 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
d01f58f9 10721 int n = list_length (arglist);
10722 tree *argarray = (tree *) alloca (n * sizeof (tree));
10723 int i;
10724
10725 for (i = 0; i < n; i++, arglist = TREE_CHAIN (arglist))
10726 argarray[i] = TREE_VALUE (arglist);
10727 return fold_builtin_call_array (TREE_TYPE (fntype), fn, n, argarray);
c2f47e15 10728}
10729
10730/* Conveniently construct a function call expression. FNDECL names the
10731 function to be called, N is the number of arguments, and the "..."
10732 parameters are the argument expressions. */
10733
10734tree
10735build_call_expr (tree fndecl, int n, ...)
10736{
10737 va_list ap;
c2f47e15 10738 tree fntype = TREE_TYPE (fndecl);
10739 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
d01f58f9 10740 tree *argarray = (tree *) alloca (n * sizeof (tree));
10741 int i;
c2f47e15 10742
10743 va_start (ap, n);
d01f58f9 10744 for (i = 0; i < n; i++)
10745 argarray[i] = va_arg (ap, tree);
c2f47e15 10746 va_end (ap);
d01f58f9 10747 return fold_builtin_call_array (TREE_TYPE (fntype), fn, n, argarray);
4ee9c684 10748}
10749
c2f47e15 10750/* Construct a CALL_EXPR with type TYPE with FN as the function expression.
d01f58f9 10751 N arguments are passed in the array ARGARRAY. */
805e22b2 10752
10753tree
d01f58f9 10754fold_builtin_call_array (tree type,
10755 tree fn,
10756 int n,
10757 tree *argarray)
7e15618b 10758{
c2f47e15 10759 tree ret = NULL_TREE;
10760 int i;
10761 tree exp;
10762
10763 if (TREE_CODE (fn) == ADDR_EXPR)
10764 {
10765 tree fndecl = TREE_OPERAND (fn, 0);
10766 if (TREE_CODE (fndecl) == FUNCTION_DECL
10767 && DECL_BUILT_IN (fndecl))
10768 {
48dc2227 10769 /* If last argument is __builtin_va_arg_pack (), arguments to this
10770 function are not finalized yet. Defer folding until they are. */
10771 if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
10772 {
10773 tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
10774 if (fndecl2
10775 && TREE_CODE (fndecl2) == FUNCTION_DECL
10776 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
10777 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
10778 return build_call_array (type, fn, n, argarray);
10779 }
c2f47e15 10780 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
10781 {
10782 tree arglist = NULL_TREE;
d01f58f9 10783 for (i = n - 1; i >= 0; i--)
10784 arglist = tree_cons (NULL_TREE, argarray[i], arglist);
c2f47e15 10785 ret = targetm.fold_builtin (fndecl, arglist, false);
10786 if (ret)
10787 return ret;
10788 }
10789 else if (n <= MAX_ARGS_TO_FOLD_BUILTIN)
10790 {
10791 /* First try the transformations that don't require consing up
10792 an exp. */
d01f58f9 10793 ret = fold_builtin_n (fndecl, argarray, n, false);
c2f47e15 10794 if (ret)
10795 return ret;
10796 }
10797
10798 /* If we got this far, we need to build an exp. */
d01f58f9 10799 exp = build_call_array (type, fn, n, argarray);
c2f47e15 10800 ret = fold_builtin_varargs (fndecl, exp, false);
10801 return ret ? ret : exp;
10802 }
10803 }
10804
d01f58f9 10805 return build_call_array (type, fn, n, argarray);
c2f47e15 10806}
10807
10808/* Construct a new CALL_EXPR using the tail of the argument list of EXP
10809 along with N new arguments specified as the "..." parameters. SKIP
10810 is the number of arguments in EXP to be omitted. This function is used
10811 to do varargs-to-varargs transformations. */
10812
10813static tree
10814rewrite_call_expr (tree exp, int skip, tree fndecl, int n, ...)
10815{
10816 int oldnargs = call_expr_nargs (exp);
10817 int nargs = oldnargs - skip + n;
10818 tree fntype = TREE_TYPE (fndecl);
10819 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
10820 tree *buffer;
10821
10822 if (n > 0)
10823 {
10824 int i, j;
10825 va_list ap;
7e15618b 10826
364c0c59 10827 buffer = XALLOCAVEC (tree, nargs);
c2f47e15 10828 va_start (ap, n);
10829 for (i = 0; i < n; i++)
10830 buffer[i] = va_arg (ap, tree);
10831 va_end (ap);
10832 for (j = skip; j < oldnargs; j++, i++)
10833 buffer[i] = CALL_EXPR_ARG (exp, j);
10834 }
10835 else
10836 buffer = CALL_EXPR_ARGP (exp) + skip;
10837
10838 return fold (build_call_array (TREE_TYPE (exp), fn, nargs, buffer));
10839}
10840
10841/* Validate a single argument ARG against a tree code CODE representing
10842 a type. */
10843
10844static bool
b7bf20db 10845validate_arg (const_tree arg, enum tree_code code)
c2f47e15 10846{
10847 if (!arg)
10848 return false;
10849 else if (code == POINTER_TYPE)
10850 return POINTER_TYPE_P (TREE_TYPE (arg));
c7f617c2 10851 else if (code == INTEGER_TYPE)
10852 return INTEGRAL_TYPE_P (TREE_TYPE (arg));
c2f47e15 10853 return code == TREE_CODE (TREE_TYPE (arg));
7e15618b 10854}
0eb671f7 10855
75a70cf9 10856/* This function validates the types of a function call argument list
10857 against a specified list of tree_codes. If the last specifier is a 0,
10858 that represents an ellipses, otherwise the last specifier must be a
10859 VOID_TYPE.
10860
10861 This is the GIMPLE version of validate_arglist. Eventually we want to
10862 completely convert builtins.c to work from GIMPLEs and the tree based
10863 validate_arglist will then be removed. */
10864
10865bool
10866validate_gimple_arglist (const_gimple call, ...)
10867{
10868 enum tree_code code;
10869 bool res = 0;
10870 va_list ap;
10871 const_tree arg;
10872 size_t i;
10873
10874 va_start (ap, call);
10875 i = 0;
10876
10877 do
10878 {
10879 code = va_arg (ap, enum tree_code);
10880 switch (code)
10881 {
10882 case 0:
10883 /* This signifies an ellipses, any further arguments are all ok. */
10884 res = true;
10885 goto end;
10886 case VOID_TYPE:
10887 /* This signifies an endlink, if no arguments remain, return
10888 true, otherwise return false. */
10889 res = (i == gimple_call_num_args (call));
10890 goto end;
10891 default:
10892 /* If no parameters remain or the parameter's code does not
10893 match the specified code, return false. Otherwise continue
10894 checking any remaining arguments. */
10895 arg = gimple_call_arg (call, i++);
10896 if (!validate_arg (arg, code))
10897 goto end;
10898 break;
10899 }
10900 }
10901 while (1);
10902
10903 /* We need gotos here since we can only have one VA_CLOSE in a
10904 function. */
10905 end: ;
10906 va_end (ap);
10907
10908 return res;
10909}
10910
0eb671f7 10911/* This function validates the types of a function call argument list
c2f47e15 10912 against a specified list of tree_codes. If the last specifier is a 0,
10913 that represents an ellipses, otherwise the last specifier must be a
10914 VOID_TYPE. */
27d0c333 10915
c2f47e15 10916bool
b7bf20db 10917validate_arglist (const_tree callexpr, ...)
0eb671f7 10918{
0eb671f7 10919 enum tree_code code;
c2f47e15 10920 bool res = 0;
ee582a61 10921 va_list ap;
b7bf20db 10922 const_call_expr_arg_iterator iter;
10923 const_tree arg;
aecda0d6 10924
c2f47e15 10925 va_start (ap, callexpr);
b7bf20db 10926 init_const_call_expr_arg_iterator (callexpr, &iter);
0eb671f7 10927
f0ce3b1f 10928 do
0eb671f7 10929 {
f0ce3b1f 10930 code = va_arg (ap, enum tree_code);
10931 switch (code)
10932 {
10933 case 0:
10934 /* This signifies an ellipses, any further arguments are all ok. */
c2f47e15 10935 res = true;
f0ce3b1f 10936 goto end;
10937 case VOID_TYPE:
10938 /* This signifies an endlink, if no arguments remain, return
10939 true, otherwise return false. */
b7bf20db 10940 res = !more_const_call_expr_args_p (&iter);
f0ce3b1f 10941 goto end;
10942 default:
10943 /* If no parameters remain or the parameter's code does not
10944 match the specified code, return false. Otherwise continue
10945 checking any remaining arguments. */
b7bf20db 10946 arg = next_const_call_expr_arg (&iter);
c2f47e15 10947 if (!validate_arg (arg, code))
f0ce3b1f 10948 goto end;
10949 break;
10950 }
0eb671f7 10951 }
f0ce3b1f 10952 while (1);
0903457a 10953
10954 /* We need gotos here since we can only have one VA_CLOSE in a
10955 function. */
10956 end: ;
ee582a61 10957 va_end (ap);
0903457a 10958
10959 return res;
0eb671f7 10960}
fc2a2dcb 10961
fc2a2dcb 10962/* Default target-specific builtin expander that does nothing. */
10963
10964rtx
aecda0d6 10965default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
10966 rtx target ATTRIBUTE_UNUSED,
10967 rtx subtarget ATTRIBUTE_UNUSED,
10968 enum machine_mode mode ATTRIBUTE_UNUSED,
10969 int ignore ATTRIBUTE_UNUSED)
fc2a2dcb 10970{
10971 return NULL_RTX;
10972}
c7926a82 10973
01537105 10974/* Returns true is EXP represents data that would potentially reside
10975 in a readonly section. */
10976
10977static bool
10978readonly_data_expr (tree exp)
10979{
10980 STRIP_NOPS (exp);
10981
9ff0637e 10982 if (TREE_CODE (exp) != ADDR_EXPR)
10983 return false;
10984
10985 exp = get_base_address (TREE_OPERAND (exp, 0));
10986 if (!exp)
10987 return false;
10988
10989 /* Make sure we call decl_readonly_section only for trees it
10990 can handle (since it returns true for everything it doesn't
10991 understand). */
491e04ef 10992 if (TREE_CODE (exp) == STRING_CST
9ff0637e 10993 || TREE_CODE (exp) == CONSTRUCTOR
10994 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
10995 return decl_readonly_section (exp, 0);
01537105 10996 else
10997 return false;
10998}
4ee9c684 10999
c2f47e15 11000/* Simplify a call to the strstr builtin. S1 and S2 are the arguments
11001 to the call, and TYPE is its return type.
4ee9c684 11002
c2f47e15 11003 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11004 simplified form of the call as a tree.
11005
11006 The simplified form may be a constant or other expression which
11007 computes the same value, but in a more efficient manner (including
11008 calls to other builtin functions).
11009
11010 The call may contain arguments which need to be evaluated, but
11011 which are not useful to determine the result of the call. In
11012 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11013 COMPOUND_EXPR will be an argument which must be evaluated.
11014 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11015 COMPOUND_EXPR in the chain will contain the tree for the simplified
11016 form of the builtin function call. */
11017
11018static tree
c2f47e15 11019fold_builtin_strstr (tree s1, tree s2, tree type)
4ee9c684 11020{
c2f47e15 11021 if (!validate_arg (s1, POINTER_TYPE)
11022 || !validate_arg (s2, POINTER_TYPE))
11023 return NULL_TREE;
4ee9c684 11024 else
11025 {
4ee9c684 11026 tree fn;
11027 const char *p1, *p2;
11028
11029 p2 = c_getstr (s2);
11030 if (p2 == NULL)
c2f47e15 11031 return NULL_TREE;
4ee9c684 11032
11033 p1 = c_getstr (s1);
11034 if (p1 != NULL)
11035 {
11036 const char *r = strstr (p1, p2);
daa1d5f5 11037 tree tem;
4ee9c684 11038
4ee9c684 11039 if (r == NULL)
779b4c41 11040 return build_int_cst (TREE_TYPE (s1), 0);
c0c67e38 11041
11042 /* Return an offset into the constant string argument. */
0de36bdb 11043 tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
11044 s1, size_int (r - p1));
daa1d5f5 11045 return fold_convert (type, tem);
4ee9c684 11046 }
11047
7efa231c 11048 /* The argument is const char *, and the result is char *, so we need
11049 a type conversion here to avoid a warning. */
4ee9c684 11050 if (p2[0] == '\0')
7efa231c 11051 return fold_convert (type, s1);
4ee9c684 11052
11053 if (p2[1] != '\0')
c2f47e15 11054 return NULL_TREE;
4ee9c684 11055
11056 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11057 if (!fn)
c2f47e15 11058 return NULL_TREE;
4ee9c684 11059
11060 /* New argument list transforming strstr(s1, s2) to
11061 strchr(s1, s2[0]). */
c2f47e15 11062 return build_call_expr (fn, 2, s1, build_int_cst (NULL_TREE, p2[0]));
4ee9c684 11063 }
11064}
11065
c2f47e15 11066/* Simplify a call to the strchr builtin. S1 and S2 are the arguments to
11067 the call, and TYPE is its return type.
4ee9c684 11068
c2f47e15 11069 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11070 simplified form of the call as a tree.
11071
11072 The simplified form may be a constant or other expression which
11073 computes the same value, but in a more efficient manner (including
11074 calls to other builtin functions).
11075
11076 The call may contain arguments which need to be evaluated, but
11077 which are not useful to determine the result of the call. In
11078 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11079 COMPOUND_EXPR will be an argument which must be evaluated.
11080 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11081 COMPOUND_EXPR in the chain will contain the tree for the simplified
11082 form of the builtin function call. */
11083
11084static tree
c2f47e15 11085fold_builtin_strchr (tree s1, tree s2, tree type)
4ee9c684 11086{
c2f47e15 11087 if (!validate_arg (s1, POINTER_TYPE)
11088 || !validate_arg (s2, INTEGER_TYPE))
11089 return NULL_TREE;
4ee9c684 11090 else
11091 {
4ee9c684 11092 const char *p1;
11093
11094 if (TREE_CODE (s2) != INTEGER_CST)
c2f47e15 11095 return NULL_TREE;
4ee9c684 11096
11097 p1 = c_getstr (s1);
11098 if (p1 != NULL)
11099 {
11100 char c;
11101 const char *r;
daa1d5f5 11102 tree tem;
4ee9c684 11103
11104 if (target_char_cast (s2, &c))
c2f47e15 11105 return NULL_TREE;
4ee9c684 11106
11107 r = strchr (p1, c);
11108
11109 if (r == NULL)
779b4c41 11110 return build_int_cst (TREE_TYPE (s1), 0);
4ee9c684 11111
11112 /* Return an offset into the constant string argument. */
0de36bdb 11113 tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
11114 s1, size_int (r - p1));
daa1d5f5 11115 return fold_convert (type, tem);
4ee9c684 11116 }
c2f47e15 11117 return NULL_TREE;
4ee9c684 11118 }
11119}
11120
c2f47e15 11121/* Simplify a call to the strrchr builtin. S1 and S2 are the arguments to
11122 the call, and TYPE is its return type.
4ee9c684 11123
c2f47e15 11124 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11125 simplified form of the call as a tree.
11126
11127 The simplified form may be a constant or other expression which
11128 computes the same value, but in a more efficient manner (including
11129 calls to other builtin functions).
11130
11131 The call may contain arguments which need to be evaluated, but
11132 which are not useful to determine the result of the call. In
11133 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11134 COMPOUND_EXPR will be an argument which must be evaluated.
11135 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11136 COMPOUND_EXPR in the chain will contain the tree for the simplified
11137 form of the builtin function call. */
11138
11139static tree
c2f47e15 11140fold_builtin_strrchr (tree s1, tree s2, tree type)
4ee9c684 11141{
c2f47e15 11142 if (!validate_arg (s1, POINTER_TYPE)
11143 || !validate_arg (s2, INTEGER_TYPE))
11144 return NULL_TREE;
4ee9c684 11145 else
11146 {
4ee9c684 11147 tree fn;
11148 const char *p1;
11149
11150 if (TREE_CODE (s2) != INTEGER_CST)
c2f47e15 11151 return NULL_TREE;
4ee9c684 11152
11153 p1 = c_getstr (s1);
11154 if (p1 != NULL)
11155 {
11156 char c;
11157 const char *r;
daa1d5f5 11158 tree tem;
4ee9c684 11159
11160 if (target_char_cast (s2, &c))
c2f47e15 11161 return NULL_TREE;
4ee9c684 11162
11163 r = strrchr (p1, c);
11164
11165 if (r == NULL)
779b4c41 11166 return build_int_cst (TREE_TYPE (s1), 0);
4ee9c684 11167
11168 /* Return an offset into the constant string argument. */
0de36bdb 11169 tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
11170 s1, size_int (r - p1));
daa1d5f5 11171 return fold_convert (type, tem);
4ee9c684 11172 }
11173
11174 if (! integer_zerop (s2))
c2f47e15 11175 return NULL_TREE;
4ee9c684 11176
11177 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11178 if (!fn)
c2f47e15 11179 return NULL_TREE;
4ee9c684 11180
11181 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
c2f47e15 11182 return build_call_expr (fn, 2, s1, s2);
4ee9c684 11183 }
11184}
11185
c2f47e15 11186/* Simplify a call to the strpbrk builtin. S1 and S2 are the arguments
11187 to the call, and TYPE is its return type.
4ee9c684 11188
c2f47e15 11189 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11190 simplified form of the call as a tree.
11191
11192 The simplified form may be a constant or other expression which
11193 computes the same value, but in a more efficient manner (including
11194 calls to other builtin functions).
11195
11196 The call may contain arguments which need to be evaluated, but
11197 which are not useful to determine the result of the call. In
11198 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11199 COMPOUND_EXPR will be an argument which must be evaluated.
11200 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11201 COMPOUND_EXPR in the chain will contain the tree for the simplified
11202 form of the builtin function call. */
11203
11204static tree
c2f47e15 11205fold_builtin_strpbrk (tree s1, tree s2, tree type)
4ee9c684 11206{
c2f47e15 11207 if (!validate_arg (s1, POINTER_TYPE)
11208 || !validate_arg (s2, POINTER_TYPE))
11209 return NULL_TREE;
4ee9c684 11210 else
11211 {
4ee9c684 11212 tree fn;
11213 const char *p1, *p2;
11214
11215 p2 = c_getstr (s2);
11216 if (p2 == NULL)
c2f47e15 11217 return NULL_TREE;
4ee9c684 11218
11219 p1 = c_getstr (s1);
11220 if (p1 != NULL)
11221 {
11222 const char *r = strpbrk (p1, p2);
daa1d5f5 11223 tree tem;
4ee9c684 11224
11225 if (r == NULL)
779b4c41 11226 return build_int_cst (TREE_TYPE (s1), 0);
4ee9c684 11227
11228 /* Return an offset into the constant string argument. */
0de36bdb 11229 tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
11230 s1, size_int (r - p1));
daa1d5f5 11231 return fold_convert (type, tem);
4ee9c684 11232 }
11233
11234 if (p2[0] == '\0')
05abc81b 11235 /* strpbrk(x, "") == NULL.
11236 Evaluate and ignore s1 in case it had side-effects. */
11237 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
4ee9c684 11238
11239 if (p2[1] != '\0')
c2f47e15 11240 return NULL_TREE; /* Really call strpbrk. */
4ee9c684 11241
11242 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11243 if (!fn)
c2f47e15 11244 return NULL_TREE;
4ee9c684 11245
11246 /* New argument list transforming strpbrk(s1, s2) to
11247 strchr(s1, s2[0]). */
c2f47e15 11248 return build_call_expr (fn, 2, s1, build_int_cst (NULL_TREE, p2[0]));
4ee9c684 11249 }
11250}
11251
c2f47e15 11252/* Simplify a call to the strcat builtin. DST and SRC are the arguments
11253 to the call.
4ee9c684 11254
c2f47e15 11255 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11256 simplified form of the call as a tree.
11257
11258 The simplified form may be a constant or other expression which
11259 computes the same value, but in a more efficient manner (including
11260 calls to other builtin functions).
11261
11262 The call may contain arguments which need to be evaluated, but
11263 which are not useful to determine the result of the call. In
11264 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11265 COMPOUND_EXPR will be an argument which must be evaluated.
11266 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11267 COMPOUND_EXPR in the chain will contain the tree for the simplified
11268 form of the builtin function call. */
11269
11270static tree
c2f47e15 11271fold_builtin_strcat (tree dst, tree src)
4ee9c684 11272{
c2f47e15 11273 if (!validate_arg (dst, POINTER_TYPE)
11274 || !validate_arg (src, POINTER_TYPE))
11275 return NULL_TREE;
4ee9c684 11276 else
11277 {
4ee9c684 11278 const char *p = c_getstr (src);
11279
11280 /* If the string length is zero, return the dst parameter. */
11281 if (p && *p == '\0')
11282 return dst;
11283
c2f47e15 11284 return NULL_TREE;
4ee9c684 11285 }
11286}
11287
c2f47e15 11288/* Simplify a call to the strncat builtin. DST, SRC, and LEN are the
11289 arguments to the call.
4ee9c684 11290
c2f47e15 11291 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11292 simplified form of the call as a tree.
11293
11294 The simplified form may be a constant or other expression which
11295 computes the same value, but in a more efficient manner (including
11296 calls to other builtin functions).
11297
11298 The call may contain arguments which need to be evaluated, but
11299 which are not useful to determine the result of the call. In
11300 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11301 COMPOUND_EXPR will be an argument which must be evaluated.
11302 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11303 COMPOUND_EXPR in the chain will contain the tree for the simplified
11304 form of the builtin function call. */
11305
11306static tree
c2f47e15 11307fold_builtin_strncat (tree dst, tree src, tree len)
4ee9c684 11308{
c2f47e15 11309 if (!validate_arg (dst, POINTER_TYPE)
11310 || !validate_arg (src, POINTER_TYPE)
11311 || !validate_arg (len, INTEGER_TYPE))
11312 return NULL_TREE;
4ee9c684 11313 else
11314 {
4ee9c684 11315 const char *p = c_getstr (src);
11316
11317 /* If the requested length is zero, or the src parameter string
0a39fd54 11318 length is zero, return the dst parameter. */
4ee9c684 11319 if (integer_zerop (len) || (p && *p == '\0'))
a0c938f0 11320 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
4ee9c684 11321
11322 /* If the requested len is greater than or equal to the string
a0c938f0 11323 length, call strcat. */
4ee9c684 11324 if (TREE_CODE (len) == INTEGER_CST && p
11325 && compare_tree_int (len, strlen (p)) >= 0)
11326 {
4ee9c684 11327 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
11328
11329 /* If the replacement _DECL isn't initialized, don't do the
11330 transformation. */
11331 if (!fn)
c2f47e15 11332 return NULL_TREE;
4ee9c684 11333
c2f47e15 11334 return build_call_expr (fn, 2, dst, src);
4ee9c684 11335 }
c2f47e15 11336 return NULL_TREE;
4ee9c684 11337 }
11338}
11339
c2f47e15 11340/* Simplify a call to the strspn builtin. S1 and S2 are the arguments
11341 to the call.
4ee9c684 11342
c2f47e15 11343 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11344 simplified form of the call as a tree.
11345
11346 The simplified form may be a constant or other expression which
11347 computes the same value, but in a more efficient manner (including
11348 calls to other builtin functions).
11349
11350 The call may contain arguments which need to be evaluated, but
11351 which are not useful to determine the result of the call. In
11352 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11353 COMPOUND_EXPR will be an argument which must be evaluated.
11354 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11355 COMPOUND_EXPR in the chain will contain the tree for the simplified
11356 form of the builtin function call. */
11357
11358static tree
c2f47e15 11359fold_builtin_strspn (tree s1, tree s2)
4ee9c684 11360{
c2f47e15 11361 if (!validate_arg (s1, POINTER_TYPE)
11362 || !validate_arg (s2, POINTER_TYPE))
11363 return NULL_TREE;
4ee9c684 11364 else
11365 {
4ee9c684 11366 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11367
11368 /* If both arguments are constants, evaluate at compile-time. */
11369 if (p1 && p2)
11370 {
11371 const size_t r = strspn (p1, p2);
11372 return size_int (r);
11373 }
11374
c2f47e15 11375 /* If either argument is "", return NULL_TREE. */
4ee9c684 11376 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9bc9f15f 11377 /* Evaluate and ignore both arguments in case either one has
11378 side-effects. */
11379 return omit_two_operands (integer_type_node, integer_zero_node,
11380 s1, s2);
c2f47e15 11381 return NULL_TREE;
4ee9c684 11382 }
11383}
11384
c2f47e15 11385/* Simplify a call to the strcspn builtin. S1 and S2 are the arguments
11386 to the call.
4ee9c684 11387
c2f47e15 11388 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11389 simplified form of the call as a tree.
11390
11391 The simplified form may be a constant or other expression which
11392 computes the same value, but in a more efficient manner (including
11393 calls to other builtin functions).
11394
11395 The call may contain arguments which need to be evaluated, but
11396 which are not useful to determine the result of the call. In
11397 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11398 COMPOUND_EXPR will be an argument which must be evaluated.
11399 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11400 COMPOUND_EXPR in the chain will contain the tree for the simplified
11401 form of the builtin function call. */
11402
11403static tree
c2f47e15 11404fold_builtin_strcspn (tree s1, tree s2)
4ee9c684 11405{
c2f47e15 11406 if (!validate_arg (s1, POINTER_TYPE)
11407 || !validate_arg (s2, POINTER_TYPE))
11408 return NULL_TREE;
4ee9c684 11409 else
11410 {
4ee9c684 11411 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11412
11413 /* If both arguments are constants, evaluate at compile-time. */
11414 if (p1 && p2)
11415 {
11416 const size_t r = strcspn (p1, p2);
11417 return size_int (r);
11418 }
11419
c2f47e15 11420 /* If the first argument is "", return NULL_TREE. */
4ee9c684 11421 if (p1 && *p1 == '\0')
11422 {
11423 /* Evaluate and ignore argument s2 in case it has
11424 side-effects. */
05abc81b 11425 return omit_one_operand (integer_type_node,
11426 integer_zero_node, s2);
4ee9c684 11427 }
11428
11429 /* If the second argument is "", return __builtin_strlen(s1). */
11430 if (p2 && *p2 == '\0')
11431 {
c2f47e15 11432 tree fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4ee9c684 11433
11434 /* If the replacement _DECL isn't initialized, don't do the
11435 transformation. */
11436 if (!fn)
c2f47e15 11437 return NULL_TREE;
4ee9c684 11438
c2f47e15 11439 return build_call_expr (fn, 1, s1);
4ee9c684 11440 }
c2f47e15 11441 return NULL_TREE;
4ee9c684 11442 }
11443}
11444
c2f47e15 11445/* Fold a call to the fputs builtin. ARG0 and ARG1 are the arguments
11446 to the call. IGNORE is true if the value returned
f0613857 11447 by the builtin will be ignored. UNLOCKED is true is true if this
11448 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
11449 the known length of the string. Return NULL_TREE if no simplification
11450 was possible. */
4ee9c684 11451
11452tree
c2f47e15 11453fold_builtin_fputs (tree arg0, tree arg1, bool ignore, bool unlocked, tree len)
4ee9c684 11454{
6d77ed92 11455 /* If we're using an unlocked function, assume the other unlocked
11456 functions exist explicitly. */
11457 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4ee9c684 11458 : implicit_built_in_decls[BUILT_IN_FPUTC];
6d77ed92 11459 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4ee9c684 11460 : implicit_built_in_decls[BUILT_IN_FWRITE];
11461
c403edd4 11462 /* If the return value is used, don't do the transformation. */
11463 if (!ignore)
c2f47e15 11464 return NULL_TREE;
4ee9c684 11465
11466 /* Verify the arguments in the original call. */
c2f47e15 11467 if (!validate_arg (arg0, POINTER_TYPE)
11468 || !validate_arg (arg1, POINTER_TYPE))
11469 return NULL_TREE;
4ee9c684 11470
f0613857 11471 if (! len)
c2f47e15 11472 len = c_strlen (arg0, 0);
4ee9c684 11473
11474 /* Get the length of the string passed to fputs. If the length
11475 can't be determined, punt. */
11476 if (!len
11477 || TREE_CODE (len) != INTEGER_CST)
c2f47e15 11478 return NULL_TREE;
4ee9c684 11479
11480 switch (compare_tree_int (len, 1))
11481 {
11482 case -1: /* length is 0, delete the call entirely . */
c2f47e15 11483 return omit_one_operand (integer_type_node, integer_zero_node, arg1);;
05abc81b 11484
4ee9c684 11485 case 0: /* length is 1, call fputc. */
11486 {
c2f47e15 11487 const char *p = c_getstr (arg0);
4ee9c684 11488
11489 if (p != NULL)
11490 {
c2f47e15 11491 if (fn_fputc)
11492 return build_call_expr (fn_fputc, 2,
11493 build_int_cst (NULL_TREE, p[0]), arg1);
11494 else
11495 return NULL_TREE;
4ee9c684 11496 }
11497 }
11498 /* FALLTHROUGH */
11499 case 1: /* length is greater than 1, call fwrite. */
11500 {
0bed3869 11501 /* If optimizing for size keep fputs. */
4ee9c684 11502 if (optimize_size)
c2f47e15 11503 return NULL_TREE;
4ee9c684 11504 /* New argument list transforming fputs(string, stream) to
11505 fwrite(string, 1, len, stream). */
c2f47e15 11506 if (fn_fwrite)
11507 return build_call_expr (fn_fwrite, 4, arg0, size_one_node, len, arg1);
11508 else
11509 return NULL_TREE;
4ee9c684 11510 }
11511 default:
64db345d 11512 gcc_unreachable ();
4ee9c684 11513 }
c2f47e15 11514 return NULL_TREE;
4ee9c684 11515}
11516
c2f47e15 11517/* Fold the next_arg or va_start call EXP. Returns true if there was an error
743b0c6a 11518 produced. False otherwise. This is done so that we don't output the error
11519 or warning twice or three times. */
75a70cf9 11520
743b0c6a 11521bool
c2f47e15 11522fold_builtin_next_arg (tree exp, bool va_start_p)
4ee9c684 11523{
11524 tree fntype = TREE_TYPE (current_function_decl);
c2f47e15 11525 int nargs = call_expr_nargs (exp);
11526 tree arg;
4ee9c684 11527
11528 if (TYPE_ARG_TYPES (fntype) == 0
11529 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
11530 == void_type_node))
743b0c6a 11531 {
11532 error ("%<va_start%> used in function with fixed args");
11533 return true;
11534 }
c2f47e15 11535
11536 if (va_start_p)
79012a9d 11537 {
c2f47e15 11538 if (va_start_p && (nargs != 2))
11539 {
11540 error ("wrong number of arguments to function %<va_start%>");
11541 return true;
11542 }
11543 arg = CALL_EXPR_ARG (exp, 1);
79012a9d 11544 }
11545 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
11546 when we checked the arguments and if needed issued a warning. */
c2f47e15 11547 else
4ee9c684 11548 {
c2f47e15 11549 if (nargs == 0)
11550 {
11551 /* Evidently an out of date version of <stdarg.h>; can't validate
11552 va_start's second argument, but can still work as intended. */
11553 warning (0, "%<__builtin_next_arg%> called without an argument");
11554 return true;
11555 }
11556 else if (nargs > 1)
a0c938f0 11557 {
c2f47e15 11558 error ("wrong number of arguments to function %<__builtin_next_arg%>");
a0c938f0 11559 return true;
11560 }
c2f47e15 11561 arg = CALL_EXPR_ARG (exp, 0);
11562 }
11563
11564 /* We destructively modify the call to be __builtin_va_start (ap, 0)
11565 or __builtin_next_arg (0) the first time we see it, after checking
11566 the arguments and if needed issuing a warning. */
11567 if (!integer_zerop (arg))
11568 {
11569 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
79012a9d 11570
4ee9c684 11571 /* Strip off all nops for the sake of the comparison. This
11572 is not quite the same as STRIP_NOPS. It does more.
11573 We must also strip off INDIRECT_EXPR for C++ reference
11574 parameters. */
72dd6141 11575 while (CONVERT_EXPR_P (arg)
4ee9c684 11576 || TREE_CODE (arg) == INDIRECT_REF)
11577 arg = TREE_OPERAND (arg, 0);
11578 if (arg != last_parm)
a0c938f0 11579 {
b08cf617 11580 /* FIXME: Sometimes with the tree optimizers we can get the
11581 not the last argument even though the user used the last
11582 argument. We just warn and set the arg to be the last
11583 argument so that we will get wrong-code because of
11584 it. */
c3ceba8e 11585 warning (0, "second parameter of %<va_start%> not last named argument");
743b0c6a 11586 }
79012a9d 11587 /* We want to verify the second parameter just once before the tree
a0c938f0 11588 optimizers are run and then avoid keeping it in the tree,
11589 as otherwise we could warn even for correct code like:
11590 void foo (int i, ...)
11591 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
c2f47e15 11592 if (va_start_p)
11593 CALL_EXPR_ARG (exp, 1) = integer_zero_node;
11594 else
11595 CALL_EXPR_ARG (exp, 0) = integer_zero_node;
743b0c6a 11596 }
11597 return false;
4ee9c684 11598}
11599
11600
c2f47e15 11601/* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG.
11602 ORIG may be null if this is a 2-argument call. We don't attempt to
11603 simplify calls with more than 3 arguments.
4ee9c684 11604
c2f47e15 11605 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11606 simplified form of the call as a tree. If IGNORED is true, it means that
11607 the caller does not use the returned value of the function. */
11608
11609static tree
c2f47e15 11610fold_builtin_sprintf (tree dest, tree fmt, tree orig, int ignored)
4ee9c684 11611{
c2f47e15 11612 tree call, retval;
4ee9c684 11613 const char *fmt_str = NULL;
11614
11615 /* Verify the required arguments in the original call. We deal with two
11616 types of sprintf() calls: 'sprintf (str, fmt)' and
11617 'sprintf (dest, "%s", orig)'. */
c2f47e15 11618 if (!validate_arg (dest, POINTER_TYPE)
11619 || !validate_arg (fmt, POINTER_TYPE))
11620 return NULL_TREE;
11621 if (orig && !validate_arg (orig, POINTER_TYPE))
4ee9c684 11622 return NULL_TREE;
4ee9c684 11623
11624 /* Check whether the format is a literal string constant. */
11625 fmt_str = c_getstr (fmt);
11626 if (fmt_str == NULL)
11627 return NULL_TREE;
11628
11629 call = NULL_TREE;
11630 retval = NULL_TREE;
11631
d4473c84 11632 if (!init_target_chars ())
c2f47e15 11633 return NULL_TREE;
99eabcc1 11634
4ee9c684 11635 /* If the format doesn't contain % args or %%, use strcpy. */
99eabcc1 11636 if (strchr (fmt_str, target_percent) == NULL)
4ee9c684 11637 {
11638 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
11639
11640 if (!fn)
11641 return NULL_TREE;
11642
72dfb3f2 11643 /* Don't optimize sprintf (buf, "abc", ptr++). */
c2f47e15 11644 if (orig)
72dfb3f2 11645 return NULL_TREE;
11646
4ee9c684 11647 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
11648 'format' is known to contain no % formats. */
c2f47e15 11649 call = build_call_expr (fn, 2, dest, fmt);
4ee9c684 11650 if (!ignored)
7016c612 11651 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
4ee9c684 11652 }
11653
11654 /* If the format is "%s", use strcpy if the result isn't used. */
99eabcc1 11655 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
4ee9c684 11656 {
c2f47e15 11657 tree fn;
4ee9c684 11658 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
11659
11660 if (!fn)
11661 return NULL_TREE;
11662
72dfb3f2 11663 /* Don't crash on sprintf (str1, "%s"). */
c2f47e15 11664 if (!orig)
72dfb3f2 11665 return NULL_TREE;
11666
4ee9c684 11667 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
4ee9c684 11668 if (!ignored)
11669 {
11670 retval = c_strlen (orig, 1);
11671 if (!retval || TREE_CODE (retval) != INTEGER_CST)
11672 return NULL_TREE;
11673 }
c2f47e15 11674 call = build_call_expr (fn, 2, dest, orig);
4ee9c684 11675 }
11676
11677 if (call && retval)
11678 {
e3b560a6 11679 retval = fold_convert
4ee9c684 11680 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
11681 retval);
05abc81b 11682 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
4ee9c684 11683 }
11684 else
11685 return call;
11686}
0a39fd54 11687
c2f47e15 11688/* Expand a call EXP to __builtin_object_size. */
0a39fd54 11689
11690rtx
11691expand_builtin_object_size (tree exp)
11692{
11693 tree ost;
11694 int object_size_type;
11695 tree fndecl = get_callee_fndecl (exp);
0a39fd54 11696
c2f47e15 11697 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
0a39fd54 11698 {
b8c23db3 11699 error ("%Kfirst argument of %D must be a pointer, second integer constant",
11700 exp, fndecl);
0a39fd54 11701 expand_builtin_trap ();
11702 return const0_rtx;
11703 }
11704
c2f47e15 11705 ost = CALL_EXPR_ARG (exp, 1);
0a39fd54 11706 STRIP_NOPS (ost);
11707
11708 if (TREE_CODE (ost) != INTEGER_CST
11709 || tree_int_cst_sgn (ost) < 0
11710 || compare_tree_int (ost, 3) > 0)
11711 {
b8c23db3 11712 error ("%Klast argument of %D is not integer constant between 0 and 3",
11713 exp, fndecl);
0a39fd54 11714 expand_builtin_trap ();
11715 return const0_rtx;
11716 }
11717
11718 object_size_type = tree_low_cst (ost, 0);
11719
11720 return object_size_type < 2 ? constm1_rtx : const0_rtx;
11721}
11722
11723/* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
11724 FCODE is the BUILT_IN_* to use.
c2f47e15 11725 Return NULL_RTX if we failed; the caller should emit a normal call,
0a39fd54 11726 otherwise try to get the result in TARGET, if convenient (and in
11727 mode MODE if that's convenient). */
11728
11729static rtx
11730expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
11731 enum built_in_function fcode)
11732{
0a39fd54 11733 tree dest, src, len, size;
11734
c2f47e15 11735 if (!validate_arglist (exp,
0a39fd54 11736 POINTER_TYPE,
11737 fcode == BUILT_IN_MEMSET_CHK
11738 ? INTEGER_TYPE : POINTER_TYPE,
11739 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
c2f47e15 11740 return NULL_RTX;
0a39fd54 11741
c2f47e15 11742 dest = CALL_EXPR_ARG (exp, 0);
11743 src = CALL_EXPR_ARG (exp, 1);
11744 len = CALL_EXPR_ARG (exp, 2);
11745 size = CALL_EXPR_ARG (exp, 3);
0a39fd54 11746
11747 if (! host_integerp (size, 1))
c2f47e15 11748 return NULL_RTX;
0a39fd54 11749
11750 if (host_integerp (len, 1) || integer_all_onesp (size))
11751 {
11752 tree fn;
11753
11754 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
11755 {
b8c23db3 11756 warning (0, "%Kcall to %D will always overflow destination buffer",
11757 exp, get_callee_fndecl (exp));
c2f47e15 11758 return NULL_RTX;
0a39fd54 11759 }
11760
0a39fd54 11761 fn = NULL_TREE;
11762 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
11763 mem{cpy,pcpy,move,set} is available. */
11764 switch (fcode)
11765 {
11766 case BUILT_IN_MEMCPY_CHK:
11767 fn = built_in_decls[BUILT_IN_MEMCPY];
11768 break;
11769 case BUILT_IN_MEMPCPY_CHK:
11770 fn = built_in_decls[BUILT_IN_MEMPCPY];
11771 break;
11772 case BUILT_IN_MEMMOVE_CHK:
11773 fn = built_in_decls[BUILT_IN_MEMMOVE];
11774 break;
11775 case BUILT_IN_MEMSET_CHK:
11776 fn = built_in_decls[BUILT_IN_MEMSET];
11777 break;
11778 default:
11779 break;
11780 }
11781
11782 if (! fn)
c2f47e15 11783 return NULL_RTX;
0a39fd54 11784
c2f47e15 11785 fn = build_call_expr (fn, 3, dest, src, len);
6d54e886 11786 STRIP_TYPE_NOPS (fn);
11787 while (TREE_CODE (fn) == COMPOUND_EXPR)
11788 {
11789 expand_expr (TREE_OPERAND (fn, 0), const0_rtx, VOIDmode,
11790 EXPAND_NORMAL);
11791 fn = TREE_OPERAND (fn, 1);
11792 }
0a39fd54 11793 if (TREE_CODE (fn) == CALL_EXPR)
11794 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
11795 return expand_expr (fn, target, mode, EXPAND_NORMAL);
11796 }
11797 else if (fcode == BUILT_IN_MEMSET_CHK)
c2f47e15 11798 return NULL_RTX;
0a39fd54 11799 else
11800 {
11801 unsigned int dest_align
11802 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
11803
11804 /* If DEST is not a pointer type, call the normal function. */
11805 if (dest_align == 0)
c2f47e15 11806 return NULL_RTX;
0a39fd54 11807
11808 /* If SRC and DEST are the same (and not volatile), do nothing. */
11809 if (operand_equal_p (src, dest, 0))
11810 {
11811 tree expr;
11812
11813 if (fcode != BUILT_IN_MEMPCPY_CHK)
11814 {
11815 /* Evaluate and ignore LEN in case it has side-effects. */
11816 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
11817 return expand_expr (dest, target, mode, EXPAND_NORMAL);
11818 }
11819
0de36bdb 11820 expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
0a39fd54 11821 return expand_expr (expr, target, mode, EXPAND_NORMAL);
11822 }
11823
11824 /* __memmove_chk special case. */
11825 if (fcode == BUILT_IN_MEMMOVE_CHK)
11826 {
11827 unsigned int src_align
11828 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
11829
11830 if (src_align == 0)
c2f47e15 11831 return NULL_RTX;
0a39fd54 11832
11833 /* If src is categorized for a readonly section we can use
11834 normal __memcpy_chk. */
11835 if (readonly_data_expr (src))
11836 {
11837 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
11838 if (!fn)
c2f47e15 11839 return NULL_RTX;
11840 fn = build_call_expr (fn, 4, dest, src, len, size);
6d54e886 11841 STRIP_TYPE_NOPS (fn);
11842 while (TREE_CODE (fn) == COMPOUND_EXPR)
11843 {
11844 expand_expr (TREE_OPERAND (fn, 0), const0_rtx, VOIDmode,
11845 EXPAND_NORMAL);
11846 fn = TREE_OPERAND (fn, 1);
11847 }
0a39fd54 11848 if (TREE_CODE (fn) == CALL_EXPR)
11849 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
11850 return expand_expr (fn, target, mode, EXPAND_NORMAL);
11851 }
11852 }
c2f47e15 11853 return NULL_RTX;
0a39fd54 11854 }
11855}
11856
11857/* Emit warning if a buffer overflow is detected at compile time. */
11858
11859static void
11860maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
11861{
c2f47e15 11862 int is_strlen = 0;
0a39fd54 11863 tree len, size;
0a39fd54 11864
11865 switch (fcode)
11866 {
11867 case BUILT_IN_STRCPY_CHK:
11868 case BUILT_IN_STPCPY_CHK:
11869 /* For __strcat_chk the warning will be emitted only if overflowing
11870 by at least strlen (dest) + 1 bytes. */
11871 case BUILT_IN_STRCAT_CHK:
c2f47e15 11872 len = CALL_EXPR_ARG (exp, 1);
11873 size = CALL_EXPR_ARG (exp, 2);
0a39fd54 11874 is_strlen = 1;
11875 break;
b356dfef 11876 case BUILT_IN_STRNCAT_CHK:
0a39fd54 11877 case BUILT_IN_STRNCPY_CHK:
c2f47e15 11878 len = CALL_EXPR_ARG (exp, 2);
11879 size = CALL_EXPR_ARG (exp, 3);
0a39fd54 11880 break;
11881 case BUILT_IN_SNPRINTF_CHK:
11882 case BUILT_IN_VSNPRINTF_CHK:
c2f47e15 11883 len = CALL_EXPR_ARG (exp, 1);
11884 size = CALL_EXPR_ARG (exp, 3);
0a39fd54 11885 break;
11886 default:
11887 gcc_unreachable ();
11888 }
11889
0a39fd54 11890 if (!len || !size)
11891 return;
11892
0a39fd54 11893 if (! host_integerp (size, 1) || integer_all_onesp (size))
11894 return;
11895
11896 if (is_strlen)
11897 {
11898 len = c_strlen (len, 1);
11899 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
11900 return;
11901 }
b356dfef 11902 else if (fcode == BUILT_IN_STRNCAT_CHK)
11903 {
c2f47e15 11904 tree src = CALL_EXPR_ARG (exp, 1);
b356dfef 11905 if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
11906 return;
11907 src = c_strlen (src, 1);
11908 if (! src || ! host_integerp (src, 1))
11909 {
b8c23db3 11910 warning (0, "%Kcall to %D might overflow destination buffer",
11911 exp, get_callee_fndecl (exp));
b356dfef 11912 return;
11913 }
11914 else if (tree_int_cst_lt (src, size))
11915 return;
11916 }
0a39fd54 11917 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
11918 return;
11919
b8c23db3 11920 warning (0, "%Kcall to %D will always overflow destination buffer",
11921 exp, get_callee_fndecl (exp));
0a39fd54 11922}
11923
11924/* Emit warning if a buffer overflow is detected at compile time
11925 in __sprintf_chk/__vsprintf_chk calls. */
11926
11927static void
11928maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
11929{
0a39fd54 11930 tree dest, size, len, fmt, flag;
11931 const char *fmt_str;
c2f47e15 11932 int nargs = call_expr_nargs (exp);
0a39fd54 11933
11934 /* Verify the required arguments in the original call. */
c2f47e15 11935
11936 if (nargs < 4)
0a39fd54 11937 return;
c2f47e15 11938 dest = CALL_EXPR_ARG (exp, 0);
11939 flag = CALL_EXPR_ARG (exp, 1);
11940 size = CALL_EXPR_ARG (exp, 2);
11941 fmt = CALL_EXPR_ARG (exp, 3);
0a39fd54 11942
11943 if (! host_integerp (size, 1) || integer_all_onesp (size))
11944 return;
11945
11946 /* Check whether the format is a literal string constant. */
11947 fmt_str = c_getstr (fmt);
11948 if (fmt_str == NULL)
11949 return;
11950
d4473c84 11951 if (!init_target_chars ())
99eabcc1 11952 return;
11953
0a39fd54 11954 /* If the format doesn't contain % args or %%, we know its size. */
99eabcc1 11955 if (strchr (fmt_str, target_percent) == 0)
0a39fd54 11956 len = build_int_cstu (size_type_node, strlen (fmt_str));
11957 /* If the format is "%s" and first ... argument is a string literal,
11958 we know it too. */
c2f47e15 11959 else if (fcode == BUILT_IN_SPRINTF_CHK
11960 && strcmp (fmt_str, target_percent_s) == 0)
0a39fd54 11961 {
11962 tree arg;
11963
c2f47e15 11964 if (nargs < 5)
0a39fd54 11965 return;
c2f47e15 11966 arg = CALL_EXPR_ARG (exp, 4);
0a39fd54 11967 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
11968 return;
11969
11970 len = c_strlen (arg, 1);
11971 if (!len || ! host_integerp (len, 1))
11972 return;
11973 }
11974 else
11975 return;
11976
11977 if (! tree_int_cst_lt (len, size))
11978 {
b8c23db3 11979 warning (0, "%Kcall to %D will always overflow destination buffer",
11980 exp, get_callee_fndecl (exp));
0a39fd54 11981 }
11982}
11983
c2f47e15 11984/* Fold a call to __builtin_object_size with arguments PTR and OST,
11985 if possible. */
0a39fd54 11986
11987tree
c2f47e15 11988fold_builtin_object_size (tree ptr, tree ost)
0a39fd54 11989{
c2f47e15 11990 tree ret = NULL_TREE;
0a39fd54 11991 int object_size_type;
11992
c2f47e15 11993 if (!validate_arg (ptr, POINTER_TYPE)
11994 || !validate_arg (ost, INTEGER_TYPE))
11995 return NULL_TREE;
0a39fd54 11996
0a39fd54 11997 STRIP_NOPS (ost);
11998
11999 if (TREE_CODE (ost) != INTEGER_CST
12000 || tree_int_cst_sgn (ost) < 0
12001 || compare_tree_int (ost, 3) > 0)
c2f47e15 12002 return NULL_TREE;
0a39fd54 12003
12004 object_size_type = tree_low_cst (ost, 0);
12005
12006 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
12007 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
12008 and (size_t) 0 for types 2 and 3. */
12009 if (TREE_SIDE_EFFECTS (ptr))
697bbc3f 12010 return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0);
0a39fd54 12011
12012 if (TREE_CODE (ptr) == ADDR_EXPR)
12013 ret = build_int_cstu (size_type_node,
697bbc3f 12014 compute_builtin_object_size (ptr, object_size_type));
0a39fd54 12015
12016 else if (TREE_CODE (ptr) == SSA_NAME)
12017 {
12018 unsigned HOST_WIDE_INT bytes;
12019
12020 /* If object size is not known yet, delay folding until
12021 later. Maybe subsequent passes will help determining
12022 it. */
12023 bytes = compute_builtin_object_size (ptr, object_size_type);
12024 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
12025 ? -1 : 0))
12026 ret = build_int_cstu (size_type_node, bytes);
12027 }
12028
12029 if (ret)
12030 {
697bbc3f 12031 unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (ret);
12032 HOST_WIDE_INT high = TREE_INT_CST_HIGH (ret);
12033 if (fit_double_type (low, high, &low, &high, TREE_TYPE (ret)))
12034 ret = NULL_TREE;
0a39fd54 12035 }
12036
12037 return ret;
12038}
12039
12040/* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
c2f47e15 12041 DEST, SRC, LEN, and SIZE are the arguments to the call.
0a39fd54 12042 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
12043 code of the builtin. If MAXLEN is not NULL, it is maximum length
12044 passed as third argument. */
12045
12046tree
c2f47e15 12047fold_builtin_memory_chk (tree fndecl,
12048 tree dest, tree src, tree len, tree size,
12049 tree maxlen, bool ignore,
0a39fd54 12050 enum built_in_function fcode)
12051{
c2f47e15 12052 tree fn;
0a39fd54 12053
c2f47e15 12054 if (!validate_arg (dest, POINTER_TYPE)
12055 || !validate_arg (src,
12056 (fcode == BUILT_IN_MEMSET_CHK
12057 ? INTEGER_TYPE : POINTER_TYPE))
12058 || !validate_arg (len, INTEGER_TYPE)
12059 || !validate_arg (size, INTEGER_TYPE))
12060 return NULL_TREE;
0a39fd54 12061
12062 /* If SRC and DEST are the same (and not volatile), return DEST
12063 (resp. DEST+LEN for __mempcpy_chk). */
12064 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
12065 {
12066 if (fcode != BUILT_IN_MEMPCPY_CHK)
12067 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
12068 else
12069 {
0de36bdb 12070 tree temp = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
0a39fd54 12071 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
12072 }
12073 }
12074
12075 if (! host_integerp (size, 1))
c2f47e15 12076 return NULL_TREE;
0a39fd54 12077
12078 if (! integer_all_onesp (size))
12079 {
12080 if (! host_integerp (len, 1))
12081 {
12082 /* If LEN is not constant, try MAXLEN too.
12083 For MAXLEN only allow optimizing into non-_ocs function
12084 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12085 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12086 {
12087 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
12088 {
12089 /* (void) __mempcpy_chk () can be optimized into
12090 (void) __memcpy_chk (). */
12091 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12092 if (!fn)
c2f47e15 12093 return NULL_TREE;
0a39fd54 12094
c2f47e15 12095 return build_call_expr (fn, 4, dest, src, len, size);
0a39fd54 12096 }
c2f47e15 12097 return NULL_TREE;
0a39fd54 12098 }
0a39fd54 12099 }
ad89623c 12100 else
12101 maxlen = len;
0a39fd54 12102
ad89623c 12103 if (tree_int_cst_lt (size, maxlen))
c2f47e15 12104 return NULL_TREE;
0a39fd54 12105 }
12106
0a39fd54 12107 fn = NULL_TREE;
12108 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12109 mem{cpy,pcpy,move,set} is available. */
12110 switch (fcode)
12111 {
12112 case BUILT_IN_MEMCPY_CHK:
12113 fn = built_in_decls[BUILT_IN_MEMCPY];
12114 break;
12115 case BUILT_IN_MEMPCPY_CHK:
12116 fn = built_in_decls[BUILT_IN_MEMPCPY];
12117 break;
12118 case BUILT_IN_MEMMOVE_CHK:
12119 fn = built_in_decls[BUILT_IN_MEMMOVE];
12120 break;
12121 case BUILT_IN_MEMSET_CHK:
12122 fn = built_in_decls[BUILT_IN_MEMSET];
12123 break;
12124 default:
12125 break;
12126 }
12127
12128 if (!fn)
c2f47e15 12129 return NULL_TREE;
0a39fd54 12130
c2f47e15 12131 return build_call_expr (fn, 3, dest, src, len);
0a39fd54 12132}
12133
12134/* Fold a call to the __st[rp]cpy_chk builtin.
c2f47e15 12135 DEST, SRC, and SIZE are the arguments to the call.
12136 IGNORE is true if return value can be ignored. FCODE is the BUILT_IN_*
0a39fd54 12137 code of the builtin. If MAXLEN is not NULL, it is maximum length of
12138 strings passed as second argument. */
12139
12140tree
c2f47e15 12141fold_builtin_stxcpy_chk (tree fndecl, tree dest, tree src, tree size,
12142 tree maxlen, bool ignore,
0a39fd54 12143 enum built_in_function fcode)
12144{
c2f47e15 12145 tree len, fn;
0a39fd54 12146
c2f47e15 12147 if (!validate_arg (dest, POINTER_TYPE)
12148 || !validate_arg (src, POINTER_TYPE)
12149 || !validate_arg (size, INTEGER_TYPE))
12150 return NULL_TREE;
0a39fd54 12151
12152 /* If SRC and DEST are the same (and not volatile), return DEST. */
12153 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
12154 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
a0c938f0 12155
0a39fd54 12156 if (! host_integerp (size, 1))
c2f47e15 12157 return NULL_TREE;
0a39fd54 12158
12159 if (! integer_all_onesp (size))
12160 {
12161 len = c_strlen (src, 1);
12162 if (! len || ! host_integerp (len, 1))
12163 {
12164 /* If LEN is not constant, try MAXLEN too.
12165 For MAXLEN only allow optimizing into non-_ocs function
12166 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12167 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12168 {
12169 if (fcode == BUILT_IN_STPCPY_CHK)
12170 {
12171 if (! ignore)
c2f47e15 12172 return NULL_TREE;
0a39fd54 12173
12174 /* If return value of __stpcpy_chk is ignored,
12175 optimize into __strcpy_chk. */
12176 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
12177 if (!fn)
c2f47e15 12178 return NULL_TREE;
0a39fd54 12179
c2f47e15 12180 return build_call_expr (fn, 3, dest, src, size);
0a39fd54 12181 }
12182
12183 if (! len || TREE_SIDE_EFFECTS (len))
c2f47e15 12184 return NULL_TREE;
0a39fd54 12185
12186 /* If c_strlen returned something, but not a constant,
12187 transform __strcpy_chk into __memcpy_chk. */
12188 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12189 if (!fn)
c2f47e15 12190 return NULL_TREE;
0a39fd54 12191
12192 len = size_binop (PLUS_EXPR, len, ssize_int (1));
0a39fd54 12193 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
c2f47e15 12194 build_call_expr (fn, 4,
12195 dest, src, len, size));
0a39fd54 12196 }
0a39fd54 12197 }
ad89623c 12198 else
12199 maxlen = len;
12200
12201 if (! tree_int_cst_lt (maxlen, size))
c2f47e15 12202 return NULL_TREE;
0a39fd54 12203 }
12204
0a39fd54 12205 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
12206 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
12207 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
12208 if (!fn)
c2f47e15 12209 return NULL_TREE;
0a39fd54 12210
c2f47e15 12211 return build_call_expr (fn, 2, dest, src);
0a39fd54 12212}
12213
c2f47e15 12214/* Fold a call to the __strncpy_chk builtin. DEST, SRC, LEN, and SIZE
12215 are the arguments to the call. If MAXLEN is not NULL, it is maximum
12216 length passed as third argument. */
0a39fd54 12217
12218tree
c2f47e15 12219fold_builtin_strncpy_chk (tree dest, tree src, tree len, tree size,
12220 tree maxlen)
0a39fd54 12221{
c2f47e15 12222 tree fn;
0a39fd54 12223
c2f47e15 12224 if (!validate_arg (dest, POINTER_TYPE)
12225 || !validate_arg (src, POINTER_TYPE)
12226 || !validate_arg (len, INTEGER_TYPE)
12227 || !validate_arg (size, INTEGER_TYPE))
12228 return NULL_TREE;
0a39fd54 12229
12230 if (! host_integerp (size, 1))
c2f47e15 12231 return NULL_TREE;
0a39fd54 12232
12233 if (! integer_all_onesp (size))
12234 {
12235 if (! host_integerp (len, 1))
12236 {
12237 /* If LEN is not constant, try MAXLEN too.
12238 For MAXLEN only allow optimizing into non-_ocs function
12239 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12240 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
c2f47e15 12241 return NULL_TREE;
0a39fd54 12242 }
ad89623c 12243 else
12244 maxlen = len;
0a39fd54 12245
ad89623c 12246 if (tree_int_cst_lt (size, maxlen))
c2f47e15 12247 return NULL_TREE;
0a39fd54 12248 }
12249
0a39fd54 12250 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
12251 fn = built_in_decls[BUILT_IN_STRNCPY];
12252 if (!fn)
c2f47e15 12253 return NULL_TREE;
0a39fd54 12254
c2f47e15 12255 return build_call_expr (fn, 3, dest, src, len);
0a39fd54 12256}
12257
c2f47e15 12258/* Fold a call to the __strcat_chk builtin FNDECL. DEST, SRC, and SIZE
12259 are the arguments to the call. */
0a39fd54 12260
12261static tree
c2f47e15 12262fold_builtin_strcat_chk (tree fndecl, tree dest, tree src, tree size)
0a39fd54 12263{
c2f47e15 12264 tree fn;
0a39fd54 12265 const char *p;
12266
c2f47e15 12267 if (!validate_arg (dest, POINTER_TYPE)
12268 || !validate_arg (src, POINTER_TYPE)
12269 || !validate_arg (size, INTEGER_TYPE))
12270 return NULL_TREE;
0a39fd54 12271
12272 p = c_getstr (src);
12273 /* If the SRC parameter is "", return DEST. */
12274 if (p && *p == '\0')
12275 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
12276
12277 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
c2f47e15 12278 return NULL_TREE;
0a39fd54 12279
12280 /* If __builtin_strcat_chk is used, assume strcat is available. */
12281 fn = built_in_decls[BUILT_IN_STRCAT];
12282 if (!fn)
c2f47e15 12283 return NULL_TREE;
0a39fd54 12284
c2f47e15 12285 return build_call_expr (fn, 2, dest, src);
0a39fd54 12286}
12287
c2f47e15 12288/* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
12289 LEN, and SIZE. */
0a39fd54 12290
12291static tree
c2f47e15 12292fold_builtin_strncat_chk (tree fndecl,
12293 tree dest, tree src, tree len, tree size)
0a39fd54 12294{
c2f47e15 12295 tree fn;
0a39fd54 12296 const char *p;
12297
c2f47e15 12298 if (!validate_arg (dest, POINTER_TYPE)
12299 || !validate_arg (src, POINTER_TYPE)
12300 || !validate_arg (size, INTEGER_TYPE)
12301 || !validate_arg (size, INTEGER_TYPE))
12302 return NULL_TREE;
0a39fd54 12303
12304 p = c_getstr (src);
12305 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
12306 if (p && *p == '\0')
12307 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
12308 else if (integer_zerop (len))
12309 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
12310
12311 if (! host_integerp (size, 1))
c2f47e15 12312 return NULL_TREE;
0a39fd54 12313
12314 if (! integer_all_onesp (size))
12315 {
12316 tree src_len = c_strlen (src, 1);
12317 if (src_len
12318 && host_integerp (src_len, 1)
12319 && host_integerp (len, 1)
12320 && ! tree_int_cst_lt (len, src_len))
12321 {
12322 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
12323 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
12324 if (!fn)
c2f47e15 12325 return NULL_TREE;
0a39fd54 12326
c2f47e15 12327 return build_call_expr (fn, 3, dest, src, size);
0a39fd54 12328 }
c2f47e15 12329 return NULL_TREE;
0a39fd54 12330 }
12331
0a39fd54 12332 /* If __builtin_strncat_chk is used, assume strncat is available. */
12333 fn = built_in_decls[BUILT_IN_STRNCAT];
12334 if (!fn)
c2f47e15 12335 return NULL_TREE;
0a39fd54 12336
c2f47e15 12337 return build_call_expr (fn, 3, dest, src, len);
0a39fd54 12338}
12339
c2f47e15 12340/* Fold a call EXP to __{,v}sprintf_chk. Return NULL_TREE if
0a39fd54 12341 a normal call should be emitted rather than expanding the function
12342 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
12343
12344static tree
c2f47e15 12345fold_builtin_sprintf_chk (tree exp, enum built_in_function fcode)
0a39fd54 12346{
12347 tree dest, size, len, fn, fmt, flag;
12348 const char *fmt_str;
c2f47e15 12349 int nargs = call_expr_nargs (exp);
0a39fd54 12350
12351 /* Verify the required arguments in the original call. */
c2f47e15 12352 if (nargs < 4)
12353 return NULL_TREE;
12354 dest = CALL_EXPR_ARG (exp, 0);
12355 if (!validate_arg (dest, POINTER_TYPE))
12356 return NULL_TREE;
12357 flag = CALL_EXPR_ARG (exp, 1);
12358 if (!validate_arg (flag, INTEGER_TYPE))
12359 return NULL_TREE;
12360 size = CALL_EXPR_ARG (exp, 2);
12361 if (!validate_arg (size, INTEGER_TYPE))
12362 return NULL_TREE;
12363 fmt = CALL_EXPR_ARG (exp, 3);
12364 if (!validate_arg (fmt, POINTER_TYPE))
12365 return NULL_TREE;
0a39fd54 12366
12367 if (! host_integerp (size, 1))
c2f47e15 12368 return NULL_TREE;
0a39fd54 12369
12370 len = NULL_TREE;
12371
d4473c84 12372 if (!init_target_chars ())
c2f47e15 12373 return NULL_TREE;
99eabcc1 12374
0a39fd54 12375 /* Check whether the format is a literal string constant. */
12376 fmt_str = c_getstr (fmt);
12377 if (fmt_str != NULL)
12378 {
12379 /* If the format doesn't contain % args or %%, we know the size. */
99eabcc1 12380 if (strchr (fmt_str, target_percent) == 0)
0a39fd54 12381 {
c2f47e15 12382 if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
0a39fd54 12383 len = build_int_cstu (size_type_node, strlen (fmt_str));
12384 }
12385 /* If the format is "%s" and first ... argument is a string literal,
12386 we know the size too. */
c2f47e15 12387 else if (fcode == BUILT_IN_SPRINTF_CHK
12388 && strcmp (fmt_str, target_percent_s) == 0)
0a39fd54 12389 {
12390 tree arg;
12391
c2f47e15 12392 if (nargs == 5)
0a39fd54 12393 {
c2f47e15 12394 arg = CALL_EXPR_ARG (exp, 4);
12395 if (validate_arg (arg, POINTER_TYPE))
0a39fd54 12396 {
12397 len = c_strlen (arg, 1);
12398 if (! len || ! host_integerp (len, 1))
12399 len = NULL_TREE;
12400 }
12401 }
12402 }
12403 }
12404
12405 if (! integer_all_onesp (size))
12406 {
12407 if (! len || ! tree_int_cst_lt (len, size))
c2f47e15 12408 return NULL_TREE;
0a39fd54 12409 }
12410
12411 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
12412 or if format doesn't contain % chars or is "%s". */
12413 if (! integer_zerop (flag))
12414 {
12415 if (fmt_str == NULL)
c2f47e15 12416 return NULL_TREE;
12417 if (strchr (fmt_str, target_percent) != NULL
12418 && strcmp (fmt_str, target_percent_s))
12419 return NULL_TREE;
0a39fd54 12420 }
12421
0a39fd54 12422 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
12423 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
12424 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
12425 if (!fn)
c2f47e15 12426 return NULL_TREE;
0a39fd54 12427
c2f47e15 12428 return rewrite_call_expr (exp, 4, fn, 2, dest, fmt);
0a39fd54 12429}
12430
c2f47e15 12431/* Fold a call EXP to {,v}snprintf. Return NULL_TREE if
0a39fd54 12432 a normal call should be emitted rather than expanding the function
12433 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
12434 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
12435 passed as second argument. */
12436
12437tree
c2f47e15 12438fold_builtin_snprintf_chk (tree exp, tree maxlen,
0a39fd54 12439 enum built_in_function fcode)
12440{
12441 tree dest, size, len, fn, fmt, flag;
12442 const char *fmt_str;
12443
12444 /* Verify the required arguments in the original call. */
c2f47e15 12445 if (call_expr_nargs (exp) < 5)
12446 return NULL_TREE;
12447 dest = CALL_EXPR_ARG (exp, 0);
12448 if (!validate_arg (dest, POINTER_TYPE))
12449 return NULL_TREE;
12450 len = CALL_EXPR_ARG (exp, 1);
12451 if (!validate_arg (len, INTEGER_TYPE))
12452 return NULL_TREE;
12453 flag = CALL_EXPR_ARG (exp, 2);
12454 if (!validate_arg (flag, INTEGER_TYPE))
12455 return NULL_TREE;
12456 size = CALL_EXPR_ARG (exp, 3);
12457 if (!validate_arg (size, INTEGER_TYPE))
12458 return NULL_TREE;
12459 fmt = CALL_EXPR_ARG (exp, 4);
12460 if (!validate_arg (fmt, POINTER_TYPE))
12461 return NULL_TREE;
0a39fd54 12462
12463 if (! host_integerp (size, 1))
c2f47e15 12464 return NULL_TREE;
0a39fd54 12465
12466 if (! integer_all_onesp (size))
12467 {
12468 if (! host_integerp (len, 1))
12469 {
12470 /* If LEN is not constant, try MAXLEN too.
12471 For MAXLEN only allow optimizing into non-_ocs function
12472 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12473 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
c2f47e15 12474 return NULL_TREE;
0a39fd54 12475 }
ad89623c 12476 else
12477 maxlen = len;
0a39fd54 12478
ad89623c 12479 if (tree_int_cst_lt (size, maxlen))
c2f47e15 12480 return NULL_TREE;
0a39fd54 12481 }
12482
d4473c84 12483 if (!init_target_chars ())
c2f47e15 12484 return NULL_TREE;
99eabcc1 12485
0a39fd54 12486 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
12487 or if format doesn't contain % chars or is "%s". */
12488 if (! integer_zerop (flag))
12489 {
12490 fmt_str = c_getstr (fmt);
12491 if (fmt_str == NULL)
c2f47e15 12492 return NULL_TREE;
12493 if (strchr (fmt_str, target_percent) != NULL
12494 && strcmp (fmt_str, target_percent_s))
12495 return NULL_TREE;
0a39fd54 12496 }
12497
0a39fd54 12498 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
12499 available. */
12500 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
12501 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
12502 if (!fn)
c2f47e15 12503 return NULL_TREE;
0a39fd54 12504
c2f47e15 12505 return rewrite_call_expr (exp, 5, fn, 3, dest, len, fmt);
0a39fd54 12506}
12507
12508/* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
c2f47e15 12509 FMT and ARG are the arguments to the call; we don't fold cases with
12510 more than 2 arguments, and ARG may be null if this is a 1-argument case.
0a39fd54 12511
c2f47e15 12512 Return NULL_TREE if no simplification was possible, otherwise return the
0a39fd54 12513 simplified form of the call as a tree. FCODE is the BUILT_IN_*
12514 code of the function to be simplified. */
12515
12516static tree
c2f47e15 12517fold_builtin_printf (tree fndecl, tree fmt, tree arg, bool ignore,
0a39fd54 12518 enum built_in_function fcode)
12519{
c2f47e15 12520 tree fn_putchar, fn_puts, newarg, call = NULL_TREE;
0a39fd54 12521 const char *fmt_str = NULL;
12522
12523 /* If the return value is used, don't do the transformation. */
12524 if (! ignore)
c2f47e15 12525 return NULL_TREE;
0a39fd54 12526
12527 /* Verify the required arguments in the original call. */
c2f47e15 12528 if (!validate_arg (fmt, POINTER_TYPE))
12529 return NULL_TREE;
0a39fd54 12530
12531 /* Check whether the format is a literal string constant. */
12532 fmt_str = c_getstr (fmt);
12533 if (fmt_str == NULL)
12534 return NULL_TREE;
12535
12536 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
12537 {
6d77ed92 12538 /* If we're using an unlocked function, assume the other
12539 unlocked functions exist explicitly. */
12540 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
12541 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
0a39fd54 12542 }
12543 else
12544 {
12545 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
12546 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
12547 }
12548
d4473c84 12549 if (!init_target_chars ())
c2f47e15 12550 return NULL_TREE;
a0c938f0 12551
c2f47e15 12552 if (strcmp (fmt_str, target_percent_s) == 0
12553 || strchr (fmt_str, target_percent) == NULL)
0a39fd54 12554 {
12555 const char *str;
12556
99eabcc1 12557 if (strcmp (fmt_str, target_percent_s) == 0)
0a39fd54 12558 {
12559 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
c2f47e15 12560 return NULL_TREE;
0a39fd54 12561
c2f47e15 12562 if (!arg || !validate_arg (arg, POINTER_TYPE))
12563 return NULL_TREE;
0a39fd54 12564
c2f47e15 12565 str = c_getstr (arg);
0a39fd54 12566 if (str == NULL)
c2f47e15 12567 return NULL_TREE;
0a39fd54 12568 }
12569 else
12570 {
12571 /* The format specifier doesn't contain any '%' characters. */
12572 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
c2f47e15 12573 && arg)
12574 return NULL_TREE;
0a39fd54 12575 str = fmt_str;
12576 }
12577
12578 /* If the string was "", printf does nothing. */
12579 if (str[0] == '\0')
12580 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
12581
12582 /* If the string has length of 1, call putchar. */
12583 if (str[1] == '\0')
12584 {
12585 /* Given printf("c"), (where c is any one character,)
12586 convert "c"[0] to an int and pass that to the replacement
12587 function. */
c2f47e15 12588 newarg = build_int_cst (NULL_TREE, str[0]);
12589 if (fn_putchar)
12590 call = build_call_expr (fn_putchar, 1, newarg);
0a39fd54 12591 }
12592 else
12593 {
12594 /* If the string was "string\n", call puts("string"). */
12595 size_t len = strlen (str);
99eabcc1 12596 if ((unsigned char)str[len - 1] == target_newline)
0a39fd54 12597 {
12598 /* Create a NUL-terminated string that's one char shorter
12599 than the original, stripping off the trailing '\n'. */
364c0c59 12600 char *newstr = XALLOCAVEC (char, len);
0a39fd54 12601 memcpy (newstr, str, len - 1);
12602 newstr[len - 1] = 0;
12603
c2f47e15 12604 newarg = build_string_literal (len, newstr);
12605 if (fn_puts)
12606 call = build_call_expr (fn_puts, 1, newarg);
0a39fd54 12607 }
12608 else
12609 /* We'd like to arrange to call fputs(string,stdout) here,
12610 but we need stdout and don't have a way to get it yet. */
c2f47e15 12611 return NULL_TREE;
0a39fd54 12612 }
12613 }
12614
12615 /* The other optimizations can be done only on the non-va_list variants. */
12616 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
c2f47e15 12617 return NULL_TREE;
0a39fd54 12618
12619 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
99eabcc1 12620 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
0a39fd54 12621 {
c2f47e15 12622 if (!arg || !validate_arg (arg, POINTER_TYPE))
12623 return NULL_TREE;
12624 if (fn_puts)
12625 call = build_call_expr (fn_puts, 1, arg);
0a39fd54 12626 }
12627
12628 /* If the format specifier was "%c", call __builtin_putchar(arg). */
99eabcc1 12629 else if (strcmp (fmt_str, target_percent_c) == 0)
0a39fd54 12630 {
c2f47e15 12631 if (!arg || !validate_arg (arg, INTEGER_TYPE))
12632 return NULL_TREE;
12633 if (fn_putchar)
12634 call = build_call_expr (fn_putchar, 1, arg);
0a39fd54 12635 }
12636
c2f47e15 12637 if (!call)
12638 return NULL_TREE;
0a39fd54 12639
0a39fd54 12640 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
12641}
12642
12643/* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
c2f47e15 12644 FP, FMT, and ARG are the arguments to the call. We don't fold calls with
12645 more than 3 arguments, and ARG may be null in the 2-argument case.
0a39fd54 12646
c2f47e15 12647 Return NULL_TREE if no simplification was possible, otherwise return the
0a39fd54 12648 simplified form of the call as a tree. FCODE is the BUILT_IN_*
12649 code of the function to be simplified. */
12650
12651static tree
c2f47e15 12652fold_builtin_fprintf (tree fndecl, tree fp, tree fmt, tree arg, bool ignore,
0a39fd54 12653 enum built_in_function fcode)
12654{
c2f47e15 12655 tree fn_fputc, fn_fputs, call = NULL_TREE;
0a39fd54 12656 const char *fmt_str = NULL;
12657
12658 /* If the return value is used, don't do the transformation. */
12659 if (! ignore)
c2f47e15 12660 return NULL_TREE;
0a39fd54 12661
12662 /* Verify the required arguments in the original call. */
c2f47e15 12663 if (!validate_arg (fp, POINTER_TYPE))
12664 return NULL_TREE;
12665 if (!validate_arg (fmt, POINTER_TYPE))
12666 return NULL_TREE;
0a39fd54 12667
12668 /* Check whether the format is a literal string constant. */
12669 fmt_str = c_getstr (fmt);
12670 if (fmt_str == NULL)
12671 return NULL_TREE;
12672
12673 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
12674 {
6d77ed92 12675 /* If we're using an unlocked function, assume the other
12676 unlocked functions exist explicitly. */
12677 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
12678 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
0a39fd54 12679 }
12680 else
12681 {
12682 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
12683 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
12684 }
12685
d4473c84 12686 if (!init_target_chars ())
c2f47e15 12687 return NULL_TREE;
a0c938f0 12688
0a39fd54 12689 /* If the format doesn't contain % args or %%, use strcpy. */
99eabcc1 12690 if (strchr (fmt_str, target_percent) == NULL)
0a39fd54 12691 {
12692 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
c2f47e15 12693 && arg)
12694 return NULL_TREE;
0a39fd54 12695
12696 /* If the format specifier was "", fprintf does nothing. */
12697 if (fmt_str[0] == '\0')
12698 {
12699 /* If FP has side-effects, just wait until gimplification is
12700 done. */
12701 if (TREE_SIDE_EFFECTS (fp))
c2f47e15 12702 return NULL_TREE;
0a39fd54 12703
12704 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
12705 }
12706
12707 /* When "string" doesn't contain %, replace all cases of
12708 fprintf (fp, string) with fputs (string, fp). The fputs
12709 builtin will take care of special cases like length == 1. */
c2f47e15 12710 if (fn_fputs)
12711 call = build_call_expr (fn_fputs, 2, fmt, fp);
0a39fd54 12712 }
12713
12714 /* The other optimizations can be done only on the non-va_list variants. */
12715 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
c2f47e15 12716 return NULL_TREE;
0a39fd54 12717
12718 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
99eabcc1 12719 else if (strcmp (fmt_str, target_percent_s) == 0)
0a39fd54 12720 {
c2f47e15 12721 if (!arg || !validate_arg (arg, POINTER_TYPE))
12722 return NULL_TREE;
12723 if (fn_fputs)
12724 call = build_call_expr (fn_fputs, 2, arg, fp);
0a39fd54 12725 }
12726
12727 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
99eabcc1 12728 else if (strcmp (fmt_str, target_percent_c) == 0)
0a39fd54 12729 {
c2f47e15 12730 if (!arg || !validate_arg (arg, INTEGER_TYPE))
12731 return NULL_TREE;
12732 if (fn_fputc)
12733 call = build_call_expr (fn_fputc, 2, arg, fp);
0a39fd54 12734 }
12735
c2f47e15 12736 if (!call)
12737 return NULL_TREE;
0a39fd54 12738 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
12739}
99eabcc1 12740
12741/* Initialize format string characters in the target charset. */
12742
12743static bool
12744init_target_chars (void)
12745{
12746 static bool init;
12747 if (!init)
12748 {
12749 target_newline = lang_hooks.to_target_charset ('\n');
12750 target_percent = lang_hooks.to_target_charset ('%');
12751 target_c = lang_hooks.to_target_charset ('c');
12752 target_s = lang_hooks.to_target_charset ('s');
12753 if (target_newline == 0 || target_percent == 0 || target_c == 0
12754 || target_s == 0)
12755 return false;
12756
12757 target_percent_c[0] = target_percent;
12758 target_percent_c[1] = target_c;
12759 target_percent_c[2] = '\0';
12760
12761 target_percent_s[0] = target_percent;
12762 target_percent_s[1] = target_s;
12763 target_percent_s[2] = '\0';
12764
12765 target_percent_s_newline[0] = target_percent;
12766 target_percent_s_newline[1] = target_s;
12767 target_percent_s_newline[2] = target_newline;
12768 target_percent_s_newline[3] = '\0';
a0c938f0 12769
99eabcc1 12770 init = true;
12771 }
12772 return true;
12773}
bffb7645 12774
f0c477f2 12775/* Helper function for do_mpfr_arg*(). Ensure M is a normal number
12776 and no overflow/underflow occurred. INEXACT is true if M was not
fa7637bd 12777 exactly calculated. TYPE is the tree type for the result. This
f0c477f2 12778 function assumes that you cleared the MPFR flags and then
12779 calculated M to see if anything subsequently set a flag prior to
12780 entering this function. Return NULL_TREE if any checks fail. */
12781
12782static tree
d4473c84 12783do_mpfr_ckconv (mpfr_srcptr m, tree type, int inexact)
f0c477f2 12784{
12785 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
12786 overflow/underflow occurred. If -frounding-math, proceed iff the
12787 result of calling FUNC was exact. */
d4473c84 12788 if (mpfr_number_p (m) && !mpfr_overflow_p () && !mpfr_underflow_p ()
f0c477f2 12789 && (!flag_rounding_math || !inexact))
12790 {
12791 REAL_VALUE_TYPE rr;
12792
66fa16e6 12793 real_from_mpfr (&rr, m, type, GMP_RNDN);
f0c477f2 12794 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
12795 check for overflow/underflow. If the REAL_VALUE_TYPE is zero
12796 but the mpft_t is not, then we underflowed in the
12797 conversion. */
776a7bab 12798 if (real_isfinite (&rr)
f0c477f2 12799 && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
12800 {
12801 REAL_VALUE_TYPE rmode;
12802
12803 real_convert (&rmode, TYPE_MODE (type), &rr);
12804 /* Proceed iff the specified mode can hold the value. */
12805 if (real_identical (&rmode, &rr))
12806 return build_real (type, rmode);
12807 }
12808 }
12809 return NULL_TREE;
12810}
12811
bffb7645 12812/* If argument ARG is a REAL_CST, call the one-argument mpfr function
12813 FUNC on it and return the resulting value as a tree with type TYPE.
728bac60 12814 If MIN and/or MAX are not NULL, then the supplied ARG must be
12815 within those bounds. If INCLUSIVE is true, then MIN/MAX are
12816 acceptable values, otherwise they are not. The mpfr precision is
12817 set to the precision of TYPE. We assume that function FUNC returns
12818 zero if the result could be calculated exactly within the requested
12819 precision. */
bffb7645 12820
12821static tree
728bac60 12822do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
12823 const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
12824 bool inclusive)
bffb7645 12825{
12826 tree result = NULL_TREE;
12827
12828 STRIP_NOPS (arg);
12829
bd7d6fa4 12830 /* To proceed, MPFR must exactly represent the target floating point
12831 format, which only happens when the target base equals two. */
12832 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
f96bd2bf 12833 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
bffb7645 12834 {
f0c477f2 12835 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
bffb7645 12836
776a7bab 12837 if (real_isfinite (ra)
f0c477f2 12838 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
12839 && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
bffb7645 12840 {
f0c477f2 12841 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
debf9994 12842 int inexact;
bffb7645 12843 mpfr_t m;
12844
12845 mpfr_init2 (m, prec);
66fa16e6 12846 mpfr_from_real (m, ra, GMP_RNDN);
d4473c84 12847 mpfr_clear_flags ();
debf9994 12848 inexact = func (m, m, GMP_RNDN);
f0c477f2 12849 result = do_mpfr_ckconv (m, type, inexact);
bffb7645 12850 mpfr_clear (m);
12851 }
12852 }
12853
12854 return result;
12855}
f0c477f2 12856
12857/* If argument ARG is a REAL_CST, call the two-argument mpfr function
12858 FUNC on it and return the resulting value as a tree with type TYPE.
12859 The mpfr precision is set to the precision of TYPE. We assume that
12860 function FUNC returns zero if the result could be calculated
12861 exactly within the requested precision. */
12862
12863static tree
12864do_mpfr_arg2 (tree arg1, tree arg2, tree type,
12865 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
12866{
12867 tree result = NULL_TREE;
12868
12869 STRIP_NOPS (arg1);
12870 STRIP_NOPS (arg2);
12871
bd7d6fa4 12872 /* To proceed, MPFR must exactly represent the target floating point
12873 format, which only happens when the target base equals two. */
12874 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
f96bd2bf 12875 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
12876 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
f0c477f2 12877 {
12878 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
12879 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
12880
776a7bab 12881 if (real_isfinite (ra1) && real_isfinite (ra2))
f0c477f2 12882 {
12883 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
12884 int inexact;
12885 mpfr_t m1, m2;
12886
12887 mpfr_inits2 (prec, m1, m2, NULL);
66fa16e6 12888 mpfr_from_real (m1, ra1, GMP_RNDN);
12889 mpfr_from_real (m2, ra2, GMP_RNDN);
d4473c84 12890 mpfr_clear_flags ();
f0c477f2 12891 inexact = func (m1, m1, m2, GMP_RNDN);
12892 result = do_mpfr_ckconv (m1, type, inexact);
12893 mpfr_clears (m1, m2, NULL);
12894 }
12895 }
12896
12897 return result;
12898}
d92f994c 12899
9917422b 12900/* If argument ARG is a REAL_CST, call the three-argument mpfr function
12901 FUNC on it and return the resulting value as a tree with type TYPE.
12902 The mpfr precision is set to the precision of TYPE. We assume that
12903 function FUNC returns zero if the result could be calculated
12904 exactly within the requested precision. */
12905
12906static tree
12907do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
12908 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
12909{
12910 tree result = NULL_TREE;
12911
12912 STRIP_NOPS (arg1);
12913 STRIP_NOPS (arg2);
12914 STRIP_NOPS (arg3);
12915
bd7d6fa4 12916 /* To proceed, MPFR must exactly represent the target floating point
12917 format, which only happens when the target base equals two. */
12918 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
f96bd2bf 12919 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
12920 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)
12921 && TREE_CODE (arg3) == REAL_CST && !TREE_OVERFLOW (arg3))
9917422b 12922 {
12923 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
12924 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
12925 const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
12926
776a7bab 12927 if (real_isfinite (ra1) && real_isfinite (ra2) && real_isfinite (ra3))
9917422b 12928 {
12929 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
12930 int inexact;
12931 mpfr_t m1, m2, m3;
12932
12933 mpfr_inits2 (prec, m1, m2, m3, NULL);
66fa16e6 12934 mpfr_from_real (m1, ra1, GMP_RNDN);
12935 mpfr_from_real (m2, ra2, GMP_RNDN);
12936 mpfr_from_real (m3, ra3, GMP_RNDN);
d4473c84 12937 mpfr_clear_flags ();
9917422b 12938 inexact = func (m1, m1, m2, m3, GMP_RNDN);
12939 result = do_mpfr_ckconv (m1, type, inexact);
12940 mpfr_clears (m1, m2, m3, NULL);
12941 }
12942 }
12943
12944 return result;
12945}
12946
d92f994c 12947/* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
12948 the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
d735c391 12949 If ARG_SINP and ARG_COSP are NULL then the result is returned
12950 as a complex value.
d92f994c 12951 The type is taken from the type of ARG and is used for setting the
12952 precision of the calculation and results. */
12953
12954static tree
12955do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
12956{
bd7d6fa4 12957 tree const type = TREE_TYPE (arg);
d92f994c 12958 tree result = NULL_TREE;
12959
12960 STRIP_NOPS (arg);
12961
bd7d6fa4 12962 /* To proceed, MPFR must exactly represent the target floating point
12963 format, which only happens when the target base equals two. */
12964 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
f96bd2bf 12965 && TREE_CODE (arg) == REAL_CST
12966 && !TREE_OVERFLOW (arg))
d92f994c 12967 {
12968 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
12969
776a7bab 12970 if (real_isfinite (ra))
d92f994c 12971 {
d92f994c 12972 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
12973 tree result_s, result_c;
12974 int inexact;
12975 mpfr_t m, ms, mc;
12976
12977 mpfr_inits2 (prec, m, ms, mc, NULL);
66fa16e6 12978 mpfr_from_real (m, ra, GMP_RNDN);
d4473c84 12979 mpfr_clear_flags ();
d92f994c 12980 inexact = mpfr_sin_cos (ms, mc, m, GMP_RNDN);
12981 result_s = do_mpfr_ckconv (ms, type, inexact);
12982 result_c = do_mpfr_ckconv (mc, type, inexact);
12983 mpfr_clears (m, ms, mc, NULL);
12984 if (result_s && result_c)
12985 {
d735c391 12986 /* If we are to return in a complex value do so. */
12987 if (!arg_sinp && !arg_cosp)
12988 return build_complex (build_complex_type (type),
12989 result_c, result_s);
12990
d92f994c 12991 /* Dereference the sin/cos pointer arguments. */
12992 arg_sinp = build_fold_indirect_ref (arg_sinp);
12993 arg_cosp = build_fold_indirect_ref (arg_cosp);
12994 /* Proceed if valid pointer type were passed in. */
12995 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
12996 && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
12997 {
12998 /* Set the values. */
41076ef6 12999 result_s = fold_build2 (MODIFY_EXPR, type, arg_sinp,
35cc02b5 13000 result_s);
d92f994c 13001 TREE_SIDE_EFFECTS (result_s) = 1;
41076ef6 13002 result_c = fold_build2 (MODIFY_EXPR, type, arg_cosp,
35cc02b5 13003 result_c);
d92f994c 13004 TREE_SIDE_EFFECTS (result_c) = 1;
13005 /* Combine the assignments into a compound expr. */
13006 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13007 result_s, result_c));
13008 }
13009 }
13010 }
13011 }
13012 return result;
13013}
65dd1378 13014
13015#if MPFR_VERSION >= MPFR_VERSION_NUM(2,3,0)
13016/* If argument ARG1 is an INTEGER_CST and ARG2 is a REAL_CST, call the
13017 two-argument mpfr order N Bessel function FUNC on them and return
13018 the resulting value as a tree with type TYPE. The mpfr precision
13019 is set to the precision of TYPE. We assume that function FUNC
13020 returns zero if the result could be calculated exactly within the
13021 requested precision. */
13022static tree
13023do_mpfr_bessel_n (tree arg1, tree arg2, tree type,
13024 int (*func)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
13025 const REAL_VALUE_TYPE *min, bool inclusive)
13026{
13027 tree result = NULL_TREE;
13028
13029 STRIP_NOPS (arg1);
13030 STRIP_NOPS (arg2);
13031
13032 /* To proceed, MPFR must exactly represent the target floating point
13033 format, which only happens when the target base equals two. */
13034 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13035 && host_integerp (arg1, 0)
13036 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
13037 {
13038 const HOST_WIDE_INT n = tree_low_cst(arg1, 0);
13039 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg2);
13040
13041 if (n == (long)n
776a7bab 13042 && real_isfinite (ra)
65dd1378 13043 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min)))
13044 {
13045 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
13046 int inexact;
13047 mpfr_t m;
13048
13049 mpfr_init2 (m, prec);
13050 mpfr_from_real (m, ra, GMP_RNDN);
13051 mpfr_clear_flags ();
13052 inexact = func (m, n, m, GMP_RNDN);
13053 result = do_mpfr_ckconv (m, type, inexact);
13054 mpfr_clear (m);
13055 }
13056 }
13057
13058 return result;
13059}
e5407ca6 13060
13061/* If arguments ARG0 and ARG1 are REAL_CSTs, call mpfr_remquo() to set
13062 the pointer *(ARG_QUO) and return the result. The type is taken
13063 from the type of ARG0 and is used for setting the precision of the
13064 calculation and results. */
13065
13066static tree
13067do_mpfr_remquo (tree arg0, tree arg1, tree arg_quo)
13068{
13069 tree const type = TREE_TYPE (arg0);
13070 tree result = NULL_TREE;
13071
13072 STRIP_NOPS (arg0);
13073 STRIP_NOPS (arg1);
13074
13075 /* To proceed, MPFR must exactly represent the target floating point
13076 format, which only happens when the target base equals two. */
13077 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13078 && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
13079 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1))
13080 {
13081 const REAL_VALUE_TYPE *const ra0 = TREE_REAL_CST_PTR (arg0);
13082 const REAL_VALUE_TYPE *const ra1 = TREE_REAL_CST_PTR (arg1);
13083
776a7bab 13084 if (real_isfinite (ra0) && real_isfinite (ra1))
e5407ca6 13085 {
13086 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
13087 tree result_rem;
13088 long integer_quo;
13089 mpfr_t m0, m1;
13090
13091 mpfr_inits2 (prec, m0, m1, NULL);
13092 mpfr_from_real (m0, ra0, GMP_RNDN);
13093 mpfr_from_real (m1, ra1, GMP_RNDN);
13094 mpfr_clear_flags ();
13095 mpfr_remquo (m0, &integer_quo, m0, m1, GMP_RNDN);
13096 /* Remquo is independent of the rounding mode, so pass
13097 inexact=0 to do_mpfr_ckconv(). */
13098 result_rem = do_mpfr_ckconv (m0, type, /*inexact=*/ 0);
13099 mpfr_clears (m0, m1, NULL);
13100 if (result_rem)
13101 {
13102 /* MPFR calculates quo in the host's long so it may
13103 return more bits in quo than the target int can hold
13104 if sizeof(host long) > sizeof(target int). This can
13105 happen even for native compilers in LP64 mode. In
13106 these cases, modulo the quo value with the largest
13107 number that the target int can hold while leaving one
13108 bit for the sign. */
13109 if (sizeof (integer_quo) * CHAR_BIT > INT_TYPE_SIZE)
13110 integer_quo %= (long)(1UL << (INT_TYPE_SIZE - 1));
13111
13112 /* Dereference the quo pointer argument. */
13113 arg_quo = build_fold_indirect_ref (arg_quo);
13114 /* Proceed iff a valid pointer type was passed in. */
13115 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_quo)) == integer_type_node)
13116 {
13117 /* Set the value. */
13118 tree result_quo = fold_build2 (MODIFY_EXPR,
13119 TREE_TYPE (arg_quo), arg_quo,
13120 build_int_cst (NULL, integer_quo));
13121 TREE_SIDE_EFFECTS (result_quo) = 1;
13122 /* Combine the quo assignment with the rem. */
13123 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13124 result_quo, result_rem));
13125 }
13126 }
13127 }
13128 }
13129 return result;
13130}
e84da7c1 13131
13132/* If ARG is a REAL_CST, call mpfr_lgamma() on it and return the
13133 resulting value as a tree with type TYPE. The mpfr precision is
13134 set to the precision of TYPE. We assume that this mpfr function
13135 returns zero if the result could be calculated exactly within the
13136 requested precision. In addition, the integer pointer represented
13137 by ARG_SG will be dereferenced and set to the appropriate signgam
13138 (-1,1) value. */
13139
13140static tree
13141do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type)
13142{
13143 tree result = NULL_TREE;
13144
13145 STRIP_NOPS (arg);
13146
13147 /* To proceed, MPFR must exactly represent the target floating point
13148 format, which only happens when the target base equals two. Also
13149 verify ARG is a constant and that ARG_SG is an int pointer. */
13150 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13151 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)
13152 && TREE_CODE (TREE_TYPE (arg_sg)) == POINTER_TYPE
13153 && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg_sg))) == integer_type_node)
13154 {
13155 const REAL_VALUE_TYPE *const ra = TREE_REAL_CST_PTR (arg);
13156
13157 /* In addition to NaN and Inf, the argument cannot be zero or a
13158 negative integer. */
776a7bab 13159 if (real_isfinite (ra)
e84da7c1 13160 && ra->cl != rvc_zero
13161 && !(real_isneg(ra) && real_isinteger(ra, TYPE_MODE (type))))
13162 {
13163 const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
13164 int inexact, sg;
13165 mpfr_t m;
13166 tree result_lg;
13167
13168 mpfr_init2 (m, prec);
13169 mpfr_from_real (m, ra, GMP_RNDN);
13170 mpfr_clear_flags ();
13171 inexact = mpfr_lgamma (m, &sg, m, GMP_RNDN);
13172 result_lg = do_mpfr_ckconv (m, type, inexact);
13173 mpfr_clear (m);
13174 if (result_lg)
13175 {
13176 tree result_sg;
13177
13178 /* Dereference the arg_sg pointer argument. */
13179 arg_sg = build_fold_indirect_ref (arg_sg);
13180 /* Assign the signgam value into *arg_sg. */
13181 result_sg = fold_build2 (MODIFY_EXPR,
13182 TREE_TYPE (arg_sg), arg_sg,
13183 build_int_cst (NULL, sg));
13184 TREE_SIDE_EFFECTS (result_sg) = 1;
13185 /* Combine the signgam assignment with the lgamma result. */
13186 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13187 result_sg, result_lg));
13188 }
13189 }
13190 }
13191
13192 return result;
13193}
65dd1378 13194#endif
75a70cf9 13195
13196/* FIXME tuples.
13197 The functions below provide an alternate interface for folding
13198 builtin function calls presented as GIMPLE_CALL statements rather
13199 than as CALL_EXPRs. The folded result is still expressed as a
13200 tree. There is too much code duplication in the handling of
13201 varargs functions, and a more intrusive re-factoring would permit
13202 better sharing of code between the tree and statement-based
13203 versions of these functions. */
13204
13205/* Construct a new CALL_EXPR using the tail of the argument list of STMT
13206 along with N new arguments specified as the "..." parameters. SKIP
13207 is the number of arguments in STMT to be omitted. This function is used
13208 to do varargs-to-varargs transformations. */
13209
13210static tree
13211gimple_rewrite_call_expr (gimple stmt, int skip, tree fndecl, int n, ...)
13212{
13213 int oldnargs = gimple_call_num_args (stmt);
13214 int nargs = oldnargs - skip + n;
13215 tree fntype = TREE_TYPE (fndecl);
13216 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
13217 tree *buffer;
13218 int i, j;
13219 va_list ap;
13220
13221 buffer = XALLOCAVEC (tree, nargs);
13222 va_start (ap, n);
13223 for (i = 0; i < n; i++)
13224 buffer[i] = va_arg (ap, tree);
13225 va_end (ap);
13226 for (j = skip; j < oldnargs; j++, i++)
13227 buffer[i] = gimple_call_arg (stmt, j);
13228
13229 return fold (build_call_array (TREE_TYPE (fntype), fn, nargs, buffer));
13230}
13231
13232/* Fold a call STMT to __{,v}sprintf_chk. Return NULL_TREE if
13233 a normal call should be emitted rather than expanding the function
13234 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
13235
13236static tree
13237gimple_fold_builtin_sprintf_chk (gimple stmt, enum built_in_function fcode)
13238{
13239 tree dest, size, len, fn, fmt, flag;
13240 const char *fmt_str;
13241 int nargs = gimple_call_num_args (stmt);
13242
13243 /* Verify the required arguments in the original call. */
13244 if (nargs < 4)
13245 return NULL_TREE;
13246 dest = gimple_call_arg (stmt, 0);
13247 if (!validate_arg (dest, POINTER_TYPE))
13248 return NULL_TREE;
13249 flag = gimple_call_arg (stmt, 1);
13250 if (!validate_arg (flag, INTEGER_TYPE))
13251 return NULL_TREE;
13252 size = gimple_call_arg (stmt, 2);
13253 if (!validate_arg (size, INTEGER_TYPE))
13254 return NULL_TREE;
13255 fmt = gimple_call_arg (stmt, 3);
13256 if (!validate_arg (fmt, POINTER_TYPE))
13257 return NULL_TREE;
13258
13259 if (! host_integerp (size, 1))
13260 return NULL_TREE;
13261
13262 len = NULL_TREE;
13263
13264 if (!init_target_chars ())
13265 return NULL_TREE;
13266
13267 /* Check whether the format is a literal string constant. */
13268 fmt_str = c_getstr (fmt);
13269 if (fmt_str != NULL)
13270 {
13271 /* If the format doesn't contain % args or %%, we know the size. */
13272 if (strchr (fmt_str, target_percent) == 0)
13273 {
13274 if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
13275 len = build_int_cstu (size_type_node, strlen (fmt_str));
13276 }
13277 /* If the format is "%s" and first ... argument is a string literal,
13278 we know the size too. */
13279 else if (fcode == BUILT_IN_SPRINTF_CHK
13280 && strcmp (fmt_str, target_percent_s) == 0)
13281 {
13282 tree arg;
13283
13284 if (nargs == 5)
13285 {
13286 arg = gimple_call_arg (stmt, 4);
13287 if (validate_arg (arg, POINTER_TYPE))
13288 {
13289 len = c_strlen (arg, 1);
13290 if (! len || ! host_integerp (len, 1))
13291 len = NULL_TREE;
13292 }
13293 }
13294 }
13295 }
13296
13297 if (! integer_all_onesp (size))
13298 {
13299 if (! len || ! tree_int_cst_lt (len, size))
13300 return NULL_TREE;
13301 }
13302
13303 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
13304 or if format doesn't contain % chars or is "%s". */
13305 if (! integer_zerop (flag))
13306 {
13307 if (fmt_str == NULL)
13308 return NULL_TREE;
13309 if (strchr (fmt_str, target_percent) != NULL
13310 && strcmp (fmt_str, target_percent_s))
13311 return NULL_TREE;
13312 }
13313
13314 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
13315 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
13316 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
13317 if (!fn)
13318 return NULL_TREE;
13319
13320 return gimple_rewrite_call_expr (stmt, 4, fn, 2, dest, fmt);
13321}
13322
13323/* Fold a call STMT to {,v}snprintf. Return NULL_TREE if
13324 a normal call should be emitted rather than expanding the function
13325 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
13326 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
13327 passed as second argument. */
13328
13329tree
13330gimple_fold_builtin_snprintf_chk (gimple stmt, tree maxlen,
13331 enum built_in_function fcode)
13332{
13333 tree dest, size, len, fn, fmt, flag;
13334 const char *fmt_str;
13335
13336 /* Verify the required arguments in the original call. */
13337 if (gimple_call_num_args (stmt) < 5)
13338 return NULL_TREE;
13339 dest = gimple_call_arg (stmt, 0);
13340 if (!validate_arg (dest, POINTER_TYPE))
13341 return NULL_TREE;
13342 len = gimple_call_arg (stmt, 1);
13343 if (!validate_arg (len, INTEGER_TYPE))
13344 return NULL_TREE;
13345 flag = gimple_call_arg (stmt, 2);
13346 if (!validate_arg (flag, INTEGER_TYPE))
13347 return NULL_TREE;
13348 size = gimple_call_arg (stmt, 3);
13349 if (!validate_arg (size, INTEGER_TYPE))
13350 return NULL_TREE;
13351 fmt = gimple_call_arg (stmt, 4);
13352 if (!validate_arg (fmt, POINTER_TYPE))
13353 return NULL_TREE;
13354
13355 if (! host_integerp (size, 1))
13356 return NULL_TREE;
13357
13358 if (! integer_all_onesp (size))
13359 {
13360 if (! host_integerp (len, 1))
13361 {
13362 /* If LEN is not constant, try MAXLEN too.
13363 For MAXLEN only allow optimizing into non-_ocs function
13364 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
13365 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
13366 return NULL_TREE;
13367 }
13368 else
13369 maxlen = len;
13370
13371 if (tree_int_cst_lt (size, maxlen))
13372 return NULL_TREE;
13373 }
13374
13375 if (!init_target_chars ())
13376 return NULL_TREE;
13377
13378 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
13379 or if format doesn't contain % chars or is "%s". */
13380 if (! integer_zerop (flag))
13381 {
13382 fmt_str = c_getstr (fmt);
13383 if (fmt_str == NULL)
13384 return NULL_TREE;
13385 if (strchr (fmt_str, target_percent) != NULL
13386 && strcmp (fmt_str, target_percent_s))
13387 return NULL_TREE;
13388 }
13389
13390 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
13391 available. */
13392 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
13393 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
13394 if (!fn)
13395 return NULL_TREE;
13396
13397 return gimple_rewrite_call_expr (stmt, 5, fn, 3, dest, len, fmt);
13398}
13399
13400/* Builtins with folding operations that operate on "..." arguments
13401 need special handling; we need to store the arguments in a convenient
13402 data structure before attempting any folding. Fortunately there are
13403 only a few builtins that fall into this category. FNDECL is the
13404 function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
13405 result of the function call is ignored. */
13406
13407static tree
13408gimple_fold_builtin_varargs (tree fndecl, gimple stmt, bool ignore ATTRIBUTE_UNUSED)
13409{
13410 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
13411 tree ret = NULL_TREE;
13412
13413 switch (fcode)
13414 {
13415 case BUILT_IN_SPRINTF_CHK:
13416 case BUILT_IN_VSPRINTF_CHK:
13417 ret = gimple_fold_builtin_sprintf_chk (stmt, fcode);
13418 break;
13419
13420 case BUILT_IN_SNPRINTF_CHK:
13421 case BUILT_IN_VSNPRINTF_CHK:
13422 ret = gimple_fold_builtin_snprintf_chk (stmt, NULL_TREE, fcode);
13423
13424 default:
13425 break;
13426 }
13427 if (ret)
13428 {
13429 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
13430 TREE_NO_WARNING (ret) = 1;
13431 return ret;
13432 }
13433 return NULL_TREE;
13434}
13435
13436/* A wrapper function for builtin folding that prevents warnings for
13437 "statement without effect" and the like, caused by removing the
13438 call node earlier than the warning is generated. */
13439
13440tree
13441fold_call_stmt (gimple stmt, bool ignore)
13442{
13443 tree ret = NULL_TREE;
13444 tree fndecl = gimple_call_fndecl (stmt);
13445 if (fndecl
13446 && TREE_CODE (fndecl) == FUNCTION_DECL
13447 && DECL_BUILT_IN (fndecl)
13448 && !gimple_call_va_arg_pack_p (stmt))
13449 {
13450 int nargs = gimple_call_num_args (stmt);
13451
13452 /* FIXME: Don't use a list in this interface. */
13453 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
13454 {
13455 tree arglist = NULL_TREE;
13456 int i;
13457 for (i = nargs - 1; i >= 0; i--)
13458 arglist = tree_cons (NULL_TREE, gimple_call_arg (stmt, i), arglist);
13459 return targetm.fold_builtin (fndecl, arglist, ignore);
13460 }
13461 else
13462 {
13463 if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
13464 {
13465 tree args[MAX_ARGS_TO_FOLD_BUILTIN];
13466 int i;
13467 for (i = 0; i < nargs; i++)
13468 args[i] = gimple_call_arg (stmt, i);
13469 ret = fold_builtin_n (fndecl, args, nargs, ignore);
13470 }
13471 if (!ret)
13472 ret = gimple_fold_builtin_varargs (fndecl, stmt, ignore);
13473 if (ret)
13474 {
13475 /* Propagate location information from original call to
13476 expansion of builtin. Otherwise things like
13477 maybe_emit_chk_warning, that operate on the expansion
13478 of a builtin, will use the wrong location information. */
13479 if (gimple_has_location (stmt))
13480 {
13481 tree realret = ret;
13482 if (TREE_CODE (ret) == NOP_EXPR)
13483 realret = TREE_OPERAND (ret, 0);
13484 if (CAN_HAVE_LOCATION_P (realret)
13485 && !EXPR_HAS_LOCATION (realret))
13486 SET_EXPR_LOCATION (realret, gimple_location (stmt));
13487 return realret;
13488 }
13489 return ret;
13490 }
13491 }
13492 }
13493 return NULL_TREE;
13494}