]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/builtins.c
New test
[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,
062b4460 3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
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
5383fb56 54#ifndef SLOW_UNALIGNED_ACCESS
55#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) STRICT_ALIGNMENT
56#endif
57
726e2588 58#ifndef PAD_VARARGS_DOWN
59#define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
60#endif
239d491a 61#ifdef HAVE_mpc
62static tree do_mpc_arg1 (tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_rnd_t));
63#endif
726e2588 64
ab7943b9 65/* Define the names of the builtin function types and codes. */
8934cb0c 66const char *const built_in_class_names[4]
ab7943b9 67 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
68
9cfddb70 69#define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
0dfc45b5 70const char * built_in_names[(int) END_BUILTINS] =
4e9d90c7 71{
72#include "builtins.def"
73};
74#undef DEF_BUILTIN
ab7943b9 75
df94cd3b 76/* Setup an array of _DECL trees, make sure each element is
77 initialized to NULL_TREE. */
d2d4bdde 78tree built_in_decls[(int) END_BUILTINS];
0a68165a 79/* Declarations used when constructing the builtin implicitly in the compiler.
80 It may be NULL_TREE when this is invalid (for instance runtime is not
4ee9c684 81 required to implement the function call in all cases). */
0a68165a 82tree implicit_built_in_decls[(int) END_BUILTINS];
df94cd3b 83
aecda0d6 84static const char *c_getstr (tree);
85static rtx c_readstr (const char *, enum machine_mode);
86static int target_char_cast (tree, char *);
d8ae1baa 87static rtx get_memory_rtx (tree, tree);
aecda0d6 88static int apply_args_size (void);
89static int apply_result_size (void);
d8c9779c 90#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
aecda0d6 91static rtx result_vector (int, rtx);
d8c9779c 92#endif
843d08a9 93static void expand_builtin_update_setjmp_buf (rtx);
aecda0d6 94static void expand_builtin_prefetch (tree);
95static rtx expand_builtin_apply_args (void);
96static rtx expand_builtin_apply_args_1 (void);
97static rtx expand_builtin_apply (rtx, rtx, rtx);
98static void expand_builtin_return (rtx);
99static enum type_class type_to_class (tree);
100static rtx expand_builtin_classify_type (tree);
101static void expand_errno_check (tree, rtx);
102static rtx expand_builtin_mathfn (tree, rtx, rtx);
103static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
6b43bae4 104static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
a67a90e5 105static rtx expand_builtin_interclass_mathfn (tree, rtx, rtx);
c3147c1a 106static rtx expand_builtin_sincos (tree);
d735c391 107static rtx expand_builtin_cexpi (tree, rtx, rtx);
ff1b14e4 108static rtx expand_builtin_int_roundingfn (tree, rtx);
109static rtx expand_builtin_int_roundingfn_2 (tree, rtx);
aecda0d6 110static rtx expand_builtin_args_info (tree);
79012a9d 111static rtx expand_builtin_next_arg (void);
aecda0d6 112static rtx expand_builtin_va_start (tree);
113static rtx expand_builtin_va_end (tree);
114static rtx expand_builtin_va_copy (tree);
7959b13b 115static rtx expand_builtin_memchr (tree, rtx, enum machine_mode);
c2f47e15 116static rtx expand_builtin_memcmp (tree, rtx, enum machine_mode);
aecda0d6 117static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
118static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
119static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
7da1412b 120static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
aecda0d6 121static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
122static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
123static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
124static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
c2f47e15 125static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode);
126static rtx expand_builtin_mempcpy_args (tree, tree, tree, tree, rtx,
127 enum machine_mode, int);
128static rtx expand_builtin_memmove (tree, rtx, enum machine_mode, int);
129static rtx expand_builtin_memmove_args (tree, tree, tree, tree, rtx,
130 enum machine_mode, int);
131static rtx expand_builtin_bcopy (tree, int);
1d89860b 132static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
c2f47e15 133static rtx expand_builtin_strcpy_args (tree, tree, tree, rtx, enum machine_mode);
aecda0d6 134static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
aecda0d6 135static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
aecda0d6 136static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
c2f47e15 137static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
138static rtx expand_builtin_memset_args (tree, tree, tree, rtx, enum machine_mode, tree);
aecda0d6 139static rtx expand_builtin_bzero (tree);
140static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
c2f47e15 141static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
142static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
143static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
144static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
aecda0d6 145static rtx expand_builtin_alloca (tree, rtx);
146static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
147static rtx expand_builtin_frame_address (tree, tree);
19bf118a 148static rtx expand_builtin_fputs (tree, rtx, bool);
149static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
150static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
6411575e 151static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
aecda0d6 152static tree stabilize_va_list (tree, int);
153static rtx expand_builtin_expect (tree, rtx);
154static tree fold_builtin_constant_p (tree);
76f5a783 155static tree fold_builtin_expect (tree, tree);
aecda0d6 156static tree fold_builtin_classify_type (tree);
e6e27594 157static tree fold_builtin_strlen (tree);
aecda0d6 158static tree fold_builtin_inf (tree, int);
159static tree fold_builtin_nan (tree, tree, int);
c2f47e15 160static tree rewrite_call_expr (tree, int, tree, int, ...);
b7bf20db 161static bool validate_arg (const_tree, enum tree_code code);
277f8dd2 162static bool integer_valued_real_p (tree);
76b9b24b 163static tree fold_trunc_transparent_mathfn (tree, tree);
aecda0d6 164static bool readonly_data_expr (tree);
165static rtx expand_builtin_fabs (tree, rtx, rtx);
27f261ef 166static rtx expand_builtin_signbit (tree, rtx);
e6e27594 167static tree fold_builtin_sqrt (tree, tree);
168static tree fold_builtin_cbrt (tree, tree);
c2f47e15 169static tree fold_builtin_pow (tree, tree, tree, tree);
170static tree fold_builtin_powi (tree, tree, tree, tree);
e6e27594 171static tree fold_builtin_cos (tree, tree, tree);
cacdc1af 172static tree fold_builtin_cosh (tree, tree, tree);
bffb7645 173static tree fold_builtin_tan (tree, tree);
7169af54 174static tree fold_builtin_trunc (tree, tree);
175static tree fold_builtin_floor (tree, tree);
176static tree fold_builtin_ceil (tree, tree);
177static tree fold_builtin_round (tree, tree);
ad52b9b7 178static tree fold_builtin_int_roundingfn (tree, tree);
10b9666f 179static tree fold_builtin_bitop (tree, tree);
c2f47e15 180static tree fold_builtin_memory_op (tree, tree, tree, tree, bool, int);
181static tree fold_builtin_strchr (tree, tree, tree);
7959b13b 182static tree fold_builtin_memchr (tree, tree, tree, tree);
c2f47e15 183static tree fold_builtin_memcmp (tree, tree, tree);
184static tree fold_builtin_strcmp (tree, tree);
185static tree fold_builtin_strncmp (tree, tree, tree);
64c18e8d 186static tree fold_builtin_signbit (tree, tree);
c2f47e15 187static tree fold_builtin_copysign (tree, tree, tree, tree);
467214fd 188static tree fold_builtin_isascii (tree);
189static tree fold_builtin_toascii (tree);
190static tree fold_builtin_isdigit (tree);
d1aade50 191static tree fold_builtin_fabs (tree, tree);
192static tree fold_builtin_abs (tree, tree);
c2f47e15 193static tree fold_builtin_unordered_cmp (tree, tree, tree, enum tree_code,
d5019fe8 194 enum tree_code);
c2f47e15 195static tree fold_builtin_n (tree, tree *, int, bool);
196static tree fold_builtin_0 (tree, bool);
3d3d84b8 197static tree fold_builtin_1 (tree, tree, bool);
c2f47e15 198static tree fold_builtin_2 (tree, tree, tree, bool);
199static tree fold_builtin_3 (tree, tree, tree, tree, bool);
200static tree fold_builtin_4 (tree, tree, tree, tree, tree, bool);
201static tree fold_builtin_varargs (tree, tree, bool);
202
203static tree fold_builtin_strpbrk (tree, tree, tree);
204static tree fold_builtin_strstr (tree, tree, tree);
205static tree fold_builtin_strrchr (tree, tree, tree);
206static tree fold_builtin_strcat (tree, tree);
207static tree fold_builtin_strncat (tree, tree, tree);
208static tree fold_builtin_strspn (tree, tree);
209static tree fold_builtin_strcspn (tree, tree);
210static tree fold_builtin_sprintf (tree, tree, tree, int);
4ee9c684 211
0a39fd54 212static rtx expand_builtin_object_size (tree);
213static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
214 enum built_in_function);
215static void maybe_emit_chk_warning (tree, enum built_in_function);
216static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
2c281b15 217static void maybe_emit_free_warning (tree);
c2f47e15 218static tree fold_builtin_object_size (tree, tree);
219static tree fold_builtin_strcat_chk (tree, tree, tree, tree);
220static tree fold_builtin_strncat_chk (tree, tree, tree, tree, tree);
0a39fd54 221static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
c2f47e15 222static tree fold_builtin_printf (tree, tree, tree, bool, enum built_in_function);
223static tree fold_builtin_fprintf (tree, tree, tree, tree, bool,
224 enum built_in_function);
99eabcc1 225static bool init_target_chars (void);
226
227static unsigned HOST_WIDE_INT target_newline;
228static unsigned HOST_WIDE_INT target_percent;
229static unsigned HOST_WIDE_INT target_c;
230static unsigned HOST_WIDE_INT target_s;
231static char target_percent_c[3];
232static char target_percent_s[3];
233static char target_percent_s_newline[4];
728bac60 234static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
235 const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool);
f0c477f2 236static tree do_mpfr_arg2 (tree, tree, tree,
237 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
9917422b 238static tree do_mpfr_arg3 (tree, tree, tree, tree,
239 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
d92f994c 240static tree do_mpfr_sincos (tree, tree, tree);
65dd1378 241static tree do_mpfr_bessel_n (tree, tree, tree,
242 int (*)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
243 const REAL_VALUE_TYPE *, bool);
e5407ca6 244static tree do_mpfr_remquo (tree, tree, tree);
e84da7c1 245static tree do_mpfr_lgamma_r (tree, tree, tree);
0a39fd54 246
1c47b3e8 247bool
248is_builtin_name (const char *name)
b6a5fc45 249{
b6a5fc45 250 if (strncmp (name, "__builtin_", 10) == 0)
251 return true;
252 if (strncmp (name, "__sync_", 7) == 0)
253 return true;
254 return false;
255}
4ee9c684 256
1c47b3e8 257/* Return true if NODE should be considered for inline expansion regardless
258 of the optimization level. This means whenever a function is invoked with
259 its "internal" name, which normally contains the prefix "__builtin". */
260
261static bool
262called_as_built_in (tree node)
263{
264 /* Note that we must use DECL_NAME, not DECL_ASSEMBLER_NAME_SET_P since
265 we want the name used to call the function, not the name it
266 will have. */
267 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
268 return is_builtin_name (name);
269}
270
698537d1 271/* Return the alignment in bits of EXP, an object.
272 Don't return more than MAX_ALIGN no matter what, ALIGN is the inital
273 guessed alignment e.g. from type alignment. */
274
275int
276get_object_alignment (tree exp, unsigned int align, unsigned int max_align)
277{
278 unsigned int inner;
279
280 inner = max_align;
281 if (handled_component_p (exp))
282 {
283 HOST_WIDE_INT bitsize, bitpos;
284 tree offset;
285 enum machine_mode mode;
286 int unsignedp, volatilep;
287
288 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
289 &mode, &unsignedp, &volatilep, true);
290 if (bitpos)
291 inner = MIN (inner, (unsigned) (bitpos & -bitpos));
292 while (offset)
293 {
294 tree next_offset;
295
296 if (TREE_CODE (offset) == PLUS_EXPR)
297 {
298 next_offset = TREE_OPERAND (offset, 0);
299 offset = TREE_OPERAND (offset, 1);
300 }
301 else
302 next_offset = NULL;
303 if (host_integerp (offset, 1))
304 {
305 /* Any overflow in calculating offset_bits won't change
306 the alignment. */
307 unsigned offset_bits
308 = ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT);
309
310 if (offset_bits)
311 inner = MIN (inner, (offset_bits & -offset_bits));
312 }
313 else if (TREE_CODE (offset) == MULT_EXPR
314 && host_integerp (TREE_OPERAND (offset, 1), 1))
315 {
316 /* Any overflow in calculating offset_factor won't change
317 the alignment. */
318 unsigned offset_factor
319 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
320 * BITS_PER_UNIT);
321
322 if (offset_factor)
323 inner = MIN (inner, (offset_factor & -offset_factor));
324 }
325 else
326 {
327 inner = MIN (inner, BITS_PER_UNIT);
328 break;
329 }
330 offset = next_offset;
331 }
332 }
333 if (DECL_P (exp))
334 align = MIN (inner, DECL_ALIGN (exp));
335#ifdef CONSTANT_ALIGNMENT
336 else if (CONSTANT_CLASS_P (exp))
337 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
338#endif
339 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
340 || TREE_CODE (exp) == INDIRECT_REF)
341 align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
342 else
343 align = MIN (align, inner);
344 return MIN (align, max_align);
345}
346
7abca321 347/* Returns true iff we can trust that alignment information has been
348 calculated properly. */
349
350bool
351can_trust_pointer_alignment (void)
352{
353 /* We rely on TER to compute accurate alignment information. */
354 return (optimize && flag_tree_ter);
355}
356
53800dbe 357/* Return the alignment in bits of EXP, a pointer valued expression.
358 But don't return more than MAX_ALIGN no matter what.
359 The alignment returned is, by default, the alignment of the thing that
27d0c333 360 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
53800dbe 361
362 Otherwise, look at the expression to see if we can do better, i.e., if the
363 expression is actually pointing at an object whose alignment is tighter. */
364
f656b751 365int
aecda0d6 366get_pointer_alignment (tree exp, unsigned int max_align)
53800dbe 367{
27d0c333 368 unsigned int align, inner;
53800dbe 369
7abca321 370 if (!can_trust_pointer_alignment ())
189575ff 371 return 0;
372
535e2026 373 if (!POINTER_TYPE_P (TREE_TYPE (exp)))
374 return 0;
375
53800dbe 376 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
377 align = MIN (align, max_align);
378
379 while (1)
380 {
381 switch (TREE_CODE (exp))
382 {
72dd6141 383 CASE_CONVERT:
53800dbe 384 exp = TREE_OPERAND (exp, 0);
552752f7 385 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
53800dbe 386 return align;
325d1c45 387
53800dbe 388 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
389 align = MIN (inner, max_align);
390 break;
391
0de36bdb 392 case POINTER_PLUS_EXPR:
53800dbe 393 /* If sum of pointer + int, restrict our maximum alignment to that
394 imposed by the integer. If not, we can't do any better than
395 ALIGN. */
325d1c45 396 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
53800dbe 397 return align;
398
0994d2ed 399 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
400 & (max_align / BITS_PER_UNIT - 1))
53800dbe 401 != 0)
402 max_align >>= 1;
403
404 exp = TREE_OPERAND (exp, 0);
405 break;
406
407 case ADDR_EXPR:
408 /* See what we are pointing at and look at its alignment. */
698537d1 409 return get_object_alignment (TREE_OPERAND (exp, 0), align, max_align);
53800dbe 410
411 default:
412 return align;
413 }
414 }
415}
416
417/* Compute the length of a C string. TREE_STRING_LENGTH is not the right
418 way, because it could contain a zero byte in the middle.
419 TREE_STRING_LENGTH is the size of the character array, not the string.
420
4172d65e 421 ONLY_VALUE should be nonzero if the result is not going to be emitted
c09841f6 422 into the instruction stream and zero if it is going to be expanded.
4172d65e 423 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
681fab1e 424 is returned, otherwise NULL, since
425 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
426 evaluate the side-effects.
427
902de8ed 428 The value returned is of type `ssizetype'.
429
53800dbe 430 Unfortunately, string_constant can't access the values of const char
431 arrays with initializers, so neither can we do so here. */
432
4ee9c684 433tree
681fab1e 434c_strlen (tree src, int only_value)
53800dbe 435{
436 tree offset_node;
27d0c333 437 HOST_WIDE_INT offset;
438 int max;
44acf429 439 const char *ptr;
53800dbe 440
681fab1e 441 STRIP_NOPS (src);
442 if (TREE_CODE (src) == COND_EXPR
443 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
444 {
445 tree len1, len2;
446
447 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
448 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
0862b7e9 449 if (tree_int_cst_equal (len1, len2))
681fab1e 450 return len1;
451 }
452
453 if (TREE_CODE (src) == COMPOUND_EXPR
454 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
455 return c_strlen (TREE_OPERAND (src, 1), only_value);
456
53800dbe 457 src = string_constant (src, &offset_node);
458 if (src == 0)
c2f47e15 459 return NULL_TREE;
902de8ed 460
83d79705 461 max = TREE_STRING_LENGTH (src) - 1;
53800dbe 462 ptr = TREE_STRING_POINTER (src);
902de8ed 463
53800dbe 464 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
465 {
466 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
467 compute the offset to the following null if we don't know where to
468 start searching for it. */
469 int i;
902de8ed 470
53800dbe 471 for (i = 0; i < max; i++)
472 if (ptr[i] == 0)
c2f47e15 473 return NULL_TREE;
902de8ed 474
53800dbe 475 /* We don't know the starting offset, but we do know that the string
476 has no internal zero bytes. We can assume that the offset falls
477 within the bounds of the string; otherwise, the programmer deserves
478 what he gets. Subtract the offset from the length of the string,
902de8ed 479 and return that. This would perhaps not be valid if we were dealing
480 with named arrays in addition to literal string constants. */
481
482 return size_diffop (size_int (max), offset_node);
53800dbe 483 }
484
485 /* We have a known offset into the string. Start searching there for
27d0c333 486 a null character if we can represent it as a single HOST_WIDE_INT. */
dabc4084 487 if (offset_node == 0)
53800dbe 488 offset = 0;
dabc4084 489 else if (! host_integerp (offset_node, 0))
490 offset = -1;
53800dbe 491 else
27d0c333 492 offset = tree_low_cst (offset_node, 0);
902de8ed 493
1f63a7d6 494 /* If the offset is known to be out of bounds, warn, and call strlen at
495 runtime. */
53800dbe 496 if (offset < 0 || offset > max)
497 {
1f63a7d6 498 /* Suppress multiple warnings for propagated constant strings. */
499 if (! TREE_NO_WARNING (src))
500 {
501 warning (0, "offset outside bounds of constant string");
502 TREE_NO_WARNING (src) = 1;
503 }
c2f47e15 504 return NULL_TREE;
53800dbe 505 }
902de8ed 506
53800dbe 507 /* Use strlen to search for the first zero byte. Since any strings
508 constructed with build_string will have nulls appended, we win even
509 if we get handed something like (char[4])"abcd".
510
511 Since OFFSET is our starting index into the string, no further
512 calculation is needed. */
902de8ed 513 return ssize_int (strlen (ptr + offset));
53800dbe 514}
515
83d79705 516/* Return a char pointer for a C string if it is a string constant
517 or sum of string constant and integer constant. */
518
519static const char *
aecda0d6 520c_getstr (tree src)
83d79705 521{
522 tree offset_node;
83d79705 523
524 src = string_constant (src, &offset_node);
525 if (src == 0)
526 return 0;
527
8c85fcb7 528 if (offset_node == 0)
529 return TREE_STRING_POINTER (src);
530 else if (!host_integerp (offset_node, 1)
531 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
83d79705 532 return 0;
83d79705 533
8c85fcb7 534 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
83d79705 535}
536
8c85fcb7 537/* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
538 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
ecc318ff 539
6840589f 540static rtx
aecda0d6 541c_readstr (const char *str, enum machine_mode mode)
6840589f 542{
543 HOST_WIDE_INT c[2];
544 HOST_WIDE_INT ch;
545 unsigned int i, j;
546
64db345d 547 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
7d3f6cc7 548
6840589f 549 c[0] = 0;
550 c[1] = 0;
551 ch = 1;
552 for (i = 0; i < GET_MODE_SIZE (mode); i++)
553 {
554 j = i;
555 if (WORDS_BIG_ENDIAN)
556 j = GET_MODE_SIZE (mode) - i - 1;
557 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
558 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
559 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
560 j *= BITS_PER_UNIT;
64db345d 561 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
7d3f6cc7 562
6840589f 563 if (ch)
564 ch = (unsigned char) str[i];
565 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
566 }
567 return immed_double_const (c[0], c[1], mode);
568}
569
ecc318ff 570/* Cast a target constant CST to target CHAR and if that value fits into
5206b159 571 host char type, return zero and put that value into variable pointed to by
ecc318ff 572 P. */
573
574static int
aecda0d6 575target_char_cast (tree cst, char *p)
ecc318ff 576{
577 unsigned HOST_WIDE_INT val, hostval;
578
27d0c333 579 if (!host_integerp (cst, 1)
ecc318ff 580 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
581 return 1;
582
27d0c333 583 val = tree_low_cst (cst, 1);
ecc318ff 584 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
585 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
586
587 hostval = val;
588 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
589 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
590
591 if (val != hostval)
592 return 1;
593
594 *p = hostval;
595 return 0;
596}
597
4ee9c684 598/* Similar to save_expr, but assumes that arbitrary code is not executed
599 in between the multiple evaluations. In particular, we assume that a
600 non-addressable local variable will not be modified. */
601
602static tree
603builtin_save_expr (tree exp)
604{
605 if (TREE_ADDRESSABLE (exp) == 0
606 && (TREE_CODE (exp) == PARM_DECL
607 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
608 return exp;
609
610 return save_expr (exp);
611}
612
53800dbe 613/* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
614 times to get the address of either a higher stack frame, or a return
615 address located within it (depending on FNDECL_CODE). */
902de8ed 616
c626df3d 617static rtx
869d0ef0 618expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
53800dbe 619{
620 int i;
621
869d0ef0 622#ifdef INITIAL_FRAME_ADDRESS_RTX
623 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
624#else
e3e15c50 625 rtx tem;
626
1b74fde7 627 /* For a zero count with __builtin_return_address, we don't care what
628 frame address we return, because target-specific definitions will
629 override us. Therefore frame pointer elimination is OK, and using
630 the soft frame pointer is OK.
631
fa7637bd 632 For a nonzero count, or a zero count with __builtin_frame_address,
1b74fde7 633 we require a stable offset from the current frame pointer to the
634 previous one, so we must use the hard frame pointer, and
e3e15c50 635 we must disable frame pointer elimination. */
1b74fde7 636 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
e3e15c50 637 tem = frame_pointer_rtx;
a0c938f0 638 else
e3e15c50 639 {
640 tem = hard_frame_pointer_rtx;
641
642 /* Tell reload not to eliminate the frame pointer. */
18d50ae6 643 crtl->accesses_prior_frames = 1;
e3e15c50 644 }
869d0ef0 645#endif
646
53800dbe 647 /* Some machines need special handling before we can access
3a69c60c 648 arbitrary frames. For example, on the SPARC, we must first flush
53800dbe 649 all register windows to the stack. */
650#ifdef SETUP_FRAME_ADDRESSES
651 if (count > 0)
652 SETUP_FRAME_ADDRESSES ();
653#endif
654
3a69c60c 655 /* On the SPARC, the return address is not in the frame, it is in a
53800dbe 656 register. There is no way to access it off of the current frame
657 pointer, but it can be accessed off the previous frame pointer by
658 reading the value from the register window save area. */
659#ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
660 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
661 count--;
662#endif
663
664 /* Scan back COUNT frames to the specified frame. */
665 for (i = 0; i < count; i++)
666 {
667 /* Assume the dynamic chain pointer is in the word that the
668 frame address points to, unless otherwise specified. */
669#ifdef DYNAMIC_CHAIN_ADDRESS
670 tem = DYNAMIC_CHAIN_ADDRESS (tem);
671#endif
672 tem = memory_address (Pmode, tem);
00060fc2 673 tem = gen_frame_mem (Pmode, tem);
83fc1478 674 tem = copy_to_reg (tem);
53800dbe 675 }
676
3a69c60c 677 /* For __builtin_frame_address, return what we've got. But, on
678 the SPARC for example, we may have to add a bias. */
53800dbe 679 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
3a69c60c 680#ifdef FRAME_ADDR_RTX
681 return FRAME_ADDR_RTX (tem);
682#else
53800dbe 683 return tem;
3a69c60c 684#endif
53800dbe 685
3a69c60c 686 /* For __builtin_return_address, get the return address from that frame. */
53800dbe 687#ifdef RETURN_ADDR_RTX
688 tem = RETURN_ADDR_RTX (count, tem);
689#else
690 tem = memory_address (Pmode,
691 plus_constant (tem, GET_MODE_SIZE (Pmode)));
00060fc2 692 tem = gen_frame_mem (Pmode, tem);
53800dbe 693#endif
694 return tem;
695}
696
f7c44134 697/* Alias set used for setjmp buffer. */
32c2fdea 698static alias_set_type setjmp_alias_set = -1;
f7c44134 699
6b7f6858 700/* Construct the leading half of a __builtin_setjmp call. Control will
2c8a1497 701 return to RECEIVER_LABEL. This is also called directly by the SJLJ
702 exception handling code. */
53800dbe 703
6b7f6858 704void
aecda0d6 705expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
53800dbe 706{
53800dbe 707 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
53800dbe 708 rtx stack_save;
f7c44134 709 rtx mem;
53800dbe 710
f7c44134 711 if (setjmp_alias_set == -1)
712 setjmp_alias_set = new_alias_set ();
713
85d654dd 714 buf_addr = convert_memory_address (Pmode, buf_addr);
53800dbe 715
37ae8504 716 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
53800dbe 717
6b7f6858 718 /* We store the frame pointer and the address of receiver_label in
719 the buffer and use the rest of it for the stack save area, which
720 is machine-dependent. */
53800dbe 721
f7c44134 722 mem = gen_rtx_MEM (Pmode, buf_addr);
ab6ab77e 723 set_mem_alias_set (mem, setjmp_alias_set);
e3e026e8 724 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
f7c44134 725
726 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
ab6ab77e 727 set_mem_alias_set (mem, setjmp_alias_set);
f7c44134 728
729 emit_move_insn (validize_mem (mem),
6b7f6858 730 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
53800dbe 731
732 stack_save = gen_rtx_MEM (sa_mode,
733 plus_constant (buf_addr,
734 2 * GET_MODE_SIZE (Pmode)));
ab6ab77e 735 set_mem_alias_set (stack_save, setjmp_alias_set);
53800dbe 736 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
737
738 /* If there is further processing to do, do it. */
739#ifdef HAVE_builtin_setjmp_setup
740 if (HAVE_builtin_setjmp_setup)
741 emit_insn (gen_builtin_setjmp_setup (buf_addr));
742#endif
743
6b7f6858 744 /* Tell optimize_save_area_alloca that extra work is going to
745 need to go on during alloca. */
18d50ae6 746 cfun->calls_setjmp = 1;
80ab81b9 747
29f09705 748 /* We have a nonlocal label. */
18d50ae6 749 cfun->has_nonlocal_label = 1;
6b7f6858 750}
53800dbe 751
2c8a1497 752/* Construct the trailing part of a __builtin_setjmp call. This is
753 also called directly by the SJLJ exception handling code. */
6b7f6858 754
755void
aecda0d6 756expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
6b7f6858 757{
53800dbe 758 /* Clobber the FP when we get here, so we have to make sure it's
759 marked as used by this function. */
18b42941 760 emit_use (hard_frame_pointer_rtx);
53800dbe 761
762 /* Mark the static chain as clobbered here so life information
763 doesn't get messed up for it. */
18b42941 764 emit_clobber (static_chain_rtx);
53800dbe 765
766 /* Now put in the code to restore the frame pointer, and argument
491e04ef 767 pointer, if needed. */
53800dbe 768#ifdef HAVE_nonlocal_goto
769 if (! HAVE_nonlocal_goto)
770#endif
5a1c3f40 771 {
772 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
773 /* This might change the hard frame pointer in ways that aren't
774 apparent to early optimization passes, so force a clobber. */
18b42941 775 emit_clobber (hard_frame_pointer_rtx);
5a1c3f40 776 }
53800dbe 777
778#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
779 if (fixed_regs[ARG_POINTER_REGNUM])
780 {
781#ifdef ELIMINABLE_REGS
782 size_t i;
e99c3a1d 783 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
53800dbe 784
3098b2d3 785 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
53800dbe 786 if (elim_regs[i].from == ARG_POINTER_REGNUM
787 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
788 break;
789
3098b2d3 790 if (i == ARRAY_SIZE (elim_regs))
53800dbe 791#endif
792 {
793 /* Now restore our arg pointer from the address at which it
05927e40 794 was saved in our stack frame. */
27a7a23a 795 emit_move_insn (crtl->args.internal_arg_pointer,
b079a207 796 copy_to_reg (get_arg_pointer_save_area ()));
53800dbe 797 }
798 }
799#endif
800
801#ifdef HAVE_builtin_setjmp_receiver
802 if (HAVE_builtin_setjmp_receiver)
6b7f6858 803 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
53800dbe 804 else
805#endif
806#ifdef HAVE_nonlocal_goto_receiver
807 if (HAVE_nonlocal_goto_receiver)
808 emit_insn (gen_nonlocal_goto_receiver ());
809 else
810#endif
6b7f6858 811 { /* Nothing */ }
57f6bb94 812
3072d30e 813 /* We must not allow the code we just generated to be reordered by
814 scheduling. Specifically, the update of the frame pointer must
815 happen immediately, not later. */
816 emit_insn (gen_blockage ());
6b7f6858 817}
53800dbe 818
53800dbe 819/* __builtin_longjmp is passed a pointer to an array of five words (not
820 all will be used on all machines). It operates similarly to the C
821 library function of the same name, but is more efficient. Much of
2c8a1497 822 the code below is copied from the handling of non-local gotos. */
53800dbe 823
c626df3d 824static void
aecda0d6 825expand_builtin_longjmp (rtx buf_addr, rtx value)
53800dbe 826{
4712c7d6 827 rtx fp, lab, stack, insn, last;
53800dbe 828 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
829
27a7a23a 830 /* DRAP is needed for stack realign if longjmp is expanded to current
831 function */
832 if (SUPPORTS_STACK_ALIGNMENT)
833 crtl->need_drap = true;
834
f7c44134 835 if (setjmp_alias_set == -1)
836 setjmp_alias_set = new_alias_set ();
837
85d654dd 838 buf_addr = convert_memory_address (Pmode, buf_addr);
479e4d5e 839
53800dbe 840 buf_addr = force_reg (Pmode, buf_addr);
841
842 /* We used to store value in static_chain_rtx, but that fails if pointers
843 are smaller than integers. We instead require that the user must pass
844 a second argument of 1, because that is what builtin_setjmp will
845 return. This also makes EH slightly more efficient, since we are no
846 longer copying around a value that we don't care about. */
64db345d 847 gcc_assert (value == const1_rtx);
53800dbe 848
4712c7d6 849 last = get_last_insn ();
53800dbe 850#ifdef HAVE_builtin_longjmp
851 if (HAVE_builtin_longjmp)
852 emit_insn (gen_builtin_longjmp (buf_addr));
853 else
854#endif
855 {
856 fp = gen_rtx_MEM (Pmode, buf_addr);
857 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
858 GET_MODE_SIZE (Pmode)));
859
860 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
861 2 * GET_MODE_SIZE (Pmode)));
ab6ab77e 862 set_mem_alias_set (fp, setjmp_alias_set);
863 set_mem_alias_set (lab, setjmp_alias_set);
864 set_mem_alias_set (stack, setjmp_alias_set);
53800dbe 865
866 /* Pick up FP, label, and SP from the block and jump. This code is
867 from expand_goto in stmt.c; see there for detailed comments. */
03fd9d2c 868#ifdef HAVE_nonlocal_goto
53800dbe 869 if (HAVE_nonlocal_goto)
870 /* We have to pass a value to the nonlocal_goto pattern that will
871 get copied into the static_chain pointer, but it does not matter
872 what that value is, because builtin_setjmp does not use it. */
28d202a8 873 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
53800dbe 874 else
875#endif
876 {
877 lab = copy_to_reg (lab);
878
18b42941 879 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
880 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
2a871ad1 881
53800dbe 882 emit_move_insn (hard_frame_pointer_rtx, fp);
883 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
884
18b42941 885 emit_use (hard_frame_pointer_rtx);
886 emit_use (stack_pointer_rtx);
53800dbe 887 emit_indirect_jump (lab);
888 }
889 }
615166bb 890
891 /* Search backwards and mark the jump insn as a non-local goto.
892 Note that this precludes the use of __builtin_longjmp to a
893 __builtin_setjmp target in the same function. However, we've
894 already cautioned the user that these functions are for
895 internal exception handling use only. */
449c0509 896 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
897 {
64db345d 898 gcc_assert (insn != last);
7d3f6cc7 899
6d7dc5b9 900 if (JUMP_P (insn))
449c0509 901 {
a1ddb869 902 add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
449c0509 903 break;
904 }
6d7dc5b9 905 else if (CALL_P (insn))
9342ee68 906 break;
449c0509 907 }
53800dbe 908}
909
4ee9c684 910/* Expand a call to __builtin_nonlocal_goto. We're passed the target label
911 and the address of the save area. */
912
913static rtx
c2f47e15 914expand_builtin_nonlocal_goto (tree exp)
4ee9c684 915{
916 tree t_label, t_save_area;
917 rtx r_label, r_save_area, r_fp, r_sp, insn;
918
c2f47e15 919 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4ee9c684 920 return NULL_RTX;
921
c2f47e15 922 t_label = CALL_EXPR_ARG (exp, 0);
923 t_save_area = CALL_EXPR_ARG (exp, 1);
4ee9c684 924
8ec3c5c2 925 r_label = expand_normal (t_label);
3dce56cc 926 r_label = convert_memory_address (Pmode, r_label);
8ec3c5c2 927 r_save_area = expand_normal (t_save_area);
3dce56cc 928 r_save_area = convert_memory_address (Pmode, r_save_area);
51adbc8a 929 /* Copy the address of the save location to a register just in case it was based
930 on the frame pointer. */
931 r_save_area = copy_to_reg (r_save_area);
4ee9c684 932 r_fp = gen_rtx_MEM (Pmode, r_save_area);
933 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
934 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
935
18d50ae6 936 crtl->has_nonlocal_goto = 1;
4ee9c684 937
03fd9d2c 938#ifdef HAVE_nonlocal_goto
4ee9c684 939 /* ??? We no longer need to pass the static chain value, afaik. */
940 if (HAVE_nonlocal_goto)
941 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
942 else
943#endif
944 {
945 r_label = copy_to_reg (r_label);
946
18b42941 947 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
948 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
491e04ef 949
4ee9c684 950 /* Restore frame pointer for containing function.
951 This sets the actual hard register used for the frame pointer
952 to the location of the function's incoming static chain info.
953 The non-local goto handler will then adjust it to contain the
954 proper value and reload the argument pointer, if needed. */
955 emit_move_insn (hard_frame_pointer_rtx, r_fp);
956 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
491e04ef 957
4ee9c684 958 /* USE of hard_frame_pointer_rtx added for consistency;
959 not clear if really needed. */
18b42941 960 emit_use (hard_frame_pointer_rtx);
961 emit_use (stack_pointer_rtx);
ad0d0af8 962
963 /* If the architecture is using a GP register, we must
964 conservatively assume that the target function makes use of it.
965 The prologue of functions with nonlocal gotos must therefore
966 initialize the GP register to the appropriate value, and we
967 must then make sure that this value is live at the point
968 of the jump. (Note that this doesn't necessarily apply
969 to targets with a nonlocal_goto pattern; they are free
970 to implement it in their own way. Note also that this is
971 a no-op if the GP register is a global invariant.) */
972 if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
973 && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
18b42941 974 emit_use (pic_offset_table_rtx);
ad0d0af8 975
4ee9c684 976 emit_indirect_jump (r_label);
977 }
491e04ef 978
4ee9c684 979 /* Search backwards to the jump insn and mark it as a
980 non-local goto. */
981 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
982 {
6d7dc5b9 983 if (JUMP_P (insn))
4ee9c684 984 {
a1ddb869 985 add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
4ee9c684 986 break;
987 }
6d7dc5b9 988 else if (CALL_P (insn))
4ee9c684 989 break;
990 }
991
992 return const0_rtx;
993}
994
843d08a9 995/* __builtin_update_setjmp_buf is passed a pointer to an array of five words
996 (not all will be used on all machines) that was passed to __builtin_setjmp.
997 It updates the stack pointer in that block to correspond to the current
998 stack pointer. */
999
1000static void
1001expand_builtin_update_setjmp_buf (rtx buf_addr)
1002{
1003 enum machine_mode sa_mode = Pmode;
1004 rtx stack_save;
1005
1006
1007#ifdef HAVE_save_stack_nonlocal
1008 if (HAVE_save_stack_nonlocal)
1009 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
1010#endif
1011#ifdef STACK_SAVEAREA_MODE
1012 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
1013#endif
1014
1015 stack_save
1016 = gen_rtx_MEM (sa_mode,
1017 memory_address
1018 (sa_mode,
1019 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
1020
1021#ifdef HAVE_setjmp
1022 if (HAVE_setjmp)
1023 emit_insn (gen_setjmp ());
1024#endif
1025
1026 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
1027}
1028
5e3608d8 1029/* Expand a call to __builtin_prefetch. For a target that does not support
1030 data prefetch, evaluate the memory address argument in case it has side
1031 effects. */
1032
1033static void
c2f47e15 1034expand_builtin_prefetch (tree exp)
5e3608d8 1035{
1036 tree arg0, arg1, arg2;
c2f47e15 1037 int nargs;
5e3608d8 1038 rtx op0, op1, op2;
1039
c2f47e15 1040 if (!validate_arglist (exp, POINTER_TYPE, 0))
26a5cadb 1041 return;
1042
c2f47e15 1043 arg0 = CALL_EXPR_ARG (exp, 0);
1044
26a5cadb 1045 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
1046 zero (read) and argument 2 (locality) defaults to 3 (high degree of
1047 locality). */
c2f47e15 1048 nargs = call_expr_nargs (exp);
1049 if (nargs > 1)
1050 arg1 = CALL_EXPR_ARG (exp, 1);
26a5cadb 1051 else
c2f47e15 1052 arg1 = integer_zero_node;
1053 if (nargs > 2)
1054 arg2 = CALL_EXPR_ARG (exp, 2);
1055 else
1056 arg2 = build_int_cst (NULL_TREE, 3);
5e3608d8 1057
1058 /* Argument 0 is an address. */
1059 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
1060
1061 /* Argument 1 (read/write flag) must be a compile-time constant int. */
1062 if (TREE_CODE (arg1) != INTEGER_CST)
1063 {
07e3a3d2 1064 error ("second argument to %<__builtin_prefetch%> must be a constant");
9342ee68 1065 arg1 = integer_zero_node;
5e3608d8 1066 }
8ec3c5c2 1067 op1 = expand_normal (arg1);
5e3608d8 1068 /* Argument 1 must be either zero or one. */
1069 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
1070 {
c3ceba8e 1071 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
07e3a3d2 1072 " using zero");
5e3608d8 1073 op1 = const0_rtx;
1074 }
1075
1076 /* Argument 2 (locality) must be a compile-time constant int. */
1077 if (TREE_CODE (arg2) != INTEGER_CST)
1078 {
07e3a3d2 1079 error ("third argument to %<__builtin_prefetch%> must be a constant");
5e3608d8 1080 arg2 = integer_zero_node;
1081 }
8ec3c5c2 1082 op2 = expand_normal (arg2);
5e3608d8 1083 /* Argument 2 must be 0, 1, 2, or 3. */
1084 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1085 {
c3ceba8e 1086 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
5e3608d8 1087 op2 = const0_rtx;
1088 }
1089
1090#ifdef HAVE_prefetch
1091 if (HAVE_prefetch)
1092 {
f0ce3b1f 1093 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
4cd21437 1094 (op0,
f0ce3b1f 1095 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
19bf118a 1096 || (GET_MODE (op0) != Pmode))
9342ee68 1097 {
85d654dd 1098 op0 = convert_memory_address (Pmode, op0);
9342ee68 1099 op0 = force_reg (Pmode, op0);
1100 }
5e3608d8 1101 emit_insn (gen_prefetch (op0, op1, op2));
1102 }
5e3608d8 1103#endif
0a534ba7 1104
f0ce3b1f 1105 /* Don't do anything with direct references to volatile memory, but
1106 generate code to handle other side effects. */
e16ceb8e 1107 if (!MEM_P (op0) && side_effects_p (op0))
f0ce3b1f 1108 emit_insn (op0);
5e3608d8 1109}
1110
f7c44134 1111/* Get a MEM rtx for expression EXP which is the address of an operand
d8ae1baa 1112 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1113 the maximum length of the block of memory that might be accessed or
1114 NULL if unknown. */
f7c44134 1115
53800dbe 1116static rtx
d8ae1baa 1117get_memory_rtx (tree exp, tree len)
53800dbe 1118{
ad0a178f 1119 tree orig_exp = exp;
1120 rtx addr, mem;
1121 HOST_WIDE_INT off;
1122
1123 /* When EXP is not resolved SAVE_EXPR, MEM_ATTRS can be still derived
1124 from its expression, for expr->a.b only <variable>.a.b is recorded. */
1125 if (TREE_CODE (exp) == SAVE_EXPR && !SAVE_EXPR_RESOLVED_P (exp))
1126 exp = TREE_OPERAND (exp, 0);
1127
1128 addr = expand_expr (orig_exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1129 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
2a631e19 1130
f7c44134 1131 /* Get an expression we can use to find the attributes to assign to MEM.
1132 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1133 we can. First remove any nops. */
72dd6141 1134 while (CONVERT_EXPR_P (exp)
f7c44134 1135 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1136 exp = TREE_OPERAND (exp, 0);
1137
ad0a178f 1138 off = 0;
1139 if (TREE_CODE (exp) == POINTER_PLUS_EXPR
1140 && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
1141 && host_integerp (TREE_OPERAND (exp, 1), 0)
1142 && (off = tree_low_cst (TREE_OPERAND (exp, 1), 0)) > 0)
1143 exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1144 else if (TREE_CODE (exp) == ADDR_EXPR)
a1a25d19 1145 exp = TREE_OPERAND (exp, 0);
f7c44134 1146 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
a1a25d19 1147 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1148 else
1149 exp = NULL;
1150
1151 /* Honor attributes derived from exp, except for the alias set
1152 (as builtin stringops may alias with anything) and the size
1153 (as stringops may access multiple array elements). */
1154 if (exp)
eec8e941 1155 {
a1a25d19 1156 set_mem_attributes (mem, exp, 0);
d8ae1baa 1157
ad0a178f 1158 if (off)
1159 mem = adjust_automodify_address_nv (mem, BLKmode, NULL, off);
1160
d8ae1baa 1161 /* Allow the string and memory builtins to overflow from one
1162 field into another, see http://gcc.gnu.org/PR23561.
1163 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1164 memory accessed by the string or memory builtin will fit
1165 within the field. */
1166 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1167 {
1168 tree mem_expr = MEM_EXPR (mem);
1169 HOST_WIDE_INT offset = -1, length = -1;
1170 tree inner = exp;
1171
1172 while (TREE_CODE (inner) == ARRAY_REF
72dd6141 1173 || CONVERT_EXPR_P (inner)
d8ae1baa 1174 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1175 || TREE_CODE (inner) == SAVE_EXPR)
1176 inner = TREE_OPERAND (inner, 0);
1177
1178 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1179
1180 if (MEM_OFFSET (mem)
971ba038 1181 && CONST_INT_P (MEM_OFFSET (mem)))
d8ae1baa 1182 offset = INTVAL (MEM_OFFSET (mem));
1183
1184 if (offset >= 0 && len && host_integerp (len, 0))
1185 length = tree_low_cst (len, 0);
1186
1187 while (TREE_CODE (inner) == COMPONENT_REF)
1188 {
1189 tree field = TREE_OPERAND (inner, 1);
d8ae1baa 1190 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1191 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1192
6933ebec 1193 /* Bitfields are generally not byte-addressable. */
1194 gcc_assert (!DECL_BIT_FIELD (field)
1195 || ((tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1196 % BITS_PER_UNIT) == 0
1197 && host_integerp (DECL_SIZE (field), 0)
1198 && (TREE_INT_CST_LOW (DECL_SIZE (field))
1199 % BITS_PER_UNIT) == 0));
1200
b2f0b2a3 1201 /* If we can prove that the memory starting at XEXP (mem, 0) and
1202 ending at XEXP (mem, 0) + LENGTH will fit into this field, we
1203 can keep the COMPONENT_REF in MEM_EXPR. But be careful with
1204 fields without DECL_SIZE_UNIT like flexible array members. */
d8ae1baa 1205 if (length >= 0
b2f0b2a3 1206 && DECL_SIZE_UNIT (field)
6933ebec 1207 && host_integerp (DECL_SIZE_UNIT (field), 0))
d8ae1baa 1208 {
1209 HOST_WIDE_INT size
6933ebec 1210 = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field));
d8ae1baa 1211 if (offset <= size
1212 && length <= size
1213 && offset + length <= size)
1214 break;
1215 }
1216
1217 if (offset >= 0
1218 && host_integerp (DECL_FIELD_OFFSET (field), 0))
6933ebec 1219 offset += TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field))
d8ae1baa 1220 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1221 / BITS_PER_UNIT;
1222 else
1223 {
1224 offset = -1;
1225 length = -1;
1226 }
1227
1228 mem_expr = TREE_OPERAND (mem_expr, 0);
1229 inner = TREE_OPERAND (inner, 0);
d8ae1baa 1230 }
1231
1232 if (mem_expr == NULL)
1233 offset = -1;
1234 if (mem_expr != MEM_EXPR (mem))
1235 {
1236 set_mem_expr (mem, mem_expr);
1237 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1238 }
1239 }
eec8e941 1240 set_mem_alias_set (mem, 0);
a1a25d19 1241 set_mem_size (mem, NULL_RTX);
eec8e941 1242 }
53800dbe 1243
53800dbe 1244 return mem;
1245}
1246\f
1247/* Built-in functions to perform an untyped call and return. */
1248
1249/* For each register that may be used for calling a function, this
1250 gives a mode used to copy the register's value. VOIDmode indicates
1251 the register is not used for calling a function. If the machine
1252 has register windows, this gives only the outbound registers.
1253 INCOMING_REGNO gives the corresponding inbound register. */
1254static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1255
1256/* For each register that may be used for returning values, this gives
1257 a mode used to copy the register's value. VOIDmode indicates the
1258 register is not used for returning values. If the machine has
1259 register windows, this gives only the outbound registers.
1260 INCOMING_REGNO gives the corresponding inbound register. */
1261static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1262
1263/* For each register that may be used for calling a function, this
1264 gives the offset of that register into the block returned by
1265 __builtin_apply_args. 0 indicates that the register is not
1266 used for calling a function. */
1267static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1268
53800dbe 1269/* Return the size required for the block returned by __builtin_apply_args,
1270 and initialize apply_args_mode. */
1271
1272static int
aecda0d6 1273apply_args_size (void)
53800dbe 1274{
1275 static int size = -1;
58e9ce8f 1276 int align;
1277 unsigned int regno;
53800dbe 1278 enum machine_mode mode;
1279
1280 /* The values computed by this function never change. */
1281 if (size < 0)
1282 {
1283 /* The first value is the incoming arg-pointer. */
1284 size = GET_MODE_SIZE (Pmode);
1285
1286 /* The second value is the structure value address unless this is
1287 passed as an "invisible" first argument. */
6812c89e 1288 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
53800dbe 1289 size += GET_MODE_SIZE (Pmode);
1290
1291 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1292 if (FUNCTION_ARG_REGNO_P (regno))
1293 {
0862b7e9 1294 mode = reg_raw_mode[regno];
1295
64db345d 1296 gcc_assert (mode != VOIDmode);
53800dbe 1297
1298 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1299 if (size % align != 0)
1300 size = CEIL (size, align) * align;
1301 apply_args_reg_offset[regno] = size;
1302 size += GET_MODE_SIZE (mode);
1303 apply_args_mode[regno] = mode;
1304 }
1305 else
1306 {
1307 apply_args_mode[regno] = VOIDmode;
1308 apply_args_reg_offset[regno] = 0;
1309 }
1310 }
1311 return size;
1312}
1313
1314/* Return the size required for the block returned by __builtin_apply,
1315 and initialize apply_result_mode. */
1316
1317static int
aecda0d6 1318apply_result_size (void)
53800dbe 1319{
1320 static int size = -1;
1321 int align, regno;
1322 enum machine_mode mode;
1323
1324 /* The values computed by this function never change. */
1325 if (size < 0)
1326 {
1327 size = 0;
1328
1329 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1330 if (FUNCTION_VALUE_REGNO_P (regno))
1331 {
0862b7e9 1332 mode = reg_raw_mode[regno];
1333
64db345d 1334 gcc_assert (mode != VOIDmode);
53800dbe 1335
1336 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1337 if (size % align != 0)
1338 size = CEIL (size, align) * align;
1339 size += GET_MODE_SIZE (mode);
1340 apply_result_mode[regno] = mode;
1341 }
1342 else
1343 apply_result_mode[regno] = VOIDmode;
1344
1345 /* Allow targets that use untyped_call and untyped_return to override
1346 the size so that machine-specific information can be stored here. */
1347#ifdef APPLY_RESULT_SIZE
1348 size = APPLY_RESULT_SIZE;
1349#endif
1350 }
1351 return size;
1352}
1353
1354#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1355/* Create a vector describing the result block RESULT. If SAVEP is true,
1356 the result block is used to save the values; otherwise it is used to
1357 restore the values. */
1358
1359static rtx
aecda0d6 1360result_vector (int savep, rtx result)
53800dbe 1361{
1362 int regno, size, align, nelts;
1363 enum machine_mode mode;
1364 rtx reg, mem;
364c0c59 1365 rtx *savevec = XALLOCAVEC (rtx, FIRST_PSEUDO_REGISTER);
bf8e3599 1366
53800dbe 1367 size = nelts = 0;
1368 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1369 if ((mode = apply_result_mode[regno]) != VOIDmode)
1370 {
1371 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1372 if (size % align != 0)
1373 size = CEIL (size, align) * align;
1374 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
e513d163 1375 mem = adjust_address (result, mode, size);
53800dbe 1376 savevec[nelts++] = (savep
1377 ? gen_rtx_SET (VOIDmode, mem, reg)
1378 : gen_rtx_SET (VOIDmode, reg, mem));
1379 size += GET_MODE_SIZE (mode);
1380 }
1381 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1382}
1383#endif /* HAVE_untyped_call or HAVE_untyped_return */
1384
1385/* Save the state required to perform an untyped call with the same
1386 arguments as were passed to the current function. */
1387
1388static rtx
aecda0d6 1389expand_builtin_apply_args_1 (void)
53800dbe 1390{
1c7e61a7 1391 rtx registers, tem;
53800dbe 1392 int size, align, regno;
1393 enum machine_mode mode;
6812c89e 1394 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
53800dbe 1395
1396 /* Create a block where the arg-pointer, structure value address,
1397 and argument registers can be saved. */
1398 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1399
1400 /* Walk past the arg-pointer and structure value address. */
1401 size = GET_MODE_SIZE (Pmode);
6812c89e 1402 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
53800dbe 1403 size += GET_MODE_SIZE (Pmode);
1404
1405 /* Save each register used in calling a function to the block. */
1406 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1407 if ((mode = apply_args_mode[regno]) != VOIDmode)
1408 {
53800dbe 1409 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1410 if (size % align != 0)
1411 size = CEIL (size, align) * align;
1412
1413 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1414
e513d163 1415 emit_move_insn (adjust_address (registers, mode, size), tem);
53800dbe 1416 size += GET_MODE_SIZE (mode);
1417 }
1418
1419 /* Save the arg pointer to the block. */
27a7a23a 1420 tem = copy_to_reg (crtl->args.internal_arg_pointer);
f083a92b 1421#ifdef STACK_GROWS_DOWNWARD
1c7e61a7 1422 /* We need the pointer as the caller actually passed them to us, not
9d4b544c 1423 as we might have pretended they were passed. Make sure it's a valid
1424 operand, as emit_move_insn isn't expected to handle a PLUS. */
1425 tem
abe32cce 1426 = force_operand (plus_constant (tem, crtl->args.pretend_args_size),
9d4b544c 1427 NULL_RTX);
1c7e61a7 1428#endif
1429 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
0862b7e9 1430
53800dbe 1431 size = GET_MODE_SIZE (Pmode);
1432
1433 /* Save the structure value address unless this is passed as an
1434 "invisible" first argument. */
45550790 1435 if (struct_incoming_value)
53800dbe 1436 {
e513d163 1437 emit_move_insn (adjust_address (registers, Pmode, size),
45550790 1438 copy_to_reg (struct_incoming_value));
53800dbe 1439 size += GET_MODE_SIZE (Pmode);
1440 }
1441
1442 /* Return the address of the block. */
1443 return copy_addr_to_reg (XEXP (registers, 0));
1444}
1445
1446/* __builtin_apply_args returns block of memory allocated on
1447 the stack into which is stored the arg pointer, structure
1448 value address, static chain, and all the registers that might
1449 possibly be used in performing a function call. The code is
1450 moved to the start of the function so the incoming values are
1451 saved. */
27d0c333 1452
53800dbe 1453static rtx
aecda0d6 1454expand_builtin_apply_args (void)
53800dbe 1455{
1456 /* Don't do __builtin_apply_args more than once in a function.
1457 Save the result of the first call and reuse it. */
1458 if (apply_args_value != 0)
1459 return apply_args_value;
1460 {
1461 /* When this function is called, it means that registers must be
1462 saved on entry to this function. So we migrate the
1463 call to the first insn of this function. */
1464 rtx temp;
1465 rtx seq;
1466
1467 start_sequence ();
1468 temp = expand_builtin_apply_args_1 ();
1469 seq = get_insns ();
1470 end_sequence ();
1471
1472 apply_args_value = temp;
1473
31d3e01c 1474 /* Put the insns after the NOTE that starts the function.
1475 If this is inside a start_sequence, make the outer-level insn
53800dbe 1476 chain current, so the code is placed at the start of the
0ef1a651 1477 function. If internal_arg_pointer is a non-virtual pseudo,
1478 it needs to be placed after the function that initializes
1479 that pseudo. */
53800dbe 1480 push_topmost_sequence ();
0ef1a651 1481 if (REG_P (crtl->args.internal_arg_pointer)
1482 && REGNO (crtl->args.internal_arg_pointer) > LAST_VIRTUAL_REGISTER)
1483 emit_insn_before (seq, parm_birth_insn);
1484 else
1485 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
53800dbe 1486 pop_topmost_sequence ();
1487 return temp;
1488 }
1489}
1490
1491/* Perform an untyped call and save the state required to perform an
1492 untyped return of whatever value was returned by the given function. */
1493
1494static rtx
aecda0d6 1495expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
53800dbe 1496{
1497 int size, align, regno;
1498 enum machine_mode mode;
2a631e19 1499 rtx incoming_args, result, reg, dest, src, call_insn;
53800dbe 1500 rtx old_stack_level = 0;
1501 rtx call_fusage = 0;
6812c89e 1502 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
53800dbe 1503
85d654dd 1504 arguments = convert_memory_address (Pmode, arguments);
726ec87c 1505
53800dbe 1506 /* Create a block where the return registers can be saved. */
1507 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1508
53800dbe 1509 /* Fetch the arg pointer from the ARGUMENTS block. */
1510 incoming_args = gen_reg_rtx (Pmode);
726ec87c 1511 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
53800dbe 1512#ifndef STACK_GROWS_DOWNWARD
ad99e708 1513 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1514 incoming_args, 0, OPTAB_LIB_WIDEN);
53800dbe 1515#endif
1516
04a46d40 1517 /* Push a new argument block and copy the arguments. Do not allow
1518 the (potential) memcpy call below to interfere with our stack
1519 manipulations. */
53800dbe 1520 do_pending_stack_adjust ();
04a46d40 1521 NO_DEFER_POP;
53800dbe 1522
2358393e 1523 /* Save the stack with nonlocal if available. */
53800dbe 1524#ifdef HAVE_save_stack_nonlocal
1525 if (HAVE_save_stack_nonlocal)
1526 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1527 else
1528#endif
1529 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1530
59647703 1531 /* Allocate a block of memory onto the stack and copy the memory
1532 arguments to the outgoing arguments address. */
1533 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
27a7a23a 1534
1535 /* Set DRAP flag to true, even though allocate_dynamic_stack_space
1536 may have already set current_function_calls_alloca to true.
1537 current_function_calls_alloca won't be set if argsize is zero,
1538 so we have to guarantee need_drap is true here. */
1539 if (SUPPORTS_STACK_ALIGNMENT)
1540 crtl->need_drap = true;
1541
59647703 1542 dest = virtual_outgoing_args_rtx;
1543#ifndef STACK_GROWS_DOWNWARD
971ba038 1544 if (CONST_INT_P (argsize))
59647703 1545 dest = plus_constant (dest, -INTVAL (argsize));
1546 else
1547 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1548#endif
2a631e19 1549 dest = gen_rtx_MEM (BLKmode, dest);
1550 set_mem_align (dest, PARM_BOUNDARY);
1551 src = gen_rtx_MEM (BLKmode, incoming_args);
1552 set_mem_align (src, PARM_BOUNDARY);
0378dbdc 1553 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
53800dbe 1554
1555 /* Refer to the argument block. */
1556 apply_args_size ();
1557 arguments = gen_rtx_MEM (BLKmode, arguments);
2a631e19 1558 set_mem_align (arguments, PARM_BOUNDARY);
53800dbe 1559
1560 /* Walk past the arg-pointer and structure value address. */
1561 size = GET_MODE_SIZE (Pmode);
45550790 1562 if (struct_value)
53800dbe 1563 size += GET_MODE_SIZE (Pmode);
1564
1565 /* Restore each of the registers previously saved. Make USE insns
1566 for each of these registers for use in making the call. */
1567 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1568 if ((mode = apply_args_mode[regno]) != VOIDmode)
1569 {
1570 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1571 if (size % align != 0)
1572 size = CEIL (size, align) * align;
1573 reg = gen_rtx_REG (mode, regno);
e513d163 1574 emit_move_insn (reg, adjust_address (arguments, mode, size));
53800dbe 1575 use_reg (&call_fusage, reg);
1576 size += GET_MODE_SIZE (mode);
1577 }
1578
1579 /* Restore the structure value address unless this is passed as an
1580 "invisible" first argument. */
1581 size = GET_MODE_SIZE (Pmode);
45550790 1582 if (struct_value)
53800dbe 1583 {
1584 rtx value = gen_reg_rtx (Pmode);
e513d163 1585 emit_move_insn (value, adjust_address (arguments, Pmode, size));
45550790 1586 emit_move_insn (struct_value, value);
8ad4c111 1587 if (REG_P (struct_value))
45550790 1588 use_reg (&call_fusage, struct_value);
53800dbe 1589 size += GET_MODE_SIZE (Pmode);
1590 }
1591
1592 /* All arguments and registers used for the call are set up by now! */
4ee9c684 1593 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
53800dbe 1594
1595 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1596 and we don't want to load it into a register as an optimization,
1597 because prepare_call_address already did it if it should be done. */
1598 if (GET_CODE (function) != SYMBOL_REF)
1599 function = memory_address (FUNCTION_MODE, function);
1600
1601 /* Generate the actual call instruction and save the return value. */
1602#ifdef HAVE_untyped_call
1603 if (HAVE_untyped_call)
1604 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1605 result, result_vector (1, result)));
1606 else
1607#endif
1608#ifdef HAVE_call_value
1609 if (HAVE_call_value)
1610 {
1611 rtx valreg = 0;
1612
1613 /* Locate the unique return register. It is not possible to
1614 express a call that sets more than one return register using
1615 call_value; use untyped_call for that. In fact, untyped_call
1616 only needs to save the return registers in the given block. */
1617 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1618 if ((mode = apply_result_mode[regno]) != VOIDmode)
1619 {
64db345d 1620 gcc_assert (!valreg); /* HAVE_untyped_call required. */
7d3f6cc7 1621
53800dbe 1622 valreg = gen_rtx_REG (mode, regno);
1623 }
1624
2ed6c343 1625 emit_call_insn (GEN_CALL_VALUE (valreg,
53800dbe 1626 gen_rtx_MEM (FUNCTION_MODE, function),
1627 const0_rtx, NULL_RTX, const0_rtx));
1628
e513d163 1629 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
53800dbe 1630 }
1631 else
1632#endif
64db345d 1633 gcc_unreachable ();
53800dbe 1634
d5f9786f 1635 /* Find the CALL insn we just emitted, and attach the register usage
1636 information. */
1637 call_insn = last_call_insn ();
1638 add_function_usage_to (call_insn, call_fusage);
53800dbe 1639
1640 /* Restore the stack. */
1641#ifdef HAVE_save_stack_nonlocal
1642 if (HAVE_save_stack_nonlocal)
1643 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1644 else
1645#endif
1646 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1647
04a46d40 1648 OK_DEFER_POP;
1649
53800dbe 1650 /* Return the address of the result block. */
85d654dd 1651 result = copy_addr_to_reg (XEXP (result, 0));
1652 return convert_memory_address (ptr_mode, result);
53800dbe 1653}
1654
1655/* Perform an untyped return. */
1656
1657static void
aecda0d6 1658expand_builtin_return (rtx result)
53800dbe 1659{
1660 int size, align, regno;
1661 enum machine_mode mode;
1662 rtx reg;
1663 rtx call_fusage = 0;
1664
85d654dd 1665 result = convert_memory_address (Pmode, result);
726ec87c 1666
53800dbe 1667 apply_result_size ();
1668 result = gen_rtx_MEM (BLKmode, result);
1669
1670#ifdef HAVE_untyped_return
1671 if (HAVE_untyped_return)
1672 {
1673 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1674 emit_barrier ();
1675 return;
1676 }
1677#endif
1678
1679 /* Restore the return value and note that each value is used. */
1680 size = 0;
1681 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1682 if ((mode = apply_result_mode[regno]) != VOIDmode)
1683 {
1684 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1685 if (size % align != 0)
1686 size = CEIL (size, align) * align;
1687 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
e513d163 1688 emit_move_insn (reg, adjust_address (result, mode, size));
53800dbe 1689
1690 push_to_sequence (call_fusage);
18b42941 1691 emit_use (reg);
53800dbe 1692 call_fusage = get_insns ();
1693 end_sequence ();
1694 size += GET_MODE_SIZE (mode);
1695 }
1696
1697 /* Put the USE insns before the return. */
31d3e01c 1698 emit_insn (call_fusage);
53800dbe 1699
1700 /* Return whatever values was restored by jumping directly to the end
1701 of the function. */
62380d2d 1702 expand_naked_return ();
53800dbe 1703}
1704
539a3a92 1705/* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
27d0c333 1706
539a3a92 1707static enum type_class
aecda0d6 1708type_to_class (tree type)
539a3a92 1709{
1710 switch (TREE_CODE (type))
1711 {
1712 case VOID_TYPE: return void_type_class;
1713 case INTEGER_TYPE: return integer_type_class;
539a3a92 1714 case ENUMERAL_TYPE: return enumeral_type_class;
1715 case BOOLEAN_TYPE: return boolean_type_class;
1716 case POINTER_TYPE: return pointer_type_class;
1717 case REFERENCE_TYPE: return reference_type_class;
1718 case OFFSET_TYPE: return offset_type_class;
1719 case REAL_TYPE: return real_type_class;
1720 case COMPLEX_TYPE: return complex_type_class;
1721 case FUNCTION_TYPE: return function_type_class;
1722 case METHOD_TYPE: return method_type_class;
1723 case RECORD_TYPE: return record_type_class;
1724 case UNION_TYPE:
1725 case QUAL_UNION_TYPE: return union_type_class;
1726 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1727 ? string_type_class : array_type_class);
539a3a92 1728 case LANG_TYPE: return lang_type_class;
1729 default: return no_type_class;
1730 }
1731}
bf8e3599 1732
c2f47e15 1733/* Expand a call EXP to __builtin_classify_type. */
27d0c333 1734
53800dbe 1735static rtx
c2f47e15 1736expand_builtin_classify_type (tree exp)
53800dbe 1737{
c2f47e15 1738 if (call_expr_nargs (exp))
1739 return GEN_INT (type_to_class (TREE_TYPE (CALL_EXPR_ARG (exp, 0))));
53800dbe 1740 return GEN_INT (no_type_class);
1741}
1742
07976da7 1743/* This helper macro, meant to be used in mathfn_built_in below,
1744 determines which among a set of three builtin math functions is
1745 appropriate for a given type mode. The `F' and `L' cases are
1746 automatically generated from the `double' case. */
1747#define CASE_MATHFN(BUILT_IN_MATHFN) \
1748 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1749 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1750 fcodel = BUILT_IN_MATHFN##L ; break;
cd2656b0 1751/* Similar to above, but appends _R after any F/L suffix. */
1752#define CASE_MATHFN_REENT(BUILT_IN_MATHFN) \
1753 case BUILT_IN_MATHFN##_R: case BUILT_IN_MATHFN##F_R: case BUILT_IN_MATHFN##L_R: \
1754 fcode = BUILT_IN_MATHFN##_R; fcodef = BUILT_IN_MATHFN##F_R ; \
1755 fcodel = BUILT_IN_MATHFN##L_R ; break;
07976da7 1756
1757/* Return mathematic function equivalent to FN but operating directly
c319d56a 1758 on TYPE, if available. If IMPLICIT is true find the function in
1759 implicit_built_in_decls[], otherwise use built_in_decls[]. If we
1760 can't do the conversion, return zero. */
1761
1762static tree
1763mathfn_built_in_1 (tree type, enum built_in_function fn, bool implicit)
0a68165a 1764{
c319d56a 1765 tree const *const fn_arr
1766 = implicit ? implicit_built_in_decls : built_in_decls;
07976da7 1767 enum built_in_function fcode, fcodef, fcodel;
1768
1769 switch (fn)
1770 {
746114e8 1771 CASE_MATHFN (BUILT_IN_ACOS)
1772 CASE_MATHFN (BUILT_IN_ACOSH)
1773 CASE_MATHFN (BUILT_IN_ASIN)
1774 CASE_MATHFN (BUILT_IN_ASINH)
07976da7 1775 CASE_MATHFN (BUILT_IN_ATAN)
746114e8 1776 CASE_MATHFN (BUILT_IN_ATAN2)
1777 CASE_MATHFN (BUILT_IN_ATANH)
1778 CASE_MATHFN (BUILT_IN_CBRT)
07976da7 1779 CASE_MATHFN (BUILT_IN_CEIL)
d735c391 1780 CASE_MATHFN (BUILT_IN_CEXPI)
746114e8 1781 CASE_MATHFN (BUILT_IN_COPYSIGN)
07976da7 1782 CASE_MATHFN (BUILT_IN_COS)
746114e8 1783 CASE_MATHFN (BUILT_IN_COSH)
1784 CASE_MATHFN (BUILT_IN_DREM)
1785 CASE_MATHFN (BUILT_IN_ERF)
1786 CASE_MATHFN (BUILT_IN_ERFC)
07976da7 1787 CASE_MATHFN (BUILT_IN_EXP)
746114e8 1788 CASE_MATHFN (BUILT_IN_EXP10)
1789 CASE_MATHFN (BUILT_IN_EXP2)
1790 CASE_MATHFN (BUILT_IN_EXPM1)
1791 CASE_MATHFN (BUILT_IN_FABS)
1792 CASE_MATHFN (BUILT_IN_FDIM)
07976da7 1793 CASE_MATHFN (BUILT_IN_FLOOR)
746114e8 1794 CASE_MATHFN (BUILT_IN_FMA)
1795 CASE_MATHFN (BUILT_IN_FMAX)
1796 CASE_MATHFN (BUILT_IN_FMIN)
1797 CASE_MATHFN (BUILT_IN_FMOD)
1798 CASE_MATHFN (BUILT_IN_FREXP)
1799 CASE_MATHFN (BUILT_IN_GAMMA)
cd2656b0 1800 CASE_MATHFN_REENT (BUILT_IN_GAMMA) /* GAMMA_R */
746114e8 1801 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1802 CASE_MATHFN (BUILT_IN_HYPOT)
1803 CASE_MATHFN (BUILT_IN_ILOGB)
1804 CASE_MATHFN (BUILT_IN_INF)
69b779ea 1805 CASE_MATHFN (BUILT_IN_ISINF)
746114e8 1806 CASE_MATHFN (BUILT_IN_J0)
1807 CASE_MATHFN (BUILT_IN_J1)
1808 CASE_MATHFN (BUILT_IN_JN)
ac148751 1809 CASE_MATHFN (BUILT_IN_LCEIL)
746114e8 1810 CASE_MATHFN (BUILT_IN_LDEXP)
ad52b9b7 1811 CASE_MATHFN (BUILT_IN_LFLOOR)
746114e8 1812 CASE_MATHFN (BUILT_IN_LGAMMA)
cd2656b0 1813 CASE_MATHFN_REENT (BUILT_IN_LGAMMA) /* LGAMMA_R */
ac148751 1814 CASE_MATHFN (BUILT_IN_LLCEIL)
ad52b9b7 1815 CASE_MATHFN (BUILT_IN_LLFLOOR)
746114e8 1816 CASE_MATHFN (BUILT_IN_LLRINT)
1817 CASE_MATHFN (BUILT_IN_LLROUND)
07976da7 1818 CASE_MATHFN (BUILT_IN_LOG)
746114e8 1819 CASE_MATHFN (BUILT_IN_LOG10)
1820 CASE_MATHFN (BUILT_IN_LOG1P)
1821 CASE_MATHFN (BUILT_IN_LOG2)
1822 CASE_MATHFN (BUILT_IN_LOGB)
1823 CASE_MATHFN (BUILT_IN_LRINT)
1824 CASE_MATHFN (BUILT_IN_LROUND)
1825 CASE_MATHFN (BUILT_IN_MODF)
1826 CASE_MATHFN (BUILT_IN_NAN)
1827 CASE_MATHFN (BUILT_IN_NANS)
07976da7 1828 CASE_MATHFN (BUILT_IN_NEARBYINT)
746114e8 1829 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1830 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1831 CASE_MATHFN (BUILT_IN_POW)
757c219d 1832 CASE_MATHFN (BUILT_IN_POWI)
746114e8 1833 CASE_MATHFN (BUILT_IN_POW10)
1834 CASE_MATHFN (BUILT_IN_REMAINDER)
1835 CASE_MATHFN (BUILT_IN_REMQUO)
1836 CASE_MATHFN (BUILT_IN_RINT)
07976da7 1837 CASE_MATHFN (BUILT_IN_ROUND)
746114e8 1838 CASE_MATHFN (BUILT_IN_SCALB)
1839 CASE_MATHFN (BUILT_IN_SCALBLN)
1840 CASE_MATHFN (BUILT_IN_SCALBN)
c319d56a 1841 CASE_MATHFN (BUILT_IN_SIGNBIT)
746114e8 1842 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
07976da7 1843 CASE_MATHFN (BUILT_IN_SIN)
746114e8 1844 CASE_MATHFN (BUILT_IN_SINCOS)
1845 CASE_MATHFN (BUILT_IN_SINH)
07976da7 1846 CASE_MATHFN (BUILT_IN_SQRT)
1847 CASE_MATHFN (BUILT_IN_TAN)
746114e8 1848 CASE_MATHFN (BUILT_IN_TANH)
1849 CASE_MATHFN (BUILT_IN_TGAMMA)
07976da7 1850 CASE_MATHFN (BUILT_IN_TRUNC)
746114e8 1851 CASE_MATHFN (BUILT_IN_Y0)
1852 CASE_MATHFN (BUILT_IN_Y1)
1853 CASE_MATHFN (BUILT_IN_YN)
07976da7 1854
0a68165a 1855 default:
c2f47e15 1856 return NULL_TREE;
0a68165a 1857 }
07976da7 1858
96b9f485 1859 if (TYPE_MAIN_VARIANT (type) == double_type_node)
c319d56a 1860 return fn_arr[fcode];
96b9f485 1861 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
c319d56a 1862 return fn_arr[fcodef];
96b9f485 1863 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
c319d56a 1864 return fn_arr[fcodel];
07976da7 1865 else
c2f47e15 1866 return NULL_TREE;
0a68165a 1867}
1868
c319d56a 1869/* Like mathfn_built_in_1(), but always use the implicit array. */
1870
1871tree
1872mathfn_built_in (tree type, enum built_in_function fn)
1873{
1874 return mathfn_built_in_1 (type, fn, /*implicit=*/ 1);
1875}
1876
0fd605a5 1877/* If errno must be maintained, expand the RTL to check if the result,
1878 TARGET, of a built-in function call, EXP, is NaN, and if so set
1879 errno to EDOM. */
1880
1881static void
aecda0d6 1882expand_errno_check (tree exp, rtx target)
0fd605a5 1883{
7f05340e 1884 rtx lab = gen_label_rtx ();
0fd605a5 1885
7f05340e 1886 /* Test the result; if it is NaN, set errno=EDOM because
1887 the argument was not in the domain. */
3fcf767f 1888 do_compare_rtx_and_jump (target, target, EQ, 0, GET_MODE (target),
1889 NULL_RTX, NULL_RTX, lab);
0fd605a5 1890
1891#ifdef TARGET_EDOM
7f05340e 1892 /* If this built-in doesn't throw an exception, set errno directly. */
c2f47e15 1893 if (TREE_NOTHROW (TREE_OPERAND (CALL_EXPR_FN (exp), 0)))
7f05340e 1894 {
0fd605a5 1895#ifdef GEN_ERRNO_RTX
7f05340e 1896 rtx errno_rtx = GEN_ERRNO_RTX;
0fd605a5 1897#else
7f05340e 1898 rtx errno_rtx
0fd605a5 1899 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1900#endif
7f05340e 1901 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
0fd605a5 1902 emit_label (lab);
7f05340e 1903 return;
0fd605a5 1904 }
7f05340e 1905#endif
1906
08491912 1907 /* Make sure the library call isn't expanded as a tail call. */
1908 CALL_EXPR_TAILCALL (exp) = 0;
1909
7f05340e 1910 /* We can't set errno=EDOM directly; let the library call do it.
1911 Pop the arguments right away in case the call gets deleted. */
1912 NO_DEFER_POP;
1913 expand_call (exp, target, 0);
1914 OK_DEFER_POP;
1915 emit_label (lab);
0fd605a5 1916}
1917
6b43bae4 1918/* Expand a call to one of the builtin math functions (sqrt, exp, or log).
c2f47e15 1919 Return NULL_RTX if a normal call should be emitted rather than expanding
1920 the function in-line. EXP is the expression that is a call to the builtin
53800dbe 1921 function; if convenient, the result should be placed in TARGET.
1922 SUBTARGET may be used as the target for computing one of EXP's operands. */
27d0c333 1923
53800dbe 1924static rtx
aecda0d6 1925expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
53800dbe 1926{
bf8e3599 1927 optab builtin_optab;
bd421108 1928 rtx op0, insns, before_call;
c6e6ecb1 1929 tree fndecl = get_callee_fndecl (exp);
7f05340e 1930 enum machine_mode mode;
528ee710 1931 bool errno_set = false;
abfea505 1932 tree arg;
53800dbe 1933
c2f47e15 1934 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
1935 return NULL_RTX;
53800dbe 1936
c2f47e15 1937 arg = CALL_EXPR_ARG (exp, 0);
53800dbe 1938
1939 switch (DECL_FUNCTION_CODE (fndecl))
1940 {
4f35b1fc 1941 CASE_FLT_FN (BUILT_IN_SQRT):
7f05340e 1942 errno_set = ! tree_expr_nonnegative_p (arg);
1943 builtin_optab = sqrt_optab;
1944 break;
4f35b1fc 1945 CASE_FLT_FN (BUILT_IN_EXP):
528ee710 1946 errno_set = true; builtin_optab = exp_optab; break;
4f35b1fc 1947 CASE_FLT_FN (BUILT_IN_EXP10):
1948 CASE_FLT_FN (BUILT_IN_POW10):
750ef9f5 1949 errno_set = true; builtin_optab = exp10_optab; break;
4f35b1fc 1950 CASE_FLT_FN (BUILT_IN_EXP2):
750ef9f5 1951 errno_set = true; builtin_optab = exp2_optab; break;
4f35b1fc 1952 CASE_FLT_FN (BUILT_IN_EXPM1):
a6b4eed2 1953 errno_set = true; builtin_optab = expm1_optab; break;
4f35b1fc 1954 CASE_FLT_FN (BUILT_IN_LOGB):
4efbc641 1955 errno_set = true; builtin_optab = logb_optab; break;
4f35b1fc 1956 CASE_FLT_FN (BUILT_IN_LOG):
528ee710 1957 errno_set = true; builtin_optab = log_optab; break;
4f35b1fc 1958 CASE_FLT_FN (BUILT_IN_LOG10):
d3cd9bde 1959 errno_set = true; builtin_optab = log10_optab; break;
4f35b1fc 1960 CASE_FLT_FN (BUILT_IN_LOG2):
d3cd9bde 1961 errno_set = true; builtin_optab = log2_optab; break;
4f35b1fc 1962 CASE_FLT_FN (BUILT_IN_LOG1P):
f474cd93 1963 errno_set = true; builtin_optab = log1p_optab; break;
4f35b1fc 1964 CASE_FLT_FN (BUILT_IN_ASIN):
8de2f465 1965 builtin_optab = asin_optab; break;
4f35b1fc 1966 CASE_FLT_FN (BUILT_IN_ACOS):
8de2f465 1967 builtin_optab = acos_optab; break;
4f35b1fc 1968 CASE_FLT_FN (BUILT_IN_TAN):
528ee710 1969 builtin_optab = tan_optab; break;
4f35b1fc 1970 CASE_FLT_FN (BUILT_IN_ATAN):
528ee710 1971 builtin_optab = atan_optab; break;
4f35b1fc 1972 CASE_FLT_FN (BUILT_IN_FLOOR):
528ee710 1973 builtin_optab = floor_optab; break;
4f35b1fc 1974 CASE_FLT_FN (BUILT_IN_CEIL):
528ee710 1975 builtin_optab = ceil_optab; break;
4f35b1fc 1976 CASE_FLT_FN (BUILT_IN_TRUNC):
a7cc195f 1977 builtin_optab = btrunc_optab; break;
4f35b1fc 1978 CASE_FLT_FN (BUILT_IN_ROUND):
528ee710 1979 builtin_optab = round_optab; break;
4f35b1fc 1980 CASE_FLT_FN (BUILT_IN_NEARBYINT):
0ddf4ad9 1981 builtin_optab = nearbyint_optab;
1982 if (flag_trapping_math)
1983 break;
1984 /* Else fallthrough and expand as rint. */
4f35b1fc 1985 CASE_FLT_FN (BUILT_IN_RINT):
aef94a0f 1986 builtin_optab = rint_optab; break;
b3154a1f 1987 CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
1988 builtin_optab = significand_optab; break;
42721db0 1989 default:
64db345d 1990 gcc_unreachable ();
53800dbe 1991 }
1992
7f05340e 1993 /* Make a suitable register to place result in. */
1994 mode = TYPE_MODE (TREE_TYPE (exp));
fc4eef90 1995
7f05340e 1996 if (! flag_errno_math || ! HONOR_NANS (mode))
1997 errno_set = false;
1998
bd421108 1999 /* Before working hard, check whether the instruction is available. */
99bdde56 2000 if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing)
68e6cb9d 2001 {
bd421108 2002 target = gen_reg_rtx (mode);
7f05340e 2003
bd421108 2004 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2005 need to expand the argument again. This way, we will not perform
2006 side-effects more the once. */
abfea505 2007 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
7f05340e 2008
1db6d067 2009 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
7f05340e 2010
bd421108 2011 start_sequence ();
53800dbe 2012
bd421108 2013 /* Compute into TARGET.
2014 Set TARGET to wherever the result comes back. */
2015 target = expand_unop (mode, builtin_optab, op0, target, 0);
2016
2017 if (target != 0)
2018 {
2019 if (errno_set)
2020 expand_errno_check (exp, target);
2021
2022 /* Output the entire sequence. */
2023 insns = get_insns ();
2024 end_sequence ();
2025 emit_insn (insns);
2026 return target;
2027 }
2028
2029 /* If we were unable to expand via the builtin, stop the sequence
2030 (without outputting the insns) and call to the library function
2031 with the stabilized argument list. */
53800dbe 2032 end_sequence ();
53800dbe 2033 }
2034
bd421108 2035 before_call = get_last_insn ();
2036
1e5b92fa 2037 return expand_call (exp, target, target == const0_rtx);
0fd605a5 2038}
2039
2040/* Expand a call to the builtin binary math functions (pow and atan2).
c2f47e15 2041 Return NULL_RTX if a normal call should be emitted rather than expanding the
0fd605a5 2042 function in-line. EXP is the expression that is a call to the builtin
2043 function; if convenient, the result should be placed in TARGET.
2044 SUBTARGET may be used as the target for computing one of EXP's
2045 operands. */
2046
2047static rtx
aecda0d6 2048expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
0fd605a5 2049{
2050 optab builtin_optab;
2051 rtx op0, op1, insns;
4737caf2 2052 int op1_type = REAL_TYPE;
c6e6ecb1 2053 tree fndecl = get_callee_fndecl (exp);
abfea505 2054 tree arg0, arg1;
7f05340e 2055 enum machine_mode mode;
0fd605a5 2056 bool errno_set = true;
0fd605a5 2057
73a954a1 2058 switch (DECL_FUNCTION_CODE (fndecl))
2059 {
2060 CASE_FLT_FN (BUILT_IN_SCALBN):
2061 CASE_FLT_FN (BUILT_IN_SCALBLN):
2062 CASE_FLT_FN (BUILT_IN_LDEXP):
2063 op1_type = INTEGER_TYPE;
2064 default:
2065 break;
2066 }
4737caf2 2067
c2f47e15 2068 if (!validate_arglist (exp, REAL_TYPE, op1_type, VOID_TYPE))
2069 return NULL_RTX;
0fd605a5 2070
c2f47e15 2071 arg0 = CALL_EXPR_ARG (exp, 0);
2072 arg1 = CALL_EXPR_ARG (exp, 1);
0fd605a5 2073
0fd605a5 2074 switch (DECL_FUNCTION_CODE (fndecl))
2075 {
4f35b1fc 2076 CASE_FLT_FN (BUILT_IN_POW):
0fd605a5 2077 builtin_optab = pow_optab; break;
4f35b1fc 2078 CASE_FLT_FN (BUILT_IN_ATAN2):
0fd605a5 2079 builtin_optab = atan2_optab; break;
73a954a1 2080 CASE_FLT_FN (BUILT_IN_SCALB):
2081 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2082 return 0;
2083 builtin_optab = scalb_optab; break;
2084 CASE_FLT_FN (BUILT_IN_SCALBN):
2085 CASE_FLT_FN (BUILT_IN_SCALBLN):
2086 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2087 return 0;
2088 /* Fall through... */
4f35b1fc 2089 CASE_FLT_FN (BUILT_IN_LDEXP):
4737caf2 2090 builtin_optab = ldexp_optab; break;
4f35b1fc 2091 CASE_FLT_FN (BUILT_IN_FMOD):
80ed5c06 2092 builtin_optab = fmod_optab; break;
ef722005 2093 CASE_FLT_FN (BUILT_IN_REMAINDER):
4f35b1fc 2094 CASE_FLT_FN (BUILT_IN_DREM):
ef722005 2095 builtin_optab = remainder_optab; break;
0fd605a5 2096 default:
64db345d 2097 gcc_unreachable ();
0fd605a5 2098 }
2099
7f05340e 2100 /* Make a suitable register to place result in. */
2101 mode = TYPE_MODE (TREE_TYPE (exp));
fc4eef90 2102
2103 /* Before working hard, check whether the instruction is available. */
99bdde56 2104 if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing)
c2f47e15 2105 return NULL_RTX;
fc4eef90 2106
7f05340e 2107 target = gen_reg_rtx (mode);
2108
2109 if (! flag_errno_math || ! HONOR_NANS (mode))
2110 errno_set = false;
2111
4ee9c684 2112 /* Always stabilize the argument list. */
abfea505 2113 CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
2114 CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1);
7f05340e 2115
8ec3c5c2 2116 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2117 op1 = expand_normal (arg1);
7f05340e 2118
7f05340e 2119 start_sequence ();
2120
0fd605a5 2121 /* Compute into TARGET.
2122 Set TARGET to wherever the result comes back. */
7f05340e 2123 target = expand_binop (mode, builtin_optab, op0, op1,
0fd605a5 2124 target, 0, OPTAB_DIRECT);
53800dbe 2125
68e6cb9d 2126 /* If we were unable to expand via the builtin, stop the sequence
2127 (without outputting the insns) and call to the library function
2128 with the stabilized argument list. */
0fd605a5 2129 if (target == 0)
2130 {
2131 end_sequence ();
68e6cb9d 2132 return expand_call (exp, target, target == const0_rtx);
53800dbe 2133 }
2134
a4356fb9 2135 if (errno_set)
2136 expand_errno_check (exp, target);
0fd605a5 2137
53800dbe 2138 /* Output the entire sequence. */
2139 insns = get_insns ();
2140 end_sequence ();
31d3e01c 2141 emit_insn (insns);
bf8e3599 2142
53800dbe 2143 return target;
2144}
2145
6b43bae4 2146/* Expand a call to the builtin sin and cos math functions.
c2f47e15 2147 Return NULL_RTX if a normal call should be emitted rather than expanding the
6b43bae4 2148 function in-line. EXP is the expression that is a call to the builtin
2149 function; if convenient, the result should be placed in TARGET.
2150 SUBTARGET may be used as the target for computing one of EXP's
2151 operands. */
2152
2153static rtx
2154expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2155{
2156 optab builtin_optab;
7511b819 2157 rtx op0, insns;
6b43bae4 2158 tree fndecl = get_callee_fndecl (exp);
6b43bae4 2159 enum machine_mode mode;
abfea505 2160 tree arg;
6b43bae4 2161
c2f47e15 2162 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2163 return NULL_RTX;
6b43bae4 2164
c2f47e15 2165 arg = CALL_EXPR_ARG (exp, 0);
6b43bae4 2166
2167 switch (DECL_FUNCTION_CODE (fndecl))
2168 {
4f35b1fc 2169 CASE_FLT_FN (BUILT_IN_SIN):
2170 CASE_FLT_FN (BUILT_IN_COS):
6b43bae4 2171 builtin_optab = sincos_optab; break;
2172 default:
64db345d 2173 gcc_unreachable ();
6b43bae4 2174 }
2175
2176 /* Make a suitable register to place result in. */
2177 mode = TYPE_MODE (TREE_TYPE (exp));
2178
6b43bae4 2179 /* Check if sincos insn is available, otherwise fallback
0bed3869 2180 to sin or cos insn. */
99bdde56 2181 if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing)
6b43bae4 2182 switch (DECL_FUNCTION_CODE (fndecl))
2183 {
4f35b1fc 2184 CASE_FLT_FN (BUILT_IN_SIN):
6b43bae4 2185 builtin_optab = sin_optab; break;
4f35b1fc 2186 CASE_FLT_FN (BUILT_IN_COS):
6b43bae4 2187 builtin_optab = cos_optab; break;
2188 default:
64db345d 2189 gcc_unreachable ();
6b43bae4 2190 }
6b43bae4 2191
2192 /* Before working hard, check whether the instruction is available. */
99bdde56 2193 if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing)
6b43bae4 2194 {
2195 target = gen_reg_rtx (mode);
2196
2197 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2198 need to expand the argument again. This way, we will not perform
2199 side-effects more the once. */
abfea505 2200 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
6b43bae4 2201
1db6d067 2202 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
6b43bae4 2203
6b43bae4 2204 start_sequence ();
2205
2206 /* Compute into TARGET.
2207 Set TARGET to wherever the result comes back. */
2208 if (builtin_optab == sincos_optab)
2209 {
64db345d 2210 int result;
7d3f6cc7 2211
6b43bae4 2212 switch (DECL_FUNCTION_CODE (fndecl))
2213 {
4f35b1fc 2214 CASE_FLT_FN (BUILT_IN_SIN):
64db345d 2215 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
6b43bae4 2216 break;
4f35b1fc 2217 CASE_FLT_FN (BUILT_IN_COS):
64db345d 2218 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
6b43bae4 2219 break;
2220 default:
64db345d 2221 gcc_unreachable ();
6b43bae4 2222 }
64db345d 2223 gcc_assert (result);
6b43bae4 2224 }
2225 else
2226 {
2227 target = expand_unop (mode, builtin_optab, op0, target, 0);
2228 }
2229
2230 if (target != 0)
2231 {
6b43bae4 2232 /* Output the entire sequence. */
2233 insns = get_insns ();
2234 end_sequence ();
2235 emit_insn (insns);
2236 return target;
2237 }
2238
2239 /* If we were unable to expand via the builtin, stop the sequence
2240 (without outputting the insns) and call to the library function
2241 with the stabilized argument list. */
2242 end_sequence ();
2243 }
2244
6b43bae4 2245 target = expand_call (exp, target, target == const0_rtx);
2246
2247 return target;
2248}
2249
a67a90e5 2250/* Expand a call to one of the builtin math functions that operate on
2251 floating point argument and output an integer result (ilogb, isinf,
2252 isnan, etc).
2253 Return 0 if a normal call should be emitted rather than expanding the
2254 function in-line. EXP is the expression that is a call to the builtin
2255 function; if convenient, the result should be placed in TARGET.
2256 SUBTARGET may be used as the target for computing one of EXP's operands. */
2257
2258static rtx
2259expand_builtin_interclass_mathfn (tree exp, rtx target, rtx subtarget)
2260{
cde061c1 2261 optab builtin_optab = 0;
2262 enum insn_code icode = CODE_FOR_nothing;
a67a90e5 2263 rtx op0;
2264 tree fndecl = get_callee_fndecl (exp);
a67a90e5 2265 enum machine_mode mode;
2266 bool errno_set = false;
abfea505 2267 tree arg;
a67a90e5 2268
c2f47e15 2269 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2270 return NULL_RTX;
a67a90e5 2271
c2f47e15 2272 arg = CALL_EXPR_ARG (exp, 0);
a67a90e5 2273
2274 switch (DECL_FUNCTION_CODE (fndecl))
2275 {
2276 CASE_FLT_FN (BUILT_IN_ILOGB):
2277 errno_set = true; builtin_optab = ilogb_optab; break;
69b779ea 2278 CASE_FLT_FN (BUILT_IN_ISINF):
2279 builtin_optab = isinf_optab; break;
8a1a9cb7 2280 case BUILT_IN_ISNORMAL:
cde061c1 2281 case BUILT_IN_ISFINITE:
2282 CASE_FLT_FN (BUILT_IN_FINITE):
2283 /* These builtins have no optabs (yet). */
2284 break;
a67a90e5 2285 default:
2286 gcc_unreachable ();
2287 }
2288
2289 /* There's no easy way to detect the case we need to set EDOM. */
2290 if (flag_errno_math && errno_set)
2291 return NULL_RTX;
2292
2293 /* Optab mode depends on the mode of the input argument. */
2294 mode = TYPE_MODE (TREE_TYPE (arg));
2295
cde061c1 2296 if (builtin_optab)
99bdde56 2297 icode = optab_handler (builtin_optab, mode)->insn_code;
a67a90e5 2298
2299 /* Before working hard, check whether the instruction is available. */
2300 if (icode != CODE_FOR_nothing)
2301 {
2302 /* Make a suitable register to place result in. */
2303 if (!target
2304 || GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
2305 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
2306
2307 gcc_assert (insn_data[icode].operand[0].predicate
2308 (target, GET_MODE (target)));
2309
2310 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2311 need to expand the argument again. This way, we will not perform
2312 side-effects more the once. */
abfea505 2313 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
a67a90e5 2314
1db6d067 2315 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
a67a90e5 2316
2317 if (mode != GET_MODE (op0))
2318 op0 = convert_to_mode (mode, op0, 0);
2319
2320 /* Compute into TARGET.
2321 Set TARGET to wherever the result comes back. */
2322 emit_unop_insn (icode, target, op0, UNKNOWN);
2323 return target;
2324 }
2325
06f7a99d 2326 /* If there is no optab, try generic code. */
2327 switch (DECL_FUNCTION_CODE (fndecl))
2328 {
2329 tree result;
2330
2331 CASE_FLT_FN (BUILT_IN_ISINF):
2332 {
2333 /* isinf(x) -> isgreater(fabs(x),DBL_MAX). */
2334 tree const isgr_fn = built_in_decls[BUILT_IN_ISGREATER];
2335 tree const type = TREE_TYPE (arg);
2336 REAL_VALUE_TYPE r;
2337 char buf[128];
2338
2339 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2340 real_from_string (&r, buf);
2341 result = build_call_expr (isgr_fn, 2,
2342 fold_build1 (ABS_EXPR, type, arg),
2343 build_real (type, r));
2344 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2345 }
cde061c1 2346 CASE_FLT_FN (BUILT_IN_FINITE):
2347 case BUILT_IN_ISFINITE:
2348 {
2349 /* isfinite(x) -> islessequal(fabs(x),DBL_MAX). */
2350 tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
2351 tree const type = TREE_TYPE (arg);
2352 REAL_VALUE_TYPE r;
2353 char buf[128];
2354
2355 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2356 real_from_string (&r, buf);
2357 result = build_call_expr (isle_fn, 2,
2358 fold_build1 (ABS_EXPR, type, arg),
2359 build_real (type, r));
2360 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2361 }
8a1a9cb7 2362 case BUILT_IN_ISNORMAL:
2363 {
2364 /* isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) &
2365 islessequal(fabs(x),DBL_MAX). */
2366 tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
2367 tree const isge_fn = built_in_decls[BUILT_IN_ISGREATEREQUAL];
2368 tree const type = TREE_TYPE (arg);
2369 REAL_VALUE_TYPE rmax, rmin;
2370 char buf[128];
2371
2372 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2373 real_from_string (&rmax, buf);
2374 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
2375 real_from_string (&rmin, buf);
2376 arg = builtin_save_expr (fold_build1 (ABS_EXPR, type, arg));
2377 result = build_call_expr (isle_fn, 2, arg,
2378 build_real (type, rmax));
2379 result = fold_build2 (BIT_AND_EXPR, integer_type_node, result,
2380 build_call_expr (isge_fn, 2, arg,
2381 build_real (type, rmin)));
2382 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2383 }
06f7a99d 2384 default:
2385 break;
2386 }
2387
a67a90e5 2388 target = expand_call (exp, target, target == const0_rtx);
2389
2390 return target;
2391}
2392
c3147c1a 2393/* Expand a call to the builtin sincos math function.
c2f47e15 2394 Return NULL_RTX if a normal call should be emitted rather than expanding the
c3147c1a 2395 function in-line. EXP is the expression that is a call to the builtin
2396 function. */
2397
2398static rtx
2399expand_builtin_sincos (tree exp)
2400{
2401 rtx op0, op1, op2, target1, target2;
c3147c1a 2402 enum machine_mode mode;
2403 tree arg, sinp, cosp;
2404 int result;
2405
c2f47e15 2406 if (!validate_arglist (exp, REAL_TYPE,
2407 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2408 return NULL_RTX;
c3147c1a 2409
c2f47e15 2410 arg = CALL_EXPR_ARG (exp, 0);
2411 sinp = CALL_EXPR_ARG (exp, 1);
2412 cosp = CALL_EXPR_ARG (exp, 2);
c3147c1a 2413
2414 /* Make a suitable register to place result in. */
2415 mode = TYPE_MODE (TREE_TYPE (arg));
2416
2417 /* Check if sincos insn is available, otherwise emit the call. */
99bdde56 2418 if (optab_handler (sincos_optab, mode)->insn_code == CODE_FOR_nothing)
c3147c1a 2419 return NULL_RTX;
2420
2421 target1 = gen_reg_rtx (mode);
2422 target2 = gen_reg_rtx (mode);
2423
8ec3c5c2 2424 op0 = expand_normal (arg);
2425 op1 = expand_normal (build_fold_indirect_ref (sinp));
2426 op2 = expand_normal (build_fold_indirect_ref (cosp));
c3147c1a 2427
2428 /* Compute into target1 and target2.
2429 Set TARGET to wherever the result comes back. */
2430 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2431 gcc_assert (result);
2432
2433 /* Move target1 and target2 to the memory locations indicated
2434 by op1 and op2. */
2435 emit_move_insn (op1, target1);
2436 emit_move_insn (op2, target2);
2437
2438 return const0_rtx;
2439}
2440
d735c391 2441/* Expand a call to the internal cexpi builtin to the sincos math function.
2442 EXP is the expression that is a call to the builtin function; if convenient,
2443 the result should be placed in TARGET. SUBTARGET may be used as the target
2444 for computing one of EXP's operands. */
2445
2446static rtx
2447expand_builtin_cexpi (tree exp, rtx target, rtx subtarget)
2448{
2449 tree fndecl = get_callee_fndecl (exp);
d735c391 2450 tree arg, type;
c2f47e15 2451 enum machine_mode mode;
d735c391 2452 rtx op0, op1, op2;
2453
c2f47e15 2454 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2455 return NULL_RTX;
d735c391 2456
c2f47e15 2457 arg = CALL_EXPR_ARG (exp, 0);
d735c391 2458 type = TREE_TYPE (arg);
2459 mode = TYPE_MODE (TREE_TYPE (arg));
2460
2461 /* Try expanding via a sincos optab, fall back to emitting a libcall
18b8d8ae 2462 to sincos or cexp. We are sure we have sincos or cexp because cexpi
2463 is only generated from sincos, cexp or if we have either of them. */
99bdde56 2464 if (optab_handler (sincos_optab, mode)->insn_code != CODE_FOR_nothing)
d735c391 2465 {
2466 op1 = gen_reg_rtx (mode);
2467 op2 = gen_reg_rtx (mode);
2468
1db6d067 2469 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
d735c391 2470
2471 /* Compute into op1 and op2. */
2472 expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
2473 }
18b8d8ae 2474 else if (TARGET_HAS_SINCOS)
d735c391 2475 {
c2f47e15 2476 tree call, fn = NULL_TREE;
d735c391 2477 tree top1, top2;
2478 rtx op1a, op2a;
2479
2480 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2481 fn = built_in_decls[BUILT_IN_SINCOSF];
2482 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2483 fn = built_in_decls[BUILT_IN_SINCOS];
2484 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2485 fn = built_in_decls[BUILT_IN_SINCOSL];
c2f47e15 2486 else
2487 gcc_unreachable ();
d735c391 2488
2489 op1 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2490 op2 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2491 op1a = copy_to_mode_reg (Pmode, XEXP (op1, 0));
2492 op2a = copy_to_mode_reg (Pmode, XEXP (op2, 0));
2493 top1 = make_tree (build_pointer_type (TREE_TYPE (arg)), op1a);
2494 top2 = make_tree (build_pointer_type (TREE_TYPE (arg)), op2a);
2495
d735c391 2496 /* Make sure not to fold the sincos call again. */
2497 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
c2f47e15 2498 expand_normal (build_call_nary (TREE_TYPE (TREE_TYPE (fn)),
2499 call, 3, arg, top1, top2));
d735c391 2500 }
18b8d8ae 2501 else
2502 {
0ecbc158 2503 tree call, fn = NULL_TREE, narg;
18b8d8ae 2504 tree ctype = build_complex_type (type);
2505
0ecbc158 2506 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2507 fn = built_in_decls[BUILT_IN_CEXPF];
2508 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2509 fn = built_in_decls[BUILT_IN_CEXP];
2510 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2511 fn = built_in_decls[BUILT_IN_CEXPL];
c2f47e15 2512 else
2513 gcc_unreachable ();
fc0dfa6e 2514
2515 /* If we don't have a decl for cexp create one. This is the
2516 friendliest fallback if the user calls __builtin_cexpi
2517 without full target C99 function support. */
2518 if (fn == NULL_TREE)
2519 {
2520 tree fntype;
2521 const char *name = NULL;
2522
2523 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2524 name = "cexpf";
2525 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2526 name = "cexp";
2527 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2528 name = "cexpl";
2529
2530 fntype = build_function_type_list (ctype, ctype, NULL_TREE);
2531 fn = build_fn_decl (name, fntype);
2532 }
2533
18b8d8ae 2534 narg = fold_build2 (COMPLEX_EXPR, ctype,
2535 build_real (type, dconst0), arg);
2536
2537 /* Make sure not to fold the cexp call again. */
2538 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
3737e769 2539 return expand_expr (build_call_nary (ctype, call, 1, narg),
1db6d067 2540 target, VOIDmode, EXPAND_NORMAL);
18b8d8ae 2541 }
d735c391 2542
2543 /* Now build the proper return type. */
2544 return expand_expr (build2 (COMPLEX_EXPR, build_complex_type (type),
2545 make_tree (TREE_TYPE (arg), op2),
2546 make_tree (TREE_TYPE (arg), op1)),
1db6d067 2547 target, VOIDmode, EXPAND_NORMAL);
d735c391 2548}
2549
7d3afc77 2550/* Expand a call to one of the builtin rounding functions gcc defines
2551 as an extension (lfloor and lceil). As these are gcc extensions we
2552 do not need to worry about setting errno to EDOM.
ad52b9b7 2553 If expanding via optab fails, lower expression to (int)(floor(x)).
2554 EXP is the expression that is a call to the builtin function;
ff1b14e4 2555 if convenient, the result should be placed in TARGET. */
ad52b9b7 2556
2557static rtx
ff1b14e4 2558expand_builtin_int_roundingfn (tree exp, rtx target)
ad52b9b7 2559{
9c42dd28 2560 convert_optab builtin_optab;
ad52b9b7 2561 rtx op0, insns, tmp;
2562 tree fndecl = get_callee_fndecl (exp);
ad52b9b7 2563 enum built_in_function fallback_fn;
2564 tree fallback_fndecl;
2565 enum machine_mode mode;
4de0924f 2566 tree arg;
ad52b9b7 2567
c2f47e15 2568 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
ad52b9b7 2569 gcc_unreachable ();
2570
c2f47e15 2571 arg = CALL_EXPR_ARG (exp, 0);
ad52b9b7 2572
2573 switch (DECL_FUNCTION_CODE (fndecl))
2574 {
4f35b1fc 2575 CASE_FLT_FN (BUILT_IN_LCEIL):
2576 CASE_FLT_FN (BUILT_IN_LLCEIL):
ac148751 2577 builtin_optab = lceil_optab;
2578 fallback_fn = BUILT_IN_CEIL;
2579 break;
2580
4f35b1fc 2581 CASE_FLT_FN (BUILT_IN_LFLOOR):
2582 CASE_FLT_FN (BUILT_IN_LLFLOOR):
ad52b9b7 2583 builtin_optab = lfloor_optab;
2584 fallback_fn = BUILT_IN_FLOOR;
2585 break;
2586
2587 default:
2588 gcc_unreachable ();
2589 }
2590
2591 /* Make a suitable register to place result in. */
2592 mode = TYPE_MODE (TREE_TYPE (exp));
2593
9c42dd28 2594 target = gen_reg_rtx (mode);
ad52b9b7 2595
9c42dd28 2596 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2597 need to expand the argument again. This way, we will not perform
2598 side-effects more the once. */
abfea505 2599 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
ad52b9b7 2600
ff1b14e4 2601 op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
ad52b9b7 2602
9c42dd28 2603 start_sequence ();
ad52b9b7 2604
9c42dd28 2605 /* Compute into TARGET. */
2606 if (expand_sfix_optab (target, op0, builtin_optab))
2607 {
2608 /* Output the entire sequence. */
2609 insns = get_insns ();
ad52b9b7 2610 end_sequence ();
9c42dd28 2611 emit_insn (insns);
2612 return target;
ad52b9b7 2613 }
2614
9c42dd28 2615 /* If we were unable to expand via the builtin, stop the sequence
2616 (without outputting the insns). */
2617 end_sequence ();
2618
ad52b9b7 2619 /* Fall back to floating point rounding optab. */
2620 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
fc0dfa6e 2621
2622 /* For non-C99 targets we may end up without a fallback fndecl here
2623 if the user called __builtin_lfloor directly. In this case emit
2624 a call to the floor/ceil variants nevertheless. This should result
2625 in the best user experience for not full C99 targets. */
2626 if (fallback_fndecl == NULL_TREE)
2627 {
2628 tree fntype;
2629 const char *name = NULL;
2630
2631 switch (DECL_FUNCTION_CODE (fndecl))
2632 {
2633 case BUILT_IN_LCEIL:
2634 case BUILT_IN_LLCEIL:
2635 name = "ceil";
2636 break;
2637 case BUILT_IN_LCEILF:
2638 case BUILT_IN_LLCEILF:
2639 name = "ceilf";
2640 break;
2641 case BUILT_IN_LCEILL:
2642 case BUILT_IN_LLCEILL:
2643 name = "ceill";
2644 break;
2645 case BUILT_IN_LFLOOR:
2646 case BUILT_IN_LLFLOOR:
2647 name = "floor";
2648 break;
2649 case BUILT_IN_LFLOORF:
2650 case BUILT_IN_LLFLOORF:
2651 name = "floorf";
2652 break;
2653 case BUILT_IN_LFLOORL:
2654 case BUILT_IN_LLFLOORL:
2655 name = "floorl";
2656 break;
2657 default:
2658 gcc_unreachable ();
2659 }
2660
2661 fntype = build_function_type_list (TREE_TYPE (arg),
2662 TREE_TYPE (arg), NULL_TREE);
2663 fallback_fndecl = build_fn_decl (name, fntype);
2664 }
2665
c2f47e15 2666 exp = build_call_expr (fallback_fndecl, 1, arg);
ad52b9b7 2667
d4c690af 2668 tmp = expand_normal (exp);
ad52b9b7 2669
2670 /* Truncate the result of floating point optab to integer
2671 via expand_fix (). */
2672 target = gen_reg_rtx (mode);
2673 expand_fix (target, tmp, 0);
2674
2675 return target;
2676}
2677
7d3afc77 2678/* Expand a call to one of the builtin math functions doing integer
2679 conversion (lrint).
2680 Return 0 if a normal call should be emitted rather than expanding the
2681 function in-line. EXP is the expression that is a call to the builtin
ff1b14e4 2682 function; if convenient, the result should be placed in TARGET. */
7d3afc77 2683
2684static rtx
ff1b14e4 2685expand_builtin_int_roundingfn_2 (tree exp, rtx target)
7d3afc77 2686{
5f51ee59 2687 convert_optab builtin_optab;
7d3afc77 2688 rtx op0, insns;
2689 tree fndecl = get_callee_fndecl (exp);
4de0924f 2690 tree arg;
c2f47e15 2691 enum machine_mode mode;
7d3afc77 2692
2693 /* There's no easy way to detect the case we need to set EDOM. */
2694 if (flag_errno_math)
2695 return NULL_RTX;
2696
c2f47e15 2697 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2698 gcc_unreachable ();
2699
2700 arg = CALL_EXPR_ARG (exp, 0);
7d3afc77 2701
2702 switch (DECL_FUNCTION_CODE (fndecl))
2703 {
2704 CASE_FLT_FN (BUILT_IN_LRINT):
2705 CASE_FLT_FN (BUILT_IN_LLRINT):
2706 builtin_optab = lrint_optab; break;
ef2f1a10 2707 CASE_FLT_FN (BUILT_IN_LROUND):
2708 CASE_FLT_FN (BUILT_IN_LLROUND):
2709 builtin_optab = lround_optab; break;
7d3afc77 2710 default:
2711 gcc_unreachable ();
2712 }
2713
2714 /* Make a suitable register to place result in. */
2715 mode = TYPE_MODE (TREE_TYPE (exp));
2716
5f51ee59 2717 target = gen_reg_rtx (mode);
7d3afc77 2718
5f51ee59 2719 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2720 need to expand the argument again. This way, we will not perform
2721 side-effects more the once. */
abfea505 2722 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
7d3afc77 2723
ff1b14e4 2724 op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
7d3afc77 2725
5f51ee59 2726 start_sequence ();
7d3afc77 2727
5f51ee59 2728 if (expand_sfix_optab (target, op0, builtin_optab))
2729 {
2730 /* Output the entire sequence. */
2731 insns = get_insns ();
7d3afc77 2732 end_sequence ();
5f51ee59 2733 emit_insn (insns);
2734 return target;
7d3afc77 2735 }
2736
5f51ee59 2737 /* If we were unable to expand via the builtin, stop the sequence
2738 (without outputting the insns) and call to the library function
2739 with the stabilized argument list. */
2740 end_sequence ();
2741
7d3afc77 2742 target = expand_call (exp, target, target == const0_rtx);
2743
2744 return target;
2745}
2746
f1b844c6 2747/* To evaluate powi(x,n), the floating point value x raised to the
2748 constant integer exponent n, we use a hybrid algorithm that
2749 combines the "window method" with look-up tables. For an
2750 introduction to exponentiation algorithms and "addition chains",
2751 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2752 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2753 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2754 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2755
2756/* Provide a default value for POWI_MAX_MULTS, the maximum number of
2757 multiplications to inline before calling the system library's pow
2758 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2759 so this default never requires calling pow, powf or powl. */
0862b7e9 2760
f1b844c6 2761#ifndef POWI_MAX_MULTS
2762#define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2763#endif
2764
2765/* The size of the "optimal power tree" lookup table. All
2766 exponents less than this value are simply looked up in the
2767 powi_table below. This threshold is also used to size the
2768 cache of pseudo registers that hold intermediate results. */
2769#define POWI_TABLE_SIZE 256
2770
2771/* The size, in bits of the window, used in the "window method"
2772 exponentiation algorithm. This is equivalent to a radix of
2773 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2774#define POWI_WINDOW_SIZE 3
2775
2776/* The following table is an efficient representation of an
2777 "optimal power tree". For each value, i, the corresponding
2778 value, j, in the table states than an optimal evaluation
2779 sequence for calculating pow(x,i) can be found by evaluating
2780 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2781 100 integers is given in Knuth's "Seminumerical algorithms". */
2782
2783static const unsigned char powi_table[POWI_TABLE_SIZE] =
2784 {
2785 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2786 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2787 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2788 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2789 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2790 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2791 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2792 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2793 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2794 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2795 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2796 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2797 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2798 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2799 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2800 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2801 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2802 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2803 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2804 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2805 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2806 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2807 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2808 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2809 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2810 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2811 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2812 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2813 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2814 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2815 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2816 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2817 };
2818
2819
2820/* Return the number of multiplications required to calculate
2821 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2822 subroutine of powi_cost. CACHE is an array indicating
2823 which exponents have already been calculated. */
2824
2825static int
2826powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2827{
2828 /* If we've already calculated this exponent, then this evaluation
2829 doesn't require any additional multiplications. */
2830 if (cache[n])
2831 return 0;
2832
2833 cache[n] = true;
2834 return powi_lookup_cost (n - powi_table[n], cache)
2835 + powi_lookup_cost (powi_table[n], cache) + 1;
2836}
2837
2838/* Return the number of multiplications required to calculate
2839 powi(x,n) for an arbitrary x, given the exponent N. This
2840 function needs to be kept in sync with expand_powi below. */
2841
2842static int
2843powi_cost (HOST_WIDE_INT n)
2844{
2845 bool cache[POWI_TABLE_SIZE];
2846 unsigned HOST_WIDE_INT digit;
2847 unsigned HOST_WIDE_INT val;
2848 int result;
2849
2850 if (n == 0)
2851 return 0;
2852
2853 /* Ignore the reciprocal when calculating the cost. */
2854 val = (n < 0) ? -n : n;
2855
2856 /* Initialize the exponent cache. */
2857 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2858 cache[1] = true;
2859
2860 result = 0;
2861
2862 while (val >= POWI_TABLE_SIZE)
2863 {
2864 if (val & 1)
2865 {
2866 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2867 result += powi_lookup_cost (digit, cache)
2868 + POWI_WINDOW_SIZE + 1;
2869 val >>= POWI_WINDOW_SIZE;
2870 }
2871 else
2872 {
2873 val >>= 1;
2874 result++;
2875 }
2876 }
0862b7e9 2877
6881dbab 2878 return result + powi_lookup_cost (val, cache);
f1b844c6 2879}
2880
2881/* Recursive subroutine of expand_powi. This function takes the array,
2882 CACHE, of already calculated exponents and an exponent N and returns
2883 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2884
2885static rtx
2886expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2887{
2888 unsigned HOST_WIDE_INT digit;
2889 rtx target, result;
2890 rtx op0, op1;
2891
2892 if (n < POWI_TABLE_SIZE)
2893 {
2894 if (cache[n])
a0c938f0 2895 return cache[n];
f1b844c6 2896
2897 target = gen_reg_rtx (mode);
2898 cache[n] = target;
2899
2900 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2901 op1 = expand_powi_1 (mode, powi_table[n], cache);
2902 }
2903 else if (n & 1)
2904 {
2905 target = gen_reg_rtx (mode);
2906 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2907 op0 = expand_powi_1 (mode, n - digit, cache);
2908 op1 = expand_powi_1 (mode, digit, cache);
2909 }
2910 else
2911 {
2912 target = gen_reg_rtx (mode);
2913 op0 = expand_powi_1 (mode, n >> 1, cache);
2914 op1 = op0;
2915 }
2916
2917 result = expand_mult (mode, op0, op1, target, 0);
2918 if (result != target)
2919 emit_move_insn (target, result);
2920 return target;
2921}
2922
2923/* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2924 floating point operand in mode MODE, and N is the exponent. This
2925 function needs to be kept in sync with powi_cost above. */
0862b7e9 2926
f1b844c6 2927static rtx
2928expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2929{
2930 unsigned HOST_WIDE_INT val;
2931 rtx cache[POWI_TABLE_SIZE];
2932 rtx result;
2933
2934 if (n == 0)
2935 return CONST1_RTX (mode);
2936
2937 val = (n < 0) ? -n : n;
2938
19bf118a 2939 memset (cache, 0, sizeof (cache));
f1b844c6 2940 cache[1] = x;
2941
2942 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2943
2944 /* If the original exponent was negative, reciprocate the result. */
2945 if (n < 0)
2946 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2947 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2948
2949 return result;
2950}
2951
c2f47e15 2952/* Expand a call to the pow built-in mathematical function. Return NULL_RTX if
f1b844c6 2953 a normal call should be emitted rather than expanding the function
2954 in-line. EXP is the expression that is a call to the builtin
2955 function; if convenient, the result should be placed in TARGET. */
2956
2957static rtx
2958expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2959{
c2f47e15 2960 tree arg0, arg1;
2961 tree fn, narg0;
1c4709b4 2962 tree type = TREE_TYPE (exp);
2963 REAL_VALUE_TYPE cint, c, c2;
2964 HOST_WIDE_INT n;
2965 rtx op, op2;
2966 enum machine_mode mode = TYPE_MODE (type);
f1b844c6 2967
c2f47e15 2968 if (! validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2969 return NULL_RTX;
f1b844c6 2970
c2f47e15 2971 arg0 = CALL_EXPR_ARG (exp, 0);
2972 arg1 = CALL_EXPR_ARG (exp, 1);
f1b844c6 2973
1c4709b4 2974 if (TREE_CODE (arg1) != REAL_CST
f96bd2bf 2975 || TREE_OVERFLOW (arg1))
1c4709b4 2976 return expand_builtin_mathfn_2 (exp, target, subtarget);
2977
2978 /* Handle constant exponents. */
2979
2980 /* For integer valued exponents we can expand to an optimal multiplication
2981 sequence using expand_powi. */
2982 c = TREE_REAL_CST (arg1);
2983 n = real_to_integer (&c);
2984 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2985 if (real_identical (&c, &cint)
2986 && ((n >= -1 && n <= 2)
2987 || (flag_unsafe_math_optimizations
a0d18cec 2988 && optimize_insn_for_speed_p ()
1c4709b4 2989 && powi_cost (n) <= POWI_MAX_MULTS)))
f1b844c6 2990 {
1db6d067 2991 op = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
1c4709b4 2992 if (n != 1)
2993 {
2994 op = force_reg (mode, op);
2995 op = expand_powi (op, mode, n);
2996 }
2997 return op;
2998 }
2999
3000 narg0 = builtin_save_expr (arg0);
f1b844c6 3001
1c4709b4 3002 /* If the exponent is not integer valued, check if it is half of an integer.
3003 In this case we can expand to sqrt (x) * x**(n/2). */
3004 fn = mathfn_built_in (type, BUILT_IN_SQRT);
3005 if (fn != NULL_TREE)
3006 {
3007 real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
3008 n = real_to_integer (&c2);
f1b844c6 3009 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
1c4709b4 3010 if (real_identical (&c2, &cint)
3011 && ((flag_unsafe_math_optimizations
a0d18cec 3012 && optimize_insn_for_speed_p ()
1c4709b4 3013 && powi_cost (n/2) <= POWI_MAX_MULTS)
3014 || n == 1))
f1b844c6 3015 {
c2f47e15 3016 tree call_expr = build_call_expr (fn, 1, narg0);
8697cf4d 3017 /* Use expand_expr in case the newly built call expression
3018 was folded to a non-call. */
3019 op = expand_expr (call_expr, subtarget, mode, EXPAND_NORMAL);
1c4709b4 3020 if (n != 1)
8c5cac78 3021 {
1db6d067 3022 op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL);
1c4709b4 3023 op2 = force_reg (mode, op2);
3024 op2 = expand_powi (op2, mode, abs (n / 2));
3025 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
3026 0, OPTAB_LIB_WIDEN);
3027 /* If the original exponent was negative, reciprocate the
3028 result. */
3029 if (n < 0)
3030 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
3031 op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
8c5cac78 3032 }
1c4709b4 3033 return op;
f1b844c6 3034 }
3035 }
b613c2a6 3036
1c4709b4 3037 /* Try if the exponent is a third of an integer. In this case
5a84ba55 3038 we can expand to x**(n/3) * cbrt(x)**(n%3). As cbrt (x) is
3039 different from pow (x, 1./3.) due to rounding and behavior
3040 with negative x we need to constrain this transformation to
3041 unsafe math and positive x or finite math. */
1c4709b4 3042 fn = mathfn_built_in (type, BUILT_IN_CBRT);
5a84ba55 3043 if (fn != NULL_TREE
3044 && flag_unsafe_math_optimizations
3045 && (tree_expr_nonnegative_p (arg0)
3046 || !HONOR_NANS (mode)))
1c4709b4 3047 {
3fa759a9 3048 REAL_VALUE_TYPE dconst3;
3049 real_from_integer (&dconst3, VOIDmode, 3, 0, 0);
1c4709b4 3050 real_arithmetic (&c2, MULT_EXPR, &c, &dconst3);
3051 real_round (&c2, mode, &c2);
3052 n = real_to_integer (&c2);
3053 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
3054 real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
3055 real_convert (&c2, mode, &c2);
3056 if (real_identical (&c2, &c)
a0d18cec 3057 && ((optimize_insn_for_speed_p ()
1c4709b4 3058 && powi_cost (n/3) <= POWI_MAX_MULTS)
3059 || n == 1))
3060 {
c2f47e15 3061 tree call_expr = build_call_expr (fn, 1,narg0);
1c4709b4 3062 op = expand_builtin (call_expr, NULL_RTX, subtarget, mode, 0);
3063 if (abs (n) % 3 == 2)
3064 op = expand_simple_binop (mode, MULT, op, op, op,
3065 0, OPTAB_LIB_WIDEN);
3066 if (n != 1)
3067 {
1db6d067 3068 op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL);
1c4709b4 3069 op2 = force_reg (mode, op2);
3070 op2 = expand_powi (op2, mode, abs (n / 3));
3071 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
3072 0, OPTAB_LIB_WIDEN);
3073 /* If the original exponent was negative, reciprocate the
3074 result. */
3075 if (n < 0)
3076 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
3077 op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
3078 }
3079 return op;
3080 }
3081 }
3082
3083 /* Fall back to optab expansion. */
b613c2a6 3084 return expand_builtin_mathfn_2 (exp, target, subtarget);
f1b844c6 3085}
3086
c2f47e15 3087/* Expand a call to the powi built-in mathematical function. Return NULL_RTX if
757c219d 3088 a normal call should be emitted rather than expanding the function
3089 in-line. EXP is the expression that is a call to the builtin
3090 function; if convenient, the result should be placed in TARGET. */
3091
3092static rtx
3093expand_builtin_powi (tree exp, rtx target, rtx subtarget)
3094{
757c219d 3095 tree arg0, arg1;
3096 rtx op0, op1;
3097 enum machine_mode mode;
d0405f40 3098 enum machine_mode mode2;
757c219d 3099
c2f47e15 3100 if (! validate_arglist (exp, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
3101 return NULL_RTX;
757c219d 3102
c2f47e15 3103 arg0 = CALL_EXPR_ARG (exp, 0);
3104 arg1 = CALL_EXPR_ARG (exp, 1);
757c219d 3105 mode = TYPE_MODE (TREE_TYPE (exp));
3106
3107 /* Handle constant power. */
3108
3109 if (TREE_CODE (arg1) == INTEGER_CST
f96bd2bf 3110 && !TREE_OVERFLOW (arg1))
757c219d 3111 {
3112 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
3113
3114 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
3115 Otherwise, check the number of multiplications required. */
3116 if ((TREE_INT_CST_HIGH (arg1) == 0
3117 || TREE_INT_CST_HIGH (arg1) == -1)
3118 && ((n >= -1 && n <= 2)
a0d18cec 3119 || (optimize_insn_for_speed_p ()
757c219d 3120 && powi_cost (n) <= POWI_MAX_MULTS)))
3121 {
1db6d067 3122 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
757c219d 3123 op0 = force_reg (mode, op0);
3124 return expand_powi (op0, mode, n);
3125 }
3126 }
3127
3128 /* Emit a libcall to libgcc. */
3129
c2f47e15 3130 /* Mode of the 2nd argument must match that of an int. */
d0405f40 3131 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
3132
757c219d 3133 if (target == NULL_RTX)
3134 target = gen_reg_rtx (mode);
3135
1db6d067 3136 op0 = expand_expr (arg0, subtarget, mode, EXPAND_NORMAL);
757c219d 3137 if (GET_MODE (op0) != mode)
3138 op0 = convert_to_mode (mode, op0, 0);
1db6d067 3139 op1 = expand_expr (arg1, NULL_RTX, mode2, EXPAND_NORMAL);
d0405f40 3140 if (GET_MODE (op1) != mode2)
3141 op1 = convert_to_mode (mode2, op1, 0);
757c219d 3142
f36b9f69 3143 target = emit_library_call_value (optab_libfunc (powi_optab, mode),
2dd6f9ed 3144 target, LCT_CONST, mode, 2,
d0405f40 3145 op0, mode, op1, mode2);
757c219d 3146
3147 return target;
3148}
3149
c2f47e15 3150/* Expand expression EXP which is a call to the strlen builtin. Return
3151 NULL_RTX if we failed the caller should emit a normal call, otherwise
aed0bd19 3152 try to get the result in TARGET, if convenient. */
f7c44134 3153
53800dbe 3154static rtx
c2f47e15 3155expand_builtin_strlen (tree exp, rtx target,
aecda0d6 3156 enum machine_mode target_mode)
53800dbe 3157{
c2f47e15 3158 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
3159 return NULL_RTX;
53800dbe 3160 else
3161 {
911c0150 3162 rtx pat;
c2f47e15 3163 tree len;
3164 tree src = CALL_EXPR_ARG (exp, 0);
911c0150 3165 rtx result, src_reg, char_rtx, before_strlen;
80cd7a5e 3166 enum machine_mode insn_mode = target_mode, char_mode;
ef2c4a29 3167 enum insn_code icode = CODE_FOR_nothing;
6248e345 3168 int align;
3169
3170 /* If the length can be computed at compile-time, return it. */
681fab1e 3171 len = c_strlen (src, 0);
6248e345 3172 if (len)
80cd7a5e 3173 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
6248e345 3174
681fab1e 3175 /* If the length can be computed at compile-time and is constant
3176 integer, but there are side-effects in src, evaluate
3177 src for side-effects, then return len.
3178 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
3179 can be optimized into: i++; x = 3; */
3180 len = c_strlen (src, 1);
3181 if (len && TREE_CODE (len) == INTEGER_CST)
3182 {
3183 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3184 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
3185 }
3186
6248e345 3187 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
53800dbe 3188
53800dbe 3189 /* If SRC is not a pointer type, don't do this operation inline. */
3190 if (align == 0)
c2f47e15 3191 return NULL_RTX;
53800dbe 3192
911c0150 3193 /* Bail out if we can't compute strlen in the right mode. */
53800dbe 3194 while (insn_mode != VOIDmode)
3195 {
99bdde56 3196 icode = optab_handler (strlen_optab, insn_mode)->insn_code;
53800dbe 3197 if (icode != CODE_FOR_nothing)
c28ae87f 3198 break;
53800dbe 3199
3200 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
3201 }
3202 if (insn_mode == VOIDmode)
c2f47e15 3203 return NULL_RTX;
53800dbe 3204
3205 /* Make a place to write the result of the instruction. */
3206 result = target;
3207 if (! (result != 0
8ad4c111 3208 && REG_P (result)
53800dbe 3209 && GET_MODE (result) == insn_mode
3210 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3211 result = gen_reg_rtx (insn_mode);
3212
911c0150 3213 /* Make a place to hold the source address. We will not expand
3214 the actual source until we are sure that the expansion will
3215 not fail -- there are trees that cannot be expanded twice. */
3216 src_reg = gen_reg_rtx (Pmode);
53800dbe 3217
911c0150 3218 /* Mark the beginning of the strlen sequence so we can emit the
3219 source operand later. */
f0ce3b1f 3220 before_strlen = get_last_insn ();
53800dbe 3221
53800dbe 3222 char_rtx = const0_rtx;
f7c44134 3223 char_mode = insn_data[(int) icode].operand[2].mode;
3224 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
3225 char_mode))
53800dbe 3226 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
3227
911c0150 3228 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
3229 char_rtx, GEN_INT (align));
3230 if (! pat)
c2f47e15 3231 return NULL_RTX;
911c0150 3232 emit_insn (pat);
3233
3234 /* Now that we are assured of success, expand the source. */
3235 start_sequence ();
c5aba89c 3236 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
911c0150 3237 if (pat != src_reg)
3238 emit_move_insn (src_reg, pat);
31d3e01c 3239 pat = get_insns ();
911c0150 3240 end_sequence ();
bceb0d1f 3241
3242 if (before_strlen)
3243 emit_insn_after (pat, before_strlen);
3244 else
3245 emit_insn_before (pat, get_insns ());
53800dbe 3246
3247 /* Return the value in the proper mode for this function. */
80cd7a5e 3248 if (GET_MODE (result) == target_mode)
911c0150 3249 target = result;
53800dbe 3250 else if (target != 0)
911c0150 3251 convert_move (target, result, 0);
53800dbe 3252 else
80cd7a5e 3253 target = convert_to_mode (target_mode, result, 0);
911c0150 3254
3255 return target;
53800dbe 3256 }
3257}
3258
c2f47e15 3259/* Expand a call to the strstr builtin. Return NULL_RTX if we failed the
17f5ea87 3260 caller should emit a normal call, otherwise try to get the result
3261 in TARGET, if convenient (and in mode MODE if that's convenient). */
3262
3263static rtx
c2f47e15 3264expand_builtin_strstr (tree exp, rtx target, enum machine_mode mode)
17f5ea87 3265{
c2f47e15 3266 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
17f5ea87 3267 {
c2f47e15 3268 tree type = TREE_TYPE (exp);
3269 tree result = fold_builtin_strstr (CALL_EXPR_ARG (exp, 0),
3270 CALL_EXPR_ARG (exp, 1), type);
2c84ee37 3271 if (result)
3272 return expand_expr (result, target, mode, EXPAND_NORMAL);
17f5ea87 3273 }
c2f47e15 3274 return NULL_RTX;
17f5ea87 3275}
3276
c2f47e15 3277/* Expand a call to the strchr builtin. Return NULL_RTX if we failed the
46f3a74a 3278 caller should emit a normal call, otherwise try to get the result
3279 in TARGET, if convenient (and in mode MODE if that's convenient). */
3280
3281static rtx
c2f47e15 3282expand_builtin_strchr (tree exp, rtx target, enum machine_mode mode)
46f3a74a 3283{
c2f47e15 3284 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
46f3a74a 3285 {
c2f47e15 3286 tree type = TREE_TYPE (exp);
3287 tree result = fold_builtin_strchr (CALL_EXPR_ARG (exp, 0),
3288 CALL_EXPR_ARG (exp, 1), type);
2c84ee37 3289 if (result)
3290 return expand_expr (result, target, mode, EXPAND_NORMAL);
83d79705 3291
2c84ee37 3292 /* FIXME: Should use strchrM optab so that ports can optimize this. */
83d79705 3293 }
c2f47e15 3294 return NULL_RTX;
83d79705 3295}
3296
c2f47e15 3297/* Expand a call to the strrchr builtin. Return NULL_RTX if we failed the
83d79705 3298 caller should emit a normal call, otherwise try to get the result
3299 in TARGET, if convenient (and in mode MODE if that's convenient). */
3300
3301static rtx
c2f47e15 3302expand_builtin_strrchr (tree exp, rtx target, enum machine_mode mode)
83d79705 3303{
c2f47e15 3304 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
83d79705 3305 {
c2f47e15 3306 tree type = TREE_TYPE (exp);
3307 tree result = fold_builtin_strrchr (CALL_EXPR_ARG (exp, 0),
3308 CALL_EXPR_ARG (exp, 1), type);
2c84ee37 3309 if (result)
3310 return expand_expr (result, target, mode, EXPAND_NORMAL);
83d79705 3311 }
c2f47e15 3312 return NULL_RTX;
83d79705 3313}
3314
c2f47e15 3315/* Expand a call to the strpbrk builtin. Return NULL_RTX if we failed the
83d79705 3316 caller should emit a normal call, otherwise try to get the result
3317 in TARGET, if convenient (and in mode MODE if that's convenient). */
3318
3319static rtx
c2f47e15 3320expand_builtin_strpbrk (tree exp, rtx target, enum machine_mode mode)
83d79705 3321{
c2f47e15 3322 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
83d79705 3323 {
c2f47e15 3324 tree type = TREE_TYPE (exp);
3325 tree result = fold_builtin_strpbrk (CALL_EXPR_ARG (exp, 0),
3326 CALL_EXPR_ARG (exp, 1), type);
2c84ee37 3327 if (result)
3328 return expand_expr (result, target, mode, EXPAND_NORMAL);
46f3a74a 3329 }
c2f47e15 3330 return NULL_RTX;
46f3a74a 3331}
3332
6840589f 3333/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3334 bytes from constant string DATA + OFFSET and return it as target
3335 constant. */
3336
3337static rtx
aecda0d6 3338builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
3339 enum machine_mode mode)
6840589f 3340{
3341 const char *str = (const char *) data;
3342
64db345d 3343 gcc_assert (offset >= 0
3344 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
3345 <= strlen (str) + 1));
6840589f 3346
3347 return c_readstr (str + offset, mode);
3348}
3349
c2f47e15 3350/* Expand a call EXP to the memcpy builtin.
3351 Return NULL_RTX if we failed, the caller should emit a normal call,
3b824fa6 3352 otherwise try to get the result in TARGET, if convenient (and in
9fe0e1b8 3353 mode MODE if that's convenient). */
c2f47e15 3354
53800dbe 3355static rtx
5a0de151 3356expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
53800dbe 3357{
8e76ec06 3358 tree fndecl = get_callee_fndecl (exp);
c2f47e15 3359
3360 if (!validate_arglist (exp,
3361 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3362 return NULL_RTX;
53800dbe 3363 else
3364 {
c2f47e15 3365 tree dest = CALL_EXPR_ARG (exp, 0);
3366 tree src = CALL_EXPR_ARG (exp, 1);
3367 tree len = CALL_EXPR_ARG (exp, 2);
6840589f 3368 const char *src_str;
27d0c333 3369 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3370 unsigned int dest_align
3371 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
53800dbe 3372 rtx dest_mem, src_mem, dest_addr, len_rtx;
c2f47e15 3373 tree result = fold_builtin_memory_op (dest, src, len,
3374 TREE_TYPE (TREE_TYPE (fndecl)),
4f46f2b9 3375 false, /*endp=*/0);
162719b3 3376 HOST_WIDE_INT expected_size = -1;
3377 unsigned int expected_align = 0;
75a70cf9 3378 tree_ann_common_t ann;
5a0de151 3379
3380 if (result)
4f46f2b9 3381 {
3382 while (TREE_CODE (result) == COMPOUND_EXPR)
3383 {
3384 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3385 EXPAND_NORMAL);
3386 result = TREE_OPERAND (result, 1);
3387 }
3388 return expand_expr (result, target, mode, EXPAND_NORMAL);
3389 }
53800dbe 3390
6f428e8b 3391 /* If DEST is not a pointer type, call the normal function. */
3392 if (dest_align == 0)
c2f47e15 3393 return NULL_RTX;
6f428e8b 3394
6f428e8b 3395 /* If either SRC is not a pointer type, don't do this
a0c938f0 3396 operation in-line. */
6f428e8b 3397 if (src_align == 0)
c2f47e15 3398 return NULL_RTX;
162719b3 3399
75a70cf9 3400 ann = tree_common_ann (exp);
3401 if (ann)
3402 stringop_block_profile (ann->stmt, &expected_align, &expected_size);
3403
162719b3 3404 if (expected_align < dest_align)
3405 expected_align = dest_align;
d8ae1baa 3406 dest_mem = get_memory_rtx (dest, len);
2a631e19 3407 set_mem_align (dest_mem, dest_align);
8ec3c5c2 3408 len_rtx = expand_normal (len);
6840589f 3409 src_str = c_getstr (src);
3410
3411 /* If SRC is a string constant and block move would be done
3412 by pieces, we can avoid loading the string from memory
3413 and only stored the computed constants. */
3414 if (src_str
971ba038 3415 && CONST_INT_P (len_rtx)
6840589f 3416 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3417 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
364c0c59 3418 CONST_CAST (char *, src_str),
3419 dest_align, false))
6840589f 3420 {
9fe0e1b8 3421 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3422 builtin_memcpy_read_str,
364c0c59 3423 CONST_CAST (char *, src_str),
3424 dest_align, false, 0);
e5716f7e 3425 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3426 dest_mem = convert_memory_address (ptr_mode, dest_mem);
9fe0e1b8 3427 return dest_mem;
6840589f 3428 }
3429
d8ae1baa 3430 src_mem = get_memory_rtx (src, len);
2a631e19 3431 set_mem_align (src_mem, src_align);
53800dbe 3432
53800dbe 3433 /* Copy word part most expediently. */
162719b3 3434 dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx,
3435 CALL_EXPR_TAILCALL (exp)
3436 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3437 expected_align, expected_size);
53800dbe 3438
3439 if (dest_addr == 0)
e5716f7e 3440 {
3441 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3442 dest_addr = convert_memory_address (ptr_mode, dest_addr);
e5716f7e 3443 }
9fe0e1b8 3444 return dest_addr;
53800dbe 3445 }
3446}
3447
c2f47e15 3448/* Expand a call EXP to the mempcpy builtin.
3449 Return NULL_RTX if we failed; the caller should emit a normal call,
647661c6 3450 otherwise try to get the result in TARGET, if convenient (and in
9fe0e1b8 3451 mode MODE if that's convenient). If ENDP is 0 return the
3452 destination pointer, if ENDP is 1 return the end pointer ala
3453 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3454 stpcpy. */
647661c6 3455
3456static rtx
c8b17b2e 3457expand_builtin_mempcpy (tree exp, rtx target, enum machine_mode mode)
647661c6 3458{
c2f47e15 3459 if (!validate_arglist (exp,
3460 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3461 return NULL_RTX;
3462 else
3463 {
3464 tree dest = CALL_EXPR_ARG (exp, 0);
3465 tree src = CALL_EXPR_ARG (exp, 1);
3466 tree len = CALL_EXPR_ARG (exp, 2);
3467 return expand_builtin_mempcpy_args (dest, src, len,
3468 TREE_TYPE (exp),
3469 target, mode, /*endp=*/ 1);
3470 }
3471}
3472
3473/* Helper function to do the actual work for expand_builtin_mempcpy. The
3474 arguments to the builtin_mempcpy call DEST, SRC, and LEN are broken out
3475 so that this can also be called without constructing an actual CALL_EXPR.
3476 TYPE is the return type of the call. The other arguments and return value
3477 are the same as for expand_builtin_mempcpy. */
3478
3479static rtx
3480expand_builtin_mempcpy_args (tree dest, tree src, tree len, tree type,
3481 rtx target, enum machine_mode mode, int endp)
3482{
3483 /* If return value is ignored, transform mempcpy into memcpy. */
c8b17b2e 3484 if (target == const0_rtx && implicit_built_in_decls[BUILT_IN_MEMCPY])
9fe0e1b8 3485 {
3486 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
c8b17b2e 3487 tree result = build_call_expr (fn, 3, dest, src, len);
9fe0e1b8 3488
c8b17b2e 3489 while (TREE_CODE (result) == COMPOUND_EXPR)
3490 {
3491 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3492 EXPAND_NORMAL);
3493 result = TREE_OPERAND (result, 1);
3494 }
3495 return expand_expr (result, target, mode, EXPAND_NORMAL);
9fe0e1b8 3496 }
647661c6 3497 else
3498 {
9fe0e1b8 3499 const char *src_str;
3500 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3501 unsigned int dest_align
3502 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3503 rtx dest_mem, src_mem, len_rtx;
c2f47e15 3504 tree result = fold_builtin_memory_op (dest, src, len, type, false, endp);
9fe0e1b8 3505
7da1412b 3506 if (result)
4f46f2b9 3507 {
3508 while (TREE_CODE (result) == COMPOUND_EXPR)
3509 {
3510 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3511 EXPAND_NORMAL);
3512 result = TREE_OPERAND (result, 1);
3513 }
3514 return expand_expr (result, target, mode, EXPAND_NORMAL);
3515 }
a0c938f0 3516
7da1412b 3517 /* If either SRC or DEST is not a pointer type, don't do this
a0c938f0 3518 operation in-line. */
7da1412b 3519 if (dest_align == 0 || src_align == 0)
c2f47e15 3520 return NULL_RTX;
9fe0e1b8 3521
6217c238 3522 /* If LEN is not constant, call the normal function. */
3523 if (! host_integerp (len, 1))
c2f47e15 3524 return NULL_RTX;
0862b7e9 3525
8ec3c5c2 3526 len_rtx = expand_normal (len);
9fe0e1b8 3527 src_str = c_getstr (src);
647661c6 3528
9fe0e1b8 3529 /* If SRC is a string constant and block move would be done
3530 by pieces, we can avoid loading the string from memory
3531 and only stored the computed constants. */
3532 if (src_str
971ba038 3533 && CONST_INT_P (len_rtx)
9fe0e1b8 3534 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3535 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
364c0c59 3536 CONST_CAST (char *, src_str),
3537 dest_align, false))
9fe0e1b8 3538 {
d8ae1baa 3539 dest_mem = get_memory_rtx (dest, len);
9fe0e1b8 3540 set_mem_align (dest_mem, dest_align);
3541 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3542 builtin_memcpy_read_str,
364c0c59 3543 CONST_CAST (char *, src_str),
3544 dest_align, false, endp);
9fe0e1b8 3545 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3546 dest_mem = convert_memory_address (ptr_mode, dest_mem);
9fe0e1b8 3547 return dest_mem;
647661c6 3548 }
3549
971ba038 3550 if (CONST_INT_P (len_rtx)
9fe0e1b8 3551 && can_move_by_pieces (INTVAL (len_rtx),
3552 MIN (dest_align, src_align)))
3553 {
d8ae1baa 3554 dest_mem = get_memory_rtx (dest, len);
9fe0e1b8 3555 set_mem_align (dest_mem, dest_align);
d8ae1baa 3556 src_mem = get_memory_rtx (src, len);
9fe0e1b8 3557 set_mem_align (src_mem, src_align);
3558 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3559 MIN (dest_align, src_align), endp);
3560 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3561 dest_mem = convert_memory_address (ptr_mode, dest_mem);
9fe0e1b8 3562 return dest_mem;
3563 }
3564
c2f47e15 3565 return NULL_RTX;
647661c6 3566 }
3567}
3568
c2f47e15 3569/* Expand expression EXP, which is a call to the memmove builtin. Return
3570 NULL_RTX if we failed; the caller should emit a normal call. */
c4950093 3571
3572static rtx
c2f47e15 3573expand_builtin_memmove (tree exp, rtx target, enum machine_mode mode, int ignore)
c4950093 3574{
c2f47e15 3575 if (!validate_arglist (exp,
3576 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3577 return NULL_RTX;
c4950093 3578 else
3579 {
c2f47e15 3580 tree dest = CALL_EXPR_ARG (exp, 0);
3581 tree src = CALL_EXPR_ARG (exp, 1);
3582 tree len = CALL_EXPR_ARG (exp, 2);
3583 return expand_builtin_memmove_args (dest, src, len, TREE_TYPE (exp),
3584 target, mode, ignore);
3585 }
3586}
7e72af53 3587
c2f47e15 3588/* Helper function to do the actual work for expand_builtin_memmove. The
3589 arguments to the builtin_memmove call DEST, SRC, and LEN are broken out
3590 so that this can also be called without constructing an actual CALL_EXPR.
3591 TYPE is the return type of the call. The other arguments and return value
3592 are the same as for expand_builtin_memmove. */
3593
3594static rtx
3595expand_builtin_memmove_args (tree dest, tree src, tree len,
3596 tree type, rtx target, enum machine_mode mode,
3597 int ignore)
3598{
3599 tree result = fold_builtin_memory_op (dest, src, len, type, ignore, /*endp=*/3);
3600
3601 if (result)
3602 {
05be68f3 3603 STRIP_TYPE_NOPS (result);
c2f47e15 3604 while (TREE_CODE (result) == COMPOUND_EXPR)
4f46f2b9 3605 {
c2f47e15 3606 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3607 EXPAND_NORMAL);
3608 result = TREE_OPERAND (result, 1);
4f46f2b9 3609 }
c2f47e15 3610 return expand_expr (result, target, mode, EXPAND_NORMAL);
3611 }
3612
3613 /* Otherwise, call the normal function. */
3614 return NULL_RTX;
c4950093 3615}
3616
c2f47e15 3617/* Expand expression EXP, which is a call to the bcopy builtin. Return
3618 NULL_RTX if we failed the caller should emit a normal call. */
c4950093 3619
3620static rtx
c2f47e15 3621expand_builtin_bcopy (tree exp, int ignore)
c4950093 3622{
0b25db21 3623 tree type = TREE_TYPE (exp);
c2f47e15 3624 tree src, dest, size;
c4950093 3625
c2f47e15 3626 if (!validate_arglist (exp,
3627 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
c4950093 3628 return NULL_RTX;
3629
c2f47e15 3630 src = CALL_EXPR_ARG (exp, 0);
3631 dest = CALL_EXPR_ARG (exp, 1);
3632 size = CALL_EXPR_ARG (exp, 2);
c4950093 3633
c2f47e15 3634 /* Transform bcopy(ptr x, ptr y, int z) to memmove(ptr y, ptr x, size_t z).
3635 This is done this way so that if it isn't expanded inline, we fall
3636 back to calling bcopy instead of memmove. */
3637 return expand_builtin_memmove_args (dest, src,
3638 fold_convert (sizetype, size),
3639 type, const0_rtx, VOIDmode,
3640 ignore);
c4950093 3641}
3642
727c62dd 3643#ifndef HAVE_movstr
3644# define HAVE_movstr 0
3645# define CODE_FOR_movstr CODE_FOR_nothing
3646#endif
3647
c2f47e15 3648/* Expand into a movstr instruction, if one is available. Return NULL_RTX if
727c62dd 3649 we failed, the caller should emit a normal call, otherwise try to
3650 get the result in TARGET, if convenient. If ENDP is 0 return the
3651 destination pointer, if ENDP is 1 return the end pointer ala
3652 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3653 stpcpy. */
3654
3655static rtx
3656expand_movstr (tree dest, tree src, rtx target, int endp)
3657{
3658 rtx end;
3659 rtx dest_mem;
3660 rtx src_mem;
3661 rtx insn;
3662 const struct insn_data * data;
3663
3664 if (!HAVE_movstr)
c2f47e15 3665 return NULL_RTX;
727c62dd 3666
d8ae1baa 3667 dest_mem = get_memory_rtx (dest, NULL);
3668 src_mem = get_memory_rtx (src, NULL);
727c62dd 3669 if (!endp)
3670 {
3671 target = force_reg (Pmode, XEXP (dest_mem, 0));
3672 dest_mem = replace_equiv_address (dest_mem, target);
3673 end = gen_reg_rtx (Pmode);
3674 }
3675 else
3676 {
3677 if (target == 0 || target == const0_rtx)
3678 {
3679 end = gen_reg_rtx (Pmode);
3680 if (target == 0)
3681 target = end;
3682 }
3683 else
3684 end = target;
3685 }
3686
3687 data = insn_data + CODE_FOR_movstr;
3688
3689 if (data->operand[0].mode != VOIDmode)
3690 end = gen_lowpart (data->operand[0].mode, end);
3691
3692 insn = data->genfun (end, dest_mem, src_mem);
3693
64db345d 3694 gcc_assert (insn);
727c62dd 3695
3696 emit_insn (insn);
3697
3698 /* movstr is supposed to set end to the address of the NUL
3699 terminator. If the caller requested a mempcpy-like return value,
3700 adjust it. */
3701 if (endp == 1 && target != const0_rtx)
c5aba89c 3702 {
3703 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3704 emit_move_insn (target, force_operand (tem, NULL_RTX));
3705 }
727c62dd 3706
3707 return target;
3708}
3709
c2f47e15 3710/* Expand expression EXP, which is a call to the strcpy builtin. Return
3711 NULL_RTX if we failed the caller should emit a normal call, otherwise
3712 try to get the result in TARGET, if convenient (and in mode MODE if that's
6f428e8b 3713 convenient). */
902de8ed 3714
53800dbe 3715static rtx
c2f47e15 3716expand_builtin_strcpy (tree fndecl, tree exp, rtx target, enum machine_mode mode)
53800dbe 3717{
c2f47e15 3718 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3719 {
3720 tree dest = CALL_EXPR_ARG (exp, 0);
3721 tree src = CALL_EXPR_ARG (exp, 1);
3722 return expand_builtin_strcpy_args (fndecl, dest, src, target, mode);
3723 }
3724 return NULL_RTX;
3725}
3726
3727/* Helper function to do the actual work for expand_builtin_strcpy. The
3728 arguments to the builtin_strcpy call DEST and SRC are broken out
3729 so that this can also be called without constructing an actual CALL_EXPR.
3730 The other arguments and return value are the same as for
3731 expand_builtin_strcpy. */
3732
3733static rtx
3734expand_builtin_strcpy_args (tree fndecl, tree dest, tree src,
3735 rtx target, enum machine_mode mode)
3736{
3737 tree result = fold_builtin_strcpy (fndecl, dest, src, 0);
3738 if (result)
3739 return expand_expr (result, target, mode, EXPAND_NORMAL);
3740 return expand_movstr (dest, src, target, /*endp=*/0);
902de8ed 3741
53800dbe 3742}
3743
c2f47e15 3744/* Expand a call EXP to the stpcpy builtin.
3745 Return NULL_RTX if we failed the caller should emit a normal call,
3b824fa6 3746 otherwise try to get the result in TARGET, if convenient (and in
3747 mode MODE if that's convenient). */
3748
3749static rtx
dc369150 3750expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3b824fa6 3751{
c2f47e15 3752 tree dst, src;
3753
3754 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3755 return NULL_RTX;
3756
3757 dst = CALL_EXPR_ARG (exp, 0);
3758 src = CALL_EXPR_ARG (exp, 1);
3759
727c62dd 3760 /* If return value is ignored, transform stpcpy into strcpy. */
c8b17b2e 3761 if (target == const0_rtx && implicit_built_in_decls[BUILT_IN_STRCPY])
978836e5 3762 {
3763 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
c8b17b2e 3764 tree result = build_call_expr (fn, 2, dst, src);
978836e5 3765
c8b17b2e 3766 STRIP_NOPS (result);
3767 while (TREE_CODE (result) == COMPOUND_EXPR)
3768 {
3769 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3770 EXPAND_NORMAL);
3771 result = TREE_OPERAND (result, 1);
3772 }
3773 return expand_expr (result, target, mode, EXPAND_NORMAL);
978836e5 3774 }
3b824fa6 3775 else
3776 {
c2f47e15 3777 tree len, lenp1;
727c62dd 3778 rtx ret;
647661c6 3779
9fe0e1b8 3780 /* Ensure we get an actual string whose length can be evaluated at
a0c938f0 3781 compile-time, not an expression containing a string. This is
3782 because the latter will potentially produce pessimized code
3783 when used to produce the return value. */
681fab1e 3784 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
c2f47e15 3785 return expand_movstr (dst, src, target, /*endp=*/2);
3b824fa6 3786
7d705727 3787 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
c2f47e15 3788 ret = expand_builtin_mempcpy_args (dst, src, lenp1, TREE_TYPE (exp),
3789 target, mode, /*endp=*/2);
727c62dd 3790
3791 if (ret)
3792 return ret;
3793
3794 if (TREE_CODE (len) == INTEGER_CST)
3795 {
8ec3c5c2 3796 rtx len_rtx = expand_normal (len);
727c62dd 3797
971ba038 3798 if (CONST_INT_P (len_rtx))
727c62dd 3799 {
c2f47e15 3800 ret = expand_builtin_strcpy_args (get_callee_fndecl (exp),
3801 dst, src, target, mode);
727c62dd 3802
3803 if (ret)
3804 {
3805 if (! target)
7ac87324 3806 {
3807 if (mode != VOIDmode)
3808 target = gen_reg_rtx (mode);
3809 else
3810 target = gen_reg_rtx (GET_MODE (ret));
3811 }
727c62dd 3812 if (GET_MODE (target) != GET_MODE (ret))
3813 ret = gen_lowpart (GET_MODE (target), ret);
3814
c5aba89c 3815 ret = plus_constant (ret, INTVAL (len_rtx));
3816 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
64db345d 3817 gcc_assert (ret);
727c62dd 3818
3819 return target;
3820 }
3821 }
3822 }
3823
c2f47e15 3824 return expand_movstr (dst, src, target, /*endp=*/2);
3b824fa6 3825 }
3826}
3827
6840589f 3828/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3829 bytes from constant string DATA + OFFSET and return it as target
3830 constant. */
3831
09879952 3832rtx
aecda0d6 3833builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3834 enum machine_mode mode)
6840589f 3835{
3836 const char *str = (const char *) data;
3837
3838 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3839 return const0_rtx;
3840
3841 return c_readstr (str + offset, mode);
3842}
3843
c2f47e15 3844/* Expand expression EXP, which is a call to the strncpy builtin. Return
3845 NULL_RTX if we failed the caller should emit a normal call. */
ed09096d 3846
3847static rtx
8ff6a5cd 3848expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
ed09096d 3849{
ea726109 3850 tree fndecl = get_callee_fndecl (exp);
c2f47e15 3851
3852 if (validate_arglist (exp,
3853 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
ed09096d 3854 {
c2f47e15 3855 tree dest = CALL_EXPR_ARG (exp, 0);
3856 tree src = CALL_EXPR_ARG (exp, 1);
3857 tree len = CALL_EXPR_ARG (exp, 2);
3858 tree slen = c_strlen (src, 1);
3859 tree result = fold_builtin_strncpy (fndecl, dest, src, len, slen);
a0c938f0 3860
8ff6a5cd 3861 if (result)
4f46f2b9 3862 {
3863 while (TREE_CODE (result) == COMPOUND_EXPR)
3864 {
3865 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3866 EXPAND_NORMAL);
3867 result = TREE_OPERAND (result, 1);
3868 }
3869 return expand_expr (result, target, mode, EXPAND_NORMAL);
3870 }
6840589f 3871
8ff6a5cd 3872 /* We must be passed a constant len and src parameter. */
3873 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
c2f47e15 3874 return NULL_RTX;
ed09096d 3875
3876 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3877
3878 /* We're required to pad with trailing zeros if the requested
a0c938f0 3879 len is greater than strlen(s2)+1. In that case try to
6840589f 3880 use store_by_pieces, if it fails, punt. */
ed09096d 3881 if (tree_int_cst_lt (slen, len))
6840589f 3882 {
27d0c333 3883 unsigned int dest_align
3884 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
c2f47e15 3885 const char *p = c_getstr (src);
6840589f 3886 rtx dest_mem;
3887
27d0c333 3888 if (!p || dest_align == 0 || !host_integerp (len, 1)
3889 || !can_store_by_pieces (tree_low_cst (len, 1),
6840589f 3890 builtin_strncpy_read_str,
364c0c59 3891 CONST_CAST (char *, p),
3892 dest_align, false))
c2f47e15 3893 return NULL_RTX;
6840589f 3894
d8ae1baa 3895 dest_mem = get_memory_rtx (dest, len);
27d0c333 3896 store_by_pieces (dest_mem, tree_low_cst (len, 1),
6840589f 3897 builtin_strncpy_read_str,
364c0c59 3898 CONST_CAST (char *, p), dest_align, false, 0);
e5716f7e 3899 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3900 dest_mem = convert_memory_address (ptr_mode, dest_mem);
e5716f7e 3901 return dest_mem;
6840589f 3902 }
ed09096d 3903 }
c2f47e15 3904 return NULL_RTX;
ed09096d 3905}
3906
ecc318ff 3907/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3908 bytes from constant string DATA + OFFSET and return it as target
3909 constant. */
3910
f656b751 3911rtx
aecda0d6 3912builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3913 enum machine_mode mode)
ecc318ff 3914{
3915 const char *c = (const char *) data;
364c0c59 3916 char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
ecc318ff 3917
3918 memset (p, *c, GET_MODE_SIZE (mode));
3919
3920 return c_readstr (p, mode);
3921}
3922
a7ec6974 3923/* Callback routine for store_by_pieces. Return the RTL of a register
3924 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3925 char value given in the RTL register data. For example, if mode is
3926 4 bytes wide, return the RTL for 0x01010101*data. */
3927
3928static rtx
aecda0d6 3929builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3930 enum machine_mode mode)
a7ec6974 3931{
3932 rtx target, coeff;
3933 size_t size;
3934 char *p;
3935
3936 size = GET_MODE_SIZE (mode);
f0ce3b1f 3937 if (size == 1)
3938 return (rtx) data;
a7ec6974 3939
364c0c59 3940 p = XALLOCAVEC (char, size);
a7ec6974 3941 memset (p, 1, size);
3942 coeff = c_readstr (p, mode);
3943
f0ce3b1f 3944 target = convert_to_mode (mode, (rtx) data, 1);
a7ec6974 3945 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3946 return force_reg (mode, target);
3947}
3948
c2f47e15 3949/* Expand expression EXP, which is a call to the memset builtin. Return
3950 NULL_RTX if we failed the caller should emit a normal call, otherwise
3951 try to get the result in TARGET, if convenient (and in mode MODE if that's
6f428e8b 3952 convenient). */
902de8ed 3953
53800dbe 3954static rtx
c2f47e15 3955expand_builtin_memset (tree exp, rtx target, enum machine_mode mode)
53800dbe 3956{
c2f47e15 3957 if (!validate_arglist (exp,
3958 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3959 return NULL_RTX;
53800dbe 3960 else
3961 {
c2f47e15 3962 tree dest = CALL_EXPR_ARG (exp, 0);
3963 tree val = CALL_EXPR_ARG (exp, 1);
3964 tree len = CALL_EXPR_ARG (exp, 2);
3965 return expand_builtin_memset_args (dest, val, len, target, mode, exp);
3966 }
3967}
53800dbe 3968
c2f47e15 3969/* Helper function to do the actual work for expand_builtin_memset. The
3970 arguments to the builtin_memset call DEST, VAL, and LEN are broken out
3971 so that this can also be called without constructing an actual CALL_EXPR.
3972 The other arguments and return value are the same as for
3973 expand_builtin_memset. */
6b961939 3974
c2f47e15 3975static rtx
3976expand_builtin_memset_args (tree dest, tree val, tree len,
3977 rtx target, enum machine_mode mode, tree orig_exp)
3978{
3979 tree fndecl, fn;
3980 enum built_in_function fcode;
3981 char c;
3982 unsigned int dest_align;
3983 rtx dest_mem, dest_addr, len_rtx;
3984 HOST_WIDE_INT expected_size = -1;
3985 unsigned int expected_align = 0;
75a70cf9 3986 tree_ann_common_t ann;
53800dbe 3987
c2f47e15 3988 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
162719b3 3989
c2f47e15 3990 /* If DEST is not a pointer type, don't do this operation in-line. */
3991 if (dest_align == 0)
3992 return NULL_RTX;
6f428e8b 3993
75a70cf9 3994 ann = tree_common_ann (orig_exp);
3995 if (ann)
3996 stringop_block_profile (ann->stmt, &expected_align, &expected_size);
3997
c2f47e15 3998 if (expected_align < dest_align)
3999 expected_align = dest_align;
6b961939 4000
c2f47e15 4001 /* If the LEN parameter is zero, return DEST. */
4002 if (integer_zerop (len))
4003 {
4004 /* Evaluate and ignore VAL in case it has side-effects. */
4005 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
4006 return expand_expr (dest, target, mode, EXPAND_NORMAL);
4007 }
7a3e5564 4008
c2f47e15 4009 /* Stabilize the arguments in case we fail. */
4010 dest = builtin_save_expr (dest);
4011 val = builtin_save_expr (val);
4012 len = builtin_save_expr (len);
a7ec6974 4013
c2f47e15 4014 len_rtx = expand_normal (len);
4015 dest_mem = get_memory_rtx (dest, len);
a7ec6974 4016
c2f47e15 4017 if (TREE_CODE (val) != INTEGER_CST)
4018 {
4019 rtx val_rtx;
a7ec6974 4020
c2f47e15 4021 val_rtx = expand_normal (val);
4022 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
4023 val_rtx, 0);
53800dbe 4024
c2f47e15 4025 /* Assume that we can memset by pieces if we can store
4026 * the coefficients by pieces (in the required modes).
4027 * We can't pass builtin_memset_gen_str as that emits RTL. */
4028 c = 1;
4029 if (host_integerp (len, 1)
c2f47e15 4030 && can_store_by_pieces (tree_low_cst (len, 1),
4b297e2e 4031 builtin_memset_read_str, &c, dest_align,
4032 true))
c2f47e15 4033 {
4034 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
4035 val_rtx);
4036 store_by_pieces (dest_mem, tree_low_cst (len, 1),
4b297e2e 4037 builtin_memset_gen_str, val_rtx, dest_align,
4038 true, 0);
c2f47e15 4039 }
4040 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
4041 dest_align, expected_align,
4042 expected_size))
6b961939 4043 goto do_libcall;
c2f47e15 4044
4045 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
4046 dest_mem = convert_memory_address (ptr_mode, dest_mem);
4047 return dest_mem;
4048 }
53800dbe 4049
c2f47e15 4050 if (target_char_cast (val, &c))
4051 goto do_libcall;
ecc318ff 4052
c2f47e15 4053 if (c)
4054 {
4055 if (host_integerp (len, 1)
c2f47e15 4056 && can_store_by_pieces (tree_low_cst (len, 1),
4b297e2e 4057 builtin_memset_read_str, &c, dest_align,
4058 true))
c2f47e15 4059 store_by_pieces (dest_mem, tree_low_cst (len, 1),
4b297e2e 4060 builtin_memset_read_str, &c, dest_align, true, 0);
c2f47e15 4061 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
4062 dest_align, expected_align,
4063 expected_size))
4064 goto do_libcall;
4065
4066 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
4067 dest_mem = convert_memory_address (ptr_mode, dest_mem);
4068 return dest_mem;
4069 }
ecc318ff 4070
c2f47e15 4071 set_mem_align (dest_mem, dest_align);
4072 dest_addr = clear_storage_hints (dest_mem, len_rtx,
4073 CALL_EXPR_TAILCALL (orig_exp)
4074 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
4075 expected_align, expected_size);
53800dbe 4076
c2f47e15 4077 if (dest_addr == 0)
4078 {
4079 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
4080 dest_addr = convert_memory_address (ptr_mode, dest_addr);
4081 }
53800dbe 4082
c2f47e15 4083 return dest_addr;
6b961939 4084
c2f47e15 4085 do_libcall:
4086 fndecl = get_callee_fndecl (orig_exp);
4087 fcode = DECL_FUNCTION_CODE (fndecl);
4088 if (fcode == BUILT_IN_MEMSET)
4089 fn = build_call_expr (fndecl, 3, dest, val, len);
4090 else if (fcode == BUILT_IN_BZERO)
4091 fn = build_call_expr (fndecl, 2, dest, len);
4092 else
4093 gcc_unreachable ();
4094 if (TREE_CODE (fn) == CALL_EXPR)
4095 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
4096 return expand_call (fn, target, target == const0_rtx);
53800dbe 4097}
4098
c2f47e15 4099/* Expand expression EXP, which is a call to the bzero builtin. Return
4100 NULL_RTX if we failed the caller should emit a normal call. */
27d0c333 4101
ffc83088 4102static rtx
0b25db21 4103expand_builtin_bzero (tree exp)
ffc83088 4104{
c2f47e15 4105 tree dest, size;
ffc83088 4106
c2f47e15 4107 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7369e7ba 4108 return NULL_RTX;
ffc83088 4109
c2f47e15 4110 dest = CALL_EXPR_ARG (exp, 0);
4111 size = CALL_EXPR_ARG (exp, 1);
bf8e3599 4112
7369e7ba 4113 /* New argument list transforming bzero(ptr x, int y) to
6f428e8b 4114 memset(ptr x, int 0, size_t y). This is done this way
4115 so that if it isn't expanded inline, we fallback to
4116 calling bzero instead of memset. */
bf8e3599 4117
c2f47e15 4118 return expand_builtin_memset_args (dest, integer_zero_node,
4119 fold_convert (sizetype, size),
4120 const0_rtx, VOIDmode, exp);
ffc83088 4121}
4122
7959b13b 4123/* Expand a call to the memchr builtin. Return NULL_RTX if we failed the
4124 caller should emit a normal call, otherwise try to get the result
4125 in TARGET, if convenient (and in mode MODE if that's convenient). */
4126
4127static rtx
4128expand_builtin_memchr (tree exp, rtx target, enum machine_mode mode)
4129{
4130 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE,
4131 INTEGER_TYPE, VOID_TYPE))
4132 {
4133 tree type = TREE_TYPE (exp);
4134 tree result = fold_builtin_memchr (CALL_EXPR_ARG (exp, 0),
4135 CALL_EXPR_ARG (exp, 1),
4136 CALL_EXPR_ARG (exp, 2), type);
4137 if (result)
4138 return expand_expr (result, target, mode, EXPAND_NORMAL);
4139 }
4140 return NULL_RTX;
4141}
4142
7a3f89b5 4143/* Expand expression EXP, which is a call to the memcmp built-in function.
c2f47e15 4144 Return NULL_RTX if we failed and the
53800dbe 4145 caller should emit a normal call, otherwise try to get the result in
6f428e8b 4146 TARGET, if convenient (and in mode MODE, if that's convenient). */
27d0c333 4147
53800dbe 4148static rtx
c2f47e15 4149expand_builtin_memcmp (tree exp, rtx target, enum machine_mode mode)
53800dbe 4150{
c2f47e15 4151 if (!validate_arglist (exp,
4152 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4153 return NULL_RTX;
218bc19e 4154 else
6f428e8b 4155 {
c2f47e15 4156 tree result = fold_builtin_memcmp (CALL_EXPR_ARG (exp, 0),
4157 CALL_EXPR_ARG (exp, 1),
4158 CALL_EXPR_ARG (exp, 2));
218bc19e 4159 if (result)
4160 return expand_expr (result, target, mode, EXPAND_NORMAL);
6f428e8b 4161 }
4162
6ac5504b 4163#if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
53800dbe 4164 {
0cd832f0 4165 rtx arg1_rtx, arg2_rtx, arg3_rtx;
53800dbe 4166 rtx result;
0cd832f0 4167 rtx insn;
c2f47e15 4168 tree arg1 = CALL_EXPR_ARG (exp, 0);
4169 tree arg2 = CALL_EXPR_ARG (exp, 1);
4170 tree len = CALL_EXPR_ARG (exp, 2);
53800dbe 4171
4172 int arg1_align
4173 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4174 int arg2_align
4175 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
b428c0a5 4176 enum machine_mode insn_mode;
4177
4178#ifdef HAVE_cmpmemsi
4179 if (HAVE_cmpmemsi)
4180 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
4181 else
4182#endif
6ac5504b 4183#ifdef HAVE_cmpstrnsi
4184 if (HAVE_cmpstrnsi)
4185 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
b428c0a5 4186 else
4187#endif
c2f47e15 4188 return NULL_RTX;
53800dbe 4189
4190 /* If we don't have POINTER_TYPE, call the function. */
4191 if (arg1_align == 0 || arg2_align == 0)
c2f47e15 4192 return NULL_RTX;
53800dbe 4193
4194 /* Make a place to write the result of the instruction. */
4195 result = target;
4196 if (! (result != 0
8ad4c111 4197 && REG_P (result) && GET_MODE (result) == insn_mode
53800dbe 4198 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4199 result = gen_reg_rtx (insn_mode);
4200
d8ae1baa 4201 arg1_rtx = get_memory_rtx (arg1, len);
4202 arg2_rtx = get_memory_rtx (arg2, len);
7c1ab261 4203 arg3_rtx = expand_normal (fold_convert (sizetype, len));
83f88f8e 4204
4205 /* Set MEM_SIZE as appropriate. */
971ba038 4206 if (CONST_INT_P (arg3_rtx))
83f88f8e 4207 {
4208 set_mem_size (arg1_rtx, arg3_rtx);
4209 set_mem_size (arg2_rtx, arg3_rtx);
4210 }
4211
b428c0a5 4212#ifdef HAVE_cmpmemsi
4213 if (HAVE_cmpmemsi)
4214 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4215 GEN_INT (MIN (arg1_align, arg2_align)));
0cd832f0 4216 else
b428c0a5 4217#endif
6ac5504b 4218#ifdef HAVE_cmpstrnsi
4219 if (HAVE_cmpstrnsi)
4220 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4221 GEN_INT (MIN (arg1_align, arg2_align)));
b428c0a5 4222 else
4223#endif
64db345d 4224 gcc_unreachable ();
0cd832f0 4225
4226 if (insn)
4227 emit_insn (insn);
4228 else
2dd6f9ed 4229 emit_library_call_value (memcmp_libfunc, result, LCT_PURE,
0cd832f0 4230 TYPE_MODE (integer_type_node), 3,
4231 XEXP (arg1_rtx, 0), Pmode,
4232 XEXP (arg2_rtx, 0), Pmode,
4233 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
78a8ed03 4234 TYPE_UNSIGNED (sizetype)),
0cd832f0 4235 TYPE_MODE (sizetype));
53800dbe 4236
4237 /* Return the value in the proper mode for this function. */
4238 mode = TYPE_MODE (TREE_TYPE (exp));
4239 if (GET_MODE (result) == mode)
4240 return result;
4241 else if (target != 0)
4242 {
4243 convert_move (target, result, 0);
4244 return target;
4245 }
4246 else
4247 return convert_to_mode (mode, result, 0);
4248 }
83d79705 4249#endif
53800dbe 4250
c2f47e15 4251 return NULL_RTX;
6f428e8b 4252}
4253
c2f47e15 4254/* Expand expression EXP, which is a call to the strcmp builtin. Return NULL_RTX
53800dbe 4255 if we failed the caller should emit a normal call, otherwise try to get
4256 the result in TARGET, if convenient. */
902de8ed 4257
53800dbe 4258static rtx
aecda0d6 4259expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
53800dbe 4260{
c2f47e15 4261 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4262 return NULL_RTX;
218bc19e 4263 else
ef6c187e 4264 {
c2f47e15 4265 tree result = fold_builtin_strcmp (CALL_EXPR_ARG (exp, 0),
4266 CALL_EXPR_ARG (exp, 1));
218bc19e 4267 if (result)
4268 return expand_expr (result, target, mode, EXPAND_NORMAL);
ef6c187e 4269 }
bf8e3599 4270
6ac5504b 4271#if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
4272 if (cmpstr_optab[SImode] != CODE_FOR_nothing
4273 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
4274 {
4275 rtx arg1_rtx, arg2_rtx;
4276 rtx result, insn = NULL_RTX;
4277 tree fndecl, fn;
c2f47e15 4278 tree arg1 = CALL_EXPR_ARG (exp, 0);
4279 tree arg2 = CALL_EXPR_ARG (exp, 1);
a0c938f0 4280
6ac5504b 4281 int arg1_align
4282 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4283 int arg2_align
4284 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4285
4286 /* If we don't have POINTER_TYPE, call the function. */
4287 if (arg1_align == 0 || arg2_align == 0)
c2f47e15 4288 return NULL_RTX;
7a3f89b5 4289
6ac5504b 4290 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
4291 arg1 = builtin_save_expr (arg1);
4292 arg2 = builtin_save_expr (arg2);
7a3f89b5 4293
d8ae1baa 4294 arg1_rtx = get_memory_rtx (arg1, NULL);
4295 arg2_rtx = get_memory_rtx (arg2, NULL);
53800dbe 4296
6ac5504b 4297#ifdef HAVE_cmpstrsi
4298 /* Try to call cmpstrsi. */
4299 if (HAVE_cmpstrsi)
4300 {
a0c938f0 4301 enum machine_mode insn_mode
6ac5504b 4302 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
4303
4304 /* Make a place to write the result of the instruction. */
4305 result = target;
4306 if (! (result != 0
4307 && REG_P (result) && GET_MODE (result) == insn_mode
4308 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4309 result = gen_reg_rtx (insn_mode);
4310
4311 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
4312 GEN_INT (MIN (arg1_align, arg2_align)));
4313 }
4314#endif
03fd9d2c 4315#ifdef HAVE_cmpstrnsi
6ac5504b 4316 /* Try to determine at least one length and call cmpstrnsi. */
a0c938f0 4317 if (!insn && HAVE_cmpstrnsi)
6ac5504b 4318 {
4319 tree len;
4320 rtx arg3_rtx;
4321
a0c938f0 4322 enum machine_mode insn_mode
6ac5504b 4323 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
4324 tree len1 = c_strlen (arg1, 1);
4325 tree len2 = c_strlen (arg2, 1);
4326
4327 if (len1)
4328 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
4329 if (len2)
4330 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
4331
4332 /* If we don't have a constant length for the first, use the length
4333 of the second, if we know it. We don't require a constant for
4334 this case; some cost analysis could be done if both are available
4335 but neither is constant. For now, assume they're equally cheap,
4336 unless one has side effects. If both strings have constant lengths,
4337 use the smaller. */
4338
4339 if (!len1)
4340 len = len2;
4341 else if (!len2)
4342 len = len1;
4343 else if (TREE_SIDE_EFFECTS (len1))
4344 len = len2;
4345 else if (TREE_SIDE_EFFECTS (len2))
4346 len = len1;
4347 else if (TREE_CODE (len1) != INTEGER_CST)
4348 len = len2;
4349 else if (TREE_CODE (len2) != INTEGER_CST)
4350 len = len1;
4351 else if (tree_int_cst_lt (len1, len2))
4352 len = len1;
4353 else
4354 len = len2;
4355
4356 /* If both arguments have side effects, we cannot optimize. */
4357 if (!len || TREE_SIDE_EFFECTS (len))
6b961939 4358 goto do_libcall;
53800dbe 4359
8ec3c5c2 4360 arg3_rtx = expand_normal (len);
902de8ed 4361
6ac5504b 4362 /* Make a place to write the result of the instruction. */
4363 result = target;
4364 if (! (result != 0
4365 && REG_P (result) && GET_MODE (result) == insn_mode
4366 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4367 result = gen_reg_rtx (insn_mode);
53800dbe 4368
6ac5504b 4369 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4370 GEN_INT (MIN (arg1_align, arg2_align)));
4371 }
4372#endif
3f8aefe2 4373
6ac5504b 4374 if (insn)
4375 {
4376 emit_insn (insn);
3f8aefe2 4377
6ac5504b 4378 /* Return the value in the proper mode for this function. */
4379 mode = TYPE_MODE (TREE_TYPE (exp));
4380 if (GET_MODE (result) == mode)
4381 return result;
4382 if (target == 0)
4383 return convert_to_mode (mode, result, 0);
4384 convert_move (target, result, 0);
4385 return target;
4386 }
902de8ed 4387
6ac5504b 4388 /* Expand the library call ourselves using a stabilized argument
4389 list to avoid re-evaluating the function's arguments twice. */
2694880e 4390#ifdef HAVE_cmpstrnsi
6b961939 4391 do_libcall:
2694880e 4392#endif
6ac5504b 4393 fndecl = get_callee_fndecl (exp);
c2f47e15 4394 fn = build_call_expr (fndecl, 2, arg1, arg2);
6ac5504b 4395 if (TREE_CODE (fn) == CALL_EXPR)
4396 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4397 return expand_call (fn, target, target == const0_rtx);
4398 }
7a3f89b5 4399#endif
c2f47e15 4400 return NULL_RTX;
83d79705 4401}
53800dbe 4402
c2f47e15 4403/* Expand expression EXP, which is a call to the strncmp builtin. Return
4404 NULL_RTX if we failed the caller should emit a normal call, otherwise try to get
ed09096d 4405 the result in TARGET, if convenient. */
27d0c333 4406
ed09096d 4407static rtx
aecda0d6 4408expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
ed09096d 4409{
c2f47e15 4410 if (!validate_arglist (exp,
4411 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4412 return NULL_RTX;
218bc19e 4413 else
ef6c187e 4414 {
c2f47e15 4415 tree result = fold_builtin_strncmp (CALL_EXPR_ARG (exp, 0),
4416 CALL_EXPR_ARG (exp, 1),
4417 CALL_EXPR_ARG (exp, 2));
218bc19e 4418 if (result)
4419 return expand_expr (result, target, mode, EXPAND_NORMAL);
ef6c187e 4420 }
ed09096d 4421
6e34e617 4422 /* If c_strlen can determine an expression for one of the string
6ac5504b 4423 lengths, and it doesn't have side effects, then emit cmpstrnsi
7a3f89b5 4424 using length MIN(strlen(string)+1, arg3). */
6ac5504b 4425#ifdef HAVE_cmpstrnsi
4426 if (HAVE_cmpstrnsi)
7a3f89b5 4427 {
4428 tree len, len1, len2;
4429 rtx arg1_rtx, arg2_rtx, arg3_rtx;
4430 rtx result, insn;
0b25db21 4431 tree fndecl, fn;
c2f47e15 4432 tree arg1 = CALL_EXPR_ARG (exp, 0);
4433 tree arg2 = CALL_EXPR_ARG (exp, 1);
4434 tree arg3 = CALL_EXPR_ARG (exp, 2);
6f428e8b 4435
7a3f89b5 4436 int arg1_align
4437 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4438 int arg2_align
4439 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4440 enum machine_mode insn_mode
6ac5504b 4441 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
bf8e3599 4442
681fab1e 4443 len1 = c_strlen (arg1, 1);
4444 len2 = c_strlen (arg2, 1);
7a3f89b5 4445
4446 if (len1)
4447 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
4448 if (len2)
4449 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
4450
4451 /* If we don't have a constant length for the first, use the length
4452 of the second, if we know it. We don't require a constant for
4453 this case; some cost analysis could be done if both are available
4454 but neither is constant. For now, assume they're equally cheap,
4455 unless one has side effects. If both strings have constant lengths,
4456 use the smaller. */
4457
4458 if (!len1)
4459 len = len2;
4460 else if (!len2)
4461 len = len1;
4462 else if (TREE_SIDE_EFFECTS (len1))
4463 len = len2;
4464 else if (TREE_SIDE_EFFECTS (len2))
4465 len = len1;
4466 else if (TREE_CODE (len1) != INTEGER_CST)
4467 len = len2;
4468 else if (TREE_CODE (len2) != INTEGER_CST)
4469 len = len1;
4470 else if (tree_int_cst_lt (len1, len2))
4471 len = len1;
4472 else
4473 len = len2;
6e34e617 4474
7a3f89b5 4475 /* If both arguments have side effects, we cannot optimize. */
4476 if (!len || TREE_SIDE_EFFECTS (len))
c2f47e15 4477 return NULL_RTX;
bf8e3599 4478
7a3f89b5 4479 /* The actual new length parameter is MIN(len,arg3). */
49d00087 4480 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
4481 fold_convert (TREE_TYPE (len), arg3));
7a3f89b5 4482
4483 /* If we don't have POINTER_TYPE, call the function. */
4484 if (arg1_align == 0 || arg2_align == 0)
c2f47e15 4485 return NULL_RTX;
7a3f89b5 4486
4487 /* Make a place to write the result of the instruction. */
4488 result = target;
4489 if (! (result != 0
8ad4c111 4490 && REG_P (result) && GET_MODE (result) == insn_mode
7a3f89b5 4491 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4492 result = gen_reg_rtx (insn_mode);
4493
6ac5504b 4494 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
4ee9c684 4495 arg1 = builtin_save_expr (arg1);
4496 arg2 = builtin_save_expr (arg2);
4497 len = builtin_save_expr (len);
3f8aefe2 4498
d8ae1baa 4499 arg1_rtx = get_memory_rtx (arg1, len);
4500 arg2_rtx = get_memory_rtx (arg2, len);
8ec3c5c2 4501 arg3_rtx = expand_normal (len);
6ac5504b 4502 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4503 GEN_INT (MIN (arg1_align, arg2_align)));
3f8aefe2 4504 if (insn)
4505 {
4506 emit_insn (insn);
4507
4508 /* Return the value in the proper mode for this function. */
4509 mode = TYPE_MODE (TREE_TYPE (exp));
4510 if (GET_MODE (result) == mode)
4511 return result;
4512 if (target == 0)
4513 return convert_to_mode (mode, result, 0);
4514 convert_move (target, result, 0);
4515 return target;
4516 }
7a3f89b5 4517
3f8aefe2 4518 /* Expand the library call ourselves using a stabilized argument
4519 list to avoid re-evaluating the function's arguments twice. */
3f8aefe2 4520 fndecl = get_callee_fndecl (exp);
c2f47e15 4521 fn = build_call_expr (fndecl, 3, arg1, arg2, len);
0b25db21 4522 if (TREE_CODE (fn) == CALL_EXPR)
4523 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4524 return expand_call (fn, target, target == const0_rtx);
7a3f89b5 4525 }
4526#endif
c2f47e15 4527 return NULL_RTX;
ed09096d 4528}
4529
49f0327b 4530/* Expand expression EXP, which is a call to the strcat builtin.
c2f47e15 4531 Return NULL_RTX if we failed the caller should emit a normal call,
49f0327b 4532 otherwise try to get the result in TARGET, if convenient. */
27d0c333 4533
49f0327b 4534static rtx
c2f47e15 4535expand_builtin_strcat (tree fndecl, tree exp, rtx target, enum machine_mode mode)
49f0327b 4536{
c2f47e15 4537 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4538 return NULL_RTX;
49f0327b 4539 else
4540 {
c2f47e15 4541 tree dst = CALL_EXPR_ARG (exp, 0);
4542 tree src = CALL_EXPR_ARG (exp, 1);
49f0327b 4543 const char *p = c_getstr (src);
4544
1d89860b 4545 /* If the string length is zero, return the dst parameter. */
a0c938f0 4546 if (p && *p == '\0')
1d89860b 4547 return expand_expr (dst, target, mode, EXPAND_NORMAL);
a0c938f0 4548
a0d18cec 4549 if (optimize_insn_for_speed_p ())
ca71f89b 4550 {
1d89860b 4551 /* See if we can store by pieces into (dst + strlen(dst)). */
4552 tree newsrc, newdst,
4553 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4554 rtx insns;
4555
4556 /* Stabilize the argument list. */
4557 newsrc = builtin_save_expr (src);
1d89860b 4558 dst = builtin_save_expr (dst);
4559
4560 start_sequence ();
4561
4562 /* Create strlen (dst). */
c2f47e15 4563 newdst = build_call_expr (strlen_fn, 1, dst);
0de36bdb 4564 /* Create (dst p+ strlen (dst)). */
1d89860b 4565
0de36bdb 4566 newdst = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
1d89860b 4567 newdst = builtin_save_expr (newdst);
1d89860b 4568
c2f47e15 4569 if (!expand_builtin_strcpy_args (fndecl, newdst, newsrc, target, mode))
ca71f89b 4570 {
1d89860b 4571 end_sequence (); /* Stop sequence. */
c2f47e15 4572 return NULL_RTX;
ca71f89b 4573 }
a0c938f0 4574
1d89860b 4575 /* Output the entire sequence. */
4576 insns = get_insns ();
4577 end_sequence ();
4578 emit_insn (insns);
a0c938f0 4579
1d89860b 4580 return expand_expr (dst, target, mode, EXPAND_NORMAL);
ca71f89b 4581 }
49f0327b 4582
c2f47e15 4583 return NULL_RTX;
49f0327b 4584 }
4585}
4586
4587/* Expand expression EXP, which is a call to the strncat builtin.
c2f47e15 4588 Return NULL_RTX if we failed the caller should emit a normal call,
49f0327b 4589 otherwise try to get the result in TARGET, if convenient. */
27d0c333 4590
49f0327b 4591static rtx
c2f47e15 4592expand_builtin_strncat (tree exp, rtx target, enum machine_mode mode)
49f0327b 4593{
c2f47e15 4594 if (validate_arglist (exp,
4595 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
49f0327b 4596 {
c2f47e15 4597 tree result = fold_builtin_strncat (CALL_EXPR_ARG (exp, 0),
4598 CALL_EXPR_ARG (exp, 1),
4599 CALL_EXPR_ARG (exp, 2));
2c84ee37 4600 if (result)
4601 return expand_expr (result, target, mode, EXPAND_NORMAL);
49f0327b 4602 }
c2f47e15 4603 return NULL_RTX;
49f0327b 4604}
4605
4606/* Expand expression EXP, which is a call to the strspn builtin.
c2f47e15 4607 Return NULL_RTX if we failed the caller should emit a normal call,
49f0327b 4608 otherwise try to get the result in TARGET, if convenient. */
27d0c333 4609
49f0327b 4610static rtx
c2f47e15 4611expand_builtin_strspn (tree exp, rtx target, enum machine_mode mode)
49f0327b 4612{
c2f47e15 4613 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
49f0327b 4614 {
c2f47e15 4615 tree result = fold_builtin_strspn (CALL_EXPR_ARG (exp, 0),
4616 CALL_EXPR_ARG (exp, 1));
2c84ee37 4617 if (result)
4618 return expand_expr (result, target, mode, EXPAND_NORMAL);
49f0327b 4619 }
c2f47e15 4620 return NULL_RTX;
49f0327b 4621}
4622
4623/* Expand expression EXP, which is a call to the strcspn builtin.
c2f47e15 4624 Return NULL_RTX if we failed the caller should emit a normal call,
49f0327b 4625 otherwise try to get the result in TARGET, if convenient. */
27d0c333 4626
49f0327b 4627static rtx
c2f47e15 4628expand_builtin_strcspn (tree exp, rtx target, enum machine_mode mode)
49f0327b 4629{
c2f47e15 4630 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
49f0327b 4631 {
c2f47e15 4632 tree result = fold_builtin_strcspn (CALL_EXPR_ARG (exp, 0),
4633 CALL_EXPR_ARG (exp, 1));
2c84ee37 4634 if (result)
4635 return expand_expr (result, target, mode, EXPAND_NORMAL);
49f0327b 4636 }
c2f47e15 4637 return NULL_RTX;
49f0327b 4638}
4639
a66c9326 4640/* Expand a call to __builtin_saveregs, generating the result in TARGET,
4641 if that's convenient. */
902de8ed 4642
a66c9326 4643rtx
aecda0d6 4644expand_builtin_saveregs (void)
53800dbe 4645{
a66c9326 4646 rtx val, seq;
53800dbe 4647
4648 /* Don't do __builtin_saveregs more than once in a function.
4649 Save the result of the first call and reuse it. */
4650 if (saveregs_value != 0)
4651 return saveregs_value;
53800dbe 4652
a66c9326 4653 /* When this function is called, it means that registers must be
4654 saved on entry to this function. So we migrate the call to the
4655 first insn of this function. */
4656
4657 start_sequence ();
53800dbe 4658
a66c9326 4659 /* Do whatever the machine needs done in this case. */
45550790 4660 val = targetm.calls.expand_builtin_saveregs ();
53800dbe 4661
a66c9326 4662 seq = get_insns ();
4663 end_sequence ();
53800dbe 4664
a66c9326 4665 saveregs_value = val;
53800dbe 4666
31d3e01c 4667 /* Put the insns after the NOTE that starts the function. If this
4668 is inside a start_sequence, make the outer-level insn chain current, so
a66c9326 4669 the code is placed at the start of the function. */
4670 push_topmost_sequence ();
0ec80471 4671 emit_insn_after (seq, entry_of_function ());
a66c9326 4672 pop_topmost_sequence ();
4673
4674 return val;
53800dbe 4675}
4676
4677/* __builtin_args_info (N) returns word N of the arg space info
4678 for the current function. The number and meanings of words
4679 is controlled by the definition of CUMULATIVE_ARGS. */
f7c44134 4680
53800dbe 4681static rtx
c2f47e15 4682expand_builtin_args_info (tree exp)
53800dbe 4683{
53800dbe 4684 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
abe32cce 4685 int *word_ptr = (int *) &crtl->args.info;
53800dbe 4686
64db345d 4687 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
53800dbe 4688
c2f47e15 4689 if (call_expr_nargs (exp) != 0)
53800dbe 4690 {
c2f47e15 4691 if (!host_integerp (CALL_EXPR_ARG (exp, 0), 0))
eb586f2c 4692 error ("argument of %<__builtin_args_info%> must be constant");
53800dbe 4693 else
4694 {
c2f47e15 4695 HOST_WIDE_INT wordnum = tree_low_cst (CALL_EXPR_ARG (exp, 0), 0);
53800dbe 4696
27d0c333 4697 if (wordnum < 0 || wordnum >= nwords)
eb586f2c 4698 error ("argument of %<__builtin_args_info%> out of range");
53800dbe 4699 else
4700 return GEN_INT (word_ptr[wordnum]);
4701 }
4702 }
4703 else
eb586f2c 4704 error ("missing argument in %<__builtin_args_info%>");
53800dbe 4705
4706 return const0_rtx;
53800dbe 4707}
4708
79012a9d 4709/* Expand a call to __builtin_next_arg. */
27d0c333 4710
53800dbe 4711static rtx
79012a9d 4712expand_builtin_next_arg (void)
53800dbe 4713{
79012a9d 4714 /* Checking arguments is already done in fold_builtin_next_arg
4715 that must be called before this function. */
940ddc5c 4716 return expand_binop (ptr_mode, add_optab,
abe32cce 4717 crtl->args.internal_arg_pointer,
4718 crtl->args.arg_offset_rtx,
53800dbe 4719 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4720}
4721
a66c9326 4722/* Make it easier for the backends by protecting the valist argument
4723 from multiple evaluations. */
4724
4725static tree
aecda0d6 4726stabilize_va_list (tree valist, int needs_lvalue)
a66c9326 4727{
5f57a8b1 4728 tree vatype = targetm.canonical_va_list_type (TREE_TYPE (valist));
4729
4730 gcc_assert (vatype != NULL_TREE);
4731
4732 if (TREE_CODE (vatype) == ARRAY_TYPE)
a66c9326 4733 {
2d47cc32 4734 if (TREE_SIDE_EFFECTS (valist))
4735 valist = save_expr (valist);
11a61dea 4736
2d47cc32 4737 /* For this case, the backends will be expecting a pointer to
5f57a8b1 4738 vatype, but it's possible we've actually been given an array
4739 (an actual TARGET_CANONICAL_VA_LIST_TYPE (valist)).
2d47cc32 4740 So fix it. */
4741 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
8a15c04a 4742 {
5f57a8b1 4743 tree p1 = build_pointer_type (TREE_TYPE (vatype));
fcdd3ab3 4744 valist = build_fold_addr_expr_with_type (valist, p1);
8a15c04a 4745 }
a66c9326 4746 }
11a61dea 4747 else
a66c9326 4748 {
2d47cc32 4749 tree pt;
11a61dea 4750
2d47cc32 4751 if (! needs_lvalue)
4752 {
11a61dea 4753 if (! TREE_SIDE_EFFECTS (valist))
4754 return valist;
bf8e3599 4755
5f57a8b1 4756 pt = build_pointer_type (vatype);
49d00087 4757 valist = fold_build1 (ADDR_EXPR, pt, valist);
a66c9326 4758 TREE_SIDE_EFFECTS (valist) = 1;
a66c9326 4759 }
2d47cc32 4760
11a61dea 4761 if (TREE_SIDE_EFFECTS (valist))
2d47cc32 4762 valist = save_expr (valist);
fcdd3ab3 4763 valist = build_fold_indirect_ref (valist);
a66c9326 4764 }
4765
4766 return valist;
4767}
4768
2e15d750 4769/* The "standard" definition of va_list is void*. */
4770
4771tree
4772std_build_builtin_va_list (void)
4773{
4774 return ptr_type_node;
4775}
4776
5f57a8b1 4777/* The "standard" abi va_list is va_list_type_node. */
4778
4779tree
4780std_fn_abi_va_list (tree fndecl ATTRIBUTE_UNUSED)
4781{
4782 return va_list_type_node;
4783}
4784
4785/* The "standard" type of va_list is va_list_type_node. */
4786
4787tree
4788std_canonical_va_list_type (tree type)
4789{
4790 tree wtype, htype;
4791
4792 if (INDIRECT_REF_P (type))
4793 type = TREE_TYPE (type);
4794 else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE(type)))
4795 type = TREE_TYPE (type);
5f57a8b1 4796 wtype = va_list_type_node;
4797 htype = type;
7b36f9ab 4798 /* Treat structure va_list types. */
4799 if (TREE_CODE (wtype) == RECORD_TYPE && POINTER_TYPE_P (htype))
4800 htype = TREE_TYPE (htype);
4801 else if (TREE_CODE (wtype) == ARRAY_TYPE)
5f57a8b1 4802 {
4803 /* If va_list is an array type, the argument may have decayed
4804 to a pointer type, e.g. by being passed to another function.
4805 In that case, unwrap both types so that we can compare the
4806 underlying records. */
4807 if (TREE_CODE (htype) == ARRAY_TYPE
4808 || POINTER_TYPE_P (htype))
4809 {
4810 wtype = TREE_TYPE (wtype);
4811 htype = TREE_TYPE (htype);
4812 }
4813 }
4814 if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
4815 return va_list_type_node;
4816
4817 return NULL_TREE;
4818}
4819
a66c9326 4820/* The "standard" implementation of va_start: just assign `nextarg' to
4821 the variable. */
27d0c333 4822
a66c9326 4823void
aecda0d6 4824std_expand_builtin_va_start (tree valist, rtx nextarg)
a66c9326 4825{
f03c17bc 4826 rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
4827 convert_move (va_r, nextarg, 0);
a66c9326 4828}
4829
c2f47e15 4830/* Expand EXP, a call to __builtin_va_start. */
27d0c333 4831
a66c9326 4832static rtx
c2f47e15 4833expand_builtin_va_start (tree exp)
a66c9326 4834{
4835 rtx nextarg;
c2f47e15 4836 tree valist;
a66c9326 4837
c2f47e15 4838 if (call_expr_nargs (exp) < 2)
cb166087 4839 {
4840 error ("too few arguments to function %<va_start%>");
4841 return const0_rtx;
4842 }
a66c9326 4843
c2f47e15 4844 if (fold_builtin_next_arg (exp, true))
79012a9d 4845 return const0_rtx;
7c2f0500 4846
79012a9d 4847 nextarg = expand_builtin_next_arg ();
c2f47e15 4848 valist = stabilize_va_list (CALL_EXPR_ARG (exp, 0), 1);
a66c9326 4849
8a58ed0a 4850 if (targetm.expand_builtin_va_start)
4851 targetm.expand_builtin_va_start (valist, nextarg);
4852 else
4853 std_expand_builtin_va_start (valist, nextarg);
a66c9326 4854
4855 return const0_rtx;
4856}
4857
a66c9326 4858/* The "standard" implementation of va_arg: read the value from the
4859 current (padded) address and increment by the (padded) size. */
f7c44134 4860
e0eca1fa 4861tree
75a70cf9 4862std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
4863 gimple_seq *post_p)
fcdd3ab3 4864{
52cc2eeb 4865 tree addr, t, type_size, rounded_size, valist_tmp;
b8e8e485 4866 unsigned HOST_WIDE_INT align, boundary;
bef380a4 4867 bool indirect;
52cc2eeb 4868
4869#ifdef ARGS_GROW_DOWNWARD
4870 /* All of the alignment and movement below is for args-grow-up machines.
4871 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4872 implement their own specialized gimplify_va_arg_expr routines. */
64db345d 4873 gcc_unreachable ();
52cc2eeb 4874#endif
fcdd3ab3 4875
bef380a4 4876 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4877 if (indirect)
4878 type = build_pointer_type (type);
4879
52cc2eeb 4880 align = PARM_BOUNDARY / BITS_PER_UNIT;
c8b779eb 4881 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
4882
4883 /* When we align parameter on stack for caller, if the parameter
befa808c 4884 alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
4885 aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
c8b779eb 4886 here with caller. */
befa808c 4887 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
4888 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
c8b779eb 4889
4890 boundary /= BITS_PER_UNIT;
fcdd3ab3 4891
52cc2eeb 4892 /* Hoist the valist value into a temporary for the moment. */
ecdeeb37 4893 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4894
fcdd3ab3 4895 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4896 requires greater alignment, we must perform dynamic alignment. */
85c1f587 4897 if (boundary > align
4898 && !integer_zerop (TYPE_SIZE (type)))
fcdd3ab3 4899 {
41076ef6 4900 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
0de36bdb 4901 fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (valist),
4902 valist_tmp, size_int (boundary - 1)));
52cc2eeb 4903 gimplify_and_add (t, pre_p);
4904
0de36bdb 4905 t = fold_convert (sizetype, valist_tmp);
41076ef6 4906 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
0de36bdb 4907 fold_convert (TREE_TYPE (valist),
4908 fold_build2 (BIT_AND_EXPR, sizetype, t,
4909 size_int (-boundary))));
ecdeeb37 4910 gimplify_and_add (t, pre_p);
fcdd3ab3 4911 }
c5dc0c32 4912 else
4913 boundary = align;
4914
4915 /* If the actual alignment is less than the alignment of the type,
4916 adjust the type accordingly so that we don't assume strict alignment
f0b5f617 4917 when dereferencing the pointer. */
c5dc0c32 4918 boundary *= BITS_PER_UNIT;
4919 if (boundary < TYPE_ALIGN (type))
4920 {
4921 type = build_variant_type_copy (type);
4922 TYPE_ALIGN (type) = boundary;
4923 }
fcdd3ab3 4924
bcff3604 4925 /* Compute the rounded size of the type. */
52cc2eeb 4926 type_size = size_in_bytes (type);
4927 rounded_size = round_up (type_size, align);
4928
fcdd3ab3 4929 /* Reduce rounded_size so it's sharable with the postqueue. */
4930 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4931
4932 /* Get AP. */
ecdeeb37 4933 addr = valist_tmp;
52cc2eeb 4934 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
fcdd3ab3 4935 {
4936 /* Small args are padded downward. */
49d00087 4937 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4938 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4939 size_binop (MINUS_EXPR, rounded_size, type_size));
0de36bdb 4940 addr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (addr), addr, t);
fcdd3ab3 4941 }
4942
fcdd3ab3 4943 /* Compute new value for AP. */
0de36bdb 4944 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (valist), valist_tmp, rounded_size);
41076ef6 4945 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
ecdeeb37 4946 gimplify_and_add (t, pre_p);
e0eca1fa 4947
4948 addr = fold_convert (build_pointer_type (type), addr);
fcdd3ab3 4949
bef380a4 4950 if (indirect)
f2462d6c 4951 addr = build_va_arg_indirect_ref (addr);
4952
4953 return build_va_arg_indirect_ref (addr);
4954}
a0930a69 4955
f2462d6c 4956/* Build an indirect-ref expression over the given TREE, which represents a
4957 piece of a va_arg() expansion. */
4958tree
4959build_va_arg_indirect_ref (tree addr)
4960{
a0930a69 4961 addr = build_fold_indirect_ref (addr);
f2462d6c 4962
a0930a69 4963 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4964 mf_mark (addr);
bef380a4 4965
a0930a69 4966 return addr;
433006a9 4967}
4968
fcdd3ab3 4969/* Return a dummy expression of type TYPE in order to keep going after an
4970 error. */
4971
4972static tree
4973dummy_object (tree type)
4974{
535664e3 4975 tree t = build_int_cst (build_pointer_type (type), 0);
fcdd3ab3 4976 return build1 (INDIRECT_REF, type, t);
4977}
4978
2799a2b7 4979/* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4980 builtin function, but a very special sort of operator. */
fcdd3ab3 4981
4982enum gimplify_status
75a70cf9 4983gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
fcdd3ab3 4984{
5f57a8b1 4985 tree promoted_type, have_va_type;
fcdd3ab3 4986 tree valist = TREE_OPERAND (*expr_p, 0);
4987 tree type = TREE_TYPE (*expr_p);
4988 tree t;
e60a6f7b 4989 location_t loc = EXPR_HAS_LOCATION (*expr_p) ? EXPR_LOCATION (*expr_p) :
4990 UNKNOWN_LOCATION;
fcdd3ab3 4991
4992 /* Verify that valist is of the proper type. */
fcdd3ab3 4993 have_va_type = TREE_TYPE (valist);
f43dda35 4994 if (have_va_type == error_mark_node)
4995 return GS_ERROR;
5f57a8b1 4996 have_va_type = targetm.canonical_va_list_type (have_va_type);
f43dda35 4997
5f57a8b1 4998 if (have_va_type == NULL_TREE)
fcdd3ab3 4999 {
e60a6f7b 5000 error_at (loc, "first argument to %<va_arg%> not of type %<va_list%>");
e0eca1fa 5001 return GS_ERROR;
fcdd3ab3 5002 }
5003
5004 /* Generate a diagnostic for requesting data of a type that cannot
5005 be passed through `...' due to type promotion at the call site. */
5f57a8b1 5006 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
fcdd3ab3 5007 != type)
5008 {
5009 static bool gave_help;
a52d5726 5010 bool warned;
fcdd3ab3 5011
5012 /* Unfortunately, this is merely undefined, rather than a constraint
5013 violation, so we cannot make this an error. If this call is never
5014 executed, the program is still strictly conforming. */
e60a6f7b 5015 warned = warning_at (loc, 0,
5016 "%qT is promoted to %qT when passed through %<...%>",
5017 type, promoted_type);
a52d5726 5018 if (!gave_help && warned)
fcdd3ab3 5019 {
5020 gave_help = true;
e60a6f7b 5021 inform (loc, "(so you should pass %qT not %qT to %<va_arg%>)",
5022 promoted_type, type);
fcdd3ab3 5023 }
5024
5025 /* We can, however, treat "undefined" any way we please.
5026 Call abort to encourage the user to fix the program. */
a52d5726 5027 if (warned)
e60a6f7b 5028 inform (loc, "if this code is reached, the program will abort");
ad0e7a06 5029 /* Before the abort, allow the evaluation of the va_list
5030 expression to exit or longjmp. */
5031 gimplify_and_add (valist, pre_p);
c2f47e15 5032 t = build_call_expr (implicit_built_in_decls[BUILT_IN_TRAP], 0);
75a70cf9 5033 gimplify_and_add (t, pre_p);
fcdd3ab3 5034
5035 /* This is dead code, but go ahead and finish so that the
5036 mode of the result comes out right. */
5037 *expr_p = dummy_object (type);
5038 return GS_ALL_DONE;
5039 }
5040 else
5041 {
5042 /* Make it easier for the backends by protecting the valist argument
a0c938f0 5043 from multiple evaluations. */
5f57a8b1 5044 if (TREE_CODE (have_va_type) == ARRAY_TYPE)
e0eca1fa 5045 {
5046 /* For this case, the backends will be expecting a pointer to
5f57a8b1 5047 TREE_TYPE (abi), but it's possible we've
5048 actually been given an array (an actual TARGET_FN_ABI_VA_LIST).
e0eca1fa 5049 So fix it. */
5050 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
5051 {
5f57a8b1 5052 tree p1 = build_pointer_type (TREE_TYPE (have_va_type));
bab5904e 5053 valist = fold_convert (p1, build_fold_addr_expr (valist));
e0eca1fa 5054 }
75a70cf9 5055
e0eca1fa 5056 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
5057 }
5058 else
5059 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
fcdd3ab3 5060
17a6380d 5061 if (!targetm.gimplify_va_arg_expr)
75a70cf9 5062 /* FIXME: Once most targets are converted we should merely
89f18f73 5063 assert this is non-null. */
fcdd3ab3 5064 return GS_ALL_DONE;
5065
17a6380d 5066 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
fcdd3ab3 5067 return GS_OK;
5068 }
5069}
5070
c2f47e15 5071/* Expand EXP, a call to __builtin_va_end. */
f7c44134 5072
a66c9326 5073static rtx
c2f47e15 5074expand_builtin_va_end (tree exp)
a66c9326 5075{
c2f47e15 5076 tree valist = CALL_EXPR_ARG (exp, 0);
8a15c04a 5077
8a15c04a 5078 /* Evaluate for side effects, if needed. I hate macros that don't
5079 do that. */
5080 if (TREE_SIDE_EFFECTS (valist))
5081 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
a66c9326 5082
5083 return const0_rtx;
5084}
5085
c2f47e15 5086/* Expand EXP, a call to __builtin_va_copy. We do this as a
a66c9326 5087 builtin rather than just as an assignment in stdarg.h because of the
5088 nastiness of array-type va_list types. */
f7c44134 5089
a66c9326 5090static rtx
c2f47e15 5091expand_builtin_va_copy (tree exp)
a66c9326 5092{
5093 tree dst, src, t;
5094
c2f47e15 5095 dst = CALL_EXPR_ARG (exp, 0);
5096 src = CALL_EXPR_ARG (exp, 1);
a66c9326 5097
5098 dst = stabilize_va_list (dst, 1);
5099 src = stabilize_va_list (src, 0);
5100
5f57a8b1 5101 gcc_assert (cfun != NULL && cfun->decl != NULL_TREE);
5102
5103 if (TREE_CODE (targetm.fn_abi_va_list (cfun->decl)) != ARRAY_TYPE)
a66c9326 5104 {
5f57a8b1 5105 t = build2 (MODIFY_EXPR, targetm.fn_abi_va_list (cfun->decl), dst, src);
a66c9326 5106 TREE_SIDE_EFFECTS (t) = 1;
5107 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5108 }
5109 else
5110 {
11a61dea 5111 rtx dstb, srcb, size;
5112
5113 /* Evaluate to pointers. */
5114 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
5115 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
5f57a8b1 5116 size = expand_expr (TYPE_SIZE_UNIT (targetm.fn_abi_va_list (cfun->decl)),
5117 NULL_RTX, VOIDmode, EXPAND_NORMAL);
11a61dea 5118
85d654dd 5119 dstb = convert_memory_address (Pmode, dstb);
5120 srcb = convert_memory_address (Pmode, srcb);
726ec87c 5121
11a61dea 5122 /* "Dereference" to BLKmode memories. */
5123 dstb = gen_rtx_MEM (BLKmode, dstb);
ab6ab77e 5124 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
5f57a8b1 5125 set_mem_align (dstb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
11a61dea 5126 srcb = gen_rtx_MEM (BLKmode, srcb);
ab6ab77e 5127 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
5f57a8b1 5128 set_mem_align (srcb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
11a61dea 5129
5130 /* Copy. */
0378dbdc 5131 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
a66c9326 5132 }
5133
5134 return const0_rtx;
5135}
5136
53800dbe 5137/* Expand a call to one of the builtin functions __builtin_frame_address or
5138 __builtin_return_address. */
27d0c333 5139
53800dbe 5140static rtx
c2f47e15 5141expand_builtin_frame_address (tree fndecl, tree exp)
53800dbe 5142{
53800dbe 5143 /* The argument must be a nonnegative integer constant.
5144 It counts the number of frames to scan up the stack.
5145 The value is the return address saved in that frame. */
c2f47e15 5146 if (call_expr_nargs (exp) == 0)
53800dbe 5147 /* Warning about missing arg was already issued. */
5148 return const0_rtx;
c2f47e15 5149 else if (! host_integerp (CALL_EXPR_ARG (exp, 0), 1))
53800dbe 5150 {
5151 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
07e3a3d2 5152 error ("invalid argument to %<__builtin_frame_address%>");
53800dbe 5153 else
07e3a3d2 5154 error ("invalid argument to %<__builtin_return_address%>");
53800dbe 5155 return const0_rtx;
5156 }
5157 else
5158 {
27d0c333 5159 rtx tem
5160 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
c2f47e15 5161 tree_low_cst (CALL_EXPR_ARG (exp, 0), 1));
53800dbe 5162
5163 /* Some ports cannot access arbitrary stack frames. */
5164 if (tem == NULL)
5165 {
5166 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
c3ceba8e 5167 warning (0, "unsupported argument to %<__builtin_frame_address%>");
53800dbe 5168 else
c3ceba8e 5169 warning (0, "unsupported argument to %<__builtin_return_address%>");
53800dbe 5170 return const0_rtx;
5171 }
5172
5173 /* For __builtin_frame_address, return what we've got. */
5174 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
5175 return tem;
5176
8ad4c111 5177 if (!REG_P (tem)
53800dbe 5178 && ! CONSTANT_P (tem))
5179 tem = copy_to_mode_reg (Pmode, tem);
5180 return tem;
5181 }
5182}
5183
c2f47e15 5184/* Expand EXP, a call to the alloca builtin. Return NULL_RTX if
53800dbe 5185 we failed and the caller should emit a normal call, otherwise try to get
5186 the result in TARGET, if convenient. */
15c6cf6b 5187
53800dbe 5188static rtx
c2f47e15 5189expand_builtin_alloca (tree exp, rtx target)
53800dbe 5190{
5191 rtx op0;
15c6cf6b 5192 rtx result;
53800dbe 5193
f9fa0459 5194 /* Emit normal call if marked not-inlineable. */
5195 if (CALL_CANNOT_INLINE_P (exp))
c2f47e15 5196 return NULL_RTX;
4ee9c684 5197
c2f47e15 5198 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5199 return NULL_RTX;
53800dbe 5200
5201 /* Compute the argument. */
c2f47e15 5202 op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
53800dbe 5203
5204 /* Allocate the desired space. */
15c6cf6b 5205 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
85d654dd 5206 result = convert_memory_address (ptr_mode, result);
15c6cf6b 5207
5208 return result;
53800dbe 5209}
5210
c2f47e15 5211/* Expand a call to a bswap builtin with argument ARG0. MODE
42791117 5212 is the mode to expand with. */
5213
5214static rtx
c2f47e15 5215expand_builtin_bswap (tree exp, rtx target, rtx subtarget)
42791117 5216{
5217 enum machine_mode mode;
5218 tree arg;
5219 rtx op0;
5220
c2f47e15 5221 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5222 return NULL_RTX;
42791117 5223
c2f47e15 5224 arg = CALL_EXPR_ARG (exp, 0);
42791117 5225 mode = TYPE_MODE (TREE_TYPE (arg));
1db6d067 5226 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
42791117 5227
5228 target = expand_unop (mode, bswap_optab, op0, target, 1);
5229
5230 gcc_assert (target);
5231
5232 return convert_to_mode (mode, target, 0);
5233}
5234
c2f47e15 5235/* Expand a call to a unary builtin in EXP.
5236 Return NULL_RTX if a normal call should be emitted rather than expanding the
53800dbe 5237 function in-line. If convenient, the result should be placed in TARGET.
5238 SUBTARGET may be used as the target for computing one of EXP's operands. */
15c6cf6b 5239
53800dbe 5240static rtx
c2f47e15 5241expand_builtin_unop (enum machine_mode target_mode, tree exp, rtx target,
aecda0d6 5242 rtx subtarget, optab op_optab)
53800dbe 5243{
5244 rtx op0;
c2f47e15 5245
5246 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5247 return NULL_RTX;
53800dbe 5248
5249 /* Compute the argument. */
1db6d067 5250 op0 = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
5251 VOIDmode, EXPAND_NORMAL);
6a08d0ab 5252 /* Compute op, into TARGET if possible.
53800dbe 5253 Set TARGET to wherever the result comes back. */
c2f47e15 5254 target = expand_unop (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0))),
6a08d0ab 5255 op_optab, op0, target, 1);
64db345d 5256 gcc_assert (target);
7d3f6cc7 5257
efb070c8 5258 return convert_to_mode (target_mode, target, 0);
53800dbe 5259}
89cfe6e5 5260
df94cd3b 5261/* If the string passed to fputs is a constant and is one character
2c0e001b 5262 long, we attempt to transform this call into __builtin_fputc(). */
15c6cf6b 5263
df94cd3b 5264static rtx
c2f47e15 5265expand_builtin_fputs (tree exp, rtx target, bool unlocked)
df94cd3b 5266{
2c0e001b 5267 /* Verify the arguments in the original call. */
c2f47e15 5268 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
ce1b14f4 5269 {
c2f47e15 5270 tree result = fold_builtin_fputs (CALL_EXPR_ARG (exp, 0),
5271 CALL_EXPR_ARG (exp, 1),
5272 (target == const0_rtx),
2c84ee37 5273 unlocked, NULL_TREE);
5274 if (result)
5275 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
ce1b14f4 5276 }
c2f47e15 5277 return NULL_RTX;
3311f67b 5278}
5279
5a74f77e 5280/* Expand a call to __builtin_expect. We just return our argument
5281 as the builtin_expect semantic should've been already executed by
5282 tree branch prediction pass. */
89cfe6e5 5283
5284static rtx
c2f47e15 5285expand_builtin_expect (tree exp, rtx target)
89cfe6e5 5286{
c2f47e15 5287 tree arg, c;
89cfe6e5 5288
c2f47e15 5289 if (call_expr_nargs (exp) < 2)
89cfe6e5 5290 return const0_rtx;
c2f47e15 5291 arg = CALL_EXPR_ARG (exp, 0);
5292 c = CALL_EXPR_ARG (exp, 1);
89cfe6e5 5293
c2f47e15 5294 target = expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5a74f77e 5295 /* When guessing was done, the hints should be already stripped away. */
07311427 5296 gcc_assert (!flag_guess_branch_prob
5297 || optimize == 0 || errorcount || sorrycount);
89cfe6e5 5298 return target;
5299}
689df48e 5300
c22de3f0 5301void
aecda0d6 5302expand_builtin_trap (void)
a0ef1725 5303{
5304#ifdef HAVE_trap
5305 if (HAVE_trap)
5306 emit_insn (gen_trap ());
5307 else
5308#endif
5309 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
5310 emit_barrier ();
5311}
78a74442 5312
d2b48f0c 5313/* Expand a call to __builtin_unreachable. We do nothing except emit
5314 a barrier saying that control flow will not pass here.
5315
5316 It is the responsibility of the program being compiled to ensure
5317 that control flow does never reach __builtin_unreachable. */
5318static void
5319expand_builtin_unreachable (void)
5320{
5321 emit_barrier ();
5322}
5323
c2f47e15 5324/* Expand EXP, a call to fabs, fabsf or fabsl.
5325 Return NULL_RTX if a normal call should be emitted rather than expanding
78a74442 5326 the function inline. If convenient, the result should be placed
5327 in TARGET. SUBTARGET may be used as the target for computing
5328 the operand. */
5329
5330static rtx
c2f47e15 5331expand_builtin_fabs (tree exp, rtx target, rtx subtarget)
78a74442 5332{
5333 enum machine_mode mode;
5334 tree arg;
5335 rtx op0;
5336
c2f47e15 5337 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
5338 return NULL_RTX;
78a74442 5339
c2f47e15 5340 arg = CALL_EXPR_ARG (exp, 0);
c7f617c2 5341 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
78a74442 5342 mode = TYPE_MODE (TREE_TYPE (arg));
1db6d067 5343 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
78a74442 5344 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
5345}
5346
c2f47e15 5347/* Expand EXP, a call to copysign, copysignf, or copysignl.
270436f3 5348 Return NULL is a normal call should be emitted rather than expanding the
5349 function inline. If convenient, the result should be placed in TARGET.
5350 SUBTARGET may be used as the target for computing the operand. */
5351
5352static rtx
c2f47e15 5353expand_builtin_copysign (tree exp, rtx target, rtx subtarget)
270436f3 5354{
5355 rtx op0, op1;
5356 tree arg;
5357
c2f47e15 5358 if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
5359 return NULL_RTX;
270436f3 5360
c2f47e15 5361 arg = CALL_EXPR_ARG (exp, 0);
8ec3c5c2 5362 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
270436f3 5363
c2f47e15 5364 arg = CALL_EXPR_ARG (exp, 1);
8ec3c5c2 5365 op1 = expand_normal (arg);
270436f3 5366
5367 return expand_copysign (op0, op1, target);
5368}
5369
19bf118a 5370/* Create a new constant string literal and return a char* pointer to it.
5371 The STRING_CST value is the LEN characters at STR. */
1e8e9920 5372tree
19bf118a 5373build_string_literal (int len, const char *str)
5374{
5375 tree t, elem, index, type;
5376
5377 t = build_string (len, str);
5378 elem = build_type_variant (char_type_node, 1, 0);
40238f64 5379 index = build_index_type (size_int (len - 1));
19bf118a 5380 type = build_array_type (elem, index);
5381 TREE_TYPE (t) = type;
5382 TREE_CONSTANT (t) = 1;
5383 TREE_READONLY (t) = 1;
5384 TREE_STATIC (t) = 1;
5385
19bf118a 5386 type = build_pointer_type (elem);
40238f64 5387 t = build1 (ADDR_EXPR, type,
5388 build4 (ARRAY_REF, elem,
5389 t, integer_zero_node, NULL_TREE, NULL_TREE));
19bf118a 5390 return t;
5391}
5392
0b25db21 5393/* Expand EXP, a call to printf or printf_unlocked.
c2f47e15 5394 Return NULL_RTX if a normal call should be emitted rather than transforming
19bf118a 5395 the function inline. If convenient, the result should be placed in
0862b7e9 5396 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
19bf118a 5397 call. */
5398static rtx
0b25db21 5399expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
19bf118a 5400 bool unlocked)
5401{
6d77ed92 5402 /* If we're using an unlocked function, assume the other unlocked
5403 functions exist explicitly. */
5404 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
5405 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
5406 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
5407 : implicit_built_in_decls[BUILT_IN_PUTS];
19bf118a 5408 const char *fmt_str;
c2f47e15 5409 tree fn = 0;
5410 tree fmt, arg;
5411 int nargs = call_expr_nargs (exp);
19bf118a 5412
5413 /* If the return value is used, don't do the transformation. */
5414 if (target != const0_rtx)
c2f47e15 5415 return NULL_RTX;
19bf118a 5416
5417 /* Verify the required arguments in the original call. */
c2f47e15 5418 if (nargs == 0)
5419 return NULL_RTX;
5420 fmt = CALL_EXPR_ARG (exp, 0);
552752f7 5421 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
c2f47e15 5422 return NULL_RTX;
19bf118a 5423
5424 /* Check whether the format is a literal string constant. */
5425 fmt_str = c_getstr (fmt);
5426 if (fmt_str == NULL)
c2f47e15 5427 return NULL_RTX;
19bf118a 5428
d4473c84 5429 if (!init_target_chars ())
c2f47e15 5430 return NULL_RTX;
a0c938f0 5431
19bf118a 5432 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
99eabcc1 5433 if (strcmp (fmt_str, target_percent_s_newline) == 0)
19bf118a 5434 {
c2f47e15 5435 if ((nargs != 2)
5436 || ! POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (exp, 1))))
5437 return NULL_RTX;
5438 if (fn_puts)
5439 fn = build_call_expr (fn_puts, 1, CALL_EXPR_ARG (exp, 1));
19bf118a 5440 }
5441 /* If the format specifier was "%c", call __builtin_putchar(arg). */
99eabcc1 5442 else if (strcmp (fmt_str, target_percent_c) == 0)
19bf118a 5443 {
c2f47e15 5444 if ((nargs != 2)
5445 || TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1))) != INTEGER_TYPE)
5446 return NULL_RTX;
5447 if (fn_putchar)
5448 fn = build_call_expr (fn_putchar, 1, CALL_EXPR_ARG (exp, 1));
19bf118a 5449 }
5450 else
5451 {
5452 /* We can't handle anything else with % args or %% ... yet. */
99eabcc1 5453 if (strchr (fmt_str, target_percent))
c2f47e15 5454 return NULL_RTX;
19bf118a 5455
c2f47e15 5456 if (nargs > 1)
5457 return NULL_RTX;
19bf118a 5458
5459 /* If the format specifier was "", printf does nothing. */
5460 if (fmt_str[0] == '\0')
5461 return const0_rtx;
5462 /* If the format specifier has length of 1, call putchar. */
5463 if (fmt_str[1] == '\0')
5464 {
5465 /* Given printf("c"), (where c is any one character,)
5466 convert "c"[0] to an int and pass that to the replacement
5467 function. */
7016c612 5468 arg = build_int_cst (NULL_TREE, fmt_str[0]);
c2f47e15 5469 if (fn_putchar)
5470 fn = build_call_expr (fn_putchar, 1, arg);
19bf118a 5471 }
5472 else
5473 {
5474 /* If the format specifier was "string\n", call puts("string"). */
5475 size_t len = strlen (fmt_str);
99eabcc1 5476 if ((unsigned char)fmt_str[len - 1] == target_newline)
19bf118a 5477 {
91c82c20 5478 /* Create a NUL-terminated string that's one char shorter
19bf118a 5479 than the original, stripping off the trailing '\n'. */
364c0c59 5480 char *newstr = XALLOCAVEC (char, len);
19bf118a 5481 memcpy (newstr, fmt_str, len - 1);
5482 newstr[len - 1] = 0;
19bf118a 5483 arg = build_string_literal (len, newstr);
c2f47e15 5484 if (fn_puts)
5485 fn = build_call_expr (fn_puts, 1, arg);
19bf118a 5486 }
5487 else
5488 /* We'd like to arrange to call fputs(string,stdout) here,
5489 but we need stdout and don't have a way to get it yet. */
c2f47e15 5490 return NULL_RTX;
19bf118a 5491 }
5492 }
5493
5494 if (!fn)
c2f47e15 5495 return NULL_RTX;
0b25db21 5496 if (TREE_CODE (fn) == CALL_EXPR)
5497 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5498 return expand_expr (fn, target, mode, EXPAND_NORMAL);
19bf118a 5499}
5500
0b25db21 5501/* Expand EXP, a call to fprintf or fprintf_unlocked.
c2f47e15 5502 Return NULL_RTX if a normal call should be emitted rather than transforming
19bf118a 5503 the function inline. If convenient, the result should be placed in
0862b7e9 5504 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
19bf118a 5505 call. */
5506static rtx
0b25db21 5507expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
a0c938f0 5508 bool unlocked)
19bf118a 5509{
6d77ed92 5510 /* If we're using an unlocked function, assume the other unlocked
5511 functions exist explicitly. */
5512 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5513 : implicit_built_in_decls[BUILT_IN_FPUTC];
5514 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5515 : implicit_built_in_decls[BUILT_IN_FPUTS];
19bf118a 5516 const char *fmt_str;
c2f47e15 5517 tree fn = 0;
5518 tree fmt, fp, arg;
5519 int nargs = call_expr_nargs (exp);
19bf118a 5520
5521 /* If the return value is used, don't do the transformation. */
5522 if (target != const0_rtx)
c2f47e15 5523 return NULL_RTX;
19bf118a 5524
5525 /* Verify the required arguments in the original call. */
c2f47e15 5526 if (nargs < 2)
5527 return NULL_RTX;
5528 fp = CALL_EXPR_ARG (exp, 0);
552752f7 5529 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
c2f47e15 5530 return NULL_RTX;
5531 fmt = CALL_EXPR_ARG (exp, 1);
552752f7 5532 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
c2f47e15 5533 return NULL_RTX;
19bf118a 5534
5535 /* Check whether the format is a literal string constant. */
5536 fmt_str = c_getstr (fmt);
5537 if (fmt_str == NULL)
c2f47e15 5538 return NULL_RTX;
19bf118a 5539
d4473c84 5540 if (!init_target_chars ())
c2f47e15 5541 return NULL_RTX;
a0c938f0 5542
19bf118a 5543 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
99eabcc1 5544 if (strcmp (fmt_str, target_percent_s) == 0)
19bf118a 5545 {
c2f47e15 5546 if ((nargs != 3)
5547 || ! POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (exp, 2))))
5548 return NULL_RTX;
5549 arg = CALL_EXPR_ARG (exp, 2);
5550 if (fn_fputs)
5551 fn = build_call_expr (fn_fputs, 2, arg, fp);
19bf118a 5552 }
5553 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
99eabcc1 5554 else if (strcmp (fmt_str, target_percent_c) == 0)
19bf118a 5555 {
c2f47e15 5556 if ((nargs != 3)
5557 || TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2))) != INTEGER_TYPE)
5558 return NULL_RTX;
5559 arg = CALL_EXPR_ARG (exp, 2);
5560 if (fn_fputc)
5561 fn = build_call_expr (fn_fputc, 2, arg, fp);
19bf118a 5562 }
5563 else
5564 {
5565 /* We can't handle anything else with % args or %% ... yet. */
99eabcc1 5566 if (strchr (fmt_str, target_percent))
c2f47e15 5567 return NULL_RTX;
19bf118a 5568
c2f47e15 5569 if (nargs > 2)
5570 return NULL_RTX;
19bf118a 5571
5572 /* If the format specifier was "", fprintf does nothing. */
5573 if (fmt_str[0] == '\0')
5574 {
5575 /* Evaluate and ignore FILE* argument for side-effects. */
5576 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5577 return const0_rtx;
5578 }
5579
5580 /* When "string" doesn't contain %, replace all cases of
5581 fprintf(stream,string) with fputs(string,stream). The fputs
5582 builtin will take care of special cases like length == 1. */
c2f47e15 5583 if (fn_fputs)
5584 fn = build_call_expr (fn_fputs, 2, fmt, fp);
19bf118a 5585 }
5586
5587 if (!fn)
c2f47e15 5588 return NULL_RTX;
0b25db21 5589 if (TREE_CODE (fn) == CALL_EXPR)
5590 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5591 return expand_expr (fn, target, mode, EXPAND_NORMAL);
19bf118a 5592}
5593
c2f47e15 5594/* Expand a call EXP to sprintf. Return NULL_RTX if
6411575e 5595 a normal call should be emitted rather than expanding the function
5596 inline. If convenient, the result should be placed in TARGET with
5597 mode MODE. */
5598
5599static rtx
c2f47e15 5600expand_builtin_sprintf (tree exp, rtx target, enum machine_mode mode)
6411575e 5601{
c2f47e15 5602 tree dest, fmt;
a7a723f0 5603 const char *fmt_str;
c2f47e15 5604 int nargs = call_expr_nargs (exp);
6411575e 5605
5606 /* Verify the required arguments in the original call. */
c2f47e15 5607 if (nargs < 2)
5608 return NULL_RTX;
5609 dest = CALL_EXPR_ARG (exp, 0);
552752f7 5610 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
c2f47e15 5611 return NULL_RTX;
5612 fmt = CALL_EXPR_ARG (exp, 0);
552752f7 5613 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
c2f47e15 5614 return NULL_RTX;
6411575e 5615
5616 /* Check whether the format is a literal string constant. */
a7a723f0 5617 fmt_str = c_getstr (fmt);
5618 if (fmt_str == NULL)
c2f47e15 5619 return NULL_RTX;
6411575e 5620
d4473c84 5621 if (!init_target_chars ())
c2f47e15 5622 return NULL_RTX;
99eabcc1 5623
6411575e 5624 /* If the format doesn't contain % args or %%, use strcpy. */
99eabcc1 5625 if (strchr (fmt_str, target_percent) == 0)
6411575e 5626 {
5627 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5628 tree exp;
5629
c2f47e15 5630 if ((nargs > 2) || ! fn)
5631 return NULL_RTX;
5632 expand_expr (build_call_expr (fn, 2, dest, fmt),
6411575e 5633 const0_rtx, VOIDmode, EXPAND_NORMAL);
5634 if (target == const0_rtx)
5635 return const0_rtx;
7016c612 5636 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
6411575e 5637 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5638 }
a7a723f0 5639 /* If the format is "%s", use strcpy if the result isn't used. */
99eabcc1 5640 else if (strcmp (fmt_str, target_percent_s) == 0)
6411575e 5641 {
a7a723f0 5642 tree fn, arg, len;
5643 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
6411575e 5644
a7a723f0 5645 if (! fn)
c2f47e15 5646 return NULL_RTX;
5647 if (nargs != 3)
5648 return NULL_RTX;
5649 arg = CALL_EXPR_ARG (exp, 2);
552752f7 5650 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
c2f47e15 5651 return NULL_RTX;
6411575e 5652
5653 if (target != const0_rtx)
5654 {
681fab1e 5655 len = c_strlen (arg, 1);
a7a723f0 5656 if (! len || TREE_CODE (len) != INTEGER_CST)
c2f47e15 5657 return NULL_RTX;
6411575e 5658 }
5659 else
a7a723f0 5660 len = NULL_TREE;
6411575e 5661
c2f47e15 5662 expand_expr (build_call_expr (fn, 2, dest, arg),
6411575e 5663 const0_rtx, VOIDmode, EXPAND_NORMAL);
5664
5665 if (target == const0_rtx)
5666 return const0_rtx;
a7a723f0 5667 return expand_expr (len, target, mode, EXPAND_NORMAL);
6411575e 5668 }
5669
c2f47e15 5670 return NULL_RTX;
6411575e 5671}
27f261ef 5672
4ee9c684 5673/* Expand a call to either the entry or exit function profiler. */
5674
5675static rtx
5676expand_builtin_profile_func (bool exitp)
5677{
f4e36c33 5678 rtx this_rtx, which;
4ee9c684 5679
f4e36c33 5680 this_rtx = DECL_RTL (current_function_decl);
5681 gcc_assert (MEM_P (this_rtx));
5682 this_rtx = XEXP (this_rtx, 0);
4ee9c684 5683
5684 if (exitp)
5685 which = profile_function_exit_libfunc;
5686 else
5687 which = profile_function_entry_libfunc;
5688
f4e36c33 5689 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this_rtx, Pmode,
4ee9c684 5690 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
869d0ef0 5691 0),
4ee9c684 5692 Pmode);
5693
5694 return const0_rtx;
5695}
5696
ac8fb6db 5697/* Expand a call to __builtin___clear_cache. */
5698
5699static rtx
5700expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED)
5701{
5702#ifndef HAVE_clear_cache
5703#ifdef CLEAR_INSN_CACHE
5704 /* There is no "clear_cache" insn, and __clear_cache() in libgcc
5705 does something. Just do the default expansion to a call to
5706 __clear_cache(). */
5707 return NULL_RTX;
5708#else
5709 /* There is no "clear_cache" insn, and __clear_cache() in libgcc
5710 does nothing. There is no need to call it. Do nothing. */
5711 return const0_rtx;
5712#endif /* CLEAR_INSN_CACHE */
5713#else
5714 /* We have a "clear_cache" insn, and it will handle everything. */
5715 tree begin, end;
5716 rtx begin_rtx, end_rtx;
5717 enum insn_code icode;
5718
5719 /* We must not expand to a library call. If we did, any
5720 fallback library function in libgcc that might contain a call to
5721 __builtin___clear_cache() would recurse infinitely. */
5722 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
5723 {
5724 error ("both arguments to %<__builtin___clear_cache%> must be pointers");
5725 return const0_rtx;
5726 }
5727
5728 if (HAVE_clear_cache)
5729 {
5730 icode = CODE_FOR_clear_cache;
5731
5732 begin = CALL_EXPR_ARG (exp, 0);
5733 begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL);
5734 begin_rtx = convert_memory_address (Pmode, begin_rtx);
5735 if (!insn_data[icode].operand[0].predicate (begin_rtx, Pmode))
5736 begin_rtx = copy_to_mode_reg (Pmode, begin_rtx);
5737
5738 end = CALL_EXPR_ARG (exp, 1);
5739 end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL);
5740 end_rtx = convert_memory_address (Pmode, end_rtx);
5741 if (!insn_data[icode].operand[1].predicate (end_rtx, Pmode))
5742 end_rtx = copy_to_mode_reg (Pmode, end_rtx);
5743
5744 emit_insn (gen_clear_cache (begin_rtx, end_rtx));
5745 }
5746 return const0_rtx;
5747#endif /* HAVE_clear_cache */
5748}
5749
4ee9c684 5750/* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5751
5752static rtx
5753round_trampoline_addr (rtx tramp)
5754{
5755 rtx temp, addend, mask;
5756
5757 /* If we don't need too much alignment, we'll have been guaranteed
5758 proper alignment by get_trampoline_type. */
5759 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5760 return tramp;
5761
5762 /* Round address up to desired boundary. */
5763 temp = gen_reg_rtx (Pmode);
5764 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5765 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5766
5767 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5768 temp, 0, OPTAB_LIB_WIDEN);
5769 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5770 temp, 0, OPTAB_LIB_WIDEN);
5771
5772 return tramp;
5773}
5774
5775static rtx
c2f47e15 5776expand_builtin_init_trampoline (tree exp)
4ee9c684 5777{
5778 tree t_tramp, t_func, t_chain;
5779 rtx r_tramp, r_func, r_chain;
5780#ifdef TRAMPOLINE_TEMPLATE
5781 rtx blktramp;
5782#endif
5783
c2f47e15 5784 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE,
4ee9c684 5785 POINTER_TYPE, VOID_TYPE))
5786 return NULL_RTX;
5787
c2f47e15 5788 t_tramp = CALL_EXPR_ARG (exp, 0);
5789 t_func = CALL_EXPR_ARG (exp, 1);
5790 t_chain = CALL_EXPR_ARG (exp, 2);
4ee9c684 5791
8ec3c5c2 5792 r_tramp = expand_normal (t_tramp);
5793 r_func = expand_normal (t_func);
5794 r_chain = expand_normal (t_chain);
4ee9c684 5795
5796 /* Generate insns to initialize the trampoline. */
5797 r_tramp = round_trampoline_addr (r_tramp);
5798#ifdef TRAMPOLINE_TEMPLATE
5799 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5800 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5801 emit_block_move (blktramp, assemble_trampoline_template (),
5802 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5803#endif
5804 trampolines_created = 1;
5805 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5806
5807 return const0_rtx;
5808}
5809
5810static rtx
c2f47e15 5811expand_builtin_adjust_trampoline (tree exp)
4ee9c684 5812{
5813 rtx tramp;
5814
c2f47e15 5815 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
4ee9c684 5816 return NULL_RTX;
5817
c2f47e15 5818 tramp = expand_normal (CALL_EXPR_ARG (exp, 0));
4ee9c684 5819 tramp = round_trampoline_addr (tramp);
5820#ifdef TRAMPOLINE_ADJUST_ADDRESS
5821 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5822#endif
5823
5824 return tramp;
5825}
5826
93f564d6 5827/* Expand the call EXP to the built-in signbit, signbitf or signbitl
5828 function. The function first checks whether the back end provides
5829 an insn to implement signbit for the respective mode. If not, it
5830 checks whether the floating point format of the value is such that
5831 the sign bit can be extracted. If that is not the case, the
5832 function returns NULL_RTX to indicate that a normal call should be
5833 emitted rather than expanding the function in-line. EXP is the
5834 expression that is a call to the builtin function; if convenient,
5835 the result should be placed in TARGET. */
27f261ef 5836static rtx
5837expand_builtin_signbit (tree exp, rtx target)
5838{
5839 const struct real_format *fmt;
5840 enum machine_mode fmode, imode, rmode;
5841 HOST_WIDE_INT hi, lo;
c2f47e15 5842 tree arg;
ca4f1f5b 5843 int word, bitpos;
27eda240 5844 enum insn_code icode;
27f261ef 5845 rtx temp;
5846
c2f47e15 5847 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
5848 return NULL_RTX;
27f261ef 5849
c2f47e15 5850 arg = CALL_EXPR_ARG (exp, 0);
27f261ef 5851 fmode = TYPE_MODE (TREE_TYPE (arg));
5852 rmode = TYPE_MODE (TREE_TYPE (exp));
5853 fmt = REAL_MODE_FORMAT (fmode);
5854
93f564d6 5855 arg = builtin_save_expr (arg);
5856
5857 /* Expand the argument yielding a RTX expression. */
5858 temp = expand_normal (arg);
5859
5860 /* Check if the back end provides an insn that handles signbit for the
5861 argument's mode. */
27eda240 5862 icode = signbit_optab->handlers [(int) fmode].insn_code;
5863 if (icode != CODE_FOR_nothing)
93f564d6 5864 {
5865 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
27eda240 5866 emit_unop_insn (icode, target, temp, UNKNOWN);
93f564d6 5867 return target;
5868 }
5869
27f261ef 5870 /* For floating point formats without a sign bit, implement signbit
5871 as "ARG < 0.0". */
8d564692 5872 bitpos = fmt->signbit_ro;
ca4f1f5b 5873 if (bitpos < 0)
27f261ef 5874 {
5875 /* But we can't do this if the format supports signed zero. */
5876 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
c2f47e15 5877 return NULL_RTX;
27f261ef 5878
49d00087 5879 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5880 build_real (TREE_TYPE (arg), dconst0));
27f261ef 5881 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5882 }
5883
ca4f1f5b 5884 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
27f261ef 5885 {
ca4f1f5b 5886 imode = int_mode_for_mode (fmode);
5887 if (imode == BLKmode)
c2f47e15 5888 return NULL_RTX;
ca4f1f5b 5889 temp = gen_lowpart (imode, temp);
24fd4260 5890 }
5891 else
5892 {
ca4f1f5b 5893 imode = word_mode;
5894 /* Handle targets with different FP word orders. */
5895 if (FLOAT_WORDS_BIG_ENDIAN)
a0c938f0 5896 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
ca4f1f5b 5897 else
a0c938f0 5898 word = bitpos / BITS_PER_WORD;
ca4f1f5b 5899 temp = operand_subword_force (temp, word, fmode);
5900 bitpos = bitpos % BITS_PER_WORD;
5901 }
5902
44b0f1d0 5903 /* Force the intermediate word_mode (or narrower) result into a
5904 register. This avoids attempting to create paradoxical SUBREGs
5905 of floating point modes below. */
5906 temp = force_reg (imode, temp);
5907
ca4f1f5b 5908 /* If the bitpos is within the "result mode" lowpart, the operation
5909 can be implement with a single bitwise AND. Otherwise, we need
5910 a right shift and an AND. */
5911
5912 if (bitpos < GET_MODE_BITSIZE (rmode))
5913 {
24fd4260 5914 if (bitpos < HOST_BITS_PER_WIDE_INT)
27f261ef 5915 {
24fd4260 5916 hi = 0;
5917 lo = (HOST_WIDE_INT) 1 << bitpos;
27f261ef 5918 }
5919 else
24fd4260 5920 {
5921 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5922 lo = 0;
5923 }
27f261ef 5924
4a46f016 5925 if (GET_MODE_SIZE (imode) > GET_MODE_SIZE (rmode))
ca4f1f5b 5926 temp = gen_lowpart (rmode, temp);
24fd4260 5927 temp = expand_binop (rmode, and_optab, temp,
5928 immed_double_const (lo, hi, rmode),
ca4f1f5b 5929 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27f261ef 5930 }
ca4f1f5b 5931 else
5932 {
5933 /* Perform a logical right shift to place the signbit in the least
a0c938f0 5934 significant bit, then truncate the result to the desired mode
ca4f1f5b 5935 and mask just this bit. */
5936 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5937 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5938 temp = gen_lowpart (rmode, temp);
5939 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5940 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5941 }
5942
27f261ef 5943 return temp;
5944}
73673831 5945
5946/* Expand fork or exec calls. TARGET is the desired target of the
c2f47e15 5947 call. EXP is the call. FN is the
73673831 5948 identificator of the actual function. IGNORE is nonzero if the
5949 value is to be ignored. */
5950
5951static rtx
c2f47e15 5952expand_builtin_fork_or_exec (tree fn, tree exp, rtx target, int ignore)
73673831 5953{
5954 tree id, decl;
5955 tree call;
5956
5957 /* If we are not profiling, just call the function. */
5958 if (!profile_arc_flag)
5959 return NULL_RTX;
5960
5961 /* Otherwise call the wrapper. This should be equivalent for the rest of
5962 compiler, so the code does not diverge, and the wrapper may run the
9c9bad97 5963 code necessary for keeping the profiling sane. */
73673831 5964
5965 switch (DECL_FUNCTION_CODE (fn))
5966 {
5967 case BUILT_IN_FORK:
5968 id = get_identifier ("__gcov_fork");
5969 break;
5970
5971 case BUILT_IN_EXECL:
5972 id = get_identifier ("__gcov_execl");
5973 break;
5974
5975 case BUILT_IN_EXECV:
5976 id = get_identifier ("__gcov_execv");
5977 break;
5978
5979 case BUILT_IN_EXECLP:
5980 id = get_identifier ("__gcov_execlp");
5981 break;
5982
5983 case BUILT_IN_EXECLE:
5984 id = get_identifier ("__gcov_execle");
5985 break;
5986
5987 case BUILT_IN_EXECVP:
5988 id = get_identifier ("__gcov_execvp");
5989 break;
5990
5991 case BUILT_IN_EXECVE:
5992 id = get_identifier ("__gcov_execve");
5993 break;
5994
5995 default:
64db345d 5996 gcc_unreachable ();
73673831 5997 }
5998
e60a6f7b 5999 decl = build_decl (DECL_SOURCE_LOCATION (fn),
6000 FUNCTION_DECL, id, TREE_TYPE (fn));
73673831 6001 DECL_EXTERNAL (decl) = 1;
6002 TREE_PUBLIC (decl) = 1;
6003 DECL_ARTIFICIAL (decl) = 1;
6004 TREE_NOTHROW (decl) = 1;
e82d310b 6005 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
6006 DECL_VISIBILITY_SPECIFIED (decl) = 1;
c2f47e15 6007 call = rewrite_call_expr (exp, 0, decl, 0);
73673831 6008 return expand_call (call, target, ignore);
c2f47e15 6009 }
6010
b6a5fc45 6011
6012\f
3e272de8 6013/* Reconstitute a mode for a __sync intrinsic operation. Since the type of
6014 the pointer in these functions is void*, the tree optimizers may remove
6015 casts. The mode computed in expand_builtin isn't reliable either, due
6016 to __sync_bool_compare_and_swap.
6017
6018 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
6019 group of builtins. This gives us log2 of the mode size. */
6020
6021static inline enum machine_mode
6022get_builtin_sync_mode (int fcode_diff)
6023{
ad3a13b5 6024 /* The size is not negotiable, so ask not to get BLKmode in return
6025 if the target indicates that a smaller size would be better. */
6026 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
3e272de8 6027}
6028
041e0215 6029/* Expand the memory expression LOC and return the appropriate memory operand
6030 for the builtin_sync operations. */
6031
6032static rtx
6033get_builtin_sync_mem (tree loc, enum machine_mode mode)
6034{
6035 rtx addr, mem;
6036
1db6d067 6037 addr = expand_expr (loc, NULL_RTX, Pmode, EXPAND_SUM);
041e0215 6038
6039 /* Note that we explicitly do not want any alias information for this
6040 memory, so that we kill all other live memories. Otherwise we don't
6041 satisfy the full barrier semantics of the intrinsic. */
6042 mem = validize_mem (gen_rtx_MEM (mode, addr));
6043
6044 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
c94cfd1c 6045 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
041e0215 6046 MEM_VOLATILE_P (mem) = 1;
6047
6048 return mem;
6049}
6050
b6a5fc45 6051/* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
c2f47e15 6052 EXP is the CALL_EXPR. CODE is the rtx code
b6a5fc45 6053 that corresponds to the arithmetic or logical operation from the name;
6054 an exception here is that NOT actually means NAND. TARGET is an optional
6055 place for us to store the results; AFTER is true if this is the
6056 fetch_and_xxx form. IGNORE is true if we don't actually care about
6057 the result of the operation at all. */
6058
6059static rtx
c2f47e15 6060expand_builtin_sync_operation (enum machine_mode mode, tree exp,
3e272de8 6061 enum rtx_code code, bool after,
b6a5fc45 6062 rtx target, bool ignore)
6063{
041e0215 6064 rtx val, mem;
a8bb7059 6065 enum machine_mode old_mode;
e60a6f7b 6066 location_t loc = EXPR_LOCATION (exp);
b6a5fc45 6067
cf73e559 6068 if (code == NOT && warn_sync_nand)
6069 {
6070 tree fndecl = get_callee_fndecl (exp);
6071 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6072
6073 static bool warned_f_a_n, warned_n_a_f;
6074
6075 switch (fcode)
6076 {
6077 case BUILT_IN_FETCH_AND_NAND_1:
6078 case BUILT_IN_FETCH_AND_NAND_2:
6079 case BUILT_IN_FETCH_AND_NAND_4:
6080 case BUILT_IN_FETCH_AND_NAND_8:
6081 case BUILT_IN_FETCH_AND_NAND_16:
6082
6083 if (warned_f_a_n)
6084 break;
6085
6086 fndecl = implicit_built_in_decls[BUILT_IN_FETCH_AND_NAND_N];
e60a6f7b 6087 inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
cf73e559 6088 warned_f_a_n = true;
6089 break;
6090
6091 case BUILT_IN_NAND_AND_FETCH_1:
6092 case BUILT_IN_NAND_AND_FETCH_2:
6093 case BUILT_IN_NAND_AND_FETCH_4:
6094 case BUILT_IN_NAND_AND_FETCH_8:
6095 case BUILT_IN_NAND_AND_FETCH_16:
6096
6097 if (warned_n_a_f)
6098 break;
6099
6100 fndecl = implicit_built_in_decls[BUILT_IN_NAND_AND_FETCH_N];
e60a6f7b 6101 inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
cf73e559 6102 warned_n_a_f = true;
6103 break;
6104
6105 default:
6106 gcc_unreachable ();
6107 }
6108 }
6109
b6a5fc45 6110 /* Expand the operands. */
c2f47e15 6111 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
b6a5fc45 6112
1db6d067 6113 val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
a8bb7059 6114 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
6115 of CONST_INTs, where we know the old_mode only from the call argument. */
6116 old_mode = GET_MODE (val);
6117 if (old_mode == VOIDmode)
6118 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
6119 val = convert_modes (mode, old_mode, val, 1);
b6a5fc45 6120
b6a5fc45 6121 if (ignore)
6122 return expand_sync_operation (mem, val, code);
6123 else
6124 return expand_sync_fetch_operation (mem, val, code, after, target);
6125}
6126
6127/* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
c2f47e15 6128 intrinsics. EXP is the CALL_EXPR. IS_BOOL is
b6a5fc45 6129 true if this is the boolean form. TARGET is a place for us to store the
6130 results; this is NOT optional if IS_BOOL is true. */
6131
6132static rtx
c2f47e15 6133expand_builtin_compare_and_swap (enum machine_mode mode, tree exp,
3e272de8 6134 bool is_bool, rtx target)
b6a5fc45 6135{
041e0215 6136 rtx old_val, new_val, mem;
a8bb7059 6137 enum machine_mode old_mode;
b6a5fc45 6138
6139 /* Expand the operands. */
c2f47e15 6140 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
b6a5fc45 6141
c2f47e15 6142
1db6d067 6143 old_val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX,
6144 mode, EXPAND_NORMAL);
a8bb7059 6145 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
6146 of CONST_INTs, where we know the old_mode only from the call argument. */
6147 old_mode = GET_MODE (old_val);
6148 if (old_mode == VOIDmode)
6149 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
6150 old_val = convert_modes (mode, old_mode, old_val, 1);
b6a5fc45 6151
1db6d067 6152 new_val = expand_expr (CALL_EXPR_ARG (exp, 2), NULL_RTX,
6153 mode, EXPAND_NORMAL);
a8bb7059 6154 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
6155 of CONST_INTs, where we know the old_mode only from the call argument. */
6156 old_mode = GET_MODE (new_val);
6157 if (old_mode == VOIDmode)
6158 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2)));
6159 new_val = convert_modes (mode, old_mode, new_val, 1);
b6a5fc45 6160
b6a5fc45 6161 if (is_bool)
6162 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
6163 else
6164 return expand_val_compare_and_swap (mem, old_val, new_val, target);
6165}
6166
6167/* Expand the __sync_lock_test_and_set intrinsic. Note that the most
6168 general form is actually an atomic exchange, and some targets only
6169 support a reduced form with the second argument being a constant 1.
c2f47e15 6170 EXP is the CALL_EXPR; TARGET is an optional place for us to store
6171 the results. */
b6a5fc45 6172
6173static rtx
c2f47e15 6174expand_builtin_lock_test_and_set (enum machine_mode mode, tree exp,
3e272de8 6175 rtx target)
b6a5fc45 6176{
041e0215 6177 rtx val, mem;
a8bb7059 6178 enum machine_mode old_mode;
b6a5fc45 6179
6180 /* Expand the operands. */
c2f47e15 6181 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
1db6d067 6182 val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
a8bb7059 6183 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
6184 of CONST_INTs, where we know the old_mode only from the call argument. */
6185 old_mode = GET_MODE (val);
6186 if (old_mode == VOIDmode)
6187 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
6188 val = convert_modes (mode, old_mode, val, 1);
b6a5fc45 6189
b6a5fc45 6190 return expand_sync_lock_test_and_set (mem, val, target);
6191}
6192
6193/* Expand the __sync_synchronize intrinsic. */
6194
6195static void
6196expand_builtin_synchronize (void)
6197{
82e58396 6198 tree x;
b6a5fc45 6199
6200#ifdef HAVE_memory_barrier
6201 if (HAVE_memory_barrier)
6202 {
6203 emit_insn (gen_memory_barrier ());
6204 return;
6205 }
6206#endif
6207
047a7e40 6208 if (synchronize_libfunc != NULL_RTX)
6209 {
6210 emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
6211 return;
6212 }
6213
82e58396 6214 /* If no explicit memory barrier instruction is available, create an
6215 empty asm stmt with a memory clobber. */
6216 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
6217 tree_cons (NULL, build_string (6, "memory"), NULL));
6218 ASM_VOLATILE_P (x) = 1;
6219 expand_asm_expr (x);
b6a5fc45 6220}
6221
c2f47e15 6222/* Expand the __sync_lock_release intrinsic. EXP is the CALL_EXPR. */
b6a5fc45 6223
6224static void
c2f47e15 6225expand_builtin_lock_release (enum machine_mode mode, tree exp)
b6a5fc45 6226{
b6a5fc45 6227 enum insn_code icode;
041e0215 6228 rtx mem, insn;
3e272de8 6229 rtx val = const0_rtx;
b6a5fc45 6230
6231 /* Expand the operands. */
c2f47e15 6232 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
b6a5fc45 6233
6234 /* If there is an explicit operation in the md file, use it. */
6235 icode = sync_lock_release[mode];
6236 if (icode != CODE_FOR_nothing)
6237 {
6238 if (!insn_data[icode].operand[1].predicate (val, mode))
6239 val = force_reg (mode, val);
6240
6241 insn = GEN_FCN (icode) (mem, val);
6242 if (insn)
6243 {
6244 emit_insn (insn);
6245 return;
6246 }
6247 }
6248
6249 /* Otherwise we can implement this operation by emitting a barrier
6250 followed by a store of zero. */
6251 expand_builtin_synchronize ();
6252 emit_move_insn (mem, val);
6253}
53800dbe 6254\f
6255/* Expand an expression EXP that calls a built-in function,
6256 with result going to TARGET if that's convenient
6257 (and in mode MODE if that's convenient).
6258 SUBTARGET may be used as the target for computing one of EXP's operands.
6259 IGNORE is nonzero if the value is to be ignored. */
6260
6261rtx
aecda0d6 6262expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
6263 int ignore)
53800dbe 6264{
c6e6ecb1 6265 tree fndecl = get_callee_fndecl (exp);
53800dbe 6266 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
efb070c8 6267 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
53800dbe 6268
8305149e 6269 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
883b2e73 6270 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
bf8e3599 6271
53800dbe 6272 /* When not optimizing, generate calls to library functions for a certain
6273 set of builtins. */
cd9ff771 6274 if (!optimize
b6a5fc45 6275 && !called_as_built_in (fndecl)
cd9ff771 6276 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
2c281b15 6277 && fcode != BUILT_IN_ALLOCA
6278 && fcode != BUILT_IN_FREE)
cd9ff771 6279 return expand_call (exp, target, ignore);
53800dbe 6280
8d6d7930 6281 /* The built-in function expanders test for target == const0_rtx
6282 to determine whether the function's result will be ignored. */
6283 if (ignore)
6284 target = const0_rtx;
6285
6286 /* If the result of a pure or const built-in function is ignored, and
6287 none of its arguments are volatile, we can avoid expanding the
6288 built-in call and just evaluate the arguments for side-effects. */
6289 if (target == const0_rtx
9c2a0c05 6290 && (DECL_PURE_P (fndecl) || TREE_READONLY (fndecl)))
8d6d7930 6291 {
6292 bool volatilep = false;
6293 tree arg;
c2f47e15 6294 call_expr_arg_iterator iter;
8d6d7930 6295
c2f47e15 6296 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
6297 if (TREE_THIS_VOLATILE (arg))
8d6d7930 6298 {
6299 volatilep = true;
6300 break;
6301 }
6302
6303 if (! volatilep)
6304 {
c2f47e15 6305 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
6306 expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL);
8d6d7930 6307 return const0_rtx;
6308 }
6309 }
6310
53800dbe 6311 switch (fcode)
6312 {
4f35b1fc 6313 CASE_FLT_FN (BUILT_IN_FABS):
c2f47e15 6314 target = expand_builtin_fabs (exp, target, subtarget);
78a74442 6315 if (target)
a0c938f0 6316 return target;
78a74442 6317 break;
6318
4f35b1fc 6319 CASE_FLT_FN (BUILT_IN_COPYSIGN):
c2f47e15 6320 target = expand_builtin_copysign (exp, target, subtarget);
270436f3 6321 if (target)
6322 return target;
6323 break;
6324
7d3f6cc7 6325 /* Just do a normal library call if we were unable to fold
6326 the values. */
4f35b1fc 6327 CASE_FLT_FN (BUILT_IN_CABS):
78a74442 6328 break;
53800dbe 6329
4f35b1fc 6330 CASE_FLT_FN (BUILT_IN_EXP):
6331 CASE_FLT_FN (BUILT_IN_EXP10):
6332 CASE_FLT_FN (BUILT_IN_POW10):
6333 CASE_FLT_FN (BUILT_IN_EXP2):
6334 CASE_FLT_FN (BUILT_IN_EXPM1):
6335 CASE_FLT_FN (BUILT_IN_LOGB):
4f35b1fc 6336 CASE_FLT_FN (BUILT_IN_LOG):
6337 CASE_FLT_FN (BUILT_IN_LOG10):
6338 CASE_FLT_FN (BUILT_IN_LOG2):
6339 CASE_FLT_FN (BUILT_IN_LOG1P):
6340 CASE_FLT_FN (BUILT_IN_TAN):
6341 CASE_FLT_FN (BUILT_IN_ASIN):
6342 CASE_FLT_FN (BUILT_IN_ACOS):
6343 CASE_FLT_FN (BUILT_IN_ATAN):
b3154a1f 6344 CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
7f3be425 6345 /* Treat these like sqrt only if unsafe math optimizations are allowed,
6346 because of possible accuracy problems. */
6347 if (! flag_unsafe_math_optimizations)
53800dbe 6348 break;
4f35b1fc 6349 CASE_FLT_FN (BUILT_IN_SQRT):
6350 CASE_FLT_FN (BUILT_IN_FLOOR):
6351 CASE_FLT_FN (BUILT_IN_CEIL):
6352 CASE_FLT_FN (BUILT_IN_TRUNC):
6353 CASE_FLT_FN (BUILT_IN_ROUND):
6354 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6355 CASE_FLT_FN (BUILT_IN_RINT):
53800dbe 6356 target = expand_builtin_mathfn (exp, target, subtarget);
6357 if (target)
6358 return target;
6359 break;
6360
a67a90e5 6361 CASE_FLT_FN (BUILT_IN_ILOGB):
6362 if (! flag_unsafe_math_optimizations)
6363 break;
69b779ea 6364 CASE_FLT_FN (BUILT_IN_ISINF):
cde061c1 6365 CASE_FLT_FN (BUILT_IN_FINITE):
6366 case BUILT_IN_ISFINITE:
8a1a9cb7 6367 case BUILT_IN_ISNORMAL:
a67a90e5 6368 target = expand_builtin_interclass_mathfn (exp, target, subtarget);
6369 if (target)
6370 return target;
6371 break;
6372
4f35b1fc 6373 CASE_FLT_FN (BUILT_IN_LCEIL):
6374 CASE_FLT_FN (BUILT_IN_LLCEIL):
6375 CASE_FLT_FN (BUILT_IN_LFLOOR):
6376 CASE_FLT_FN (BUILT_IN_LLFLOOR):
ff1b14e4 6377 target = expand_builtin_int_roundingfn (exp, target);
ad52b9b7 6378 if (target)
6379 return target;
6380 break;
6381
7d3afc77 6382 CASE_FLT_FN (BUILT_IN_LRINT):
6383 CASE_FLT_FN (BUILT_IN_LLRINT):
ef2f1a10 6384 CASE_FLT_FN (BUILT_IN_LROUND):
6385 CASE_FLT_FN (BUILT_IN_LLROUND):
ff1b14e4 6386 target = expand_builtin_int_roundingfn_2 (exp, target);
7d3afc77 6387 if (target)
6388 return target;
6389 break;
6390
4f35b1fc 6391 CASE_FLT_FN (BUILT_IN_POW):
f1b844c6 6392 target = expand_builtin_pow (exp, target, subtarget);
6393 if (target)
6394 return target;
6395 break;
6396
4f35b1fc 6397 CASE_FLT_FN (BUILT_IN_POWI):
757c219d 6398 target = expand_builtin_powi (exp, target, subtarget);
6399 if (target)
6400 return target;
6401 break;
6402
4f35b1fc 6403 CASE_FLT_FN (BUILT_IN_ATAN2):
6404 CASE_FLT_FN (BUILT_IN_LDEXP):
73a954a1 6405 CASE_FLT_FN (BUILT_IN_SCALB):
6406 CASE_FLT_FN (BUILT_IN_SCALBN):
6407 CASE_FLT_FN (BUILT_IN_SCALBLN):
0fd605a5 6408 if (! flag_unsafe_math_optimizations)
6409 break;
ef722005 6410
6411 CASE_FLT_FN (BUILT_IN_FMOD):
6412 CASE_FLT_FN (BUILT_IN_REMAINDER):
6413 CASE_FLT_FN (BUILT_IN_DREM):
0fd605a5 6414 target = expand_builtin_mathfn_2 (exp, target, subtarget);
6415 if (target)
6416 return target;
6417 break;
6418
d735c391 6419 CASE_FLT_FN (BUILT_IN_CEXPI):
6420 target = expand_builtin_cexpi (exp, target, subtarget);
6421 gcc_assert (target);
6422 return target;
6423
4f35b1fc 6424 CASE_FLT_FN (BUILT_IN_SIN):
6425 CASE_FLT_FN (BUILT_IN_COS):
6b43bae4 6426 if (! flag_unsafe_math_optimizations)
6427 break;
6428 target = expand_builtin_mathfn_3 (exp, target, subtarget);
6429 if (target)
6430 return target;
6431 break;
6432
c3147c1a 6433 CASE_FLT_FN (BUILT_IN_SINCOS):
6434 if (! flag_unsafe_math_optimizations)
6435 break;
6436 target = expand_builtin_sincos (exp);
6437 if (target)
6438 return target;
6439 break;
6440
53800dbe 6441 case BUILT_IN_APPLY_ARGS:
6442 return expand_builtin_apply_args ();
6443
6444 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
6445 FUNCTION with a copy of the parameters described by
6446 ARGUMENTS, and ARGSIZE. It returns a block of memory
6447 allocated on the stack into which is stored all the registers
6448 that might possibly be used for returning the result of a
6449 function. ARGUMENTS is the value returned by
6450 __builtin_apply_args. ARGSIZE is the number of bytes of
6451 arguments that must be copied. ??? How should this value be
6452 computed? We'll also need a safe worst case value for varargs
6453 functions. */
6454 case BUILT_IN_APPLY:
c2f47e15 6455 if (!validate_arglist (exp, POINTER_TYPE,
0eb671f7 6456 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
c2f47e15 6457 && !validate_arglist (exp, REFERENCE_TYPE,
0eb671f7 6458 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
53800dbe 6459 return const0_rtx;
6460 else
6461 {
53800dbe 6462 rtx ops[3];
6463
c2f47e15 6464 ops[0] = expand_normal (CALL_EXPR_ARG (exp, 0));
6465 ops[1] = expand_normal (CALL_EXPR_ARG (exp, 1));
6466 ops[2] = expand_normal (CALL_EXPR_ARG (exp, 2));
53800dbe 6467
6468 return expand_builtin_apply (ops[0], ops[1], ops[2]);
6469 }
6470
6471 /* __builtin_return (RESULT) causes the function to return the
6472 value described by RESULT. RESULT is address of the block of
6473 memory returned by __builtin_apply. */
6474 case BUILT_IN_RETURN:
c2f47e15 6475 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6476 expand_builtin_return (expand_normal (CALL_EXPR_ARG (exp, 0)));
53800dbe 6477 return const0_rtx;
6478
6479 case BUILT_IN_SAVEREGS:
a66c9326 6480 return expand_builtin_saveregs ();
53800dbe 6481
6482 case BUILT_IN_ARGS_INFO:
c2f47e15 6483 return expand_builtin_args_info (exp);
53800dbe 6484
48dc2227 6485 case BUILT_IN_VA_ARG_PACK:
6486 /* All valid uses of __builtin_va_arg_pack () are removed during
6487 inlining. */
b8c23db3 6488 error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp);
48dc2227 6489 return const0_rtx;
6490
4e1d7ea4 6491 case BUILT_IN_VA_ARG_PACK_LEN:
6492 /* All valid uses of __builtin_va_arg_pack_len () are removed during
6493 inlining. */
b8c23db3 6494 error ("%Kinvalid use of %<__builtin_va_arg_pack_len ()%>", exp);
4e1d7ea4 6495 return const0_rtx;
6496
53800dbe 6497 /* Return the address of the first anonymous stack arg. */
6498 case BUILT_IN_NEXT_ARG:
c2f47e15 6499 if (fold_builtin_next_arg (exp, false))
a0c938f0 6500 return const0_rtx;
79012a9d 6501 return expand_builtin_next_arg ();
53800dbe 6502
ac8fb6db 6503 case BUILT_IN_CLEAR_CACHE:
6504 target = expand_builtin___clear_cache (exp);
6505 if (target)
6506 return target;
6507 break;
6508
53800dbe 6509 case BUILT_IN_CLASSIFY_TYPE:
c2f47e15 6510 return expand_builtin_classify_type (exp);
53800dbe 6511
6512 case BUILT_IN_CONSTANT_P:
4ee9c684 6513 return const0_rtx;
53800dbe 6514
6515 case BUILT_IN_FRAME_ADDRESS:
6516 case BUILT_IN_RETURN_ADDRESS:
c2f47e15 6517 return expand_builtin_frame_address (fndecl, exp);
53800dbe 6518
6519 /* Returns the address of the area where the structure is returned.
6520 0 otherwise. */
6521 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
c2f47e15 6522 if (call_expr_nargs (exp) != 0
9342ee68 6523 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
e16ceb8e 6524 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
9342ee68 6525 return const0_rtx;
53800dbe 6526 else
9342ee68 6527 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
53800dbe 6528
6529 case BUILT_IN_ALLOCA:
c2f47e15 6530 target = expand_builtin_alloca (exp, target);
53800dbe 6531 if (target)
6532 return target;
6533 break;
6534
4ee9c684 6535 case BUILT_IN_STACK_SAVE:
6536 return expand_stack_save ();
6537
6538 case BUILT_IN_STACK_RESTORE:
c2f47e15 6539 expand_stack_restore (CALL_EXPR_ARG (exp, 0));
4ee9c684 6540 return const0_rtx;
6541
42791117 6542 case BUILT_IN_BSWAP32:
6543 case BUILT_IN_BSWAP64:
c2f47e15 6544 target = expand_builtin_bswap (exp, target, subtarget);
42791117 6545
6546 if (target)
6547 return target;
6548 break;
6549
4f35b1fc 6550 CASE_INT_FN (BUILT_IN_FFS):
5053259b 6551 case BUILT_IN_FFSIMAX:
c2f47e15 6552 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6553 subtarget, ffs_optab);
6a08d0ab 6554 if (target)
6555 return target;
6556 break;
6557
4f35b1fc 6558 CASE_INT_FN (BUILT_IN_CLZ):
5053259b 6559 case BUILT_IN_CLZIMAX:
c2f47e15 6560 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6561 subtarget, clz_optab);
6a08d0ab 6562 if (target)
6563 return target;
6564 break;
6565
4f35b1fc 6566 CASE_INT_FN (BUILT_IN_CTZ):
5053259b 6567 case BUILT_IN_CTZIMAX:
c2f47e15 6568 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6569 subtarget, ctz_optab);
6a08d0ab 6570 if (target)
6571 return target;
6572 break;
6573
4f35b1fc 6574 CASE_INT_FN (BUILT_IN_POPCOUNT):
5053259b 6575 case BUILT_IN_POPCOUNTIMAX:
c2f47e15 6576 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6577 subtarget, popcount_optab);
6a08d0ab 6578 if (target)
6579 return target;
6580 break;
6581
4f35b1fc 6582 CASE_INT_FN (BUILT_IN_PARITY):
5053259b 6583 case BUILT_IN_PARITYIMAX:
c2f47e15 6584 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6585 subtarget, parity_optab);
53800dbe 6586 if (target)
6587 return target;
6588 break;
6589
6590 case BUILT_IN_STRLEN:
c2f47e15 6591 target = expand_builtin_strlen (exp, target, target_mode);
53800dbe 6592 if (target)
6593 return target;
6594 break;
6595
6596 case BUILT_IN_STRCPY:
c2f47e15 6597 target = expand_builtin_strcpy (fndecl, exp, target, mode);
53800dbe 6598 if (target)
6599 return target;
6600 break;
bf8e3599 6601
ed09096d 6602 case BUILT_IN_STRNCPY:
8ff6a5cd 6603 target = expand_builtin_strncpy (exp, target, mode);
ed09096d 6604 if (target)
6605 return target;
6606 break;
bf8e3599 6607
3b824fa6 6608 case BUILT_IN_STPCPY:
dc369150 6609 target = expand_builtin_stpcpy (exp, target, mode);
3b824fa6 6610 if (target)
6611 return target;
6612 break;
6613
49f0327b 6614 case BUILT_IN_STRCAT:
c2f47e15 6615 target = expand_builtin_strcat (fndecl, exp, target, mode);
49f0327b 6616 if (target)
6617 return target;
6618 break;
bf8e3599 6619
49f0327b 6620 case BUILT_IN_STRNCAT:
c2f47e15 6621 target = expand_builtin_strncat (exp, target, mode);
49f0327b 6622 if (target)
6623 return target;
6624 break;
bf8e3599 6625
49f0327b 6626 case BUILT_IN_STRSPN:
c2f47e15 6627 target = expand_builtin_strspn (exp, target, mode);
49f0327b 6628 if (target)
6629 return target;
6630 break;
bf8e3599 6631
49f0327b 6632 case BUILT_IN_STRCSPN:
c2f47e15 6633 target = expand_builtin_strcspn (exp, target, mode);
49f0327b 6634 if (target)
6635 return target;
6636 break;
bf8e3599 6637
17f5ea87 6638 case BUILT_IN_STRSTR:
c2f47e15 6639 target = expand_builtin_strstr (exp, target, mode);
17f5ea87 6640 if (target)
6641 return target;
6642 break;
bf8e3599 6643
46f3a74a 6644 case BUILT_IN_STRPBRK:
c2f47e15 6645 target = expand_builtin_strpbrk (exp, target, mode);
46f3a74a 6646 if (target)
6647 return target;
6648 break;
bf8e3599 6649
398aae36 6650 case BUILT_IN_INDEX:
83d79705 6651 case BUILT_IN_STRCHR:
c2f47e15 6652 target = expand_builtin_strchr (exp, target, mode);
83d79705 6653 if (target)
6654 return target;
6655 break;
6656
398aae36 6657 case BUILT_IN_RINDEX:
83d79705 6658 case BUILT_IN_STRRCHR:
c2f47e15 6659 target = expand_builtin_strrchr (exp, target, mode);
83d79705 6660 if (target)
6661 return target;
6662 break;
6663
53800dbe 6664 case BUILT_IN_MEMCPY:
5a0de151 6665 target = expand_builtin_memcpy (exp, target, mode);
3b824fa6 6666 if (target)
6667 return target;
6668 break;
6669
6670 case BUILT_IN_MEMPCPY:
c2f47e15 6671 target = expand_builtin_mempcpy (exp, target, mode);
53800dbe 6672 if (target)
6673 return target;
6674 break;
6675
c4950093 6676 case BUILT_IN_MEMMOVE:
c2f47e15 6677 target = expand_builtin_memmove (exp, target, mode, ignore);
c4950093 6678 if (target)
6679 return target;
6680 break;
6681
6682 case BUILT_IN_BCOPY:
c2f47e15 6683 target = expand_builtin_bcopy (exp, ignore);
c4950093 6684 if (target)
6685 return target;
6686 break;
6687
53800dbe 6688 case BUILT_IN_MEMSET:
c2f47e15 6689 target = expand_builtin_memset (exp, target, mode);
53800dbe 6690 if (target)
6691 return target;
6692 break;
6693
ffc83088 6694 case BUILT_IN_BZERO:
0b25db21 6695 target = expand_builtin_bzero (exp);
ffc83088 6696 if (target)
6697 return target;
6698 break;
6699
53800dbe 6700 case BUILT_IN_STRCMP:
83d79705 6701 target = expand_builtin_strcmp (exp, target, mode);
53800dbe 6702 if (target)
6703 return target;
6704 break;
6705
ed09096d 6706 case BUILT_IN_STRNCMP:
6707 target = expand_builtin_strncmp (exp, target, mode);
6708 if (target)
6709 return target;
6710 break;
6711
7959b13b 6712 case BUILT_IN_MEMCHR:
6713 target = expand_builtin_memchr (exp, target, mode);
6714 if (target)
6715 return target;
6716 break;
6717
071f1696 6718 case BUILT_IN_BCMP:
53800dbe 6719 case BUILT_IN_MEMCMP:
c2f47e15 6720 target = expand_builtin_memcmp (exp, target, mode);
53800dbe 6721 if (target)
6722 return target;
6723 break;
53800dbe 6724
6725 case BUILT_IN_SETJMP:
2c8a1497 6726 /* This should have been lowered to the builtins below. */
6727 gcc_unreachable ();
6728
6729 case BUILT_IN_SETJMP_SETUP:
6730 /* __builtin_setjmp_setup is passed a pointer to an array of five words
6731 and the receiver label. */
c2f47e15 6732 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2c8a1497 6733 {
c2f47e15 6734 rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
2c8a1497 6735 VOIDmode, EXPAND_NORMAL);
c2f47e15 6736 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 1), 0);
2c8a1497 6737 rtx label_r = label_rtx (label);
6738
6739 /* This is copied from the handling of non-local gotos. */
6740 expand_builtin_setjmp_setup (buf_addr, label_r);
6741 nonlocal_goto_handler_labels
6742 = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6743 nonlocal_goto_handler_labels);
6744 /* ??? Do not let expand_label treat us as such since we would
6745 not want to be both on the list of non-local labels and on
6746 the list of forced labels. */
6747 FORCED_LABEL (label) = 0;
6748 return const0_rtx;
6749 }
6750 break;
6751
6752 case BUILT_IN_SETJMP_DISPATCHER:
6753 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */
c2f47e15 6754 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
2c8a1497 6755 {
c2f47e15 6756 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
2c8a1497 6757 rtx label_r = label_rtx (label);
6758
6759 /* Remove the dispatcher label from the list of non-local labels
6760 since the receiver labels have been added to it above. */
6761 remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6762 return const0_rtx;
6763 }
6764 break;
6765
6766 case BUILT_IN_SETJMP_RECEIVER:
6767 /* __builtin_setjmp_receiver is passed the receiver label. */
c2f47e15 6768 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
2c8a1497 6769 {
c2f47e15 6770 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
2c8a1497 6771 rtx label_r = label_rtx (label);
6772
6773 expand_builtin_setjmp_receiver (label_r);
6774 return const0_rtx;
6775 }
6b7f6858 6776 break;
53800dbe 6777
6778 /* __builtin_longjmp is passed a pointer to an array of five words.
6779 It's similar to the C library longjmp function but works with
6780 __builtin_setjmp above. */
6781 case BUILT_IN_LONGJMP:
c2f47e15 6782 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
53800dbe 6783 {
c2f47e15 6784 rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
8ec3c5c2 6785 VOIDmode, EXPAND_NORMAL);
c2f47e15 6786 rtx value = expand_normal (CALL_EXPR_ARG (exp, 1));
53800dbe 6787
6788 if (value != const1_rtx)
6789 {
1e5fcbe2 6790 error ("%<__builtin_longjmp%> second argument must be 1");
53800dbe 6791 return const0_rtx;
6792 }
6793
6794 expand_builtin_longjmp (buf_addr, value);
6795 return const0_rtx;
6796 }
2c8a1497 6797 break;
53800dbe 6798
4ee9c684 6799 case BUILT_IN_NONLOCAL_GOTO:
c2f47e15 6800 target = expand_builtin_nonlocal_goto (exp);
4ee9c684 6801 if (target)
6802 return target;
6803 break;
6804
843d08a9 6805 /* This updates the setjmp buffer that is its argument with the value
6806 of the current stack pointer. */
6807 case BUILT_IN_UPDATE_SETJMP_BUF:
c2f47e15 6808 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
843d08a9 6809 {
6810 rtx buf_addr
c2f47e15 6811 = expand_normal (CALL_EXPR_ARG (exp, 0));
843d08a9 6812
6813 expand_builtin_update_setjmp_buf (buf_addr);
6814 return const0_rtx;
6815 }
6816 break;
6817
53800dbe 6818 case BUILT_IN_TRAP:
a0ef1725 6819 expand_builtin_trap ();
53800dbe 6820 return const0_rtx;
6821
d2b48f0c 6822 case BUILT_IN_UNREACHABLE:
6823 expand_builtin_unreachable ();
6824 return const0_rtx;
6825
19bf118a 6826 case BUILT_IN_PRINTF:
0b25db21 6827 target = expand_builtin_printf (exp, target, mode, false);
19bf118a 6828 if (target)
6829 return target;
6830 break;
6831
6832 case BUILT_IN_PRINTF_UNLOCKED:
0b25db21 6833 target = expand_builtin_printf (exp, target, mode, true);
19bf118a 6834 if (target)
6835 return target;
6836 break;
6837
df94cd3b 6838 case BUILT_IN_FPUTS:
c2f47e15 6839 target = expand_builtin_fputs (exp, target, false);
c013a46e 6840 if (target)
6841 return target;
6842 break;
6843 case BUILT_IN_FPUTS_UNLOCKED:
c2f47e15 6844 target = expand_builtin_fputs (exp, target, true);
19bf118a 6845 if (target)
6846 return target;
6847 break;
6848
6849 case BUILT_IN_FPRINTF:
0b25db21 6850 target = expand_builtin_fprintf (exp, target, mode, false);
19bf118a 6851 if (target)
6852 return target;
6853 break;
6854
6855 case BUILT_IN_FPRINTF_UNLOCKED:
0b25db21 6856 target = expand_builtin_fprintf (exp, target, mode, true);
df94cd3b 6857 if (target)
6858 return target;
6859 break;
bf8e3599 6860
6411575e 6861 case BUILT_IN_SPRINTF:
c2f47e15 6862 target = expand_builtin_sprintf (exp, target, mode);
6411575e 6863 if (target)
6864 return target;
6865 break;
6866
4f35b1fc 6867 CASE_FLT_FN (BUILT_IN_SIGNBIT):
004e23c4 6868 case BUILT_IN_SIGNBITD32:
6869 case BUILT_IN_SIGNBITD64:
6870 case BUILT_IN_SIGNBITD128:
27f261ef 6871 target = expand_builtin_signbit (exp, target);
6872 if (target)
6873 return target;
6874 break;
6875
53800dbe 6876 /* Various hooks for the DWARF 2 __throw routine. */
6877 case BUILT_IN_UNWIND_INIT:
6878 expand_builtin_unwind_init ();
6879 return const0_rtx;
6880 case BUILT_IN_DWARF_CFA:
6881 return virtual_cfa_rtx;
6882#ifdef DWARF2_UNWIND_INFO
f8f023a5 6883 case BUILT_IN_DWARF_SP_COLUMN:
6884 return expand_builtin_dwarf_sp_column ();
695e919b 6885 case BUILT_IN_INIT_DWARF_REG_SIZES:
c2f47e15 6886 expand_builtin_init_dwarf_reg_sizes (CALL_EXPR_ARG (exp, 0));
695e919b 6887 return const0_rtx;
53800dbe 6888#endif
6889 case BUILT_IN_FROB_RETURN_ADDR:
c2f47e15 6890 return expand_builtin_frob_return_addr (CALL_EXPR_ARG (exp, 0));
53800dbe 6891 case BUILT_IN_EXTRACT_RETURN_ADDR:
c2f47e15 6892 return expand_builtin_extract_return_addr (CALL_EXPR_ARG (exp, 0));
53800dbe 6893 case BUILT_IN_EH_RETURN:
c2f47e15 6894 expand_builtin_eh_return (CALL_EXPR_ARG (exp, 0),
6895 CALL_EXPR_ARG (exp, 1));
53800dbe 6896 return const0_rtx;
df4b504c 6897#ifdef EH_RETURN_DATA_REGNO
6898 case BUILT_IN_EH_RETURN_DATA_REGNO:
c2f47e15 6899 return expand_builtin_eh_return_data_regno (exp);
df4b504c 6900#endif
26093bf4 6901 case BUILT_IN_EXTEND_POINTER:
c2f47e15 6902 return expand_builtin_extend_pointer (CALL_EXPR_ARG (exp, 0));
26093bf4 6903
7ccc713a 6904 case BUILT_IN_VA_START:
c2f47e15 6905 return expand_builtin_va_start (exp);
a66c9326 6906 case BUILT_IN_VA_END:
c2f47e15 6907 return expand_builtin_va_end (exp);
a66c9326 6908 case BUILT_IN_VA_COPY:
c2f47e15 6909 return expand_builtin_va_copy (exp);
89cfe6e5 6910 case BUILT_IN_EXPECT:
c2f47e15 6911 return expand_builtin_expect (exp, target);
5e3608d8 6912 case BUILT_IN_PREFETCH:
c2f47e15 6913 expand_builtin_prefetch (exp);
5e3608d8 6914 return const0_rtx;
6915
4ee9c684 6916 case BUILT_IN_PROFILE_FUNC_ENTER:
6917 return expand_builtin_profile_func (false);
6918 case BUILT_IN_PROFILE_FUNC_EXIT:
6919 return expand_builtin_profile_func (true);
6920
6921 case BUILT_IN_INIT_TRAMPOLINE:
c2f47e15 6922 return expand_builtin_init_trampoline (exp);
4ee9c684 6923 case BUILT_IN_ADJUST_TRAMPOLINE:
c2f47e15 6924 return expand_builtin_adjust_trampoline (exp);
4ee9c684 6925
73673831 6926 case BUILT_IN_FORK:
6927 case BUILT_IN_EXECL:
6928 case BUILT_IN_EXECV:
6929 case BUILT_IN_EXECLP:
6930 case BUILT_IN_EXECLE:
6931 case BUILT_IN_EXECVP:
6932 case BUILT_IN_EXECVE:
c2f47e15 6933 target = expand_builtin_fork_or_exec (fndecl, exp, target, ignore);
73673831 6934 if (target)
6935 return target;
6936 break;
53800dbe 6937
b6a5fc45 6938 case BUILT_IN_FETCH_AND_ADD_1:
6939 case BUILT_IN_FETCH_AND_ADD_2:
6940 case BUILT_IN_FETCH_AND_ADD_4:
6941 case BUILT_IN_FETCH_AND_ADD_8:
27213ba3 6942 case BUILT_IN_FETCH_AND_ADD_16:
3e272de8 6943 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
c2f47e15 6944 target = expand_builtin_sync_operation (mode, exp, PLUS,
b6a5fc45 6945 false, target, ignore);
6946 if (target)
6947 return target;
6948 break;
6949
6950 case BUILT_IN_FETCH_AND_SUB_1:
6951 case BUILT_IN_FETCH_AND_SUB_2:
6952 case BUILT_IN_FETCH_AND_SUB_4:
6953 case BUILT_IN_FETCH_AND_SUB_8:
27213ba3 6954 case BUILT_IN_FETCH_AND_SUB_16:
3e272de8 6955 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
c2f47e15 6956 target = expand_builtin_sync_operation (mode, exp, MINUS,
b6a5fc45 6957 false, target, ignore);
6958 if (target)
6959 return target;
6960 break;
6961
6962 case BUILT_IN_FETCH_AND_OR_1:
6963 case BUILT_IN_FETCH_AND_OR_2:
6964 case BUILT_IN_FETCH_AND_OR_4:
6965 case BUILT_IN_FETCH_AND_OR_8:
27213ba3 6966 case BUILT_IN_FETCH_AND_OR_16:
3e272de8 6967 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
c2f47e15 6968 target = expand_builtin_sync_operation (mode, exp, IOR,
b6a5fc45 6969 false, target, ignore);
6970 if (target)
6971 return target;
6972 break;
6973
6974 case BUILT_IN_FETCH_AND_AND_1:
6975 case BUILT_IN_FETCH_AND_AND_2:
6976 case BUILT_IN_FETCH_AND_AND_4:
6977 case BUILT_IN_FETCH_AND_AND_8:
27213ba3 6978 case BUILT_IN_FETCH_AND_AND_16:
3e272de8 6979 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
c2f47e15 6980 target = expand_builtin_sync_operation (mode, exp, AND,
b6a5fc45 6981 false, target, ignore);
6982 if (target)
6983 return target;
6984 break;
6985
6986 case BUILT_IN_FETCH_AND_XOR_1:
6987 case BUILT_IN_FETCH_AND_XOR_2:
6988 case BUILT_IN_FETCH_AND_XOR_4:
6989 case BUILT_IN_FETCH_AND_XOR_8:
27213ba3 6990 case BUILT_IN_FETCH_AND_XOR_16:
3e272de8 6991 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
c2f47e15 6992 target = expand_builtin_sync_operation (mode, exp, XOR,
b6a5fc45 6993 false, target, ignore);
6994 if (target)
6995 return target;
6996 break;
6997
6998 case BUILT_IN_FETCH_AND_NAND_1:
6999 case BUILT_IN_FETCH_AND_NAND_2:
7000 case BUILT_IN_FETCH_AND_NAND_4:
7001 case BUILT_IN_FETCH_AND_NAND_8:
27213ba3 7002 case BUILT_IN_FETCH_AND_NAND_16:
3e272de8 7003 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
c2f47e15 7004 target = expand_builtin_sync_operation (mode, exp, NOT,
b6a5fc45 7005 false, target, ignore);
7006 if (target)
7007 return target;
7008 break;
7009
7010 case BUILT_IN_ADD_AND_FETCH_1:
7011 case BUILT_IN_ADD_AND_FETCH_2:
7012 case BUILT_IN_ADD_AND_FETCH_4:
7013 case BUILT_IN_ADD_AND_FETCH_8:
27213ba3 7014 case BUILT_IN_ADD_AND_FETCH_16:
3e272de8 7015 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
c2f47e15 7016 target = expand_builtin_sync_operation (mode, exp, PLUS,
b6a5fc45 7017 true, target, ignore);
7018 if (target)
7019 return target;
7020 break;
7021
7022 case BUILT_IN_SUB_AND_FETCH_1:
7023 case BUILT_IN_SUB_AND_FETCH_2:
7024 case BUILT_IN_SUB_AND_FETCH_4:
7025 case BUILT_IN_SUB_AND_FETCH_8:
27213ba3 7026 case BUILT_IN_SUB_AND_FETCH_16:
3e272de8 7027 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
c2f47e15 7028 target = expand_builtin_sync_operation (mode, exp, MINUS,
b6a5fc45 7029 true, target, ignore);
7030 if (target)
7031 return target;
7032 break;
7033
7034 case BUILT_IN_OR_AND_FETCH_1:
7035 case BUILT_IN_OR_AND_FETCH_2:
7036 case BUILT_IN_OR_AND_FETCH_4:
7037 case BUILT_IN_OR_AND_FETCH_8:
27213ba3 7038 case BUILT_IN_OR_AND_FETCH_16:
3e272de8 7039 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
c2f47e15 7040 target = expand_builtin_sync_operation (mode, exp, IOR,
b6a5fc45 7041 true, target, ignore);
7042 if (target)
7043 return target;
7044 break;
7045
7046 case BUILT_IN_AND_AND_FETCH_1:
7047 case BUILT_IN_AND_AND_FETCH_2:
7048 case BUILT_IN_AND_AND_FETCH_4:
7049 case BUILT_IN_AND_AND_FETCH_8:
27213ba3 7050 case BUILT_IN_AND_AND_FETCH_16:
3e272de8 7051 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
c2f47e15 7052 target = expand_builtin_sync_operation (mode, exp, AND,
b6a5fc45 7053 true, target, ignore);
7054 if (target)
7055 return target;
7056 break;
7057
7058 case BUILT_IN_XOR_AND_FETCH_1:
7059 case BUILT_IN_XOR_AND_FETCH_2:
7060 case BUILT_IN_XOR_AND_FETCH_4:
7061 case BUILT_IN_XOR_AND_FETCH_8:
27213ba3 7062 case BUILT_IN_XOR_AND_FETCH_16:
3e272de8 7063 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
c2f47e15 7064 target = expand_builtin_sync_operation (mode, exp, XOR,
b6a5fc45 7065 true, target, ignore);
7066 if (target)
7067 return target;
7068 break;
7069
7070 case BUILT_IN_NAND_AND_FETCH_1:
7071 case BUILT_IN_NAND_AND_FETCH_2:
7072 case BUILT_IN_NAND_AND_FETCH_4:
7073 case BUILT_IN_NAND_AND_FETCH_8:
27213ba3 7074 case BUILT_IN_NAND_AND_FETCH_16:
3e272de8 7075 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
c2f47e15 7076 target = expand_builtin_sync_operation (mode, exp, NOT,
b6a5fc45 7077 true, target, ignore);
7078 if (target)
7079 return target;
7080 break;
7081
7082 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
7083 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
7084 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
7085 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
27213ba3 7086 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
a601d32a 7087 if (mode == VOIDmode)
7088 mode = TYPE_MODE (boolean_type_node);
b6a5fc45 7089 if (!target || !register_operand (target, mode))
7090 target = gen_reg_rtx (mode);
3e272de8 7091
7092 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
c2f47e15 7093 target = expand_builtin_compare_and_swap (mode, exp, true, target);
b6a5fc45 7094 if (target)
7095 return target;
7096 break;
7097
7098 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
7099 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
7100 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
7101 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
27213ba3 7102 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
3e272de8 7103 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
c2f47e15 7104 target = expand_builtin_compare_and_swap (mode, exp, false, target);
b6a5fc45 7105 if (target)
7106 return target;
7107 break;
7108
7109 case BUILT_IN_LOCK_TEST_AND_SET_1:
7110 case BUILT_IN_LOCK_TEST_AND_SET_2:
7111 case BUILT_IN_LOCK_TEST_AND_SET_4:
7112 case BUILT_IN_LOCK_TEST_AND_SET_8:
27213ba3 7113 case BUILT_IN_LOCK_TEST_AND_SET_16:
3e272de8 7114 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
c2f47e15 7115 target = expand_builtin_lock_test_and_set (mode, exp, target);
b6a5fc45 7116 if (target)
7117 return target;
7118 break;
7119
7120 case BUILT_IN_LOCK_RELEASE_1:
7121 case BUILT_IN_LOCK_RELEASE_2:
7122 case BUILT_IN_LOCK_RELEASE_4:
7123 case BUILT_IN_LOCK_RELEASE_8:
27213ba3 7124 case BUILT_IN_LOCK_RELEASE_16:
3e272de8 7125 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
c2f47e15 7126 expand_builtin_lock_release (mode, exp);
b6a5fc45 7127 return const0_rtx;
7128
7129 case BUILT_IN_SYNCHRONIZE:
7130 expand_builtin_synchronize ();
7131 return const0_rtx;
7132
0a39fd54 7133 case BUILT_IN_OBJECT_SIZE:
7134 return expand_builtin_object_size (exp);
7135
7136 case BUILT_IN_MEMCPY_CHK:
7137 case BUILT_IN_MEMPCPY_CHK:
7138 case BUILT_IN_MEMMOVE_CHK:
7139 case BUILT_IN_MEMSET_CHK:
7140 target = expand_builtin_memory_chk (exp, target, mode, fcode);
7141 if (target)
7142 return target;
7143 break;
7144
7145 case BUILT_IN_STRCPY_CHK:
7146 case BUILT_IN_STPCPY_CHK:
7147 case BUILT_IN_STRNCPY_CHK:
7148 case BUILT_IN_STRCAT_CHK:
b356dfef 7149 case BUILT_IN_STRNCAT_CHK:
0a39fd54 7150 case BUILT_IN_SNPRINTF_CHK:
7151 case BUILT_IN_VSNPRINTF_CHK:
7152 maybe_emit_chk_warning (exp, fcode);
7153 break;
7154
7155 case BUILT_IN_SPRINTF_CHK:
7156 case BUILT_IN_VSPRINTF_CHK:
7157 maybe_emit_sprintf_chk_warning (exp, fcode);
7158 break;
7159
2c281b15 7160 case BUILT_IN_FREE:
7161 maybe_emit_free_warning (exp);
7162 break;
7163
92482ee0 7164 default: /* just do library call, if unknown builtin */
146c1b4f 7165 break;
53800dbe 7166 }
7167
7168 /* The switch statement above can drop through to cause the function
7169 to be called normally. */
7170 return expand_call (exp, target, ignore);
7171}
650e4c94 7172
805e22b2 7173/* Determine whether a tree node represents a call to a built-in
52203a9d 7174 function. If the tree T is a call to a built-in function with
7175 the right number of arguments of the appropriate types, return
7176 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
7177 Otherwise the return value is END_BUILTINS. */
aecda0d6 7178
805e22b2 7179enum built_in_function
b7bf20db 7180builtin_mathfn_code (const_tree t)
805e22b2 7181{
b7bf20db 7182 const_tree fndecl, arg, parmlist;
7183 const_tree argtype, parmtype;
7184 const_call_expr_arg_iterator iter;
805e22b2 7185
7186 if (TREE_CODE (t) != CALL_EXPR
c2f47e15 7187 || TREE_CODE (CALL_EXPR_FN (t)) != ADDR_EXPR)
805e22b2 7188 return END_BUILTINS;
7189
c6e6ecb1 7190 fndecl = get_callee_fndecl (t);
7191 if (fndecl == NULL_TREE
52203a9d 7192 || TREE_CODE (fndecl) != FUNCTION_DECL
805e22b2 7193 || ! DECL_BUILT_IN (fndecl)
7194 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7195 return END_BUILTINS;
7196
52203a9d 7197 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
b7bf20db 7198 init_const_call_expr_arg_iterator (t, &iter);
52203a9d 7199 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
e9f80ff5 7200 {
52203a9d 7201 /* If a function doesn't take a variable number of arguments,
7202 the last element in the list will have type `void'. */
7203 parmtype = TREE_VALUE (parmlist);
7204 if (VOID_TYPE_P (parmtype))
7205 {
b7bf20db 7206 if (more_const_call_expr_args_p (&iter))
52203a9d 7207 return END_BUILTINS;
7208 return DECL_FUNCTION_CODE (fndecl);
7209 }
7210
b7bf20db 7211 if (! more_const_call_expr_args_p (&iter))
e9f80ff5 7212 return END_BUILTINS;
c2f47e15 7213
b7bf20db 7214 arg = next_const_call_expr_arg (&iter);
c2f47e15 7215 argtype = TREE_TYPE (arg);
52203a9d 7216
7217 if (SCALAR_FLOAT_TYPE_P (parmtype))
7218 {
7219 if (! SCALAR_FLOAT_TYPE_P (argtype))
7220 return END_BUILTINS;
7221 }
7222 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
7223 {
7224 if (! COMPLEX_FLOAT_TYPE_P (argtype))
7225 return END_BUILTINS;
7226 }
7227 else if (POINTER_TYPE_P (parmtype))
7228 {
7229 if (! POINTER_TYPE_P (argtype))
7230 return END_BUILTINS;
7231 }
7232 else if (INTEGRAL_TYPE_P (parmtype))
7233 {
7234 if (! INTEGRAL_TYPE_P (argtype))
7235 return END_BUILTINS;
7236 }
7237 else
e9f80ff5 7238 return END_BUILTINS;
e9f80ff5 7239 }
7240
52203a9d 7241 /* Variable-length argument list. */
805e22b2 7242 return DECL_FUNCTION_CODE (fndecl);
7243}
7244
c2f47e15 7245/* Fold a call to __builtin_constant_p, if we know its argument ARG will
7246 evaluate to a constant. */
650e4c94 7247
7248static tree
c2f47e15 7249fold_builtin_constant_p (tree arg)
650e4c94 7250{
650e4c94 7251 /* We return 1 for a numeric type that's known to be a constant
7252 value at compile-time or for an aggregate type that's a
7253 literal constant. */
c2f47e15 7254 STRIP_NOPS (arg);
650e4c94 7255
7256 /* If we know this is a constant, emit the constant of one. */
c2f47e15 7257 if (CONSTANT_CLASS_P (arg)
7258 || (TREE_CODE (arg) == CONSTRUCTOR
7259 && TREE_CONSTANT (arg)))
650e4c94 7260 return integer_one_node;
c2f47e15 7261 if (TREE_CODE (arg) == ADDR_EXPR)
adcfa3a3 7262 {
c2f47e15 7263 tree op = TREE_OPERAND (arg, 0);
adcfa3a3 7264 if (TREE_CODE (op) == STRING_CST
7265 || (TREE_CODE (op) == ARRAY_REF
7266 && integer_zerop (TREE_OPERAND (op, 1))
7267 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
7268 return integer_one_node;
7269 }
650e4c94 7270
1fb4300c 7271 /* If this expression has side effects, show we don't know it to be a
7272 constant. Likewise if it's a pointer or aggregate type since in
7273 those case we only want literals, since those are only optimized
f97c71a1 7274 when generating RTL, not later.
7275 And finally, if we are compiling an initializer, not code, we
7276 need to return a definite result now; there's not going to be any
7277 more optimization done. */
c2f47e15 7278 if (TREE_SIDE_EFFECTS (arg)
7279 || AGGREGATE_TYPE_P (TREE_TYPE (arg))
7280 || POINTER_TYPE_P (TREE_TYPE (arg))
47be647d 7281 || cfun == 0
7282 || folding_initializer)
650e4c94 7283 return integer_zero_node;
7284
c2f47e15 7285 return NULL_TREE;
650e4c94 7286}
7287
76f5a783 7288/* Create builtin_expect with PRED and EXPECTED as its arguments and
7289 return it as a truthvalue. */
4ee9c684 7290
7291static tree
76f5a783 7292build_builtin_expect_predicate (tree pred, tree expected)
4ee9c684 7293{
76f5a783 7294 tree fn, arg_types, pred_type, expected_type, call_expr, ret_type;
4ee9c684 7295
76f5a783 7296 fn = built_in_decls[BUILT_IN_EXPECT];
7297 arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
7298 ret_type = TREE_TYPE (TREE_TYPE (fn));
7299 pred_type = TREE_VALUE (arg_types);
7300 expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
7301
7302 pred = fold_convert (pred_type, pred);
7303 expected = fold_convert (expected_type, expected);
7304 call_expr = build_call_expr (fn, 2, pred, expected);
7305
7306 return build2 (NE_EXPR, TREE_TYPE (pred), call_expr,
7307 build_int_cst (ret_type, 0));
7308}
7309
7310/* Fold a call to builtin_expect with arguments ARG0 and ARG1. Return
7311 NULL_TREE if no simplification is possible. */
7312
7313static tree
7314fold_builtin_expect (tree arg0, tree arg1)
7315{
7316 tree inner, fndecl;
7317 enum tree_code code;
7318
7319 /* If this is a builtin_expect within a builtin_expect keep the
7320 inner one. See through a comparison against a constant. It
7321 might have been added to create a thruthvalue. */
7322 inner = arg0;
7323 if (COMPARISON_CLASS_P (inner)
7324 && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST)
7325 inner = TREE_OPERAND (inner, 0);
7326
7327 if (TREE_CODE (inner) == CALL_EXPR
7328 && (fndecl = get_callee_fndecl (inner))
7329 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
7330 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT)
7331 return arg0;
7332
7333 /* Distribute the expected value over short-circuiting operators.
7334 See through the cast from truthvalue_type_node to long. */
7335 inner = arg0;
7336 while (TREE_CODE (inner) == NOP_EXPR
7337 && INTEGRAL_TYPE_P (TREE_TYPE (inner))
7338 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (inner, 0))))
7339 inner = TREE_OPERAND (inner, 0);
7340
7341 code = TREE_CODE (inner);
7342 if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
7343 {
7344 tree op0 = TREE_OPERAND (inner, 0);
7345 tree op1 = TREE_OPERAND (inner, 1);
7346
7347 op0 = build_builtin_expect_predicate (op0, arg1);
7348 op1 = build_builtin_expect_predicate (op1, arg1);
7349 inner = build2 (code, TREE_TYPE (inner), op0, op1);
7350
7351 return fold_convert (TREE_TYPE (arg0), inner);
7352 }
7353
7354 /* If the argument isn't invariant then there's nothing else we can do. */
c7d4e749 7355 if (!TREE_CONSTANT (arg0))
c2f47e15 7356 return NULL_TREE;
4ee9c684 7357
76f5a783 7358 /* If we expect that a comparison against the argument will fold to
7359 a constant return the constant. In practice, this means a true
7360 constant or the address of a non-weak symbol. */
7361 inner = arg0;
4ee9c684 7362 STRIP_NOPS (inner);
7363 if (TREE_CODE (inner) == ADDR_EXPR)
7364 {
7365 do
7366 {
7367 inner = TREE_OPERAND (inner, 0);
7368 }
7369 while (TREE_CODE (inner) == COMPONENT_REF
7370 || TREE_CODE (inner) == ARRAY_REF);
062b4460 7371 if ((TREE_CODE (inner) == VAR_DECL
7372 || TREE_CODE (inner) == FUNCTION_DECL)
7373 && DECL_WEAK (inner))
c2f47e15 7374 return NULL_TREE;
4ee9c684 7375 }
7376
76f5a783 7377 /* Otherwise, ARG0 already has the proper type for the return value. */
7378 return arg0;
4ee9c684 7379}
7380
c2f47e15 7381/* Fold a call to __builtin_classify_type with argument ARG. */
27d0c333 7382
539a3a92 7383static tree
c2f47e15 7384fold_builtin_classify_type (tree arg)
539a3a92 7385{
c2f47e15 7386 if (arg == 0)
7016c612 7387 return build_int_cst (NULL_TREE, no_type_class);
539a3a92 7388
c2f47e15 7389 return build_int_cst (NULL_TREE, type_to_class (TREE_TYPE (arg)));
539a3a92 7390}
7391
c2f47e15 7392/* Fold a call to __builtin_strlen with argument ARG. */
e6e27594 7393
7394static tree
c2f47e15 7395fold_builtin_strlen (tree arg)
e6e27594 7396{
c2f47e15 7397 if (!validate_arg (arg, POINTER_TYPE))
e6e27594 7398 return NULL_TREE;
7399 else
7400 {
c2f47e15 7401 tree len = c_strlen (arg, 0);
e6e27594 7402
7403 if (len)
7404 {
7405 /* Convert from the internal "sizetype" type to "size_t". */
7406 if (size_type_node)
7407 len = fold_convert (size_type_node, len);
7408 return len;
7409 }
7410
7411 return NULL_TREE;
7412 }
7413}
7414
92c43e3c 7415/* Fold a call to __builtin_inf or __builtin_huge_val. */
7416
7417static tree
aecda0d6 7418fold_builtin_inf (tree type, int warn)
92c43e3c 7419{
aa870c1b 7420 REAL_VALUE_TYPE real;
7421
40f4dbd5 7422 /* __builtin_inff is intended to be usable to define INFINITY on all
7423 targets. If an infinity is not available, INFINITY expands "to a
7424 positive constant of type float that overflows at translation
7425 time", footnote "In this case, using INFINITY will violate the
7426 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
7427 Thus we pedwarn to ensure this constraint violation is
7428 diagnosed. */
92c43e3c 7429 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
21ca8540 7430 pedwarn (input_location, 0, "target format does not support infinity");
92c43e3c 7431
aa870c1b 7432 real_inf (&real);
7433 return build_real (type, real);
92c43e3c 7434}
7435
c2f47e15 7436/* Fold a call to __builtin_nan or __builtin_nans with argument ARG. */
b0db7939 7437
7438static tree
c2f47e15 7439fold_builtin_nan (tree arg, tree type, int quiet)
b0db7939 7440{
7441 REAL_VALUE_TYPE real;
7442 const char *str;
7443
c2f47e15 7444 if (!validate_arg (arg, POINTER_TYPE))
7445 return NULL_TREE;
7446 str = c_getstr (arg);
b0db7939 7447 if (!str)
c2f47e15 7448 return NULL_TREE;
b0db7939 7449
7450 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
c2f47e15 7451 return NULL_TREE;
b0db7939 7452
7453 return build_real (type, real);
7454}
7455
277f8dd2 7456/* Return true if the floating point expression T has an integer value.
7457 We also allow +Inf, -Inf and NaN to be considered integer values. */
7458
7459static bool
7460integer_valued_real_p (tree t)
7461{
7462 switch (TREE_CODE (t))
7463 {
7464 case FLOAT_EXPR:
7465 return true;
7466
7467 case ABS_EXPR:
7468 case SAVE_EXPR:
277f8dd2 7469 return integer_valued_real_p (TREE_OPERAND (t, 0));
7470
7471 case COMPOUND_EXPR:
41076ef6 7472 case MODIFY_EXPR:
277f8dd2 7473 case BIND_EXPR:
75a70cf9 7474 return integer_valued_real_p (TREE_OPERAND (t, 1));
277f8dd2 7475
7476 case PLUS_EXPR:
7477 case MINUS_EXPR:
7478 case MULT_EXPR:
7479 case MIN_EXPR:
7480 case MAX_EXPR:
7481 return integer_valued_real_p (TREE_OPERAND (t, 0))
7482 && integer_valued_real_p (TREE_OPERAND (t, 1));
7483
7484 case COND_EXPR:
7485 return integer_valued_real_p (TREE_OPERAND (t, 1))
7486 && integer_valued_real_p (TREE_OPERAND (t, 2));
7487
7488 case REAL_CST:
0570334c 7489 return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t)));
277f8dd2 7490
7491 case NOP_EXPR:
7492 {
7493 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
7494 if (TREE_CODE (type) == INTEGER_TYPE)
7495 return true;
7496 if (TREE_CODE (type) == REAL_TYPE)
7497 return integer_valued_real_p (TREE_OPERAND (t, 0));
7498 break;
7499 }
7500
7501 case CALL_EXPR:
7502 switch (builtin_mathfn_code (t))
7503 {
4f35b1fc 7504 CASE_FLT_FN (BUILT_IN_CEIL):
7505 CASE_FLT_FN (BUILT_IN_FLOOR):
7506 CASE_FLT_FN (BUILT_IN_NEARBYINT):
7507 CASE_FLT_FN (BUILT_IN_RINT):
7508 CASE_FLT_FN (BUILT_IN_ROUND):
7509 CASE_FLT_FN (BUILT_IN_TRUNC):
277f8dd2 7510 return true;
7511
d4a43a03 7512 CASE_FLT_FN (BUILT_IN_FMIN):
7513 CASE_FLT_FN (BUILT_IN_FMAX):
c2f47e15 7514 return integer_valued_real_p (CALL_EXPR_ARG (t, 0))
7515 && integer_valued_real_p (CALL_EXPR_ARG (t, 1));
d4a43a03 7516
277f8dd2 7517 default:
7518 break;
7519 }
7520 break;
7521
7522 default:
7523 break;
7524 }
7525 return false;
7526}
7527
c2f47e15 7528/* FNDECL is assumed to be a builtin where truncation can be propagated
6528f4f4 7529 across (for instance floor((double)f) == (double)floorf (f).
c2f47e15 7530 Do the transformation for a call with argument ARG. */
277f8dd2 7531
6528f4f4 7532static tree
c2f47e15 7533fold_trunc_transparent_mathfn (tree fndecl, tree arg)
6528f4f4 7534{
6528f4f4 7535 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
277f8dd2 7536
c2f47e15 7537 if (!validate_arg (arg, REAL_TYPE))
7538 return NULL_TREE;
6528f4f4 7539
277f8dd2 7540 /* Integer rounding functions are idempotent. */
7541 if (fcode == builtin_mathfn_code (arg))
7542 return arg;
7543
7544 /* If argument is already integer valued, and we don't need to worry
7545 about setting errno, there's no need to perform rounding. */
7546 if (! flag_errno_math && integer_valued_real_p (arg))
7547 return arg;
7548
7549 if (optimize)
6528f4f4 7550 {
277f8dd2 7551 tree arg0 = strip_float_extensions (arg);
2426241c 7552 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6528f4f4 7553 tree newtype = TREE_TYPE (arg0);
7554 tree decl;
7555
7556 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7557 && (decl = mathfn_built_in (newtype, fcode)))
c2f47e15 7558 return fold_convert (ftype,
7559 build_call_expr (decl, 1,
7560 fold_convert (newtype, arg0)));
6528f4f4 7561 }
c2f47e15 7562 return NULL_TREE;
6528f4f4 7563}
7564
c2f47e15 7565/* FNDECL is assumed to be builtin which can narrow the FP type of
7566 the argument, for instance lround((double)f) -> lroundf (f).
7567 Do the transformation for a call with argument ARG. */
9ed65c7f 7568
7569static tree
c2f47e15 7570fold_fixed_mathfn (tree fndecl, tree arg)
9ed65c7f 7571{
9ed65c7f 7572 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
9ed65c7f 7573
c2f47e15 7574 if (!validate_arg (arg, REAL_TYPE))
7575 return NULL_TREE;
9ed65c7f 7576
7577 /* If argument is already integer valued, and we don't need to worry
7578 about setting errno, there's no need to perform rounding. */
7579 if (! flag_errno_math && integer_valued_real_p (arg))
49d00087 7580 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
9ed65c7f 7581
7582 if (optimize)
7583 {
7584 tree ftype = TREE_TYPE (arg);
7585 tree arg0 = strip_float_extensions (arg);
7586 tree newtype = TREE_TYPE (arg0);
7587 tree decl;
7588
7589 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7590 && (decl = mathfn_built_in (newtype, fcode)))
c2f47e15 7591 return build_call_expr (decl, 1, fold_convert (newtype, arg0));
9ed65c7f 7592 }
73a0da56 7593
7594 /* Canonicalize llround (x) to lround (x) on LP64 targets where
7595 sizeof (long long) == sizeof (long). */
7596 if (TYPE_PRECISION (long_long_integer_type_node)
7597 == TYPE_PRECISION (long_integer_type_node))
7598 {
7599 tree newfn = NULL_TREE;
7600 switch (fcode)
7601 {
7602 CASE_FLT_FN (BUILT_IN_LLCEIL):
7603 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7604 break;
7605
7606 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7607 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7608 break;
7609
7610 CASE_FLT_FN (BUILT_IN_LLROUND):
7611 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7612 break;
7613
7614 CASE_FLT_FN (BUILT_IN_LLRINT):
7615 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7616 break;
7617
7618 default:
7619 break;
7620 }
7621
7622 if (newfn)
7623 {
c2f47e15 7624 tree newcall = build_call_expr(newfn, 1, arg);
73a0da56 7625 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
7626 }
7627 }
7628
c2f47e15 7629 return NULL_TREE;
9ed65c7f 7630}
7631
c2f47e15 7632/* Fold call to builtin cabs, cabsf or cabsl with argument ARG. TYPE is the
7633 return type. Return NULL_TREE if no simplification can be made. */
c63f4ad3 7634
7635static tree
c2f47e15 7636fold_builtin_cabs (tree arg, tree type, tree fndecl)
c63f4ad3 7637{
c2f47e15 7638 tree res;
c63f4ad3 7639
c63f4ad3 7640 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
7641 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7642 return NULL_TREE;
7643
b4725390 7644 /* Calculate the result when the argument is a constant. */
7645 if (TREE_CODE (arg) == COMPLEX_CST
7646 && (res = do_mpfr_arg2 (TREE_REALPART (arg), TREE_IMAGPART (arg),
7647 type, mpfr_hypot)))
7648 return res;
7649
1af0d139 7650 if (TREE_CODE (arg) == COMPLEX_EXPR)
7651 {
7652 tree real = TREE_OPERAND (arg, 0);
7653 tree imag = TREE_OPERAND (arg, 1);
7654
7655 /* If either part is zero, cabs is fabs of the other. */
7656 if (real_zerop (real))
7657 return fold_build1 (ABS_EXPR, type, imag);
7658 if (real_zerop (imag))
7659 return fold_build1 (ABS_EXPR, type, real);
7660
7661 /* cabs(x+xi) -> fabs(x)*sqrt(2). */
7662 if (flag_unsafe_math_optimizations
7663 && operand_equal_p (real, imag, OEP_PURE_SAME))
7664 {
2e7ca27b 7665 const REAL_VALUE_TYPE sqrt2_trunc
7910b2fb 7666 = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
1af0d139 7667 STRIP_NOPS (real);
7668 return fold_build2 (MULT_EXPR, type,
7669 fold_build1 (ABS_EXPR, type, real),
2e7ca27b 7670 build_real (type, sqrt2_trunc));
1af0d139 7671 }
7672 }
c63f4ad3 7673
749891b2 7674 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
7675 if (TREE_CODE (arg) == NEGATE_EXPR
7676 || TREE_CODE (arg) == CONJ_EXPR)
c2f47e15 7677 return build_call_expr (fndecl, 1, TREE_OPERAND (arg, 0));
749891b2 7678
7d3f6cc7 7679 /* Don't do this when optimizing for size. */
7680 if (flag_unsafe_math_optimizations
0bfd8d5c 7681 && optimize && optimize_function_for_speed_p (cfun))
c63f4ad3 7682 {
0da0dbfa 7683 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
c63f4ad3 7684
7685 if (sqrtfn != NULL_TREE)
7686 {
c2f47e15 7687 tree rpart, ipart, result;
c63f4ad3 7688
4ee9c684 7689 arg = builtin_save_expr (arg);
29a6518e 7690
49d00087 7691 rpart = fold_build1 (REALPART_EXPR, type, arg);
7692 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
c63f4ad3 7693
4ee9c684 7694 rpart = builtin_save_expr (rpart);
7695 ipart = builtin_save_expr (ipart);
c63f4ad3 7696
49d00087 7697 result = fold_build2 (PLUS_EXPR, type,
7698 fold_build2 (MULT_EXPR, type,
7699 rpart, rpart),
7700 fold_build2 (MULT_EXPR, type,
7701 ipart, ipart));
c63f4ad3 7702
c2f47e15 7703 return build_call_expr (sqrtfn, 1, result);
c63f4ad3 7704 }
7705 }
7706
7707 return NULL_TREE;
7708}
7709
c2f47e15 7710/* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG.
7711 Return NULL_TREE if no simplification can be made. */
e6e27594 7712
7713static tree
c2f47e15 7714fold_builtin_sqrt (tree arg, tree type)
e6e27594 7715{
7716
7717 enum built_in_function fcode;
b4e8ab0c 7718 tree res;
c2f47e15 7719
7720 if (!validate_arg (arg, REAL_TYPE))
e6e27594 7721 return NULL_TREE;
7722
b4e8ab0c 7723 /* Calculate the result when the argument is a constant. */
7724 if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst0, NULL, true)))
7725 return res;
7726
e6e27594 7727 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7728 fcode = builtin_mathfn_code (arg);
7729 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7730 {
c2f47e15 7731 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
49d00087 7732 arg = fold_build2 (MULT_EXPR, type,
c2f47e15 7733 CALL_EXPR_ARG (arg, 0),
49d00087 7734 build_real (type, dconsthalf));
c2f47e15 7735 return build_call_expr (expfn, 1, arg);
e6e27594 7736 }
7737
7738 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7739 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7740 {
7741 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7742
7743 if (powfn)
7744 {
c2f47e15 7745 tree arg0 = CALL_EXPR_ARG (arg, 0);
e6e27594 7746 tree tree_root;
7747 /* The inner root was either sqrt or cbrt. */
57510da6 7748 /* This was a conditional expression but it triggered a bug
18381619 7749 in Sun C 5.5. */
ce6cd837 7750 REAL_VALUE_TYPE dconstroot;
7751 if (BUILTIN_SQRT_P (fcode))
7752 dconstroot = dconsthalf;
7753 else
7754 dconstroot = dconst_third ();
e6e27594 7755
7756 /* Adjust for the outer root. */
7757 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7758 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7759 tree_root = build_real (type, dconstroot);
c2f47e15 7760 return build_call_expr (powfn, 2, arg0, tree_root);
e6e27594 7761 }
7762 }
7763
bc33117f 7764 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
e6e27594 7765 if (flag_unsafe_math_optimizations
7766 && (fcode == BUILT_IN_POW
7767 || fcode == BUILT_IN_POWF
7768 || fcode == BUILT_IN_POWL))
7769 {
c2f47e15 7770 tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7771 tree arg0 = CALL_EXPR_ARG (arg, 0);
7772 tree arg1 = CALL_EXPR_ARG (arg, 1);
bc33117f 7773 tree narg1;
7774 if (!tree_expr_nonnegative_p (arg0))
7775 arg0 = build1 (ABS_EXPR, type, arg0);
49d00087 7776 narg1 = fold_build2 (MULT_EXPR, type, arg1,
7777 build_real (type, dconsthalf));
c2f47e15 7778 return build_call_expr (powfn, 2, arg0, narg1);
e6e27594 7779 }
7780
7781 return NULL_TREE;
7782}
7783
c2f47e15 7784/* Fold a builtin function call to cbrt, cbrtf, or cbrtl with argument ARG.
7785 Return NULL_TREE if no simplification can be made. */
7786
e6e27594 7787static tree
c2f47e15 7788fold_builtin_cbrt (tree arg, tree type)
e6e27594 7789{
e6e27594 7790 const enum built_in_function fcode = builtin_mathfn_code (arg);
29f4cd78 7791 tree res;
e6e27594 7792
c2f47e15 7793 if (!validate_arg (arg, REAL_TYPE))
e6e27594 7794 return NULL_TREE;
7795
29f4cd78 7796 /* Calculate the result when the argument is a constant. */
7797 if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7798 return res;
e6e27594 7799
cdfeb715 7800 if (flag_unsafe_math_optimizations)
e6e27594 7801 {
cdfeb715 7802 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7803 if (BUILTIN_EXPONENT_P (fcode))
a0c938f0 7804 {
c2f47e15 7805 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
cdfeb715 7806 const REAL_VALUE_TYPE third_trunc =
7910b2fb 7807 real_value_truncate (TYPE_MODE (type), dconst_third ());
49d00087 7808 arg = fold_build2 (MULT_EXPR, type,
c2f47e15 7809 CALL_EXPR_ARG (arg, 0),
49d00087 7810 build_real (type, third_trunc));
c2f47e15 7811 return build_call_expr (expfn, 1, arg);
cdfeb715 7812 }
e6e27594 7813
cdfeb715 7814 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7815 if (BUILTIN_SQRT_P (fcode))
a0c938f0 7816 {
cdfeb715 7817 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
e6e27594 7818
cdfeb715 7819 if (powfn)
7820 {
c2f47e15 7821 tree arg0 = CALL_EXPR_ARG (arg, 0);
cdfeb715 7822 tree tree_root;
7910b2fb 7823 REAL_VALUE_TYPE dconstroot = dconst_third ();
cdfeb715 7824
7825 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7826 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7827 tree_root = build_real (type, dconstroot);
c2f47e15 7828 return build_call_expr (powfn, 2, arg0, tree_root);
cdfeb715 7829 }
e6e27594 7830 }
7831
cdfeb715 7832 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7833 if (BUILTIN_CBRT_P (fcode))
a0c938f0 7834 {
c2f47e15 7835 tree arg0 = CALL_EXPR_ARG (arg, 0);
cdfeb715 7836 if (tree_expr_nonnegative_p (arg0))
7837 {
7838 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7839
7840 if (powfn)
a0c938f0 7841 {
cdfeb715 7842 tree tree_root;
7843 REAL_VALUE_TYPE dconstroot;
a0c938f0 7844
3fa759a9 7845 real_arithmetic (&dconstroot, MULT_EXPR,
7910b2fb 7846 dconst_third_ptr (), dconst_third_ptr ());
cdfeb715 7847 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7848 tree_root = build_real (type, dconstroot);
c2f47e15 7849 return build_call_expr (powfn, 2, arg0, tree_root);
cdfeb715 7850 }
7851 }
7852 }
a0c938f0 7853
cdfeb715 7854 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
c2f47e15 7855 if (fcode == BUILT_IN_POW
7856 || fcode == BUILT_IN_POWF
cdfeb715 7857 || fcode == BUILT_IN_POWL)
a0c938f0 7858 {
c2f47e15 7859 tree arg00 = CALL_EXPR_ARG (arg, 0);
7860 tree arg01 = CALL_EXPR_ARG (arg, 1);
cdfeb715 7861 if (tree_expr_nonnegative_p (arg00))
7862 {
c2f47e15 7863 tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
cdfeb715 7864 const REAL_VALUE_TYPE dconstroot
7910b2fb 7865 = real_value_truncate (TYPE_MODE (type), dconst_third ());
49d00087 7866 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7867 build_real (type, dconstroot));
c2f47e15 7868 return build_call_expr (powfn, 2, arg00, narg01);
cdfeb715 7869 }
7870 }
e6e27594 7871 }
7872 return NULL_TREE;
7873}
7874
c2f47e15 7875/* Fold function call to builtin cos, cosf, or cosl with argument ARG.
7876 TYPE is the type of the return value. Return NULL_TREE if no
7877 simplification can be made. */
7878
e6e27594 7879static tree
c2f47e15 7880fold_builtin_cos (tree arg, tree type, tree fndecl)
e6e27594 7881{
e6ab33d8 7882 tree res, narg;
e6e27594 7883
c2f47e15 7884 if (!validate_arg (arg, REAL_TYPE))
e6e27594 7885 return NULL_TREE;
7886
bffb7645 7887 /* Calculate the result when the argument is a constant. */
728bac60 7888 if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
bffb7645 7889 return res;
7890
e6e27594 7891 /* Optimize cos(-x) into cos (x). */
e6ab33d8 7892 if ((narg = fold_strip_sign_ops (arg)))
c2f47e15 7893 return build_call_expr (fndecl, 1, narg);
e6e27594 7894
7895 return NULL_TREE;
7896}
7897
c2f47e15 7898/* Fold function call to builtin cosh, coshf, or coshl with argument ARG.
7899 Return NULL_TREE if no simplification can be made. */
7900
cacdc1af 7901static tree
c2f47e15 7902fold_builtin_cosh (tree arg, tree type, tree fndecl)
cacdc1af 7903{
c2f47e15 7904 if (validate_arg (arg, REAL_TYPE))
cacdc1af 7905 {
cacdc1af 7906 tree res, narg;
7907
7908 /* Calculate the result when the argument is a constant. */
7909 if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0)))
7910 return res;
7911
7912 /* Optimize cosh(-x) into cosh (x). */
7913 if ((narg = fold_strip_sign_ops (arg)))
c2f47e15 7914 return build_call_expr (fndecl, 1, narg);
cacdc1af 7915 }
7916
7917 return NULL_TREE;
7918}
7919
239d491a 7920/* Fold function call to builtin ccos (or ccosh if HYPER is TRUE) with
7921 argument ARG. TYPE is the type of the return value. Return
7922 NULL_TREE if no simplification can be made. */
7923
7924static tree
7925fold_builtin_ccos (tree arg, tree type ATTRIBUTE_UNUSED, tree fndecl,
7926 bool hyper ATTRIBUTE_UNUSED)
7927{
7928 if (validate_arg (arg, COMPLEX_TYPE)
7929 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
7930 {
7931 tree tmp;
7932
7933#ifdef HAVE_mpc
7934 /* Calculate the result when the argument is a constant. */
7935 if ((tmp = do_mpc_arg1 (arg, type, (hyper ? mpc_cosh : mpc_cos))))
7936 return tmp;
7937#endif
7938
7939 /* Optimize fn(-x) into fn(x). */
7940 if ((tmp = fold_strip_sign_ops (arg)))
7941 return build_call_expr (fndecl, 1, tmp);
7942 }
7943
7944 return NULL_TREE;
7945}
7946
c2f47e15 7947/* Fold function call to builtin tan, tanf, or tanl with argument ARG.
7948 Return NULL_TREE if no simplification can be made. */
7949
e6e27594 7950static tree
c2f47e15 7951fold_builtin_tan (tree arg, tree type)
e6e27594 7952{
7953 enum built_in_function fcode;
29f4cd78 7954 tree res;
e6e27594 7955
c2f47e15 7956 if (!validate_arg (arg, REAL_TYPE))
e6e27594 7957 return NULL_TREE;
7958
bffb7645 7959 /* Calculate the result when the argument is a constant. */
728bac60 7960 if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0)))
bffb7645 7961 return res;
7962
e6e27594 7963 /* Optimize tan(atan(x)) = x. */
7964 fcode = builtin_mathfn_code (arg);
7965 if (flag_unsafe_math_optimizations
7966 && (fcode == BUILT_IN_ATAN
7967 || fcode == BUILT_IN_ATANF
7968 || fcode == BUILT_IN_ATANL))
c2f47e15 7969 return CALL_EXPR_ARG (arg, 0);
e6e27594 7970
7971 return NULL_TREE;
7972}
7973
d735c391 7974/* Fold function call to builtin sincos, sincosf, or sincosl. Return
7975 NULL_TREE if no simplification can be made. */
7976
7977static tree
c2f47e15 7978fold_builtin_sincos (tree arg0, tree arg1, tree arg2)
d735c391 7979{
c2f47e15 7980 tree type;
d735c391 7981 tree res, fn, call;
7982
c2f47e15 7983 if (!validate_arg (arg0, REAL_TYPE)
7984 || !validate_arg (arg1, POINTER_TYPE)
7985 || !validate_arg (arg2, POINTER_TYPE))
d735c391 7986 return NULL_TREE;
7987
d735c391 7988 type = TREE_TYPE (arg0);
d735c391 7989
7990 /* Calculate the result when the argument is a constant. */
7991 if ((res = do_mpfr_sincos (arg0, arg1, arg2)))
7992 return res;
7993
7994 /* Canonicalize sincos to cexpi. */
2a6b4c77 7995 if (!TARGET_C99_FUNCTIONS)
7996 return NULL_TREE;
d735c391 7997 fn = mathfn_built_in (type, BUILT_IN_CEXPI);
7998 if (!fn)
7999 return NULL_TREE;
8000
c2f47e15 8001 call = build_call_expr (fn, 1, arg0);
d735c391 8002 call = builtin_save_expr (call);
8003
a75b1c71 8004 return build2 (COMPOUND_EXPR, void_type_node,
d735c391 8005 build2 (MODIFY_EXPR, void_type_node,
8006 build_fold_indirect_ref (arg1),
8007 build1 (IMAGPART_EXPR, type, call)),
8008 build2 (MODIFY_EXPR, void_type_node,
8009 build_fold_indirect_ref (arg2),
8010 build1 (REALPART_EXPR, type, call)));
8011}
8012
c5bb2c4b 8013/* Fold function call to builtin cexp, cexpf, or cexpl. Return
8014 NULL_TREE if no simplification can be made. */
8015
8016static tree
c2f47e15 8017fold_builtin_cexp (tree arg0, tree type)
c5bb2c4b 8018{
c2f47e15 8019 tree rtype;
c5bb2c4b 8020 tree realp, imagp, ifn;
239d491a 8021#ifdef HAVE_mpc
8022 tree res;
8023#endif
c5bb2c4b 8024
239d491a 8025 if (!validate_arg (arg0, COMPLEX_TYPE)
8026 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
c5bb2c4b 8027 return NULL_TREE;
8028
239d491a 8029#ifdef HAVE_mpc
8030 /* Calculate the result when the argument is a constant. */
8031 if ((res = do_mpc_arg1 (arg0, type, mpc_exp)))
8032 return res;
8033#endif
8034
c5bb2c4b 8035 rtype = TREE_TYPE (TREE_TYPE (arg0));
8036
8037 /* In case we can figure out the real part of arg0 and it is constant zero
8038 fold to cexpi. */
2a6b4c77 8039 if (!TARGET_C99_FUNCTIONS)
8040 return NULL_TREE;
c5bb2c4b 8041 ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
8042 if (!ifn)
8043 return NULL_TREE;
8044
8045 if ((realp = fold_unary (REALPART_EXPR, rtype, arg0))
8046 && real_zerop (realp))
8047 {
8048 tree narg = fold_build1 (IMAGPART_EXPR, rtype, arg0);
c2f47e15 8049 return build_call_expr (ifn, 1, narg);
c5bb2c4b 8050 }
8051
8052 /* In case we can easily decompose real and imaginary parts split cexp
8053 to exp (r) * cexpi (i). */
8054 if (flag_unsafe_math_optimizations
8055 && realp)
8056 {
8057 tree rfn, rcall, icall;
8058
8059 rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
8060 if (!rfn)
8061 return NULL_TREE;
8062
8063 imagp = fold_unary (IMAGPART_EXPR, rtype, arg0);
8064 if (!imagp)
8065 return NULL_TREE;
8066
c2f47e15 8067 icall = build_call_expr (ifn, 1, imagp);
c5bb2c4b 8068 icall = builtin_save_expr (icall);
c2f47e15 8069 rcall = build_call_expr (rfn, 1, realp);
c5bb2c4b 8070 rcall = builtin_save_expr (rcall);
71bf42bb 8071 return fold_build2 (COMPLEX_EXPR, type,
8072 fold_build2 (MULT_EXPR, rtype,
8073 rcall,
8074 fold_build1 (REALPART_EXPR, rtype, icall)),
8075 fold_build2 (MULT_EXPR, rtype,
8076 rcall,
8077 fold_build1 (IMAGPART_EXPR, rtype, icall)));
c5bb2c4b 8078 }
8079
8080 return NULL_TREE;
8081}
8082
c2f47e15 8083/* Fold function call to builtin trunc, truncf or truncl with argument ARG.
8084 Return NULL_TREE if no simplification can be made. */
277f8dd2 8085
8086static tree
c2f47e15 8087fold_builtin_trunc (tree fndecl, tree arg)
277f8dd2 8088{
c2f47e15 8089 if (!validate_arg (arg, REAL_TYPE))
8090 return NULL_TREE;
277f8dd2 8091
8092 /* Optimize trunc of constant value. */
f96bd2bf 8093 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
277f8dd2 8094 {
8095 REAL_VALUE_TYPE r, x;
2426241c 8096 tree type = TREE_TYPE (TREE_TYPE (fndecl));
277f8dd2 8097
8098 x = TREE_REAL_CST (arg);
8099 real_trunc (&r, TYPE_MODE (type), &x);
8100 return build_real (type, r);
8101 }
8102
c2f47e15 8103 return fold_trunc_transparent_mathfn (fndecl, arg);
277f8dd2 8104}
8105
c2f47e15 8106/* Fold function call to builtin floor, floorf or floorl with argument ARG.
8107 Return NULL_TREE if no simplification can be made. */
277f8dd2 8108
8109static tree
c2f47e15 8110fold_builtin_floor (tree fndecl, tree arg)
277f8dd2 8111{
c2f47e15 8112 if (!validate_arg (arg, REAL_TYPE))
8113 return NULL_TREE;
277f8dd2 8114
8115 /* Optimize floor of constant value. */
f96bd2bf 8116 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
277f8dd2 8117 {
8118 REAL_VALUE_TYPE x;
8119
8120 x = TREE_REAL_CST (arg);
8121 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
8122 {
2426241c 8123 tree type = TREE_TYPE (TREE_TYPE (fndecl));
277f8dd2 8124 REAL_VALUE_TYPE r;
8125
8126 real_floor (&r, TYPE_MODE (type), &x);
8127 return build_real (type, r);
8128 }
8129 }
8130
acc2b92e 8131 /* Fold floor (x) where x is nonnegative to trunc (x). */
8132 if (tree_expr_nonnegative_p (arg))
30fe8286 8133 {
8134 tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
8135 if (truncfn)
c2f47e15 8136 return build_call_expr (truncfn, 1, arg);
30fe8286 8137 }
acc2b92e 8138
c2f47e15 8139 return fold_trunc_transparent_mathfn (fndecl, arg);
277f8dd2 8140}
8141
c2f47e15 8142/* Fold function call to builtin ceil, ceilf or ceill with argument ARG.
8143 Return NULL_TREE if no simplification can be made. */
277f8dd2 8144
8145static tree
c2f47e15 8146fold_builtin_ceil (tree fndecl, tree arg)
277f8dd2 8147{
c2f47e15 8148 if (!validate_arg (arg, REAL_TYPE))
8149 return NULL_TREE;
277f8dd2 8150
8151 /* Optimize ceil of constant value. */
f96bd2bf 8152 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
277f8dd2 8153 {
8154 REAL_VALUE_TYPE x;
8155
8156 x = TREE_REAL_CST (arg);
8157 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
8158 {
2426241c 8159 tree type = TREE_TYPE (TREE_TYPE (fndecl));
277f8dd2 8160 REAL_VALUE_TYPE r;
8161
8162 real_ceil (&r, TYPE_MODE (type), &x);
8163 return build_real (type, r);
8164 }
8165 }
8166
c2f47e15 8167 return fold_trunc_transparent_mathfn (fndecl, arg);
277f8dd2 8168}
8169
c2f47e15 8170/* Fold function call to builtin round, roundf or roundl with argument ARG.
8171 Return NULL_TREE if no simplification can be made. */
89ab3887 8172
8173static tree
c2f47e15 8174fold_builtin_round (tree fndecl, tree arg)
89ab3887 8175{
c2f47e15 8176 if (!validate_arg (arg, REAL_TYPE))
8177 return NULL_TREE;
89ab3887 8178
34f17811 8179 /* Optimize round of constant value. */
f96bd2bf 8180 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
89ab3887 8181 {
8182 REAL_VALUE_TYPE x;
8183
8184 x = TREE_REAL_CST (arg);
8185 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
8186 {
2426241c 8187 tree type = TREE_TYPE (TREE_TYPE (fndecl));
89ab3887 8188 REAL_VALUE_TYPE r;
8189
8190 real_round (&r, TYPE_MODE (type), &x);
8191 return build_real (type, r);
8192 }
8193 }
8194
c2f47e15 8195 return fold_trunc_transparent_mathfn (fndecl, arg);
89ab3887 8196}
8197
34f17811 8198/* Fold function call to builtin lround, lroundf or lroundl (or the
c2f47e15 8199 corresponding long long versions) and other rounding functions. ARG
8200 is the argument to the call. Return NULL_TREE if no simplification
8201 can be made. */
34f17811 8202
8203static tree
c2f47e15 8204fold_builtin_int_roundingfn (tree fndecl, tree arg)
34f17811 8205{
c2f47e15 8206 if (!validate_arg (arg, REAL_TYPE))
8207 return NULL_TREE;
34f17811 8208
8209 /* Optimize lround of constant value. */
f96bd2bf 8210 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
34f17811 8211 {
8212 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
8213
776a7bab 8214 if (real_isfinite (&x))
34f17811 8215 {
2426241c 8216 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
ca9b061d 8217 tree ftype = TREE_TYPE (arg);
8218 unsigned HOST_WIDE_INT lo2;
34f17811 8219 HOST_WIDE_INT hi, lo;
8220 REAL_VALUE_TYPE r;
8221
ad52b9b7 8222 switch (DECL_FUNCTION_CODE (fndecl))
8223 {
4f35b1fc 8224 CASE_FLT_FN (BUILT_IN_LFLOOR):
8225 CASE_FLT_FN (BUILT_IN_LLFLOOR):
ad52b9b7 8226 real_floor (&r, TYPE_MODE (ftype), &x);
8227 break;
8228
4f35b1fc 8229 CASE_FLT_FN (BUILT_IN_LCEIL):
8230 CASE_FLT_FN (BUILT_IN_LLCEIL):
ac148751 8231 real_ceil (&r, TYPE_MODE (ftype), &x);
8232 break;
8233
4f35b1fc 8234 CASE_FLT_FN (BUILT_IN_LROUND):
8235 CASE_FLT_FN (BUILT_IN_LLROUND):
ad52b9b7 8236 real_round (&r, TYPE_MODE (ftype), &x);
8237 break;
8238
8239 default:
8240 gcc_unreachable ();
8241 }
8242
34f17811 8243 REAL_VALUE_TO_INT (&lo, &hi, r);
ca9b061d 8244 if (!fit_double_type (lo, hi, &lo2, &hi, itype))
8245 return build_int_cst_wide (itype, lo2, hi);
34f17811 8246 }
8247 }
8248
acc2b92e 8249 switch (DECL_FUNCTION_CODE (fndecl))
8250 {
8251 CASE_FLT_FN (BUILT_IN_LFLOOR):
8252 CASE_FLT_FN (BUILT_IN_LLFLOOR):
8253 /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x). */
8254 if (tree_expr_nonnegative_p (arg))
8255 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)),
8256 arg);
8257 break;
8258 default:;
8259 }
8260
c2f47e15 8261 return fold_fixed_mathfn (fndecl, arg);
34f17811 8262}
8263
70fb4c07 8264/* Fold function call to builtin ffs, clz, ctz, popcount and parity
c2f47e15 8265 and their long and long long variants (i.e. ffsl and ffsll). ARG is
8266 the argument to the call. Return NULL_TREE if no simplification can
8267 be made. */
70fb4c07 8268
8269static tree
c2f47e15 8270fold_builtin_bitop (tree fndecl, tree arg)
70fb4c07 8271{
c2f47e15 8272 if (!validate_arg (arg, INTEGER_TYPE))
70fb4c07 8273 return NULL_TREE;
8274
8275 /* Optimize for constant argument. */
f96bd2bf 8276 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
70fb4c07 8277 {
8278 HOST_WIDE_INT hi, width, result;
8279 unsigned HOST_WIDE_INT lo;
7c446c95 8280 tree type;
70fb4c07 8281
8282 type = TREE_TYPE (arg);
8283 width = TYPE_PRECISION (type);
8284 lo = TREE_INT_CST_LOW (arg);
8285
8286 /* Clear all the bits that are beyond the type's precision. */
8287 if (width > HOST_BITS_PER_WIDE_INT)
8288 {
8289 hi = TREE_INT_CST_HIGH (arg);
8290 if (width < 2 * HOST_BITS_PER_WIDE_INT)
8291 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
8292 }
8293 else
8294 {
8295 hi = 0;
8296 if (width < HOST_BITS_PER_WIDE_INT)
8297 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
8298 }
8299
8300 switch (DECL_FUNCTION_CODE (fndecl))
8301 {
4f35b1fc 8302 CASE_INT_FN (BUILT_IN_FFS):
70fb4c07 8303 if (lo != 0)
8304 result = exact_log2 (lo & -lo) + 1;
8305 else if (hi != 0)
8306 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
8307 else
8308 result = 0;
8309 break;
8310
4f35b1fc 8311 CASE_INT_FN (BUILT_IN_CLZ):
70fb4c07 8312 if (hi != 0)
8313 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
8314 else if (lo != 0)
8315 result = width - floor_log2 (lo) - 1;
8316 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8317 result = width;
8318 break;
8319
4f35b1fc 8320 CASE_INT_FN (BUILT_IN_CTZ):
70fb4c07 8321 if (lo != 0)
8322 result = exact_log2 (lo & -lo);
8323 else if (hi != 0)
8324 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
8325 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8326 result = width;
8327 break;
8328
4f35b1fc 8329 CASE_INT_FN (BUILT_IN_POPCOUNT):
70fb4c07 8330 result = 0;
8331 while (lo)
8332 result++, lo &= lo - 1;
8333 while (hi)
8334 result++, hi &= hi - 1;
8335 break;
8336
4f35b1fc 8337 CASE_INT_FN (BUILT_IN_PARITY):
70fb4c07 8338 result = 0;
8339 while (lo)
8340 result++, lo &= lo - 1;
8341 while (hi)
8342 result++, hi &= hi - 1;
8343 result &= 1;
8344 break;
8345
8346 default:
64db345d 8347 gcc_unreachable ();
70fb4c07 8348 }
8349
2426241c 8350 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
70fb4c07 8351 }
8352
8353 return NULL_TREE;
8354}
8355
42791117 8356/* Fold function call to builtin_bswap and the long and long long
8357 variants. Return NULL_TREE if no simplification can be made. */
8358static tree
c2f47e15 8359fold_builtin_bswap (tree fndecl, tree arg)
42791117 8360{
c2f47e15 8361 if (! validate_arg (arg, INTEGER_TYPE))
8362 return NULL_TREE;
42791117 8363
8364 /* Optimize constant value. */
f96bd2bf 8365 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
42791117 8366 {
8367 HOST_WIDE_INT hi, width, r_hi = 0;
8368 unsigned HOST_WIDE_INT lo, r_lo = 0;
8369 tree type;
8370
8371 type = TREE_TYPE (arg);
8372 width = TYPE_PRECISION (type);
8373 lo = TREE_INT_CST_LOW (arg);
8374 hi = TREE_INT_CST_HIGH (arg);
8375
8376 switch (DECL_FUNCTION_CODE (fndecl))
8377 {
8378 case BUILT_IN_BSWAP32:
8379 case BUILT_IN_BSWAP64:
8380 {
8381 int s;
8382
8383 for (s = 0; s < width; s += 8)
8384 {
8385 int d = width - s - 8;
8386 unsigned HOST_WIDE_INT byte;
8387
8388 if (s < HOST_BITS_PER_WIDE_INT)
8389 byte = (lo >> s) & 0xff;
8390 else
8391 byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
8392
8393 if (d < HOST_BITS_PER_WIDE_INT)
8394 r_lo |= byte << d;
8395 else
8396 r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
8397 }
8398 }
8399
8400 break;
8401
8402 default:
8403 gcc_unreachable ();
8404 }
8405
8406 if (width < HOST_BITS_PER_WIDE_INT)
8407 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo);
8408 else
8409 return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi);
8410 }
8411
8412 return NULL_TREE;
8413}
c2f47e15 8414
8918c507 8415/* A subroutine of fold_builtin to fold the various logarithmic
29f4cd78 8416 functions. Return NULL_TREE if no simplification can me made.
8417 FUNC is the corresponding MPFR logarithm function. */
8918c507 8418
8419static tree
c2f47e15 8420fold_builtin_logarithm (tree fndecl, tree arg,
29f4cd78 8421 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8918c507 8422{
c2f47e15 8423 if (validate_arg (arg, REAL_TYPE))
8918c507 8424 {
8918c507 8425 tree type = TREE_TYPE (TREE_TYPE (fndecl));
29f4cd78 8426 tree res;
8918c507 8427 const enum built_in_function fcode = builtin_mathfn_code (arg);
0862b7e9 8428
29f4cd78 8429 /* Calculate the result when the argument is a constant. */
8430 if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
8431 return res;
8432
8918c507 8433 /* Special case, optimize logN(expN(x)) = x. */
8434 if (flag_unsafe_math_optimizations
29f4cd78 8435 && ((func == mpfr_log
8918c507 8436 && (fcode == BUILT_IN_EXP
8437 || fcode == BUILT_IN_EXPF
8438 || fcode == BUILT_IN_EXPL))
29f4cd78 8439 || (func == mpfr_log2
8918c507 8440 && (fcode == BUILT_IN_EXP2
8441 || fcode == BUILT_IN_EXP2F
8442 || fcode == BUILT_IN_EXP2L))
29f4cd78 8443 || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
c2f47e15 8444 return fold_convert (type, CALL_EXPR_ARG (arg, 0));
8918c507 8445
ca273d4a 8446 /* Optimize logN(func()) for various exponential functions. We
a0c938f0 8447 want to determine the value "x" and the power "exponent" in
8448 order to transform logN(x**exponent) into exponent*logN(x). */
8918c507 8449 if (flag_unsafe_math_optimizations)
a0c938f0 8450 {
8918c507 8451 tree exponent = 0, x = 0;
0862b7e9 8452
8918c507 8453 switch (fcode)
8454 {
4f35b1fc 8455 CASE_FLT_FN (BUILT_IN_EXP):
8918c507 8456 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7910b2fb 8457 x = build_real (type, real_value_truncate (TYPE_MODE (type),
8458 dconst_e ()));
c2f47e15 8459 exponent = CALL_EXPR_ARG (arg, 0);
8918c507 8460 break;
4f35b1fc 8461 CASE_FLT_FN (BUILT_IN_EXP2):
8918c507 8462 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
8463 x = build_real (type, dconst2);
c2f47e15 8464 exponent = CALL_EXPR_ARG (arg, 0);
8918c507 8465 break;
4f35b1fc 8466 CASE_FLT_FN (BUILT_IN_EXP10):
8467 CASE_FLT_FN (BUILT_IN_POW10):
8918c507 8468 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
3fa759a9 8469 {
8470 REAL_VALUE_TYPE dconst10;
8471 real_from_integer (&dconst10, VOIDmode, 10, 0, 0);
8472 x = build_real (type, dconst10);
8473 }
c2f47e15 8474 exponent = CALL_EXPR_ARG (arg, 0);
8918c507 8475 break;
4f35b1fc 8476 CASE_FLT_FN (BUILT_IN_SQRT):
8918c507 8477 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
c2f47e15 8478 x = CALL_EXPR_ARG (arg, 0);
8918c507 8479 exponent = build_real (type, dconsthalf);
8480 break;
4f35b1fc 8481 CASE_FLT_FN (BUILT_IN_CBRT):
8918c507 8482 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
c2f47e15 8483 x = CALL_EXPR_ARG (arg, 0);
8918c507 8484 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7910b2fb 8485 dconst_third ()));
8918c507 8486 break;
4f35b1fc 8487 CASE_FLT_FN (BUILT_IN_POW):
8918c507 8488 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
c2f47e15 8489 x = CALL_EXPR_ARG (arg, 0);
8490 exponent = CALL_EXPR_ARG (arg, 1);
8918c507 8491 break;
8492 default:
8493 break;
8494 }
8495
8496 /* Now perform the optimization. */
8497 if (x && exponent)
8498 {
c2f47e15 8499 tree logfn = build_call_expr (fndecl, 1, x);
49d00087 8500 return fold_build2 (MULT_EXPR, type, exponent, logfn);
8918c507 8501 }
8502 }
8503 }
8504
c2f47e15 8505 return NULL_TREE;
8918c507 8506}
0862b7e9 8507
f0c477f2 8508/* Fold a builtin function call to hypot, hypotf, or hypotl. Return
8509 NULL_TREE if no simplification can be made. */
8510
8511static tree
c2f47e15 8512fold_builtin_hypot (tree fndecl, tree arg0, tree arg1, tree type)
f0c477f2 8513{
e6ab33d8 8514 tree res, narg0, narg1;
f0c477f2 8515
c2f47e15 8516 if (!validate_arg (arg0, REAL_TYPE)
8517 || !validate_arg (arg1, REAL_TYPE))
f0c477f2 8518 return NULL_TREE;
8519
8520 /* Calculate the result when the argument is a constant. */
8521 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
8522 return res;
8523
6c95f21c 8524 /* If either argument to hypot has a negate or abs, strip that off.
8525 E.g. hypot(-x,fabs(y)) -> hypot(x,y). */
e6ab33d8 8526 narg0 = fold_strip_sign_ops (arg0);
8527 narg1 = fold_strip_sign_ops (arg1);
8528 if (narg0 || narg1)
8529 {
c2f47e15 8530 return build_call_expr (fndecl, 2, narg0 ? narg0 : arg0,
8531 narg1 ? narg1 : arg1);
6c95f21c 8532 }
8533
f0c477f2 8534 /* If either argument is zero, hypot is fabs of the other. */
8535 if (real_zerop (arg0))
8536 return fold_build1 (ABS_EXPR, type, arg1);
8537 else if (real_zerop (arg1))
8538 return fold_build1 (ABS_EXPR, type, arg0);
8539
6c95f21c 8540 /* hypot(x,x) -> fabs(x)*sqrt(2). */
8541 if (flag_unsafe_math_optimizations
8542 && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
f0c477f2 8543 {
2e7ca27b 8544 const REAL_VALUE_TYPE sqrt2_trunc
7910b2fb 8545 = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
6c95f21c 8546 return fold_build2 (MULT_EXPR, type,
8547 fold_build1 (ABS_EXPR, type, arg0),
2e7ca27b 8548 build_real (type, sqrt2_trunc));
f0c477f2 8549 }
8550
f0c477f2 8551 return NULL_TREE;
8552}
8553
8554
e6e27594 8555/* Fold a builtin function call to pow, powf, or powl. Return
8556 NULL_TREE if no simplification can be made. */
8557static tree
c2f47e15 8558fold_builtin_pow (tree fndecl, tree arg0, tree arg1, tree type)
e6e27594 8559{
f0c477f2 8560 tree res;
e6e27594 8561
c2f47e15 8562 if (!validate_arg (arg0, REAL_TYPE)
8563 || !validate_arg (arg1, REAL_TYPE))
e6e27594 8564 return NULL_TREE;
8565
f0c477f2 8566 /* Calculate the result when the argument is a constant. */
8567 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
8568 return res;
8569
e6e27594 8570 /* Optimize pow(1.0,y) = 1.0. */
8571 if (real_onep (arg0))
8572 return omit_one_operand (type, build_real (type, dconst1), arg1);
8573
8574 if (TREE_CODE (arg1) == REAL_CST
f96bd2bf 8575 && !TREE_OVERFLOW (arg1))
e6e27594 8576 {
198d9bbe 8577 REAL_VALUE_TYPE cint;
e6e27594 8578 REAL_VALUE_TYPE c;
198d9bbe 8579 HOST_WIDE_INT n;
8580
e6e27594 8581 c = TREE_REAL_CST (arg1);
8582
8583 /* Optimize pow(x,0.0) = 1.0. */
8584 if (REAL_VALUES_EQUAL (c, dconst0))
8585 return omit_one_operand (type, build_real (type, dconst1),
8586 arg0);
8587
8588 /* Optimize pow(x,1.0) = x. */
8589 if (REAL_VALUES_EQUAL (c, dconst1))
8590 return arg0;
8591
8592 /* Optimize pow(x,-1.0) = 1.0/x. */
8593 if (REAL_VALUES_EQUAL (c, dconstm1))
49d00087 8594 return fold_build2 (RDIV_EXPR, type,
8595 build_real (type, dconst1), arg0);
e6e27594 8596
8597 /* Optimize pow(x,0.5) = sqrt(x). */
8598 if (flag_unsafe_math_optimizations
8599 && REAL_VALUES_EQUAL (c, dconsthalf))
8600 {
8601 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8602
8603 if (sqrtfn != NULL_TREE)
c2f47e15 8604 return build_call_expr (sqrtfn, 1, arg0);
e6e27594 8605 }
8606
feb5b3eb 8607 /* Optimize pow(x,1.0/3.0) = cbrt(x). */
8608 if (flag_unsafe_math_optimizations)
8609 {
8610 const REAL_VALUE_TYPE dconstroot
7910b2fb 8611 = real_value_truncate (TYPE_MODE (type), dconst_third ());
feb5b3eb 8612
8613 if (REAL_VALUES_EQUAL (c, dconstroot))
8614 {
8615 tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
8616 if (cbrtfn != NULL_TREE)
c2f47e15 8617 return build_call_expr (cbrtfn, 1, arg0);
feb5b3eb 8618 }
8619 }
8620
198d9bbe 8621 /* Check for an integer exponent. */
8622 n = real_to_integer (&c);
8623 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
8624 if (real_identical (&c, &cint))
e6e27594 8625 {
a2b30b48 8626 /* Attempt to evaluate pow at compile-time, unless this should
8627 raise an exception. */
198d9bbe 8628 if (TREE_CODE (arg0) == REAL_CST
a2b30b48 8629 && !TREE_OVERFLOW (arg0)
8630 && (n > 0
8631 || (!flag_trapping_math && !flag_errno_math)
8632 || !REAL_VALUES_EQUAL (TREE_REAL_CST (arg0), dconst0)))
e6e27594 8633 {
8634 REAL_VALUE_TYPE x;
8635 bool inexact;
8636
8637 x = TREE_REAL_CST (arg0);
8638 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8639 if (flag_unsafe_math_optimizations || !inexact)
8640 return build_real (type, x);
8641 }
198d9bbe 8642
8643 /* Strip sign ops from even integer powers. */
8644 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
8645 {
8646 tree narg0 = fold_strip_sign_ops (arg0);
8647 if (narg0)
c2f47e15 8648 return build_call_expr (fndecl, 2, narg0, arg1);
198d9bbe 8649 }
e6e27594 8650 }
8651 }
8652
cdfeb715 8653 if (flag_unsafe_math_optimizations)
e6e27594 8654 {
cdfeb715 8655 const enum built_in_function fcode = builtin_mathfn_code (arg0);
e6e27594 8656
cdfeb715 8657 /* Optimize pow(expN(x),y) = expN(x*y). */
8658 if (BUILTIN_EXPONENT_P (fcode))
a0c938f0 8659 {
c2f47e15 8660 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0);
8661 tree arg = CALL_EXPR_ARG (arg0, 0);
49d00087 8662 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
c2f47e15 8663 return build_call_expr (expfn, 1, arg);
cdfeb715 8664 }
e6e27594 8665
cdfeb715 8666 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
8667 if (BUILTIN_SQRT_P (fcode))
a0c938f0 8668 {
c2f47e15 8669 tree narg0 = CALL_EXPR_ARG (arg0, 0);
49d00087 8670 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
8671 build_real (type, dconsthalf));
c2f47e15 8672 return build_call_expr (fndecl, 2, narg0, narg1);
cdfeb715 8673 }
8674
8675 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
8676 if (BUILTIN_CBRT_P (fcode))
a0c938f0 8677 {
c2f47e15 8678 tree arg = CALL_EXPR_ARG (arg0, 0);
cdfeb715 8679 if (tree_expr_nonnegative_p (arg))
8680 {
8681 const REAL_VALUE_TYPE dconstroot
7910b2fb 8682 = real_value_truncate (TYPE_MODE (type), dconst_third ());
49d00087 8683 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
8684 build_real (type, dconstroot));
c2f47e15 8685 return build_call_expr (fndecl, 2, arg, narg1);
cdfeb715 8686 }
8687 }
a0c938f0 8688
cdfeb715 8689 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
c2f47e15 8690 if (fcode == BUILT_IN_POW
8691 || fcode == BUILT_IN_POWF
8692 || fcode == BUILT_IN_POWL)
a0c938f0 8693 {
c2f47e15 8694 tree arg00 = CALL_EXPR_ARG (arg0, 0);
8695 tree arg01 = CALL_EXPR_ARG (arg0, 1);
49d00087 8696 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
c2f47e15 8697 return build_call_expr (fndecl, 2, arg00, narg1);
cdfeb715 8698 }
e6e27594 8699 }
cdfeb715 8700
e6e27594 8701 return NULL_TREE;
8702}
8703
c2f47e15 8704/* Fold a builtin function call to powi, powif, or powil with argument ARG.
8705 Return NULL_TREE if no simplification can be made. */
b4d0c20c 8706static tree
c2f47e15 8707fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED,
8708 tree arg0, tree arg1, tree type)
b4d0c20c 8709{
c2f47e15 8710 if (!validate_arg (arg0, REAL_TYPE)
8711 || !validate_arg (arg1, INTEGER_TYPE))
b4d0c20c 8712 return NULL_TREE;
8713
8714 /* Optimize pow(1.0,y) = 1.0. */
8715 if (real_onep (arg0))
8716 return omit_one_operand (type, build_real (type, dconst1), arg1);
8717
8718 if (host_integerp (arg1, 0))
8719 {
8720 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
8721
8722 /* Evaluate powi at compile-time. */
8723 if (TREE_CODE (arg0) == REAL_CST
f96bd2bf 8724 && !TREE_OVERFLOW (arg0))
b4d0c20c 8725 {
8726 REAL_VALUE_TYPE x;
8727 x = TREE_REAL_CST (arg0);
8728 real_powi (&x, TYPE_MODE (type), &x, c);
8729 return build_real (type, x);
8730 }
8731
8732 /* Optimize pow(x,0) = 1.0. */
8733 if (c == 0)
8734 return omit_one_operand (type, build_real (type, dconst1),
8735 arg0);
8736
8737 /* Optimize pow(x,1) = x. */
8738 if (c == 1)
8739 return arg0;
8740
8741 /* Optimize pow(x,-1) = 1.0/x. */
8742 if (c == -1)
49d00087 8743 return fold_build2 (RDIV_EXPR, type,
8744 build_real (type, dconst1), arg0);
b4d0c20c 8745 }
8746
8747 return NULL_TREE;
8748}
8749
8918c507 8750/* A subroutine of fold_builtin to fold the various exponent
c2f47e15 8751 functions. Return NULL_TREE if no simplification can be made.
debf9994 8752 FUNC is the corresponding MPFR exponent function. */
8918c507 8753
8754static tree
c2f47e15 8755fold_builtin_exponent (tree fndecl, tree arg,
debf9994 8756 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8918c507 8757{
c2f47e15 8758 if (validate_arg (arg, REAL_TYPE))
8918c507 8759 {
8918c507 8760 tree type = TREE_TYPE (TREE_TYPE (fndecl));
29f4cd78 8761 tree res;
debf9994 8762
8763 /* Calculate the result when the argument is a constant. */
728bac60 8764 if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
debf9994 8765 return res;
8918c507 8766
8767 /* Optimize expN(logN(x)) = x. */
8768 if (flag_unsafe_math_optimizations)
a0c938f0 8769 {
8918c507 8770 const enum built_in_function fcode = builtin_mathfn_code (arg);
8771
debf9994 8772 if ((func == mpfr_exp
8918c507 8773 && (fcode == BUILT_IN_LOG
8774 || fcode == BUILT_IN_LOGF
8775 || fcode == BUILT_IN_LOGL))
debf9994 8776 || (func == mpfr_exp2
8918c507 8777 && (fcode == BUILT_IN_LOG2
8778 || fcode == BUILT_IN_LOG2F
8779 || fcode == BUILT_IN_LOG2L))
debf9994 8780 || (func == mpfr_exp10
8918c507 8781 && (fcode == BUILT_IN_LOG10
8782 || fcode == BUILT_IN_LOG10F
8783 || fcode == BUILT_IN_LOG10L)))
c2f47e15 8784 return fold_convert (type, CALL_EXPR_ARG (arg, 0));
8918c507 8785 }
8786 }
8787
c2f47e15 8788 return NULL_TREE;
8918c507 8789}
8790
e973ffcc 8791/* Return true if VAR is a VAR_DECL or a component thereof. */
8792
8793static bool
8794var_decl_component_p (tree var)
8795{
8796 tree inner = var;
8797 while (handled_component_p (inner))
8798 inner = TREE_OPERAND (inner, 0);
8799 return SSA_VAR_P (inner);
8800}
8801
4f46f2b9 8802/* Fold function call to builtin memset. Return
9c8a1629 8803 NULL_TREE if no simplification can be made. */
8804
8805static tree
c2f47e15 8806fold_builtin_memset (tree dest, tree c, tree len, tree type, bool ignore)
9c8a1629 8807{
45bb3afb 8808 tree var, ret, etype;
4f46f2b9 8809 unsigned HOST_WIDE_INT length, cval;
9c8a1629 8810
c2f47e15 8811 if (! validate_arg (dest, POINTER_TYPE)
8812 || ! validate_arg (c, INTEGER_TYPE)
8813 || ! validate_arg (len, INTEGER_TYPE))
8814 return NULL_TREE;
9c8a1629 8815
4f46f2b9 8816 if (! host_integerp (len, 1))
c2f47e15 8817 return NULL_TREE;
4f46f2b9 8818
9c8a1629 8819 /* If the LEN parameter is zero, return DEST. */
8820 if (integer_zerop (len))
4f46f2b9 8821 return omit_one_operand (type, dest, c);
9c8a1629 8822
4f46f2b9 8823 if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
c2f47e15 8824 return NULL_TREE;
9c8a1629 8825
4f46f2b9 8826 var = dest;
8827 STRIP_NOPS (var);
8828 if (TREE_CODE (var) != ADDR_EXPR)
c2f47e15 8829 return NULL_TREE;
4f46f2b9 8830
8831 var = TREE_OPERAND (var, 0);
8832 if (TREE_THIS_VOLATILE (var))
c2f47e15 8833 return NULL_TREE;
4f46f2b9 8834
45bb3afb 8835 etype = TREE_TYPE (var);
8836 if (TREE_CODE (etype) == ARRAY_TYPE)
8837 etype = TREE_TYPE (etype);
8838
8839 if (!INTEGRAL_TYPE_P (etype)
8840 && !POINTER_TYPE_P (etype))
c2f47e15 8841 return NULL_TREE;
4f46f2b9 8842
e973ffcc 8843 if (! var_decl_component_p (var))
c2f47e15 8844 return NULL_TREE;
e973ffcc 8845
4f46f2b9 8846 length = tree_low_cst (len, 1);
45bb3afb 8847 if (GET_MODE_SIZE (TYPE_MODE (etype)) != length
4f46f2b9 8848 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8849 < (int) length)
c2f47e15 8850 return NULL_TREE;
4f46f2b9 8851
8852 if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
c2f47e15 8853 return NULL_TREE;
4f46f2b9 8854
8855 if (integer_zerop (c))
8856 cval = 0;
8857 else
8858 {
8859 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
c2f47e15 8860 return NULL_TREE;
4f46f2b9 8861
8862 cval = tree_low_cst (c, 1);
8863 cval &= 0xff;
8864 cval |= cval << 8;
8865 cval |= cval << 16;
8866 cval |= (cval << 31) << 1;
8867 }
8868
45bb3afb 8869 ret = build_int_cst_type (etype, cval);
8870 var = build_fold_indirect_ref (fold_convert (build_pointer_type (etype),
8871 dest));
8872 ret = build2 (MODIFY_EXPR, etype, var, ret);
4f46f2b9 8873 if (ignore)
8874 return ret;
8875
8876 return omit_one_operand (type, dest, ret);
9c8a1629 8877}
8878
4f46f2b9 8879/* Fold function call to builtin memset. Return
9c8a1629 8880 NULL_TREE if no simplification can be made. */
8881
8882static tree
c2f47e15 8883fold_builtin_bzero (tree dest, tree size, bool ignore)
9c8a1629 8884{
c2f47e15 8885 if (! validate_arg (dest, POINTER_TYPE)
8886 || ! validate_arg (size, INTEGER_TYPE))
8887 return NULL_TREE;
9c8a1629 8888
4f46f2b9 8889 if (!ignore)
c2f47e15 8890 return NULL_TREE;
a0c938f0 8891
4f46f2b9 8892 /* New argument list transforming bzero(ptr x, int y) to
8893 memset(ptr x, int 0, size_t y). This is done this way
8894 so that if it isn't expanded inline, we fallback to
8895 calling bzero instead of memset. */
8896
c2f47e15 8897 return fold_builtin_memset (dest, integer_zero_node,
8898 fold_convert (sizetype, size),
8899 void_type_node, ignore);
9c8a1629 8900}
8901
4f46f2b9 8902/* Fold function call to builtin mem{{,p}cpy,move}. Return
8903 NULL_TREE if no simplification can be made.
8904 If ENDP is 0, return DEST (like memcpy).
8905 If ENDP is 1, return DEST+LEN (like mempcpy).
8906 If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8907 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8908 (memmove). */
9c8a1629 8909
8910static tree
c2f47e15 8911fold_builtin_memory_op (tree dest, tree src, tree len, tree type, bool ignore, int endp)
9c8a1629 8912{
c2f47e15 8913 tree destvar, srcvar, expr;
9c8a1629 8914
c2f47e15 8915 if (! validate_arg (dest, POINTER_TYPE)
8916 || ! validate_arg (src, POINTER_TYPE)
8917 || ! validate_arg (len, INTEGER_TYPE))
8918 return NULL_TREE;
9c8a1629 8919
8920 /* If the LEN parameter is zero, return DEST. */
8921 if (integer_zerop (len))
7e72af53 8922 return omit_one_operand (type, dest, src);
9c8a1629 8923
4f46f2b9 8924 /* If SRC and DEST are the same (and not volatile), return
8925 DEST{,+LEN,+LEN-1}. */
9c8a1629 8926 if (operand_equal_p (src, dest, 0))
4f46f2b9 8927 expr = len;
8928 else
8929 {
5a84fdd6 8930 tree srctype, desttype;
5383fb56 8931 int src_align, dest_align;
8932
3b1757a2 8933 if (endp == 3)
8934 {
5383fb56 8935 src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
8936 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
5a84fdd6 8937
3b1757a2 8938 /* Both DEST and SRC must be pointer types.
8939 ??? This is what old code did. Is the testing for pointer types
8940 really mandatory?
8941
8942 If either SRC is readonly or length is 1, we can use memcpy. */
3f95c690 8943 if (!dest_align || !src_align)
8944 return NULL_TREE;
8945 if (readonly_data_expr (src)
8946 || (host_integerp (len, 1)
8947 && (MIN (src_align, dest_align) / BITS_PER_UNIT
8948 >= tree_low_cst (len, 1))))
3b1757a2 8949 {
8950 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8951 if (!fn)
c2f47e15 8952 return NULL_TREE;
8953 return build_call_expr (fn, 3, dest, src, len);
3b1757a2 8954 }
3f95c690 8955
8956 /* If *src and *dest can't overlap, optimize into memcpy as well. */
8957 srcvar = build_fold_indirect_ref (src);
8958 destvar = build_fold_indirect_ref (dest);
8959 if (srcvar
8960 && !TREE_THIS_VOLATILE (srcvar)
8961 && destvar
8962 && !TREE_THIS_VOLATILE (destvar))
8963 {
8964 tree src_base, dest_base, fn;
8965 HOST_WIDE_INT src_offset = 0, dest_offset = 0;
8966 HOST_WIDE_INT size = -1;
8967 HOST_WIDE_INT maxsize = -1;
8968
8969 src_base = srcvar;
8970 if (handled_component_p (src_base))
8971 src_base = get_ref_base_and_extent (src_base, &src_offset,
8972 &size, &maxsize);
8973 dest_base = destvar;
8974 if (handled_component_p (dest_base))
8975 dest_base = get_ref_base_and_extent (dest_base, &dest_offset,
8976 &size, &maxsize);
8977 if (host_integerp (len, 1))
8978 {
8979 maxsize = tree_low_cst (len, 1);
8980 if (maxsize
8981 > INTTYPE_MAXIMUM (HOST_WIDE_INT) / BITS_PER_UNIT)
8982 maxsize = -1;
8983 else
8984 maxsize *= BITS_PER_UNIT;
8985 }
8986 else
8987 maxsize = -1;
8988 if (SSA_VAR_P (src_base)
8989 && SSA_VAR_P (dest_base))
8990 {
8991 if (operand_equal_p (src_base, dest_base, 0)
8992 && ranges_overlap_p (src_offset, maxsize,
8993 dest_offset, maxsize))
8994 return NULL_TREE;
8995 }
8996 else if (TREE_CODE (src_base) == INDIRECT_REF
8997 && TREE_CODE (dest_base) == INDIRECT_REF)
8998 {
8999 if (! operand_equal_p (TREE_OPERAND (src_base, 0),
9000 TREE_OPERAND (dest_base, 0), 0)
9001 || ranges_overlap_p (src_offset, maxsize,
9002 dest_offset, maxsize))
9003 return NULL_TREE;
9004 }
9005 else
9006 return NULL_TREE;
9007
9008 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
9009 if (!fn)
9010 return NULL_TREE;
9011 return build_call_expr (fn, 3, dest, src, len);
9012 }
c2f47e15 9013 return NULL_TREE;
3b1757a2 9014 }
4f46f2b9 9015
5a84fdd6 9016 if (!host_integerp (len, 0))
c2f47e15 9017 return NULL_TREE;
5a84fdd6 9018 /* FIXME:
9019 This logic lose for arguments like (type *)malloc (sizeof (type)),
9020 since we strip the casts of up to VOID return value from malloc.
9021 Perhaps we ought to inherit type from non-VOID argument here? */
9022 STRIP_NOPS (src);
9023 STRIP_NOPS (dest);
45bb3afb 9024 /* As we fold (void *)(p + CST) to (void *)p + CST undo this here. */
9025 if (TREE_CODE (src) == POINTER_PLUS_EXPR)
9026 {
9027 tree tem = TREE_OPERAND (src, 0);
9028 STRIP_NOPS (tem);
9029 if (tem != TREE_OPERAND (src, 0))
9030 src = build1 (NOP_EXPR, TREE_TYPE (tem), src);
9031 }
9032 if (TREE_CODE (dest) == POINTER_PLUS_EXPR)
9033 {
9034 tree tem = TREE_OPERAND (dest, 0);
9035 STRIP_NOPS (tem);
9036 if (tem != TREE_OPERAND (dest, 0))
9037 dest = build1 (NOP_EXPR, TREE_TYPE (tem), dest);
9038 }
5a84fdd6 9039 srctype = TREE_TYPE (TREE_TYPE (src));
45bb3afb 9040 if (srctype
97d4c6a6 9041 && TREE_CODE (srctype) == ARRAY_TYPE
9042 && !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
45bb3afb 9043 {
9044 srctype = TREE_TYPE (srctype);
9045 STRIP_NOPS (src);
9046 src = build1 (NOP_EXPR, build_pointer_type (srctype), src);
9047 }
5a84fdd6 9048 desttype = TREE_TYPE (TREE_TYPE (dest));
45bb3afb 9049 if (desttype
97d4c6a6 9050 && TREE_CODE (desttype) == ARRAY_TYPE
9051 && !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
45bb3afb 9052 {
9053 desttype = TREE_TYPE (desttype);
9054 STRIP_NOPS (dest);
9055 dest = build1 (NOP_EXPR, build_pointer_type (desttype), dest);
9056 }
5a84fdd6 9057 if (!srctype || !desttype
9058 || !TYPE_SIZE_UNIT (srctype)
9059 || !TYPE_SIZE_UNIT (desttype)
9060 || TREE_CODE (TYPE_SIZE_UNIT (srctype)) != INTEGER_CST
6f52ebeb 9061 || TREE_CODE (TYPE_SIZE_UNIT (desttype)) != INTEGER_CST
9062 || TYPE_VOLATILE (srctype)
9063 || TYPE_VOLATILE (desttype))
c2f47e15 9064 return NULL_TREE;
4f46f2b9 9065
5383fb56 9066 src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
9067 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
9068 if (dest_align < (int) TYPE_ALIGN (desttype)
9069 || src_align < (int) TYPE_ALIGN (srctype))
c2f47e15 9070 return NULL_TREE;
e973ffcc 9071
5a84fdd6 9072 if (!ignore)
9073 dest = builtin_save_expr (dest);
4f46f2b9 9074
5383fb56 9075 srcvar = NULL_TREE;
9076 if (tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
9077 {
9078 srcvar = build_fold_indirect_ref (src);
9079 if (TREE_THIS_VOLATILE (srcvar))
6f52ebeb 9080 return NULL_TREE;
5383fb56 9081 else if (!tree_int_cst_equal (lang_hooks.expr_size (srcvar), len))
9082 srcvar = NULL_TREE;
9083 /* With memcpy, it is possible to bypass aliasing rules, so without
9084 this check i.e. execute/20060930-2.c would be misoptimized,
9085 because it use conflicting alias set to hold argument for the
9086 memcpy call. This check is probably unnecessary with
9087 -fno-strict-aliasing. Similarly for destvar. See also
9088 PR29286. */
9089 else if (!var_decl_component_p (srcvar))
9090 srcvar = NULL_TREE;
9091 }
4f46f2b9 9092
5383fb56 9093 destvar = NULL_TREE;
9094 if (tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
9095 {
9096 destvar = build_fold_indirect_ref (dest);
9097 if (TREE_THIS_VOLATILE (destvar))
6f52ebeb 9098 return NULL_TREE;
5383fb56 9099 else if (!tree_int_cst_equal (lang_hooks.expr_size (destvar), len))
9100 destvar = NULL_TREE;
9101 else if (!var_decl_component_p (destvar))
9102 destvar = NULL_TREE;
9103 }
9104
9105 if (srcvar == NULL_TREE && destvar == NULL_TREE)
c2f47e15 9106 return NULL_TREE;
4f46f2b9 9107
5383fb56 9108 if (srcvar == NULL_TREE)
9109 {
9110 tree srcptype;
9111 if (TREE_ADDRESSABLE (TREE_TYPE (destvar)))
9112 return NULL_TREE;
9113
6f52ebeb 9114 srctype = build_qualified_type (desttype, 0);
5383fb56 9115 if (src_align < (int) TYPE_ALIGN (srctype))
9116 {
9117 if (AGGREGATE_TYPE_P (srctype)
9118 || SLOW_UNALIGNED_ACCESS (TYPE_MODE (srctype), src_align))
9119 return NULL_TREE;
9120
9121 srctype = build_variant_type_copy (srctype);
9122 TYPE_ALIGN (srctype) = src_align;
9123 TYPE_USER_ALIGN (srctype) = 1;
9124 TYPE_PACKED (srctype) = 1;
9125 }
9126 srcptype = build_pointer_type_for_mode (srctype, ptr_mode, true);
9127 src = fold_convert (srcptype, src);
9128 srcvar = build_fold_indirect_ref (src);
9129 }
9130 else if (destvar == NULL_TREE)
9131 {
9132 tree destptype;
9133 if (TREE_ADDRESSABLE (TREE_TYPE (srcvar)))
9134 return NULL_TREE;
9135
6f52ebeb 9136 desttype = build_qualified_type (srctype, 0);
5383fb56 9137 if (dest_align < (int) TYPE_ALIGN (desttype))
9138 {
9139 if (AGGREGATE_TYPE_P (desttype)
9140 || SLOW_UNALIGNED_ACCESS (TYPE_MODE (desttype), dest_align))
9141 return NULL_TREE;
9142
9143 desttype = build_variant_type_copy (desttype);
9144 TYPE_ALIGN (desttype) = dest_align;
9145 TYPE_USER_ALIGN (desttype) = 1;
9146 TYPE_PACKED (desttype) = 1;
9147 }
9148 destptype = build_pointer_type_for_mode (desttype, ptr_mode, true);
9149 dest = fold_convert (destptype, dest);
9150 destvar = build_fold_indirect_ref (dest);
9151 }
9152
5a84fdd6 9153 if (srctype == desttype
2d04fd8d 9154 || (gimple_in_ssa_p (cfun)
548044d8 9155 && useless_type_conversion_p (desttype, srctype)))
5a84fdd6 9156 expr = srcvar;
9157 else if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
4f46f2b9 9158 || POINTER_TYPE_P (TREE_TYPE (srcvar)))
9159 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
9160 || POINTER_TYPE_P (TREE_TYPE (destvar))))
9161 expr = fold_convert (TREE_TYPE (destvar), srcvar);
9162 else
9163 expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar);
41076ef6 9164 expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, expr);
4f46f2b9 9165 }
9166
9167 if (ignore)
9168 return expr;
9169
9170 if (endp == 0 || endp == 3)
9171 return omit_one_operand (type, dest, expr);
9172
9173 if (expr == len)
c2f47e15 9174 expr = NULL_TREE;
4f46f2b9 9175
9176 if (endp == 2)
9177 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
9178 ssize_int (1));
9179
f5fec377 9180 len = fold_convert (sizetype, len);
0de36bdb 9181 dest = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
4f46f2b9 9182 dest = fold_convert (type, dest);
9183 if (expr)
9184 dest = omit_one_operand (type, dest, expr);
9185 return dest;
9186}
9187
c2f47e15 9188/* Fold function call to builtin strcpy with arguments DEST and SRC.
9189 If LEN is not NULL, it represents the length of the string to be
9190 copied. Return NULL_TREE if no simplification can be made. */
9c8a1629 9191
f0613857 9192tree
c2f47e15 9193fold_builtin_strcpy (tree fndecl, tree dest, tree src, tree len)
9c8a1629 9194{
c2f47e15 9195 tree fn;
9c8a1629 9196
c2f47e15 9197 if (!validate_arg (dest, POINTER_TYPE)
9198 || !validate_arg (src, POINTER_TYPE))
9199 return NULL_TREE;
9c8a1629 9200
9201 /* If SRC and DEST are the same (and not volatile), return DEST. */
9202 if (operand_equal_p (src, dest, 0))
2426241c 9203 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
9c8a1629 9204
0bfd8d5c 9205 if (optimize_function_for_size_p (cfun))
c2f47e15 9206 return NULL_TREE;
f0613857 9207
9208 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
9209 if (!fn)
c2f47e15 9210 return NULL_TREE;
f0613857 9211
9212 if (!len)
9213 {
9214 len = c_strlen (src, 1);
9215 if (! len || TREE_SIDE_EFFECTS (len))
c2f47e15 9216 return NULL_TREE;
f0613857 9217 }
9218
9219 len = size_binop (PLUS_EXPR, len, ssize_int (1));
2426241c 9220 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
c2f47e15 9221 build_call_expr (fn, 3, dest, src, len));
9c8a1629 9222}
9223
c2f47e15 9224/* Fold function call to builtin strncpy with arguments DEST, SRC, and LEN.
9225 If SLEN is not NULL, it represents the length of the source string.
9226 Return NULL_TREE if no simplification can be made. */
9c8a1629 9227
f0613857 9228tree
c2f47e15 9229fold_builtin_strncpy (tree fndecl, tree dest, tree src, tree len, tree slen)
9c8a1629 9230{
c2f47e15 9231 tree fn;
9c8a1629 9232
c2f47e15 9233 if (!validate_arg (dest, POINTER_TYPE)
9234 || !validate_arg (src, POINTER_TYPE)
9235 || !validate_arg (len, INTEGER_TYPE))
9236 return NULL_TREE;
9c8a1629 9237
9238 /* If the LEN parameter is zero, return DEST. */
9239 if (integer_zerop (len))
2426241c 9240 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
9c8a1629 9241
19226313 9242 /* We can't compare slen with len as constants below if len is not a
9243 constant. */
9244 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
c2f47e15 9245 return NULL_TREE;
19226313 9246
f0613857 9247 if (!slen)
9248 slen = c_strlen (src, 1);
9249
9250 /* Now, we must be passed a constant src ptr parameter. */
9251 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
c2f47e15 9252 return NULL_TREE;
f0613857 9253
9254 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
9255
9256 /* We do not support simplification of this case, though we do
9257 support it when expanding trees into RTL. */
9258 /* FIXME: generate a call to __builtin_memset. */
9259 if (tree_int_cst_lt (slen, len))
c2f47e15 9260 return NULL_TREE;
f0613857 9261
9262 /* OK transform into builtin memcpy. */
9263 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
9264 if (!fn)
c2f47e15 9265 return NULL_TREE;
2426241c 9266 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
c2f47e15 9267 build_call_expr (fn, 3, dest, src, len));
9c8a1629 9268}
9269
7959b13b 9270/* Fold function call to builtin memchr. ARG1, ARG2 and LEN are the
9271 arguments to the call, and TYPE is its return type.
9272 Return NULL_TREE if no simplification can be made. */
9273
9274static tree
9275fold_builtin_memchr (tree arg1, tree arg2, tree len, tree type)
9276{
9277 if (!validate_arg (arg1, POINTER_TYPE)
9278 || !validate_arg (arg2, INTEGER_TYPE)
9279 || !validate_arg (len, INTEGER_TYPE))
9280 return NULL_TREE;
9281 else
9282 {
9283 const char *p1;
9284
9285 if (TREE_CODE (arg2) != INTEGER_CST
9286 || !host_integerp (len, 1))
9287 return NULL_TREE;
9288
9289 p1 = c_getstr (arg1);
9290 if (p1 && compare_tree_int (len, strlen (p1) + 1) <= 0)
9291 {
9292 char c;
9293 const char *r;
9294 tree tem;
9295
9296 if (target_char_cast (arg2, &c))
9297 return NULL_TREE;
9298
364c0c59 9299 r = (char *) memchr (p1, c, tree_low_cst (len, 1));
7959b13b 9300
9301 if (r == NULL)
9302 return build_int_cst (TREE_TYPE (arg1), 0);
9303
0de36bdb 9304 tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (arg1), arg1,
9305 size_int (r - p1));
7959b13b 9306 return fold_convert (type, tem);
9307 }
9308 return NULL_TREE;
9309 }
9310}
9311
c2f47e15 9312/* Fold function call to builtin memcmp with arguments ARG1 and ARG2.
9313 Return NULL_TREE if no simplification can be made. */
9c8a1629 9314
9315static tree
c2f47e15 9316fold_builtin_memcmp (tree arg1, tree arg2, tree len)
9c8a1629 9317{
c4fef134 9318 const char *p1, *p2;
9c8a1629 9319
c2f47e15 9320 if (!validate_arg (arg1, POINTER_TYPE)
9321 || !validate_arg (arg2, POINTER_TYPE)
9322 || !validate_arg (len, INTEGER_TYPE))
9323 return NULL_TREE;
9c8a1629 9324
9325 /* If the LEN parameter is zero, return zero. */
9326 if (integer_zerop (len))
c4fef134 9327 return omit_two_operands (integer_type_node, integer_zero_node,
9328 arg1, arg2);
9c8a1629 9329
9330 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
9331 if (operand_equal_p (arg1, arg2, 0))
c4fef134 9332 return omit_one_operand (integer_type_node, integer_zero_node, len);
9333
9334 p1 = c_getstr (arg1);
9335 p2 = c_getstr (arg2);
9336
9337 /* If all arguments are constant, and the value of len is not greater
9338 than the lengths of arg1 and arg2, evaluate at compile-time. */
9339 if (host_integerp (len, 1) && p1 && p2
9340 && compare_tree_int (len, strlen (p1) + 1) <= 0
9341 && compare_tree_int (len, strlen (p2) + 1) <= 0)
9342 {
9343 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
9344
9345 if (r > 0)
9346 return integer_one_node;
9347 else if (r < 0)
9348 return integer_minus_one_node;
9349 else
9350 return integer_zero_node;
9351 }
9352
9353 /* If len parameter is one, return an expression corresponding to
9354 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
9355 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9356 {
9357 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9358 tree cst_uchar_ptr_node
9359 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9360
c4fef134 9361 tree ind1 = fold_convert (integer_type_node,
9362 build1 (INDIRECT_REF, cst_uchar_node,
9363 fold_convert (cst_uchar_ptr_node,
9364 arg1)));
9365 tree ind2 = fold_convert (integer_type_node,
9366 build1 (INDIRECT_REF, cst_uchar_node,
9367 fold_convert (cst_uchar_ptr_node,
9368 arg2)));
49d00087 9369 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
c4fef134 9370 }
9c8a1629 9371
c2f47e15 9372 return NULL_TREE;
9c8a1629 9373}
9374
c2f47e15 9375/* Fold function call to builtin strcmp with arguments ARG1 and ARG2.
9376 Return NULL_TREE if no simplification can be made. */
9c8a1629 9377
9378static tree
c2f47e15 9379fold_builtin_strcmp (tree arg1, tree arg2)
9c8a1629 9380{
9c8a1629 9381 const char *p1, *p2;
9382
c2f47e15 9383 if (!validate_arg (arg1, POINTER_TYPE)
9384 || !validate_arg (arg2, POINTER_TYPE))
9385 return NULL_TREE;
9c8a1629 9386
9387 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
9388 if (operand_equal_p (arg1, arg2, 0))
c4fef134 9389 return integer_zero_node;
9c8a1629 9390
9391 p1 = c_getstr (arg1);
9392 p2 = c_getstr (arg2);
9393
9394 if (p1 && p2)
9395 {
9c8a1629 9396 const int i = strcmp (p1, p2);
9397 if (i < 0)
c4fef134 9398 return integer_minus_one_node;
9c8a1629 9399 else if (i > 0)
c4fef134 9400 return integer_one_node;
9c8a1629 9401 else
c4fef134 9402 return integer_zero_node;
9403 }
9404
9405 /* If the second arg is "", return *(const unsigned char*)arg1. */
9406 if (p2 && *p2 == '\0')
9407 {
9408 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9409 tree cst_uchar_ptr_node
9410 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9411
c4fef134 9412 return fold_convert (integer_type_node,
9413 build1 (INDIRECT_REF, cst_uchar_node,
9414 fold_convert (cst_uchar_ptr_node,
9415 arg1)));
9416 }
9417
9418 /* If the first arg is "", return -*(const unsigned char*)arg2. */
9419 if (p1 && *p1 == '\0')
9420 {
9421 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9422 tree cst_uchar_ptr_node
9423 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9424
c4fef134 9425 tree temp = fold_convert (integer_type_node,
9426 build1 (INDIRECT_REF, cst_uchar_node,
9427 fold_convert (cst_uchar_ptr_node,
9428 arg2)));
49d00087 9429 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
9c8a1629 9430 }
9431
c2f47e15 9432 return NULL_TREE;
9c8a1629 9433}
9434
c2f47e15 9435/* Fold function call to builtin strncmp with arguments ARG1, ARG2, and LEN.
9436 Return NULL_TREE if no simplification can be made. */
9c8a1629 9437
9438static tree
c2f47e15 9439fold_builtin_strncmp (tree arg1, tree arg2, tree len)
9c8a1629 9440{
9c8a1629 9441 const char *p1, *p2;
9442
c2f47e15 9443 if (!validate_arg (arg1, POINTER_TYPE)
9444 || !validate_arg (arg2, POINTER_TYPE)
9445 || !validate_arg (len, INTEGER_TYPE))
9446 return NULL_TREE;
9c8a1629 9447
9448 /* If the LEN parameter is zero, return zero. */
9449 if (integer_zerop (len))
c4fef134 9450 return omit_two_operands (integer_type_node, integer_zero_node,
9451 arg1, arg2);
9c8a1629 9452
9453 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
9454 if (operand_equal_p (arg1, arg2, 0))
c4fef134 9455 return omit_one_operand (integer_type_node, integer_zero_node, len);
9c8a1629 9456
9457 p1 = c_getstr (arg1);
9458 p2 = c_getstr (arg2);
9459
9460 if (host_integerp (len, 1) && p1 && p2)
9461 {
9c8a1629 9462 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
c4fef134 9463 if (i > 0)
9464 return integer_one_node;
9465 else if (i < 0)
9466 return integer_minus_one_node;
9c8a1629 9467 else
c4fef134 9468 return integer_zero_node;
9469 }
9470
9471 /* If the second arg is "", and the length is greater than zero,
9472 return *(const unsigned char*)arg1. */
9473 if (p2 && *p2 == '\0'
9474 && TREE_CODE (len) == INTEGER_CST
9475 && tree_int_cst_sgn (len) == 1)
9476 {
9477 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9478 tree cst_uchar_ptr_node
9479 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9480
c4fef134 9481 return fold_convert (integer_type_node,
9482 build1 (INDIRECT_REF, cst_uchar_node,
9483 fold_convert (cst_uchar_ptr_node,
9484 arg1)));
9485 }
9486
9487 /* If the first arg is "", and the length is greater than zero,
9488 return -*(const unsigned char*)arg2. */
9489 if (p1 && *p1 == '\0'
9490 && TREE_CODE (len) == INTEGER_CST
9491 && tree_int_cst_sgn (len) == 1)
9492 {
9493 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9494 tree cst_uchar_ptr_node
9495 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9496
c4fef134 9497 tree temp = fold_convert (integer_type_node,
9498 build1 (INDIRECT_REF, cst_uchar_node,
9499 fold_convert (cst_uchar_ptr_node,
9500 arg2)));
49d00087 9501 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
c4fef134 9502 }
9503
9504 /* If len parameter is one, return an expression corresponding to
9505 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
9506 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9507 {
9508 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9509 tree cst_uchar_ptr_node
9510 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9511
c4fef134 9512 tree ind1 = fold_convert (integer_type_node,
9513 build1 (INDIRECT_REF, cst_uchar_node,
9514 fold_convert (cst_uchar_ptr_node,
9515 arg1)));
9516 tree ind2 = fold_convert (integer_type_node,
9517 build1 (INDIRECT_REF, cst_uchar_node,
9518 fold_convert (cst_uchar_ptr_node,
9519 arg2)));
49d00087 9520 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
9c8a1629 9521 }
9522
c2f47e15 9523 return NULL_TREE;
9c8a1629 9524}
9525
c2f47e15 9526/* Fold function call to builtin signbit, signbitf or signbitl with argument
9527 ARG. Return NULL_TREE if no simplification can be made. */
27f261ef 9528
9529static tree
c2f47e15 9530fold_builtin_signbit (tree arg, tree type)
27f261ef 9531{
c2f47e15 9532 tree temp;
27f261ef 9533
c2f47e15 9534 if (!validate_arg (arg, REAL_TYPE))
27f261ef 9535 return NULL_TREE;
9536
27f261ef 9537 /* If ARG is a compile-time constant, determine the result. */
9538 if (TREE_CODE (arg) == REAL_CST
f96bd2bf 9539 && !TREE_OVERFLOW (arg))
27f261ef 9540 {
9541 REAL_VALUE_TYPE c;
9542
9543 c = TREE_REAL_CST (arg);
9544 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
2426241c 9545 return fold_convert (type, temp);
27f261ef 9546 }
9547
9548 /* If ARG is non-negative, the result is always zero. */
9549 if (tree_expr_nonnegative_p (arg))
2426241c 9550 return omit_one_operand (type, integer_zero_node, arg);
27f261ef 9551
9552 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
9553 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
49d00087 9554 return fold_build2 (LT_EXPR, type, arg,
9555 build_real (TREE_TYPE (arg), dconst0));
27f261ef 9556
9557 return NULL_TREE;
9558}
9559
c2f47e15 9560/* Fold function call to builtin copysign, copysignf or copysignl with
9561 arguments ARG1 and ARG2. Return NULL_TREE if no simplification can
9562 be made. */
467214fd 9563
9564static tree
c2f47e15 9565fold_builtin_copysign (tree fndecl, tree arg1, tree arg2, tree type)
467214fd 9566{
c2f47e15 9567 tree tem;
467214fd 9568
c2f47e15 9569 if (!validate_arg (arg1, REAL_TYPE)
9570 || !validate_arg (arg2, REAL_TYPE))
467214fd 9571 return NULL_TREE;
9572
467214fd 9573 /* copysign(X,X) is X. */
9574 if (operand_equal_p (arg1, arg2, 0))
9575 return fold_convert (type, arg1);
9576
9577 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
9578 if (TREE_CODE (arg1) == REAL_CST
9579 && TREE_CODE (arg2) == REAL_CST
f96bd2bf 9580 && !TREE_OVERFLOW (arg1)
9581 && !TREE_OVERFLOW (arg2))
467214fd 9582 {
9583 REAL_VALUE_TYPE c1, c2;
9584
9585 c1 = TREE_REAL_CST (arg1);
9586 c2 = TREE_REAL_CST (arg2);
749680e2 9587 /* c1.sign := c2.sign. */
467214fd 9588 real_copysign (&c1, &c2);
9589 return build_real (type, c1);
467214fd 9590 }
9591
9592 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
9593 Remember to evaluate Y for side-effects. */
9594 if (tree_expr_nonnegative_p (arg2))
9595 return omit_one_operand (type,
49d00087 9596 fold_build1 (ABS_EXPR, type, arg1),
467214fd 9597 arg2);
9598
198d9bbe 9599 /* Strip sign changing operations for the first argument. */
9600 tem = fold_strip_sign_ops (arg1);
9601 if (tem)
c2f47e15 9602 return build_call_expr (fndecl, 2, tem, arg2);
198d9bbe 9603
467214fd 9604 return NULL_TREE;
9605}
9606
c2f47e15 9607/* Fold a call to builtin isascii with argument ARG. */
d49367d4 9608
9609static tree
c2f47e15 9610fold_builtin_isascii (tree arg)
d49367d4 9611{
c2f47e15 9612 if (!validate_arg (arg, INTEGER_TYPE))
9613 return NULL_TREE;
d49367d4 9614 else
9615 {
9616 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
7c446c95 9617 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
9618 build_int_cst (NULL_TREE,
7016c612 9619 ~ (unsigned HOST_WIDE_INT) 0x7f));
f2532264 9620 return fold_build2 (EQ_EXPR, integer_type_node,
9621 arg, integer_zero_node);
d49367d4 9622 }
9623}
9624
c2f47e15 9625/* Fold a call to builtin toascii with argument ARG. */
d49367d4 9626
9627static tree
c2f47e15 9628fold_builtin_toascii (tree arg)
d49367d4 9629{
c2f47e15 9630 if (!validate_arg (arg, INTEGER_TYPE))
9631 return NULL_TREE;
9632
9633 /* Transform toascii(c) -> (c & 0x7f). */
9634 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
9635 build_int_cst (NULL_TREE, 0x7f));
d49367d4 9636}
9637
c2f47e15 9638/* Fold a call to builtin isdigit with argument ARG. */
df1cf42e 9639
9640static tree
c2f47e15 9641fold_builtin_isdigit (tree arg)
df1cf42e 9642{
c2f47e15 9643 if (!validate_arg (arg, INTEGER_TYPE))
9644 return NULL_TREE;
df1cf42e 9645 else
9646 {
9647 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
624d37a6 9648 /* According to the C standard, isdigit is unaffected by locale.
9649 However, it definitely is affected by the target character set. */
624d37a6 9650 unsigned HOST_WIDE_INT target_digit0
9651 = lang_hooks.to_target_charset ('0');
9652
9653 if (target_digit0 == 0)
9654 return NULL_TREE;
9655
c2f47e15 9656 arg = fold_convert (unsigned_type_node, arg);
05abc81b 9657 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
624d37a6 9658 build_int_cst (unsigned_type_node, target_digit0));
f2532264 9659 return fold_build2 (LE_EXPR, integer_type_node, arg,
9660 build_int_cst (unsigned_type_node, 9));
df1cf42e 9661 }
9662}
27f261ef 9663
c2f47e15 9664/* Fold a call to fabs, fabsf or fabsl with argument ARG. */
d1aade50 9665
9666static tree
c2f47e15 9667fold_builtin_fabs (tree arg, tree type)
d1aade50 9668{
c2f47e15 9669 if (!validate_arg (arg, REAL_TYPE))
9670 return NULL_TREE;
d1aade50 9671
9829e110 9672 arg = fold_convert (type, arg);
d1aade50 9673 if (TREE_CODE (arg) == REAL_CST)
9674 return fold_abs_const (arg, type);
49d00087 9675 return fold_build1 (ABS_EXPR, type, arg);
d1aade50 9676}
9677
c2f47e15 9678/* Fold a call to abs, labs, llabs or imaxabs with argument ARG. */
d1aade50 9679
9680static tree
c2f47e15 9681fold_builtin_abs (tree arg, tree type)
d1aade50 9682{
c2f47e15 9683 if (!validate_arg (arg, INTEGER_TYPE))
9684 return NULL_TREE;
d1aade50 9685
9829e110 9686 arg = fold_convert (type, arg);
d1aade50 9687 if (TREE_CODE (arg) == INTEGER_CST)
9688 return fold_abs_const (arg, type);
49d00087 9689 return fold_build1 (ABS_EXPR, type, arg);
d1aade50 9690}
9691
d4a43a03 9692/* Fold a call to builtin fmin or fmax. */
9693
9694static tree
c2f47e15 9695fold_builtin_fmin_fmax (tree arg0, tree arg1, tree type, bool max)
d4a43a03 9696{
c2f47e15 9697 if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, REAL_TYPE))
d4a43a03 9698 {
d4a43a03 9699 /* Calculate the result when the argument is a constant. */
9700 tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
9701
9702 if (res)
9703 return res;
9704
61fe3555 9705 /* If either argument is NaN, return the other one. Avoid the
9706 transformation if we get (and honor) a signalling NaN. Using
9707 omit_one_operand() ensures we create a non-lvalue. */
9708 if (TREE_CODE (arg0) == REAL_CST
9709 && real_isnan (&TREE_REAL_CST (arg0))
9710 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
9711 || ! TREE_REAL_CST (arg0).signalling))
9712 return omit_one_operand (type, arg1, arg0);
9713 if (TREE_CODE (arg1) == REAL_CST
9714 && real_isnan (&TREE_REAL_CST (arg1))
9715 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
9716 || ! TREE_REAL_CST (arg1).signalling))
9717 return omit_one_operand (type, arg0, arg1);
9718
d4a43a03 9719 /* Transform fmin/fmax(x,x) -> x. */
9720 if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
9721 return omit_one_operand (type, arg0, arg1);
9722
9723 /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR. C99 requires these
9724 functions to return the numeric arg if the other one is NaN.
9725 These tree codes don't honor that, so only transform if
9726 -ffinite-math-only is set. C99 doesn't require -0.0 to be
9727 handled, so we don't have to worry about it either. */
9728 if (flag_finite_math_only)
9729 return fold_build2 ((max ? MAX_EXPR : MIN_EXPR), type,
9730 fold_convert (type, arg0),
9731 fold_convert (type, arg1));
9732 }
9733 return NULL_TREE;
9734}
9735
abe4dcf6 9736/* Fold a call to builtin carg(a+bi) -> atan2(b,a). */
9737
9738static tree
c2f47e15 9739fold_builtin_carg (tree arg, tree type)
abe4dcf6 9740{
239d491a 9741 if (validate_arg (arg, COMPLEX_TYPE)
9742 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
abe4dcf6 9743 {
9744 tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2);
9745
9746 if (atan2_fn)
9747 {
c2f47e15 9748 tree new_arg = builtin_save_expr (arg);
9749 tree r_arg = fold_build1 (REALPART_EXPR, type, new_arg);
9750 tree i_arg = fold_build1 (IMAGPART_EXPR, type, new_arg);
9751 return build_call_expr (atan2_fn, 2, i_arg, r_arg);
abe4dcf6 9752 }
9753 }
9754
9755 return NULL_TREE;
9756}
9757
cb2b9385 9758/* Fold a call to builtin logb/ilogb. */
9759
9760static tree
9761fold_builtin_logb (tree arg, tree rettype)
9762{
9763 if (! validate_arg (arg, REAL_TYPE))
9764 return NULL_TREE;
9765
9766 STRIP_NOPS (arg);
9767
9768 if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9769 {
9770 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9771
9772 switch (value->cl)
9773 {
9774 case rvc_nan:
9775 case rvc_inf:
9776 /* If arg is Inf or NaN and we're logb, return it. */
9777 if (TREE_CODE (rettype) == REAL_TYPE)
9778 return fold_convert (rettype, arg);
9779 /* Fall through... */
9780 case rvc_zero:
9781 /* Zero may set errno and/or raise an exception for logb, also
9782 for ilogb we don't know FP_ILOGB0. */
9783 return NULL_TREE;
9784 case rvc_normal:
9785 /* For normal numbers, proceed iff radix == 2. In GCC,
9786 normalized significands are in the range [0.5, 1.0). We
9787 want the exponent as if they were [1.0, 2.0) so get the
9788 exponent and subtract 1. */
9789 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9790 return fold_convert (rettype, build_int_cst (NULL_TREE,
9791 REAL_EXP (value)-1));
9792 break;
9793 }
9794 }
9795
9796 return NULL_TREE;
9797}
9798
9799/* Fold a call to builtin significand, if radix == 2. */
9800
9801static tree
9802fold_builtin_significand (tree arg, tree rettype)
9803{
9804 if (! validate_arg (arg, REAL_TYPE))
9805 return NULL_TREE;
9806
9807 STRIP_NOPS (arg);
9808
9809 if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9810 {
9811 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9812
9813 switch (value->cl)
9814 {
9815 case rvc_zero:
9816 case rvc_nan:
9817 case rvc_inf:
9818 /* If arg is +-0, +-Inf or +-NaN, then return it. */
9819 return fold_convert (rettype, arg);
9820 case rvc_normal:
9821 /* For normal numbers, proceed iff radix == 2. */
9822 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9823 {
9824 REAL_VALUE_TYPE result = *value;
9825 /* In GCC, normalized significands are in the range [0.5,
9826 1.0). We want them to be [1.0, 2.0) so set the
9827 exponent to 1. */
9828 SET_REAL_EXP (&result, 1);
9829 return build_real (rettype, result);
9830 }
9831 break;
9832 }
9833 }
9834
9835 return NULL_TREE;
9836}
9837
3838b9ae 9838/* Fold a call to builtin frexp, we can assume the base is 2. */
9839
9840static tree
9841fold_builtin_frexp (tree arg0, tree arg1, tree rettype)
9842{
9843 if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9844 return NULL_TREE;
9845
9846 STRIP_NOPS (arg0);
9847
9848 if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9849 return NULL_TREE;
9850
9851 arg1 = build_fold_indirect_ref (arg1);
9852
9853 /* Proceed if a valid pointer type was passed in. */
9854 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == integer_type_node)
9855 {
9856 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9857 tree frac, exp;
9858
9859 switch (value->cl)
9860 {
9861 case rvc_zero:
9862 /* For +-0, return (*exp = 0, +-0). */
9863 exp = integer_zero_node;
9864 frac = arg0;
9865 break;
9866 case rvc_nan:
9867 case rvc_inf:
9868 /* For +-NaN or +-Inf, *exp is unspecified, return arg0. */
9869 return omit_one_operand (rettype, arg0, arg1);
9870 case rvc_normal:
9871 {
9872 /* Since the frexp function always expects base 2, and in
9873 GCC normalized significands are already in the range
9874 [0.5, 1.0), we have exactly what frexp wants. */
9875 REAL_VALUE_TYPE frac_rvt = *value;
9876 SET_REAL_EXP (&frac_rvt, 0);
9877 frac = build_real (rettype, frac_rvt);
9878 exp = build_int_cst (NULL_TREE, REAL_EXP (value));
9879 }
9880 break;
9881 default:
9882 gcc_unreachable ();
9883 }
9884
9885 /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9886 arg1 = fold_build2 (MODIFY_EXPR, rettype, arg1, exp);
9887 TREE_SIDE_EFFECTS (arg1) = 1;
9888 return fold_build2 (COMPOUND_EXPR, rettype, arg1, frac);
9889 }
9890
9891 return NULL_TREE;
9892}
9893
7587301b 9894/* Fold a call to builtin ldexp or scalbn/scalbln. If LDEXP is true
9895 then we can assume the base is two. If it's false, then we have to
9896 check the mode of the TYPE parameter in certain cases. */
9897
9898static tree
9899fold_builtin_load_exponent (tree arg0, tree arg1, tree type, bool ldexp)
9900{
9901 if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, INTEGER_TYPE))
9902 {
9903 STRIP_NOPS (arg0);
9904 STRIP_NOPS (arg1);
9905
9906 /* If arg0 is 0, Inf or NaN, or if arg1 is 0, then return arg0. */
9907 if (real_zerop (arg0) || integer_zerop (arg1)
9908 || (TREE_CODE (arg0) == REAL_CST
776a7bab 9909 && !real_isfinite (&TREE_REAL_CST (arg0))))
7587301b 9910 return omit_one_operand (type, arg0, arg1);
9911
9912 /* If both arguments are constant, then try to evaluate it. */
9913 if ((ldexp || REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2)
9914 && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
9915 && host_integerp (arg1, 0))
9916 {
9917 /* Bound the maximum adjustment to twice the range of the
9918 mode's valid exponents. Use abs to ensure the range is
9919 positive as a sanity check. */
9920 const long max_exp_adj = 2 *
9921 labs (REAL_MODE_FORMAT (TYPE_MODE (type))->emax
9922 - REAL_MODE_FORMAT (TYPE_MODE (type))->emin);
9923
9924 /* Get the user-requested adjustment. */
9925 const HOST_WIDE_INT req_exp_adj = tree_low_cst (arg1, 0);
9926
9927 /* The requested adjustment must be inside this range. This
9928 is a preliminary cap to avoid things like overflow, we
9929 may still fail to compute the result for other reasons. */
9930 if (-max_exp_adj < req_exp_adj && req_exp_adj < max_exp_adj)
9931 {
9932 REAL_VALUE_TYPE initial_result;
9933
9934 real_ldexp (&initial_result, &TREE_REAL_CST (arg0), req_exp_adj);
9935
9936 /* Ensure we didn't overflow. */
9937 if (! real_isinf (&initial_result))
9938 {
9939 const REAL_VALUE_TYPE trunc_result
9940 = real_value_truncate (TYPE_MODE (type), initial_result);
9941
9942 /* Only proceed if the target mode can hold the
9943 resulting value. */
9944 if (REAL_VALUES_EQUAL (initial_result, trunc_result))
9945 return build_real (type, trunc_result);
9946 }
9947 }
9948 }
9949 }
9950
9951 return NULL_TREE;
9952}
9953
ebf8b4f5 9954/* Fold a call to builtin modf. */
9955
9956static tree
9957fold_builtin_modf (tree arg0, tree arg1, tree rettype)
9958{
9959 if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9960 return NULL_TREE;
9961
9962 STRIP_NOPS (arg0);
9963
9964 if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9965 return NULL_TREE;
9966
9967 arg1 = build_fold_indirect_ref (arg1);
9968
9969 /* Proceed if a valid pointer type was passed in. */
9970 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == TYPE_MAIN_VARIANT (rettype))
9971 {
9972 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9973 REAL_VALUE_TYPE trunc, frac;
9974
9975 switch (value->cl)
9976 {
9977 case rvc_nan:
9978 case rvc_zero:
9979 /* For +-NaN or +-0, return (*arg1 = arg0, arg0). */
9980 trunc = frac = *value;
9981 break;
9982 case rvc_inf:
9983 /* For +-Inf, return (*arg1 = arg0, +-0). */
9984 frac = dconst0;
9985 frac.sign = value->sign;
9986 trunc = *value;
9987 break;
9988 case rvc_normal:
9989 /* Return (*arg1 = trunc(arg0), arg0-trunc(arg0)). */
9990 real_trunc (&trunc, VOIDmode, value);
9991 real_arithmetic (&frac, MINUS_EXPR, value, &trunc);
9992 /* If the original number was negative and already
9993 integral, then the fractional part is -0.0. */
9994 if (value->sign && frac.cl == rvc_zero)
9995 frac.sign = value->sign;
9996 break;
9997 }
9998
9999 /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
10000 arg1 = fold_build2 (MODIFY_EXPR, rettype, arg1,
10001 build_real (rettype, trunc));
10002 TREE_SIDE_EFFECTS (arg1) = 1;
10003 return fold_build2 (COMPOUND_EXPR, rettype, arg1,
10004 build_real (rettype, frac));
10005 }
10006
10007 return NULL_TREE;
10008}
10009
726069ba 10010/* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
c2f47e15 10011 ARG is the argument for the call. */
726069ba 10012
10013static tree
c2f47e15 10014fold_builtin_classify (tree fndecl, tree arg, int builtin_index)
726069ba 10015{
726069ba 10016 tree type = TREE_TYPE (TREE_TYPE (fndecl));
726069ba 10017 REAL_VALUE_TYPE r;
10018
c2f47e15 10019 if (!validate_arg (arg, REAL_TYPE))
d43cee80 10020 return NULL_TREE;
726069ba 10021
726069ba 10022 switch (builtin_index)
10023 {
10024 case BUILT_IN_ISINF:
b70bfd00 10025 if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
a0c938f0 10026 return omit_one_operand (type, integer_zero_node, arg);
726069ba 10027
10028 if (TREE_CODE (arg) == REAL_CST)
10029 {
10030 r = TREE_REAL_CST (arg);
10031 if (real_isinf (&r))
10032 return real_compare (GT_EXPR, &r, &dconst0)
10033 ? integer_one_node : integer_minus_one_node;
10034 else
10035 return integer_zero_node;
10036 }
10037
10038 return NULL_TREE;
10039
c319d56a 10040 case BUILT_IN_ISINF_SIGN:
10041 {
10042 /* isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 */
10043 /* In a boolean context, GCC will fold the inner COND_EXPR to
10044 1. So e.g. "if (isinf_sign(x))" would be folded to just
10045 "if (isinf(x) ? 1 : 0)" which becomes "if (isinf(x))". */
10046 tree signbit_fn = mathfn_built_in_1 (TREE_TYPE (arg), BUILT_IN_SIGNBIT, 0);
10047 tree isinf_fn = built_in_decls[BUILT_IN_ISINF];
10048 tree tmp = NULL_TREE;
10049
10050 arg = builtin_save_expr (arg);
10051
10052 if (signbit_fn && isinf_fn)
10053 {
10054 tree signbit_call = build_call_expr (signbit_fn, 1, arg);
10055 tree isinf_call = build_call_expr (isinf_fn, 1, arg);
10056
10057 signbit_call = fold_build2 (NE_EXPR, integer_type_node,
10058 signbit_call, integer_zero_node);
10059 isinf_call = fold_build2 (NE_EXPR, integer_type_node,
10060 isinf_call, integer_zero_node);
10061
10062 tmp = fold_build3 (COND_EXPR, integer_type_node, signbit_call,
10063 integer_minus_one_node, integer_one_node);
10064 tmp = fold_build3 (COND_EXPR, integer_type_node, isinf_call, tmp,
10065 integer_zero_node);
10066 }
10067
10068 return tmp;
10069 }
10070
cde061c1 10071 case BUILT_IN_ISFINITE:
b70bfd00 10072 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
10073 && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
34709e02 10074 return omit_one_operand (type, integer_one_node, arg);
726069ba 10075
10076 if (TREE_CODE (arg) == REAL_CST)
10077 {
10078 r = TREE_REAL_CST (arg);
776a7bab 10079 return real_isfinite (&r) ? integer_one_node : integer_zero_node;
726069ba 10080 }
10081
10082 return NULL_TREE;
10083
10084 case BUILT_IN_ISNAN:
b70bfd00 10085 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
a0c938f0 10086 return omit_one_operand (type, integer_zero_node, arg);
726069ba 10087
10088 if (TREE_CODE (arg) == REAL_CST)
10089 {
10090 r = TREE_REAL_CST (arg);
10091 return real_isnan (&r) ? integer_one_node : integer_zero_node;
10092 }
10093
10094 arg = builtin_save_expr (arg);
49d00087 10095 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
726069ba 10096
10097 default:
64db345d 10098 gcc_unreachable ();
726069ba 10099 }
10100}
10101
19fbe3a4 10102/* Fold a call to __builtin_fpclassify(int, int, int, int, int, ...).
10103 This builtin will generate code to return the appropriate floating
10104 point classification depending on the value of the floating point
10105 number passed in. The possible return values must be supplied as
921b27c0 10106 int arguments to the call in the following order: FP_NAN, FP_INFINITE,
19fbe3a4 10107 FP_NORMAL, FP_SUBNORMAL and FP_ZERO. The ellipses is for exactly
10108 one floating point argument which is "type generic". */
10109
10110static tree
10111fold_builtin_fpclassify (tree exp)
10112{
921b27c0 10113 tree fp_nan, fp_infinite, fp_normal, fp_subnormal, fp_zero,
10114 arg, type, res, tmp;
19fbe3a4 10115 enum machine_mode mode;
10116 REAL_VALUE_TYPE r;
10117 char buf[128];
10118
10119 /* Verify the required arguments in the original call. */
10120 if (!validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE,
10121 INTEGER_TYPE, INTEGER_TYPE,
10122 INTEGER_TYPE, REAL_TYPE, VOID_TYPE))
10123 return NULL_TREE;
10124
10125 fp_nan = CALL_EXPR_ARG (exp, 0);
921b27c0 10126 fp_infinite = CALL_EXPR_ARG (exp, 1);
19fbe3a4 10127 fp_normal = CALL_EXPR_ARG (exp, 2);
10128 fp_subnormal = CALL_EXPR_ARG (exp, 3);
10129 fp_zero = CALL_EXPR_ARG (exp, 4);
10130 arg = CALL_EXPR_ARG (exp, 5);
10131 type = TREE_TYPE (arg);
10132 mode = TYPE_MODE (type);
10133 arg = builtin_save_expr (fold_build1 (ABS_EXPR, type, arg));
10134
10135 /* fpclassify(x) ->
10136 isnan(x) ? FP_NAN :
921b27c0 10137 (fabs(x) == Inf ? FP_INFINITE :
19fbe3a4 10138 (fabs(x) >= DBL_MIN ? FP_NORMAL :
10139 (x == 0 ? FP_ZERO : FP_SUBNORMAL))). */
10140
10141 tmp = fold_build2 (EQ_EXPR, integer_type_node, arg,
10142 build_real (type, dconst0));
10143 res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_zero, fp_subnormal);
10144
10145 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
10146 real_from_string (&r, buf);
10147 tmp = fold_build2 (GE_EXPR, integer_type_node, arg, build_real (type, r));
10148 res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_normal, res);
10149
10150 if (HONOR_INFINITIES (mode))
10151 {
10152 real_inf (&r);
10153 tmp = fold_build2 (EQ_EXPR, integer_type_node, arg,
10154 build_real (type, r));
921b27c0 10155 res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_infinite, res);
19fbe3a4 10156 }
10157
10158 if (HONOR_NANS (mode))
10159 {
10160 tmp = fold_build2 (ORDERED_EXPR, integer_type_node, arg, arg);
10161 res = fold_build3 (COND_EXPR, integer_type_node, tmp, res, fp_nan);
10162 }
10163
10164 return res;
10165}
10166
9bc9f15f 10167/* Fold a call to an unordered comparison function such as
d5019fe8 10168 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
c2f47e15 10169 being called and ARG0 and ARG1 are the arguments for the call.
726069ba 10170 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
10171 the opposite of the desired result. UNORDERED_CODE is used
10172 for modes that can hold NaNs and ORDERED_CODE is used for
10173 the rest. */
9bc9f15f 10174
10175static tree
c2f47e15 10176fold_builtin_unordered_cmp (tree fndecl, tree arg0, tree arg1,
9bc9f15f 10177 enum tree_code unordered_code,
10178 enum tree_code ordered_code)
10179{
859f903a 10180 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9bc9f15f 10181 enum tree_code code;
6978db0d 10182 tree type0, type1;
10183 enum tree_code code0, code1;
10184 tree cmp_type = NULL_TREE;
9bc9f15f 10185
6978db0d 10186 type0 = TREE_TYPE (arg0);
10187 type1 = TREE_TYPE (arg1);
a0c938f0 10188
6978db0d 10189 code0 = TREE_CODE (type0);
10190 code1 = TREE_CODE (type1);
a0c938f0 10191
6978db0d 10192 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
10193 /* Choose the wider of two real types. */
10194 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
10195 ? type0 : type1;
10196 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
10197 cmp_type = type0;
10198 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
10199 cmp_type = type1;
a0c938f0 10200
6978db0d 10201 arg0 = fold_convert (cmp_type, arg0);
10202 arg1 = fold_convert (cmp_type, arg1);
859f903a 10203
10204 if (unordered_code == UNORDERED_EXPR)
10205 {
b70bfd00 10206 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
859f903a 10207 return omit_two_operands (type, integer_zero_node, arg0, arg1);
49d00087 10208 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
859f903a 10209 }
9bc9f15f 10210
b70bfd00 10211 code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
10212 : ordered_code;
49d00087 10213 return fold_build1 (TRUTH_NOT_EXPR, type,
10214 fold_build2 (code, type, arg0, arg1));
9bc9f15f 10215}
10216
c2f47e15 10217/* Fold a call to built-in function FNDECL with 0 arguments.
10218 IGNORE is true if the result of the function call is ignored. This
10219 function returns NULL_TREE if no simplification was possible. */
650e4c94 10220
4ee9c684 10221static tree
c2f47e15 10222fold_builtin_0 (tree fndecl, bool ignore ATTRIBUTE_UNUSED)
650e4c94 10223{
e9f80ff5 10224 tree type = TREE_TYPE (TREE_TYPE (fndecl));
c2f47e15 10225 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
189b3398 10226 switch (fcode)
650e4c94 10227 {
c2f47e15 10228 CASE_FLT_FN (BUILT_IN_INF):
10229 case BUILT_IN_INFD32:
10230 case BUILT_IN_INFD64:
10231 case BUILT_IN_INFD128:
10232 return fold_builtin_inf (type, true);
7c2f0500 10233
c2f47e15 10234 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
10235 return fold_builtin_inf (type, false);
7c2f0500 10236
c2f47e15 10237 case BUILT_IN_CLASSIFY_TYPE:
10238 return fold_builtin_classify_type (NULL_TREE);
7c2f0500 10239
c2f47e15 10240 default:
10241 break;
10242 }
10243 return NULL_TREE;
10244}
7c2f0500 10245
c2f47e15 10246/* Fold a call to built-in function FNDECL with 1 argument, ARG0.
10247 IGNORE is true if the result of the function call is ignored. This
10248 function returns NULL_TREE if no simplification was possible. */
7c2f0500 10249
c2f47e15 10250static tree
10251fold_builtin_1 (tree fndecl, tree arg0, bool ignore)
10252{
10253 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10254 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10255 switch (fcode)
10256 {
7c2f0500 10257
650e4c94 10258 case BUILT_IN_CONSTANT_P:
7c2f0500 10259 {
c2f47e15 10260 tree val = fold_builtin_constant_p (arg0);
7c2f0500 10261
7c2f0500 10262 /* Gimplification will pull the CALL_EXPR for the builtin out of
10263 an if condition. When not optimizing, we'll not CSE it back.
10264 To avoid link error types of regressions, return false now. */
10265 if (!val && !optimize)
10266 val = integer_zero_node;
10267
10268 return val;
10269 }
650e4c94 10270
539a3a92 10271 case BUILT_IN_CLASSIFY_TYPE:
c2f47e15 10272 return fold_builtin_classify_type (arg0);
539a3a92 10273
650e4c94 10274 case BUILT_IN_STRLEN:
c2f47e15 10275 return fold_builtin_strlen (arg0);
650e4c94 10276
4f35b1fc 10277 CASE_FLT_FN (BUILT_IN_FABS):
c2f47e15 10278 return fold_builtin_fabs (arg0, type);
d1aade50 10279
10280 case BUILT_IN_ABS:
10281 case BUILT_IN_LABS:
10282 case BUILT_IN_LLABS:
10283 case BUILT_IN_IMAXABS:
c2f47e15 10284 return fold_builtin_abs (arg0, type);
c63f4ad3 10285
4f35b1fc 10286 CASE_FLT_FN (BUILT_IN_CONJ):
239d491a 10287 if (validate_arg (arg0, COMPLEX_TYPE)
10288 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
c2f47e15 10289 return fold_build1 (CONJ_EXPR, type, arg0);
10290 break;
36d3581d 10291
4f35b1fc 10292 CASE_FLT_FN (BUILT_IN_CREAL):
239d491a 10293 if (validate_arg (arg0, COMPLEX_TYPE)
10294 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
c2f47e15 10295 return non_lvalue (fold_build1 (REALPART_EXPR, type, arg0));;
10296 break;
36d3581d 10297
4f35b1fc 10298 CASE_FLT_FN (BUILT_IN_CIMAG):
c2f47e15 10299 if (validate_arg (arg0, COMPLEX_TYPE))
10300 return non_lvalue (fold_build1 (IMAGPART_EXPR, type, arg0));
10301 break;
36d3581d 10302
503733d5 10303 CASE_FLT_FN (BUILT_IN_CCOS):
239d491a 10304 return fold_builtin_ccos(arg0, type, fndecl, /*hyper=*/ false);
10305
503733d5 10306 CASE_FLT_FN (BUILT_IN_CCOSH):
239d491a 10307 return fold_builtin_ccos(arg0, type, fndecl, /*hyper=*/ true);
10308
10309#ifdef HAVE_mpc
10310 CASE_FLT_FN (BUILT_IN_CSIN):
10311 if (validate_arg (arg0, COMPLEX_TYPE)
10312 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10313 return do_mpc_arg1 (arg0, type, mpc_sin);
c2f47e15 10314 break;
239d491a 10315
10316 CASE_FLT_FN (BUILT_IN_CSINH):
10317 if (validate_arg (arg0, COMPLEX_TYPE)
10318 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10319 return do_mpc_arg1 (arg0, type, mpc_sinh);
10320 break;
10321
10322 CASE_FLT_FN (BUILT_IN_CTAN):
10323 if (validate_arg (arg0, COMPLEX_TYPE)
10324 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10325 return do_mpc_arg1 (arg0, type, mpc_tan);
10326 break;
10327
10328 CASE_FLT_FN (BUILT_IN_CTANH):
10329 if (validate_arg (arg0, COMPLEX_TYPE)
10330 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10331 return do_mpc_arg1 (arg0, type, mpc_tanh);
10332 break;
10333
10334 CASE_FLT_FN (BUILT_IN_CLOG):
10335 if (validate_arg (arg0, COMPLEX_TYPE)
10336 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10337 return do_mpc_arg1 (arg0, type, mpc_log);
10338 break;
10339
10340 CASE_FLT_FN (BUILT_IN_CSQRT):
10341 if (validate_arg (arg0, COMPLEX_TYPE)
10342 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10343 return do_mpc_arg1 (arg0, type, mpc_sqrt);
10344 break;
10345#endif
10346
4f35b1fc 10347 CASE_FLT_FN (BUILT_IN_CABS):
c2f47e15 10348 return fold_builtin_cabs (arg0, type, fndecl);
c63f4ad3 10349
abe4dcf6 10350 CASE_FLT_FN (BUILT_IN_CARG):
c2f47e15 10351 return fold_builtin_carg (arg0, type);
abe4dcf6 10352
4f35b1fc 10353 CASE_FLT_FN (BUILT_IN_SQRT):
c2f47e15 10354 return fold_builtin_sqrt (arg0, type);
805e22b2 10355
4f35b1fc 10356 CASE_FLT_FN (BUILT_IN_CBRT):
c2f47e15 10357 return fold_builtin_cbrt (arg0, type);
3bc5c41b 10358
728bac60 10359 CASE_FLT_FN (BUILT_IN_ASIN):
c2f47e15 10360 if (validate_arg (arg0, REAL_TYPE))
10361 return do_mpfr_arg1 (arg0, type, mpfr_asin,
728bac60 10362 &dconstm1, &dconst1, true);
10363 break;
10364
10365 CASE_FLT_FN (BUILT_IN_ACOS):
c2f47e15 10366 if (validate_arg (arg0, REAL_TYPE))
10367 return do_mpfr_arg1 (arg0, type, mpfr_acos,
728bac60 10368 &dconstm1, &dconst1, true);
10369 break;
10370
10371 CASE_FLT_FN (BUILT_IN_ATAN):
c2f47e15 10372 if (validate_arg (arg0, REAL_TYPE))
10373 return do_mpfr_arg1 (arg0, type, mpfr_atan, NULL, NULL, 0);
728bac60 10374 break;
10375
10376 CASE_FLT_FN (BUILT_IN_ASINH):
c2f47e15 10377 if (validate_arg (arg0, REAL_TYPE))
10378 return do_mpfr_arg1 (arg0, type, mpfr_asinh, NULL, NULL, 0);
728bac60 10379 break;
10380
10381 CASE_FLT_FN (BUILT_IN_ACOSH):
c2f47e15 10382 if (validate_arg (arg0, REAL_TYPE))
10383 return do_mpfr_arg1 (arg0, type, mpfr_acosh,
728bac60 10384 &dconst1, NULL, true);
10385 break;
10386
10387 CASE_FLT_FN (BUILT_IN_ATANH):
c2f47e15 10388 if (validate_arg (arg0, REAL_TYPE))
10389 return do_mpfr_arg1 (arg0, type, mpfr_atanh,
728bac60 10390 &dconstm1, &dconst1, false);
10391 break;
10392
4f35b1fc 10393 CASE_FLT_FN (BUILT_IN_SIN):
c2f47e15 10394 if (validate_arg (arg0, REAL_TYPE))
10395 return do_mpfr_arg1 (arg0, type, mpfr_sin, NULL, NULL, 0);
728bac60 10396 break;
77e89269 10397
4f35b1fc 10398 CASE_FLT_FN (BUILT_IN_COS):
c2f47e15 10399 return fold_builtin_cos (arg0, type, fndecl);
77e89269 10400
728bac60 10401 CASE_FLT_FN (BUILT_IN_TAN):
c2f47e15 10402 return fold_builtin_tan (arg0, type);
d735c391 10403
c5bb2c4b 10404 CASE_FLT_FN (BUILT_IN_CEXP):
c2f47e15 10405 return fold_builtin_cexp (arg0, type);
c5bb2c4b 10406
d735c391 10407 CASE_FLT_FN (BUILT_IN_CEXPI):
c2f47e15 10408 if (validate_arg (arg0, REAL_TYPE))
10409 return do_mpfr_sincos (arg0, NULL_TREE, NULL_TREE);
10410 break;
d92f994c 10411
728bac60 10412 CASE_FLT_FN (BUILT_IN_SINH):
c2f47e15 10413 if (validate_arg (arg0, REAL_TYPE))
10414 return do_mpfr_arg1 (arg0, type, mpfr_sinh, NULL, NULL, 0);
728bac60 10415 break;
10416
10417 CASE_FLT_FN (BUILT_IN_COSH):
c2f47e15 10418 return fold_builtin_cosh (arg0, type, fndecl);
728bac60 10419
10420 CASE_FLT_FN (BUILT_IN_TANH):
c2f47e15 10421 if (validate_arg (arg0, REAL_TYPE))
10422 return do_mpfr_arg1 (arg0, type, mpfr_tanh, NULL, NULL, 0);
728bac60 10423 break;
10424
29f4cd78 10425 CASE_FLT_FN (BUILT_IN_ERF):
c2f47e15 10426 if (validate_arg (arg0, REAL_TYPE))
10427 return do_mpfr_arg1 (arg0, type, mpfr_erf, NULL, NULL, 0);
29f4cd78 10428 break;
10429
10430 CASE_FLT_FN (BUILT_IN_ERFC):
c2f47e15 10431 if (validate_arg (arg0, REAL_TYPE))
10432 return do_mpfr_arg1 (arg0, type, mpfr_erfc, NULL, NULL, 0);
29f4cd78 10433 break;
10434
32dba52b 10435 CASE_FLT_FN (BUILT_IN_TGAMMA):
c2f47e15 10436 if (validate_arg (arg0, REAL_TYPE))
10437 return do_mpfr_arg1 (arg0, type, mpfr_gamma, NULL, NULL, 0);
32dba52b 10438 break;
10439
4f35b1fc 10440 CASE_FLT_FN (BUILT_IN_EXP):
c2f47e15 10441 return fold_builtin_exponent (fndecl, arg0, mpfr_exp);
467214fd 10442
4f35b1fc 10443 CASE_FLT_FN (BUILT_IN_EXP2):
c2f47e15 10444 return fold_builtin_exponent (fndecl, arg0, mpfr_exp2);
467214fd 10445
4f35b1fc 10446 CASE_FLT_FN (BUILT_IN_EXP10):
10447 CASE_FLT_FN (BUILT_IN_POW10):
c2f47e15 10448 return fold_builtin_exponent (fndecl, arg0, mpfr_exp10);
467214fd 10449
29f4cd78 10450 CASE_FLT_FN (BUILT_IN_EXPM1):
c2f47e15 10451 if (validate_arg (arg0, REAL_TYPE))
10452 return do_mpfr_arg1 (arg0, type, mpfr_expm1, NULL, NULL, 0);
29f4cd78 10453 break;
10454
4f35b1fc 10455 CASE_FLT_FN (BUILT_IN_LOG):
c2f47e15 10456 return fold_builtin_logarithm (fndecl, arg0, mpfr_log);
467214fd 10457
4f35b1fc 10458 CASE_FLT_FN (BUILT_IN_LOG2):
c2f47e15 10459 return fold_builtin_logarithm (fndecl, arg0, mpfr_log2);
467214fd 10460
4f35b1fc 10461 CASE_FLT_FN (BUILT_IN_LOG10):
c2f47e15 10462 return fold_builtin_logarithm (fndecl, arg0, mpfr_log10);
29f4cd78 10463
10464 CASE_FLT_FN (BUILT_IN_LOG1P):
c2f47e15 10465 if (validate_arg (arg0, REAL_TYPE))
10466 return do_mpfr_arg1 (arg0, type, mpfr_log1p,
29f4cd78 10467 &dconstm1, NULL, false);
10468 break;
805e22b2 10469
65dd1378 10470 CASE_FLT_FN (BUILT_IN_J0):
10471 if (validate_arg (arg0, REAL_TYPE))
10472 return do_mpfr_arg1 (arg0, type, mpfr_j0,
10473 NULL, NULL, 0);
10474 break;
10475
10476 CASE_FLT_FN (BUILT_IN_J1):
10477 if (validate_arg (arg0, REAL_TYPE))
10478 return do_mpfr_arg1 (arg0, type, mpfr_j1,
10479 NULL, NULL, 0);
10480 break;
6ff9eeff 10481
10482 CASE_FLT_FN (BUILT_IN_Y0):
10483 if (validate_arg (arg0, REAL_TYPE))
10484 return do_mpfr_arg1 (arg0, type, mpfr_y0,
10485 &dconst0, NULL, false);
10486 break;
10487
10488 CASE_FLT_FN (BUILT_IN_Y1):
10489 if (validate_arg (arg0, REAL_TYPE))
10490 return do_mpfr_arg1 (arg0, type, mpfr_y1,
10491 &dconst0, NULL, false);
10492 break;
65dd1378 10493
4f35b1fc 10494 CASE_FLT_FN (BUILT_IN_NAN):
c4503c0a 10495 case BUILT_IN_NAND32:
10496 case BUILT_IN_NAND64:
10497 case BUILT_IN_NAND128:
c2f47e15 10498 return fold_builtin_nan (arg0, type, true);
b0db7939 10499
4f35b1fc 10500 CASE_FLT_FN (BUILT_IN_NANS):
c2f47e15 10501 return fold_builtin_nan (arg0, type, false);
b0db7939 10502
4f35b1fc 10503 CASE_FLT_FN (BUILT_IN_FLOOR):
c2f47e15 10504 return fold_builtin_floor (fndecl, arg0);
277f8dd2 10505
4f35b1fc 10506 CASE_FLT_FN (BUILT_IN_CEIL):
c2f47e15 10507 return fold_builtin_ceil (fndecl, arg0);
277f8dd2 10508
4f35b1fc 10509 CASE_FLT_FN (BUILT_IN_TRUNC):
c2f47e15 10510 return fold_builtin_trunc (fndecl, arg0);
277f8dd2 10511
4f35b1fc 10512 CASE_FLT_FN (BUILT_IN_ROUND):
c2f47e15 10513 return fold_builtin_round (fndecl, arg0);
89ab3887 10514
4f35b1fc 10515 CASE_FLT_FN (BUILT_IN_NEARBYINT):
10516 CASE_FLT_FN (BUILT_IN_RINT):
c2f47e15 10517 return fold_trunc_transparent_mathfn (fndecl, arg0);
6528f4f4 10518
4f35b1fc 10519 CASE_FLT_FN (BUILT_IN_LCEIL):
10520 CASE_FLT_FN (BUILT_IN_LLCEIL):
10521 CASE_FLT_FN (BUILT_IN_LFLOOR):
10522 CASE_FLT_FN (BUILT_IN_LLFLOOR):
a0c938f0 10523 CASE_FLT_FN (BUILT_IN_LROUND):
4f35b1fc 10524 CASE_FLT_FN (BUILT_IN_LLROUND):
c2f47e15 10525 return fold_builtin_int_roundingfn (fndecl, arg0);
34f17811 10526
4f35b1fc 10527 CASE_FLT_FN (BUILT_IN_LRINT):
10528 CASE_FLT_FN (BUILT_IN_LLRINT):
c2f47e15 10529 return fold_fixed_mathfn (fndecl, arg0);
9ed65c7f 10530
42791117 10531 case BUILT_IN_BSWAP32:
10532 case BUILT_IN_BSWAP64:
c2f47e15 10533 return fold_builtin_bswap (fndecl, arg0);
42791117 10534
4f35b1fc 10535 CASE_INT_FN (BUILT_IN_FFS):
10536 CASE_INT_FN (BUILT_IN_CLZ):
10537 CASE_INT_FN (BUILT_IN_CTZ):
10538 CASE_INT_FN (BUILT_IN_POPCOUNT):
10539 CASE_INT_FN (BUILT_IN_PARITY):
c2f47e15 10540 return fold_builtin_bitop (fndecl, arg0);
9c8a1629 10541
4f35b1fc 10542 CASE_FLT_FN (BUILT_IN_SIGNBIT):
c2f47e15 10543 return fold_builtin_signbit (arg0, type);
27f261ef 10544
cb2b9385 10545 CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
10546 return fold_builtin_significand (arg0, type);
10547
10548 CASE_FLT_FN (BUILT_IN_ILOGB):
10549 CASE_FLT_FN (BUILT_IN_LOGB):
10550 return fold_builtin_logb (arg0, type);
10551
d49367d4 10552 case BUILT_IN_ISASCII:
c2f47e15 10553 return fold_builtin_isascii (arg0);
d49367d4 10554
10555 case BUILT_IN_TOASCII:
c2f47e15 10556 return fold_builtin_toascii (arg0);
d49367d4 10557
df1cf42e 10558 case BUILT_IN_ISDIGIT:
c2f47e15 10559 return fold_builtin_isdigit (arg0);
467214fd 10560
4f35b1fc 10561 CASE_FLT_FN (BUILT_IN_FINITE):
c4503c0a 10562 case BUILT_IN_FINITED32:
10563 case BUILT_IN_FINITED64:
10564 case BUILT_IN_FINITED128:
cde061c1 10565 case BUILT_IN_ISFINITE:
10566 return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISFINITE);
726069ba 10567
4f35b1fc 10568 CASE_FLT_FN (BUILT_IN_ISINF):
c4503c0a 10569 case BUILT_IN_ISINFD32:
10570 case BUILT_IN_ISINFD64:
10571 case BUILT_IN_ISINFD128:
c2f47e15 10572 return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISINF);
726069ba 10573
c319d56a 10574 case BUILT_IN_ISINF_SIGN:
10575 return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISINF_SIGN);
10576
4f35b1fc 10577 CASE_FLT_FN (BUILT_IN_ISNAN):
c4503c0a 10578 case BUILT_IN_ISNAND32:
10579 case BUILT_IN_ISNAND64:
10580 case BUILT_IN_ISNAND128:
c2f47e15 10581 return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISNAN);
10582
10583 case BUILT_IN_PRINTF:
10584 case BUILT_IN_PRINTF_UNLOCKED:
10585 case BUILT_IN_VPRINTF:
10586 return fold_builtin_printf (fndecl, arg0, NULL_TREE, ignore, fcode);
10587
10588 default:
10589 break;
10590 }
10591
10592 return NULL_TREE;
10593
10594}
10595
10596/* Fold a call to built-in function FNDECL with 2 arguments, ARG0 and ARG1.
10597 IGNORE is true if the result of the function call is ignored. This
10598 function returns NULL_TREE if no simplification was possible. */
10599
10600static tree
10601fold_builtin_2 (tree fndecl, tree arg0, tree arg1, bool ignore)
10602{
10603 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10604 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10605
10606 switch (fcode)
10607 {
65dd1378 10608 CASE_FLT_FN (BUILT_IN_JN):
10609 if (validate_arg (arg0, INTEGER_TYPE)
10610 && validate_arg (arg1, REAL_TYPE))
10611 return do_mpfr_bessel_n (arg0, arg1, type, mpfr_jn, NULL, 0);
10612 break;
6ff9eeff 10613
10614 CASE_FLT_FN (BUILT_IN_YN):
10615 if (validate_arg (arg0, INTEGER_TYPE)
10616 && validate_arg (arg1, REAL_TYPE))
10617 return do_mpfr_bessel_n (arg0, arg1, type, mpfr_yn,
10618 &dconst0, false);
10619 break;
e5407ca6 10620
10621 CASE_FLT_FN (BUILT_IN_DREM):
10622 CASE_FLT_FN (BUILT_IN_REMAINDER):
10623 if (validate_arg (arg0, REAL_TYPE)
10624 && validate_arg(arg1, REAL_TYPE))
10625 return do_mpfr_arg2 (arg0, arg1, type, mpfr_remainder);
10626 break;
e84da7c1 10627
10628 CASE_FLT_FN_REENT (BUILT_IN_GAMMA): /* GAMMA_R */
10629 CASE_FLT_FN_REENT (BUILT_IN_LGAMMA): /* LGAMMA_R */
10630 if (validate_arg (arg0, REAL_TYPE)
10631 && validate_arg(arg1, POINTER_TYPE))
10632 return do_mpfr_lgamma_r (arg0, arg1, type);
10633 break;
c2f47e15 10634
10635 CASE_FLT_FN (BUILT_IN_ATAN2):
10636 if (validate_arg (arg0, REAL_TYPE)
10637 && validate_arg(arg1, REAL_TYPE))
10638 return do_mpfr_arg2 (arg0, arg1, type, mpfr_atan2);
10639 break;
10640
10641 CASE_FLT_FN (BUILT_IN_FDIM):
10642 if (validate_arg (arg0, REAL_TYPE)
10643 && validate_arg(arg1, REAL_TYPE))
10644 return do_mpfr_arg2 (arg0, arg1, type, mpfr_dim);
10645 break;
10646
10647 CASE_FLT_FN (BUILT_IN_HYPOT):
10648 return fold_builtin_hypot (fndecl, arg0, arg1, type);
10649
7587301b 10650 CASE_FLT_FN (BUILT_IN_LDEXP):
10651 return fold_builtin_load_exponent (arg0, arg1, type, /*ldexp=*/true);
10652 CASE_FLT_FN (BUILT_IN_SCALBN):
10653 CASE_FLT_FN (BUILT_IN_SCALBLN):
10654 return fold_builtin_load_exponent (arg0, arg1, type, /*ldexp=*/false);
10655
3838b9ae 10656 CASE_FLT_FN (BUILT_IN_FREXP):
10657 return fold_builtin_frexp (arg0, arg1, type);
10658
ebf8b4f5 10659 CASE_FLT_FN (BUILT_IN_MODF):
10660 return fold_builtin_modf (arg0, arg1, type);
10661
c2f47e15 10662 case BUILT_IN_BZERO:
10663 return fold_builtin_bzero (arg0, arg1, ignore);
10664
10665 case BUILT_IN_FPUTS:
10666 return fold_builtin_fputs (arg0, arg1, ignore, false, NULL_TREE);
10667
10668 case BUILT_IN_FPUTS_UNLOCKED:
10669 return fold_builtin_fputs (arg0, arg1, ignore, true, NULL_TREE);
10670
10671 case BUILT_IN_STRSTR:
10672 return fold_builtin_strstr (arg0, arg1, type);
10673
10674 case BUILT_IN_STRCAT:
10675 return fold_builtin_strcat (arg0, arg1);
10676
10677 case BUILT_IN_STRSPN:
10678 return fold_builtin_strspn (arg0, arg1);
10679
10680 case BUILT_IN_STRCSPN:
10681 return fold_builtin_strcspn (arg0, arg1);
10682
10683 case BUILT_IN_STRCHR:
10684 case BUILT_IN_INDEX:
10685 return fold_builtin_strchr (arg0, arg1, type);
10686
10687 case BUILT_IN_STRRCHR:
10688 case BUILT_IN_RINDEX:
10689 return fold_builtin_strrchr (arg0, arg1, type);
10690
10691 case BUILT_IN_STRCPY:
10692 return fold_builtin_strcpy (fndecl, arg0, arg1, NULL_TREE);
10693
c8b17b2e 10694 case BUILT_IN_STPCPY:
10695 if (ignore)
10696 {
10697 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10698 if (!fn)
10699 break;
10700
10701 return build_call_expr (fn, 2, arg0, arg1);
10702 }
10703 break;
10704
c2f47e15 10705 case BUILT_IN_STRCMP:
10706 return fold_builtin_strcmp (arg0, arg1);
10707
10708 case BUILT_IN_STRPBRK:
10709 return fold_builtin_strpbrk (arg0, arg1, type);
10710
10711 case BUILT_IN_EXPECT:
76f5a783 10712 return fold_builtin_expect (arg0, arg1);
c2f47e15 10713
10714 CASE_FLT_FN (BUILT_IN_POW):
10715 return fold_builtin_pow (fndecl, arg0, arg1, type);
10716
10717 CASE_FLT_FN (BUILT_IN_POWI):
10718 return fold_builtin_powi (fndecl, arg0, arg1, type);
10719
10720 CASE_FLT_FN (BUILT_IN_COPYSIGN):
10721 return fold_builtin_copysign (fndecl, arg0, arg1, type);
10722
10723 CASE_FLT_FN (BUILT_IN_FMIN):
10724 return fold_builtin_fmin_fmax (arg0, arg1, type, /*max=*/false);
10725
10726 CASE_FLT_FN (BUILT_IN_FMAX):
10727 return fold_builtin_fmin_fmax (arg0, arg1, type, /*max=*/true);
726069ba 10728
9bc9f15f 10729 case BUILT_IN_ISGREATER:
c2f47e15 10730 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNLE_EXPR, LE_EXPR);
9bc9f15f 10731 case BUILT_IN_ISGREATEREQUAL:
c2f47e15 10732 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNLT_EXPR, LT_EXPR);
9bc9f15f 10733 case BUILT_IN_ISLESS:
c2f47e15 10734 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNGE_EXPR, GE_EXPR);
9bc9f15f 10735 case BUILT_IN_ISLESSEQUAL:
c2f47e15 10736 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNGT_EXPR, GT_EXPR);
9bc9f15f 10737 case BUILT_IN_ISLESSGREATER:
c2f47e15 10738 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNEQ_EXPR, EQ_EXPR);
9bc9f15f 10739 case BUILT_IN_ISUNORDERED:
c2f47e15 10740 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNORDERED_EXPR,
d5019fe8 10741 NOP_EXPR);
9bc9f15f 10742
7c2f0500 10743 /* We do the folding for va_start in the expander. */
10744 case BUILT_IN_VA_START:
10745 break;
f0613857 10746
c2f47e15 10747 case BUILT_IN_SPRINTF:
10748 return fold_builtin_sprintf (arg0, arg1, NULL_TREE, ignore);
10749
0a39fd54 10750 case BUILT_IN_OBJECT_SIZE:
c2f47e15 10751 return fold_builtin_object_size (arg0, arg1);
0a39fd54 10752
10753 case BUILT_IN_PRINTF:
10754 case BUILT_IN_PRINTF_UNLOCKED:
10755 case BUILT_IN_VPRINTF:
c2f47e15 10756 return fold_builtin_printf (fndecl, arg0, arg1, ignore, fcode);
10757
0a39fd54 10758 case BUILT_IN_PRINTF_CHK:
10759 case BUILT_IN_VPRINTF_CHK:
c2f47e15 10760 if (!validate_arg (arg0, INTEGER_TYPE)
10761 || TREE_SIDE_EFFECTS (arg0))
10762 return NULL_TREE;
10763 else
10764 return fold_builtin_printf (fndecl, arg1, NULL_TREE, ignore, fcode);
10765 break;
0a39fd54 10766
10767 case BUILT_IN_FPRINTF:
10768 case BUILT_IN_FPRINTF_UNLOCKED:
10769 case BUILT_IN_VFPRINTF:
c2f47e15 10770 return fold_builtin_fprintf (fndecl, arg0, arg1, NULL_TREE,
10771 ignore, fcode);
10772
10773 default:
10774 break;
10775 }
10776 return NULL_TREE;
10777}
10778
10779/* Fold a call to built-in function FNDECL with 3 arguments, ARG0, ARG1,
10780 and ARG2. IGNORE is true if the result of the function call is ignored.
10781 This function returns NULL_TREE if no simplification was possible. */
10782
10783static tree
10784fold_builtin_3 (tree fndecl, tree arg0, tree arg1, tree arg2, bool ignore)
10785{
10786 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10787 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10788 switch (fcode)
10789 {
10790
10791 CASE_FLT_FN (BUILT_IN_SINCOS):
10792 return fold_builtin_sincos (arg0, arg1, arg2);
10793
10794 CASE_FLT_FN (BUILT_IN_FMA):
10795 if (validate_arg (arg0, REAL_TYPE)
10796 && validate_arg(arg1, REAL_TYPE)
10797 && validate_arg(arg2, REAL_TYPE))
10798 return do_mpfr_arg3 (arg0, arg1, arg2, type, mpfr_fma);
10799 break;
10800
e5407ca6 10801 CASE_FLT_FN (BUILT_IN_REMQUO):
10802 if (validate_arg (arg0, REAL_TYPE)
10803 && validate_arg(arg1, REAL_TYPE)
10804 && validate_arg(arg2, POINTER_TYPE))
10805 return do_mpfr_remquo (arg0, arg1, arg2);
10806 break;
e5407ca6 10807
c2f47e15 10808 case BUILT_IN_MEMSET:
10809 return fold_builtin_memset (arg0, arg1, arg2, type, ignore);
10810
10811 case BUILT_IN_BCOPY:
10812 return fold_builtin_memory_op (arg1, arg0, arg2, void_type_node, true, /*endp=*/3);
10813
10814 case BUILT_IN_MEMCPY:
10815 return fold_builtin_memory_op (arg0, arg1, arg2, type, ignore, /*endp=*/0);
10816
10817 case BUILT_IN_MEMPCPY:
10818 return fold_builtin_memory_op (arg0, arg1, arg2, type, ignore, /*endp=*/1);
10819
10820 case BUILT_IN_MEMMOVE:
10821 return fold_builtin_memory_op (arg0, arg1, arg2, type, ignore, /*endp=*/3);
10822
10823 case BUILT_IN_STRNCAT:
10824 return fold_builtin_strncat (arg0, arg1, arg2);
10825
10826 case BUILT_IN_STRNCPY:
10827 return fold_builtin_strncpy (fndecl, arg0, arg1, arg2, NULL_TREE);
10828
10829 case BUILT_IN_STRNCMP:
10830 return fold_builtin_strncmp (arg0, arg1, arg2);
10831
7959b13b 10832 case BUILT_IN_MEMCHR:
10833 return fold_builtin_memchr (arg0, arg1, arg2, type);
10834
c2f47e15 10835 case BUILT_IN_BCMP:
10836 case BUILT_IN_MEMCMP:
10837 return fold_builtin_memcmp (arg0, arg1, arg2);;
10838
10839 case BUILT_IN_SPRINTF:
10840 return fold_builtin_sprintf (arg0, arg1, arg2, ignore);
10841
10842 case BUILT_IN_STRCPY_CHK:
10843 case BUILT_IN_STPCPY_CHK:
10844 return fold_builtin_stxcpy_chk (fndecl, arg0, arg1, arg2, NULL_TREE,
10845 ignore, fcode);
10846
10847 case BUILT_IN_STRCAT_CHK:
10848 return fold_builtin_strcat_chk (fndecl, arg0, arg1, arg2);
10849
10850 case BUILT_IN_PRINTF_CHK:
10851 case BUILT_IN_VPRINTF_CHK:
10852 if (!validate_arg (arg0, INTEGER_TYPE)
10853 || TREE_SIDE_EFFECTS (arg0))
10854 return NULL_TREE;
10855 else
10856 return fold_builtin_printf (fndecl, arg1, arg2, ignore, fcode);
10857 break;
10858
10859 case BUILT_IN_FPRINTF:
10860 case BUILT_IN_FPRINTF_UNLOCKED:
10861 case BUILT_IN_VFPRINTF:
10862 return fold_builtin_fprintf (fndecl, arg0, arg1, arg2, ignore, fcode);
10863
0a39fd54 10864 case BUILT_IN_FPRINTF_CHK:
10865 case BUILT_IN_VFPRINTF_CHK:
c2f47e15 10866 if (!validate_arg (arg1, INTEGER_TYPE)
10867 || TREE_SIDE_EFFECTS (arg1))
10868 return NULL_TREE;
10869 else
10870 return fold_builtin_fprintf (fndecl, arg0, arg2, NULL_TREE,
10871 ignore, fcode);
0a39fd54 10872
650e4c94 10873 default:
10874 break;
10875 }
c2f47e15 10876 return NULL_TREE;
10877}
650e4c94 10878
c2f47e15 10879/* Fold a call to built-in function FNDECL with 4 arguments, ARG0, ARG1,
10880 ARG2, and ARG3. IGNORE is true if the result of the function call is
10881 ignored. This function returns NULL_TREE if no simplification was
10882 possible. */
10883
10884static tree
10885fold_builtin_4 (tree fndecl, tree arg0, tree arg1, tree arg2, tree arg3,
10886 bool ignore)
10887{
10888 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10889
10890 switch (fcode)
10891 {
10892 case BUILT_IN_MEMCPY_CHK:
10893 case BUILT_IN_MEMPCPY_CHK:
10894 case BUILT_IN_MEMMOVE_CHK:
10895 case BUILT_IN_MEMSET_CHK:
10896 return fold_builtin_memory_chk (fndecl, arg0, arg1, arg2, arg3,
10897 NULL_TREE, ignore,
10898 DECL_FUNCTION_CODE (fndecl));
10899
10900 case BUILT_IN_STRNCPY_CHK:
10901 return fold_builtin_strncpy_chk (arg0, arg1, arg2, arg3, NULL_TREE);
10902
10903 case BUILT_IN_STRNCAT_CHK:
10904 return fold_builtin_strncat_chk (fndecl, arg0, arg1, arg2, arg3);
10905
10906 case BUILT_IN_FPRINTF_CHK:
10907 case BUILT_IN_VFPRINTF_CHK:
10908 if (!validate_arg (arg1, INTEGER_TYPE)
10909 || TREE_SIDE_EFFECTS (arg1))
10910 return NULL_TREE;
10911 else
10912 return fold_builtin_fprintf (fndecl, arg0, arg2, arg3,
10913 ignore, fcode);
10914 break;
10915
10916 default:
10917 break;
10918 }
10919 return NULL_TREE;
10920}
10921
10922/* Fold a call to built-in function FNDECL. ARGS is an array of NARGS
10923 arguments, where NARGS <= 4. IGNORE is true if the result of the
10924 function call is ignored. This function returns NULL_TREE if no
10925 simplification was possible. Note that this only folds builtins with
10926 fixed argument patterns. Foldings that do varargs-to-varargs
10927 transformations, or that match calls with more than 4 arguments,
10928 need to be handled with fold_builtin_varargs instead. */
10929
10930#define MAX_ARGS_TO_FOLD_BUILTIN 4
10931
10932static tree
10933fold_builtin_n (tree fndecl, tree *args, int nargs, bool ignore)
10934{
10935 tree ret = NULL_TREE;
a7f5bb2d 10936
c2f47e15 10937 switch (nargs)
10938 {
10939 case 0:
10940 ret = fold_builtin_0 (fndecl, ignore);
10941 break;
10942 case 1:
10943 ret = fold_builtin_1 (fndecl, args[0], ignore);
10944 break;
10945 case 2:
10946 ret = fold_builtin_2 (fndecl, args[0], args[1], ignore);
10947 break;
10948 case 3:
10949 ret = fold_builtin_3 (fndecl, args[0], args[1], args[2], ignore);
10950 break;
10951 case 4:
10952 ret = fold_builtin_4 (fndecl, args[0], args[1], args[2], args[3],
10953 ignore);
10954 break;
10955 default:
10956 break;
10957 }
10958 if (ret)
10959 {
75a70cf9 10960 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
c2f47e15 10961 TREE_NO_WARNING (ret) = 1;
10962 return ret;
10963 }
10964 return NULL_TREE;
10965}
10966
10967/* Builtins with folding operations that operate on "..." arguments
10968 need special handling; we need to store the arguments in a convenient
10969 data structure before attempting any folding. Fortunately there are
10970 only a few builtins that fall into this category. FNDECL is the
10971 function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
10972 result of the function call is ignored. */
10973
10974static tree
10975fold_builtin_varargs (tree fndecl, tree exp, bool ignore ATTRIBUTE_UNUSED)
10976{
10977 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10978 tree ret = NULL_TREE;
10979
10980 switch (fcode)
10981 {
10982 case BUILT_IN_SPRINTF_CHK:
10983 case BUILT_IN_VSPRINTF_CHK:
10984 ret = fold_builtin_sprintf_chk (exp, fcode);
10985 break;
10986
10987 case BUILT_IN_SNPRINTF_CHK:
10988 case BUILT_IN_VSNPRINTF_CHK:
10989 ret = fold_builtin_snprintf_chk (exp, NULL_TREE, fcode);
19fbe3a4 10990 break;
10991
10992 case BUILT_IN_FPCLASSIFY:
10993 ret = fold_builtin_fpclassify (exp);
10994 break;
c2f47e15 10995
10996 default:
10997 break;
10998 }
10999 if (ret)
11000 {
11001 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
11002 TREE_NO_WARNING (ret) = 1;
11003 return ret;
11004 }
11005 return NULL_TREE;
650e4c94 11006}
7e15618b 11007
198622c0 11008/* Return true if FNDECL shouldn't be folded right now.
11009 If a built-in function has an inline attribute always_inline
11010 wrapper, defer folding it after always_inline functions have
11011 been inlined, otherwise e.g. -D_FORTIFY_SOURCE checking
11012 might not be performed. */
11013
11014static bool
11015avoid_folding_inline_builtin (tree fndecl)
11016{
11017 return (DECL_DECLARED_INLINE_P (fndecl)
11018 && DECL_DISREGARD_INLINE_LIMITS (fndecl)
11019 && cfun
11020 && !cfun->always_inline_functions_inlined
11021 && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fndecl)));
11022}
11023
4ee9c684 11024/* A wrapper function for builtin folding that prevents warnings for
491e04ef 11025 "statement without effect" and the like, caused by removing the
4ee9c684 11026 call node earlier than the warning is generated. */
11027
11028tree
c2f47e15 11029fold_call_expr (tree exp, bool ignore)
4ee9c684 11030{
c2f47e15 11031 tree ret = NULL_TREE;
11032 tree fndecl = get_callee_fndecl (exp);
11033 if (fndecl
11034 && TREE_CODE (fndecl) == FUNCTION_DECL
48dc2227 11035 && DECL_BUILT_IN (fndecl)
11036 /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized
11037 yet. Defer folding until we see all the arguments
11038 (after inlining). */
11039 && !CALL_EXPR_VA_ARG_PACK (exp))
11040 {
11041 int nargs = call_expr_nargs (exp);
11042
11043 /* Before gimplification CALL_EXPR_VA_ARG_PACK is not set, but
11044 instead last argument is __builtin_va_arg_pack (). Defer folding
11045 even in that case, until arguments are finalized. */
11046 if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR)
11047 {
11048 tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1));
11049 if (fndecl2
11050 && TREE_CODE (fndecl2) == FUNCTION_DECL
11051 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
11052 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
11053 return NULL_TREE;
11054 }
11055
198622c0 11056 if (avoid_folding_inline_builtin (fndecl))
11057 return NULL_TREE;
11058
c2f47e15 11059 /* FIXME: Don't use a list in this interface. */
11060 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
11061 return targetm.fold_builtin (fndecl, CALL_EXPR_ARGS (exp), ignore);
11062 else
11063 {
c2f47e15 11064 if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
11065 {
11066 tree *args = CALL_EXPR_ARGP (exp);
11067 ret = fold_builtin_n (fndecl, args, nargs, ignore);
11068 }
11069 if (!ret)
11070 ret = fold_builtin_varargs (fndecl, exp, ignore);
11071 if (ret)
11072 {
11073 /* Propagate location information from original call to
11074 expansion of builtin. Otherwise things like
11075 maybe_emit_chk_warning, that operate on the expansion
11076 of a builtin, will use the wrong location information. */
11077 if (CAN_HAVE_LOCATION_P (exp) && EXPR_HAS_LOCATION (exp))
11078 {
11079 tree realret = ret;
11080 if (TREE_CODE (ret) == NOP_EXPR)
11081 realret = TREE_OPERAND (ret, 0);
11082 if (CAN_HAVE_LOCATION_P (realret)
11083 && !EXPR_HAS_LOCATION (realret))
11084 SET_EXPR_LOCATION (realret, EXPR_LOCATION (exp));
11085 }
11086 return ret;
11087 }
11088 }
4ee9c684 11089 }
c2f47e15 11090 return NULL_TREE;
11091}
11092
11093/* Conveniently construct a function call expression. FNDECL names the
11094 function to be called and ARGLIST is a TREE_LIST of arguments. */
11095
11096tree
11097build_function_call_expr (tree fndecl, tree arglist)
11098{
11099 tree fntype = TREE_TYPE (fndecl);
11100 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
d01f58f9 11101 int n = list_length (arglist);
11102 tree *argarray = (tree *) alloca (n * sizeof (tree));
11103 int i;
11104
11105 for (i = 0; i < n; i++, arglist = TREE_CHAIN (arglist))
11106 argarray[i] = TREE_VALUE (arglist);
11107 return fold_builtin_call_array (TREE_TYPE (fntype), fn, n, argarray);
c2f47e15 11108}
11109
11110/* Conveniently construct a function call expression. FNDECL names the
11111 function to be called, N is the number of arguments, and the "..."
11112 parameters are the argument expressions. */
11113
11114tree
11115build_call_expr (tree fndecl, int n, ...)
11116{
11117 va_list ap;
c2f47e15 11118 tree fntype = TREE_TYPE (fndecl);
11119 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
d01f58f9 11120 tree *argarray = (tree *) alloca (n * sizeof (tree));
11121 int i;
c2f47e15 11122
11123 va_start (ap, n);
d01f58f9 11124 for (i = 0; i < n; i++)
11125 argarray[i] = va_arg (ap, tree);
c2f47e15 11126 va_end (ap);
d01f58f9 11127 return fold_builtin_call_array (TREE_TYPE (fntype), fn, n, argarray);
4ee9c684 11128}
11129
c2f47e15 11130/* Construct a CALL_EXPR with type TYPE with FN as the function expression.
d01f58f9 11131 N arguments are passed in the array ARGARRAY. */
805e22b2 11132
11133tree
d01f58f9 11134fold_builtin_call_array (tree type,
11135 tree fn,
11136 int n,
11137 tree *argarray)
7e15618b 11138{
c2f47e15 11139 tree ret = NULL_TREE;
11140 int i;
11141 tree exp;
11142
11143 if (TREE_CODE (fn) == ADDR_EXPR)
11144 {
11145 tree fndecl = TREE_OPERAND (fn, 0);
11146 if (TREE_CODE (fndecl) == FUNCTION_DECL
11147 && DECL_BUILT_IN (fndecl))
11148 {
48dc2227 11149 /* If last argument is __builtin_va_arg_pack (), arguments to this
11150 function are not finalized yet. Defer folding until they are. */
11151 if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
11152 {
11153 tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
11154 if (fndecl2
11155 && TREE_CODE (fndecl2) == FUNCTION_DECL
11156 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
11157 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
11158 return build_call_array (type, fn, n, argarray);
11159 }
198622c0 11160 if (avoid_folding_inline_builtin (fndecl))
11161 return build_call_array (type, fn, n, argarray);
c2f47e15 11162 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
11163 {
11164 tree arglist = NULL_TREE;
d01f58f9 11165 for (i = n - 1; i >= 0; i--)
11166 arglist = tree_cons (NULL_TREE, argarray[i], arglist);
c2f47e15 11167 ret = targetm.fold_builtin (fndecl, arglist, false);
11168 if (ret)
11169 return ret;
198622c0 11170 return build_call_array (type, fn, n, argarray);
c2f47e15 11171 }
11172 else if (n <= MAX_ARGS_TO_FOLD_BUILTIN)
11173 {
11174 /* First try the transformations that don't require consing up
11175 an exp. */
d01f58f9 11176 ret = fold_builtin_n (fndecl, argarray, n, false);
c2f47e15 11177 if (ret)
11178 return ret;
11179 }
11180
11181 /* If we got this far, we need to build an exp. */
d01f58f9 11182 exp = build_call_array (type, fn, n, argarray);
c2f47e15 11183 ret = fold_builtin_varargs (fndecl, exp, false);
11184 return ret ? ret : exp;
11185 }
11186 }
11187
d01f58f9 11188 return build_call_array (type, fn, n, argarray);
c2f47e15 11189}
11190
11191/* Construct a new CALL_EXPR using the tail of the argument list of EXP
11192 along with N new arguments specified as the "..." parameters. SKIP
11193 is the number of arguments in EXP to be omitted. This function is used
11194 to do varargs-to-varargs transformations. */
11195
11196static tree
11197rewrite_call_expr (tree exp, int skip, tree fndecl, int n, ...)
11198{
11199 int oldnargs = call_expr_nargs (exp);
11200 int nargs = oldnargs - skip + n;
11201 tree fntype = TREE_TYPE (fndecl);
11202 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
11203 tree *buffer;
11204
11205 if (n > 0)
11206 {
11207 int i, j;
11208 va_list ap;
7e15618b 11209
364c0c59 11210 buffer = XALLOCAVEC (tree, nargs);
c2f47e15 11211 va_start (ap, n);
11212 for (i = 0; i < n; i++)
11213 buffer[i] = va_arg (ap, tree);
11214 va_end (ap);
11215 for (j = skip; j < oldnargs; j++, i++)
11216 buffer[i] = CALL_EXPR_ARG (exp, j);
11217 }
11218 else
11219 buffer = CALL_EXPR_ARGP (exp) + skip;
11220
11221 return fold (build_call_array (TREE_TYPE (exp), fn, nargs, buffer));
11222}
11223
11224/* Validate a single argument ARG against a tree code CODE representing
11225 a type. */
11226
11227static bool
b7bf20db 11228validate_arg (const_tree arg, enum tree_code code)
c2f47e15 11229{
11230 if (!arg)
11231 return false;
11232 else if (code == POINTER_TYPE)
11233 return POINTER_TYPE_P (TREE_TYPE (arg));
c7f617c2 11234 else if (code == INTEGER_TYPE)
11235 return INTEGRAL_TYPE_P (TREE_TYPE (arg));
c2f47e15 11236 return code == TREE_CODE (TREE_TYPE (arg));
7e15618b 11237}
0eb671f7 11238
75a70cf9 11239/* This function validates the types of a function call argument list
11240 against a specified list of tree_codes. If the last specifier is a 0,
11241 that represents an ellipses, otherwise the last specifier must be a
11242 VOID_TYPE.
11243
11244 This is the GIMPLE version of validate_arglist. Eventually we want to
11245 completely convert builtins.c to work from GIMPLEs and the tree based
11246 validate_arglist will then be removed. */
11247
11248bool
11249validate_gimple_arglist (const_gimple call, ...)
11250{
11251 enum tree_code code;
11252 bool res = 0;
11253 va_list ap;
11254 const_tree arg;
11255 size_t i;
11256
11257 va_start (ap, call);
11258 i = 0;
11259
11260 do
11261 {
d62e827b 11262 code = (enum tree_code) va_arg (ap, int);
75a70cf9 11263 switch (code)
11264 {
11265 case 0:
11266 /* This signifies an ellipses, any further arguments are all ok. */
11267 res = true;
11268 goto end;
11269 case VOID_TYPE:
11270 /* This signifies an endlink, if no arguments remain, return
11271 true, otherwise return false. */
11272 res = (i == gimple_call_num_args (call));
11273 goto end;
11274 default:
11275 /* If no parameters remain or the parameter's code does not
11276 match the specified code, return false. Otherwise continue
11277 checking any remaining arguments. */
11278 arg = gimple_call_arg (call, i++);
11279 if (!validate_arg (arg, code))
11280 goto end;
11281 break;
11282 }
11283 }
11284 while (1);
11285
11286 /* We need gotos here since we can only have one VA_CLOSE in a
11287 function. */
11288 end: ;
11289 va_end (ap);
11290
11291 return res;
11292}
11293
0eb671f7 11294/* This function validates the types of a function call argument list
c2f47e15 11295 against a specified list of tree_codes. If the last specifier is a 0,
11296 that represents an ellipses, otherwise the last specifier must be a
11297 VOID_TYPE. */
27d0c333 11298
c2f47e15 11299bool
b7bf20db 11300validate_arglist (const_tree callexpr, ...)
0eb671f7 11301{
0eb671f7 11302 enum tree_code code;
c2f47e15 11303 bool res = 0;
ee582a61 11304 va_list ap;
b7bf20db 11305 const_call_expr_arg_iterator iter;
11306 const_tree arg;
aecda0d6 11307
c2f47e15 11308 va_start (ap, callexpr);
b7bf20db 11309 init_const_call_expr_arg_iterator (callexpr, &iter);
0eb671f7 11310
f0ce3b1f 11311 do
0eb671f7 11312 {
d62e827b 11313 code = (enum tree_code) va_arg (ap, int);
f0ce3b1f 11314 switch (code)
11315 {
11316 case 0:
11317 /* This signifies an ellipses, any further arguments are all ok. */
c2f47e15 11318 res = true;
f0ce3b1f 11319 goto end;
11320 case VOID_TYPE:
11321 /* This signifies an endlink, if no arguments remain, return
11322 true, otherwise return false. */
b7bf20db 11323 res = !more_const_call_expr_args_p (&iter);
f0ce3b1f 11324 goto end;
11325 default:
11326 /* If no parameters remain or the parameter's code does not
11327 match the specified code, return false. Otherwise continue
11328 checking any remaining arguments. */
b7bf20db 11329 arg = next_const_call_expr_arg (&iter);
c2f47e15 11330 if (!validate_arg (arg, code))
f0ce3b1f 11331 goto end;
11332 break;
11333 }
0eb671f7 11334 }
f0ce3b1f 11335 while (1);
0903457a 11336
11337 /* We need gotos here since we can only have one VA_CLOSE in a
11338 function. */
11339 end: ;
ee582a61 11340 va_end (ap);
0903457a 11341
11342 return res;
0eb671f7 11343}
fc2a2dcb 11344
fc2a2dcb 11345/* Default target-specific builtin expander that does nothing. */
11346
11347rtx
aecda0d6 11348default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
11349 rtx target ATTRIBUTE_UNUSED,
11350 rtx subtarget ATTRIBUTE_UNUSED,
11351 enum machine_mode mode ATTRIBUTE_UNUSED,
11352 int ignore ATTRIBUTE_UNUSED)
fc2a2dcb 11353{
11354 return NULL_RTX;
11355}
c7926a82 11356
01537105 11357/* Returns true is EXP represents data that would potentially reside
11358 in a readonly section. */
11359
11360static bool
11361readonly_data_expr (tree exp)
11362{
11363 STRIP_NOPS (exp);
11364
9ff0637e 11365 if (TREE_CODE (exp) != ADDR_EXPR)
11366 return false;
11367
11368 exp = get_base_address (TREE_OPERAND (exp, 0));
11369 if (!exp)
11370 return false;
11371
11372 /* Make sure we call decl_readonly_section only for trees it
11373 can handle (since it returns true for everything it doesn't
11374 understand). */
491e04ef 11375 if (TREE_CODE (exp) == STRING_CST
9ff0637e 11376 || TREE_CODE (exp) == CONSTRUCTOR
11377 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
11378 return decl_readonly_section (exp, 0);
01537105 11379 else
11380 return false;
11381}
4ee9c684 11382
c2f47e15 11383/* Simplify a call to the strstr builtin. S1 and S2 are the arguments
11384 to the call, and TYPE is its return type.
4ee9c684 11385
c2f47e15 11386 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11387 simplified form of the call as a tree.
11388
11389 The simplified form may be a constant or other expression which
11390 computes the same value, but in a more efficient manner (including
11391 calls to other builtin functions).
11392
11393 The call may contain arguments which need to be evaluated, but
11394 which are not useful to determine the result of the call. In
11395 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11396 COMPOUND_EXPR will be an argument which must be evaluated.
11397 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11398 COMPOUND_EXPR in the chain will contain the tree for the simplified
11399 form of the builtin function call. */
11400
11401static tree
c2f47e15 11402fold_builtin_strstr (tree s1, tree s2, tree type)
4ee9c684 11403{
c2f47e15 11404 if (!validate_arg (s1, POINTER_TYPE)
11405 || !validate_arg (s2, POINTER_TYPE))
11406 return NULL_TREE;
4ee9c684 11407 else
11408 {
4ee9c684 11409 tree fn;
11410 const char *p1, *p2;
11411
11412 p2 = c_getstr (s2);
11413 if (p2 == NULL)
c2f47e15 11414 return NULL_TREE;
4ee9c684 11415
11416 p1 = c_getstr (s1);
11417 if (p1 != NULL)
11418 {
11419 const char *r = strstr (p1, p2);
daa1d5f5 11420 tree tem;
4ee9c684 11421
4ee9c684 11422 if (r == NULL)
779b4c41 11423 return build_int_cst (TREE_TYPE (s1), 0);
c0c67e38 11424
11425 /* Return an offset into the constant string argument. */
0de36bdb 11426 tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
11427 s1, size_int (r - p1));
daa1d5f5 11428 return fold_convert (type, tem);
4ee9c684 11429 }
11430
7efa231c 11431 /* The argument is const char *, and the result is char *, so we need
11432 a type conversion here to avoid a warning. */
4ee9c684 11433 if (p2[0] == '\0')
7efa231c 11434 return fold_convert (type, s1);
4ee9c684 11435
11436 if (p2[1] != '\0')
c2f47e15 11437 return NULL_TREE;
4ee9c684 11438
11439 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11440 if (!fn)
c2f47e15 11441 return NULL_TREE;
4ee9c684 11442
11443 /* New argument list transforming strstr(s1, s2) to
11444 strchr(s1, s2[0]). */
c2f47e15 11445 return build_call_expr (fn, 2, s1, build_int_cst (NULL_TREE, p2[0]));
4ee9c684 11446 }
11447}
11448
c2f47e15 11449/* Simplify a call to the strchr builtin. S1 and S2 are the arguments to
11450 the call, and TYPE is its return type.
4ee9c684 11451
c2f47e15 11452 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11453 simplified form of the call as a tree.
11454
11455 The simplified form may be a constant or other expression which
11456 computes the same value, but in a more efficient manner (including
11457 calls to other builtin functions).
11458
11459 The call may contain arguments which need to be evaluated, but
11460 which are not useful to determine the result of the call. In
11461 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11462 COMPOUND_EXPR will be an argument which must be evaluated.
11463 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11464 COMPOUND_EXPR in the chain will contain the tree for the simplified
11465 form of the builtin function call. */
11466
11467static tree
c2f47e15 11468fold_builtin_strchr (tree s1, tree s2, tree type)
4ee9c684 11469{
c2f47e15 11470 if (!validate_arg (s1, POINTER_TYPE)
11471 || !validate_arg (s2, INTEGER_TYPE))
11472 return NULL_TREE;
4ee9c684 11473 else
11474 {
4ee9c684 11475 const char *p1;
11476
11477 if (TREE_CODE (s2) != INTEGER_CST)
c2f47e15 11478 return NULL_TREE;
4ee9c684 11479
11480 p1 = c_getstr (s1);
11481 if (p1 != NULL)
11482 {
11483 char c;
11484 const char *r;
daa1d5f5 11485 tree tem;
4ee9c684 11486
11487 if (target_char_cast (s2, &c))
c2f47e15 11488 return NULL_TREE;
4ee9c684 11489
11490 r = strchr (p1, c);
11491
11492 if (r == NULL)
779b4c41 11493 return build_int_cst (TREE_TYPE (s1), 0);
4ee9c684 11494
11495 /* Return an offset into the constant string argument. */
0de36bdb 11496 tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
11497 s1, size_int (r - p1));
daa1d5f5 11498 return fold_convert (type, tem);
4ee9c684 11499 }
c2f47e15 11500 return NULL_TREE;
4ee9c684 11501 }
11502}
11503
c2f47e15 11504/* Simplify a call to the strrchr builtin. S1 and S2 are the arguments to
11505 the call, and TYPE is its return type.
4ee9c684 11506
c2f47e15 11507 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11508 simplified form of the call as a tree.
11509
11510 The simplified form may be a constant or other expression which
11511 computes the same value, but in a more efficient manner (including
11512 calls to other builtin functions).
11513
11514 The call may contain arguments which need to be evaluated, but
11515 which are not useful to determine the result of the call. In
11516 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11517 COMPOUND_EXPR will be an argument which must be evaluated.
11518 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11519 COMPOUND_EXPR in the chain will contain the tree for the simplified
11520 form of the builtin function call. */
11521
11522static tree
c2f47e15 11523fold_builtin_strrchr (tree s1, tree s2, tree type)
4ee9c684 11524{
c2f47e15 11525 if (!validate_arg (s1, POINTER_TYPE)
11526 || !validate_arg (s2, INTEGER_TYPE))
11527 return NULL_TREE;
4ee9c684 11528 else
11529 {
4ee9c684 11530 tree fn;
11531 const char *p1;
11532
11533 if (TREE_CODE (s2) != INTEGER_CST)
c2f47e15 11534 return NULL_TREE;
4ee9c684 11535
11536 p1 = c_getstr (s1);
11537 if (p1 != NULL)
11538 {
11539 char c;
11540 const char *r;
daa1d5f5 11541 tree tem;
4ee9c684 11542
11543 if (target_char_cast (s2, &c))
c2f47e15 11544 return NULL_TREE;
4ee9c684 11545
11546 r = strrchr (p1, c);
11547
11548 if (r == NULL)
779b4c41 11549 return build_int_cst (TREE_TYPE (s1), 0);
4ee9c684 11550
11551 /* Return an offset into the constant string argument. */
0de36bdb 11552 tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
11553 s1, size_int (r - p1));
daa1d5f5 11554 return fold_convert (type, tem);
4ee9c684 11555 }
11556
11557 if (! integer_zerop (s2))
c2f47e15 11558 return NULL_TREE;
4ee9c684 11559
11560 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11561 if (!fn)
c2f47e15 11562 return NULL_TREE;
4ee9c684 11563
11564 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
c2f47e15 11565 return build_call_expr (fn, 2, s1, s2);
4ee9c684 11566 }
11567}
11568
c2f47e15 11569/* Simplify a call to the strpbrk builtin. S1 and S2 are the arguments
11570 to the call, and TYPE is its return type.
4ee9c684 11571
c2f47e15 11572 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11573 simplified form of the call as a tree.
11574
11575 The simplified form may be a constant or other expression which
11576 computes the same value, but in a more efficient manner (including
11577 calls to other builtin functions).
11578
11579 The call may contain arguments which need to be evaluated, but
11580 which are not useful to determine the result of the call. In
11581 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11582 COMPOUND_EXPR will be an argument which must be evaluated.
11583 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11584 COMPOUND_EXPR in the chain will contain the tree for the simplified
11585 form of the builtin function call. */
11586
11587static tree
c2f47e15 11588fold_builtin_strpbrk (tree s1, tree s2, tree type)
4ee9c684 11589{
c2f47e15 11590 if (!validate_arg (s1, POINTER_TYPE)
11591 || !validate_arg (s2, POINTER_TYPE))
11592 return NULL_TREE;
4ee9c684 11593 else
11594 {
4ee9c684 11595 tree fn;
11596 const char *p1, *p2;
11597
11598 p2 = c_getstr (s2);
11599 if (p2 == NULL)
c2f47e15 11600 return NULL_TREE;
4ee9c684 11601
11602 p1 = c_getstr (s1);
11603 if (p1 != NULL)
11604 {
11605 const char *r = strpbrk (p1, p2);
daa1d5f5 11606 tree tem;
4ee9c684 11607
11608 if (r == NULL)
779b4c41 11609 return build_int_cst (TREE_TYPE (s1), 0);
4ee9c684 11610
11611 /* Return an offset into the constant string argument. */
0de36bdb 11612 tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
11613 s1, size_int (r - p1));
daa1d5f5 11614 return fold_convert (type, tem);
4ee9c684 11615 }
11616
11617 if (p2[0] == '\0')
05abc81b 11618 /* strpbrk(x, "") == NULL.
11619 Evaluate and ignore s1 in case it had side-effects. */
11620 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
4ee9c684 11621
11622 if (p2[1] != '\0')
c2f47e15 11623 return NULL_TREE; /* Really call strpbrk. */
4ee9c684 11624
11625 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11626 if (!fn)
c2f47e15 11627 return NULL_TREE;
4ee9c684 11628
11629 /* New argument list transforming strpbrk(s1, s2) to
11630 strchr(s1, s2[0]). */
c2f47e15 11631 return build_call_expr (fn, 2, s1, build_int_cst (NULL_TREE, p2[0]));
4ee9c684 11632 }
11633}
11634
c2f47e15 11635/* Simplify a call to the strcat builtin. DST and SRC are the arguments
11636 to the call.
4ee9c684 11637
c2f47e15 11638 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11639 simplified form of the call as a tree.
11640
11641 The simplified form may be a constant or other expression which
11642 computes the same value, but in a more efficient manner (including
11643 calls to other builtin functions).
11644
11645 The call may contain arguments which need to be evaluated, but
11646 which are not useful to determine the result of the call. In
11647 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11648 COMPOUND_EXPR will be an argument which must be evaluated.
11649 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11650 COMPOUND_EXPR in the chain will contain the tree for the simplified
11651 form of the builtin function call. */
11652
11653static tree
c2f47e15 11654fold_builtin_strcat (tree dst, tree src)
4ee9c684 11655{
c2f47e15 11656 if (!validate_arg (dst, POINTER_TYPE)
11657 || !validate_arg (src, POINTER_TYPE))
11658 return NULL_TREE;
4ee9c684 11659 else
11660 {
4ee9c684 11661 const char *p = c_getstr (src);
11662
11663 /* If the string length is zero, return the dst parameter. */
11664 if (p && *p == '\0')
11665 return dst;
11666
c2f47e15 11667 return NULL_TREE;
4ee9c684 11668 }
11669}
11670
c2f47e15 11671/* Simplify a call to the strncat builtin. DST, SRC, and LEN are the
11672 arguments to the call.
4ee9c684 11673
c2f47e15 11674 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11675 simplified form of the call as a tree.
11676
11677 The simplified form may be a constant or other expression which
11678 computes the same value, but in a more efficient manner (including
11679 calls to other builtin functions).
11680
11681 The call may contain arguments which need to be evaluated, but
11682 which are not useful to determine the result of the call. In
11683 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11684 COMPOUND_EXPR will be an argument which must be evaluated.
11685 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11686 COMPOUND_EXPR in the chain will contain the tree for the simplified
11687 form of the builtin function call. */
11688
11689static tree
c2f47e15 11690fold_builtin_strncat (tree dst, tree src, tree len)
4ee9c684 11691{
c2f47e15 11692 if (!validate_arg (dst, POINTER_TYPE)
11693 || !validate_arg (src, POINTER_TYPE)
11694 || !validate_arg (len, INTEGER_TYPE))
11695 return NULL_TREE;
4ee9c684 11696 else
11697 {
4ee9c684 11698 const char *p = c_getstr (src);
11699
11700 /* If the requested length is zero, or the src parameter string
0a39fd54 11701 length is zero, return the dst parameter. */
4ee9c684 11702 if (integer_zerop (len) || (p && *p == '\0'))
a0c938f0 11703 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
4ee9c684 11704
11705 /* If the requested len is greater than or equal to the string
a0c938f0 11706 length, call strcat. */
4ee9c684 11707 if (TREE_CODE (len) == INTEGER_CST && p
11708 && compare_tree_int (len, strlen (p)) >= 0)
11709 {
4ee9c684 11710 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
11711
11712 /* If the replacement _DECL isn't initialized, don't do the
11713 transformation. */
11714 if (!fn)
c2f47e15 11715 return NULL_TREE;
4ee9c684 11716
c2f47e15 11717 return build_call_expr (fn, 2, dst, src);
4ee9c684 11718 }
c2f47e15 11719 return NULL_TREE;
4ee9c684 11720 }
11721}
11722
c2f47e15 11723/* Simplify a call to the strspn builtin. S1 and S2 are the arguments
11724 to the call.
4ee9c684 11725
c2f47e15 11726 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11727 simplified form of the call as a tree.
11728
11729 The simplified form may be a constant or other expression which
11730 computes the same value, but in a more efficient manner (including
11731 calls to other builtin functions).
11732
11733 The call may contain arguments which need to be evaluated, but
11734 which are not useful to determine the result of the call. In
11735 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11736 COMPOUND_EXPR will be an argument which must be evaluated.
11737 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11738 COMPOUND_EXPR in the chain will contain the tree for the simplified
11739 form of the builtin function call. */
11740
11741static tree
c2f47e15 11742fold_builtin_strspn (tree s1, tree s2)
4ee9c684 11743{
c2f47e15 11744 if (!validate_arg (s1, POINTER_TYPE)
11745 || !validate_arg (s2, POINTER_TYPE))
11746 return NULL_TREE;
4ee9c684 11747 else
11748 {
4ee9c684 11749 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11750
11751 /* If both arguments are constants, evaluate at compile-time. */
11752 if (p1 && p2)
11753 {
11754 const size_t r = strspn (p1, p2);
11755 return size_int (r);
11756 }
11757
c2f47e15 11758 /* If either argument is "", return NULL_TREE. */
4ee9c684 11759 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9bc9f15f 11760 /* Evaluate and ignore both arguments in case either one has
11761 side-effects. */
39761420 11762 return omit_two_operands (size_type_node, size_zero_node,
9bc9f15f 11763 s1, s2);
c2f47e15 11764 return NULL_TREE;
4ee9c684 11765 }
11766}
11767
c2f47e15 11768/* Simplify a call to the strcspn builtin. S1 and S2 are the arguments
11769 to the call.
4ee9c684 11770
c2f47e15 11771 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11772 simplified form of the call as a tree.
11773
11774 The simplified form may be a constant or other expression which
11775 computes the same value, but in a more efficient manner (including
11776 calls to other builtin functions).
11777
11778 The call may contain arguments which need to be evaluated, but
11779 which are not useful to determine the result of the call. In
11780 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11781 COMPOUND_EXPR will be an argument which must be evaluated.
11782 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11783 COMPOUND_EXPR in the chain will contain the tree for the simplified
11784 form of the builtin function call. */
11785
11786static tree
c2f47e15 11787fold_builtin_strcspn (tree s1, tree s2)
4ee9c684 11788{
c2f47e15 11789 if (!validate_arg (s1, POINTER_TYPE)
11790 || !validate_arg (s2, POINTER_TYPE))
11791 return NULL_TREE;
4ee9c684 11792 else
11793 {
4ee9c684 11794 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11795
11796 /* If both arguments are constants, evaluate at compile-time. */
11797 if (p1 && p2)
11798 {
11799 const size_t r = strcspn (p1, p2);
11800 return size_int (r);
11801 }
11802
c2f47e15 11803 /* If the first argument is "", return NULL_TREE. */
4ee9c684 11804 if (p1 && *p1 == '\0')
11805 {
11806 /* Evaluate and ignore argument s2 in case it has
11807 side-effects. */
39761420 11808 return omit_one_operand (size_type_node,
11809 size_zero_node, s2);
4ee9c684 11810 }
11811
11812 /* If the second argument is "", return __builtin_strlen(s1). */
11813 if (p2 && *p2 == '\0')
11814 {
c2f47e15 11815 tree fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4ee9c684 11816
11817 /* If the replacement _DECL isn't initialized, don't do the
11818 transformation. */
11819 if (!fn)
c2f47e15 11820 return NULL_TREE;
4ee9c684 11821
c2f47e15 11822 return build_call_expr (fn, 1, s1);
4ee9c684 11823 }
c2f47e15 11824 return NULL_TREE;
4ee9c684 11825 }
11826}
11827
c2f47e15 11828/* Fold a call to the fputs builtin. ARG0 and ARG1 are the arguments
11829 to the call. IGNORE is true if the value returned
f0613857 11830 by the builtin will be ignored. UNLOCKED is true is true if this
11831 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
11832 the known length of the string. Return NULL_TREE if no simplification
11833 was possible. */
4ee9c684 11834
11835tree
c2f47e15 11836fold_builtin_fputs (tree arg0, tree arg1, bool ignore, bool unlocked, tree len)
4ee9c684 11837{
6d77ed92 11838 /* If we're using an unlocked function, assume the other unlocked
11839 functions exist explicitly. */
11840 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4ee9c684 11841 : implicit_built_in_decls[BUILT_IN_FPUTC];
6d77ed92 11842 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4ee9c684 11843 : implicit_built_in_decls[BUILT_IN_FWRITE];
11844
c403edd4 11845 /* If the return value is used, don't do the transformation. */
11846 if (!ignore)
c2f47e15 11847 return NULL_TREE;
4ee9c684 11848
11849 /* Verify the arguments in the original call. */
c2f47e15 11850 if (!validate_arg (arg0, POINTER_TYPE)
11851 || !validate_arg (arg1, POINTER_TYPE))
11852 return NULL_TREE;
4ee9c684 11853
f0613857 11854 if (! len)
c2f47e15 11855 len = c_strlen (arg0, 0);
4ee9c684 11856
11857 /* Get the length of the string passed to fputs. If the length
11858 can't be determined, punt. */
11859 if (!len
11860 || TREE_CODE (len) != INTEGER_CST)
c2f47e15 11861 return NULL_TREE;
4ee9c684 11862
11863 switch (compare_tree_int (len, 1))
11864 {
11865 case -1: /* length is 0, delete the call entirely . */
c2f47e15 11866 return omit_one_operand (integer_type_node, integer_zero_node, arg1);;
05abc81b 11867
4ee9c684 11868 case 0: /* length is 1, call fputc. */
11869 {
c2f47e15 11870 const char *p = c_getstr (arg0);
4ee9c684 11871
11872 if (p != NULL)
11873 {
c2f47e15 11874 if (fn_fputc)
11875 return build_call_expr (fn_fputc, 2,
11876 build_int_cst (NULL_TREE, p[0]), arg1);
11877 else
11878 return NULL_TREE;
4ee9c684 11879 }
11880 }
11881 /* FALLTHROUGH */
11882 case 1: /* length is greater than 1, call fwrite. */
11883 {
0bed3869 11884 /* If optimizing for size keep fputs. */
0bfd8d5c 11885 if (optimize_function_for_size_p (cfun))
c2f47e15 11886 return NULL_TREE;
4ee9c684 11887 /* New argument list transforming fputs(string, stream) to
11888 fwrite(string, 1, len, stream). */
c2f47e15 11889 if (fn_fwrite)
11890 return build_call_expr (fn_fwrite, 4, arg0, size_one_node, len, arg1);
11891 else
11892 return NULL_TREE;
4ee9c684 11893 }
11894 default:
64db345d 11895 gcc_unreachable ();
4ee9c684 11896 }
c2f47e15 11897 return NULL_TREE;
4ee9c684 11898}
11899
c2f47e15 11900/* Fold the next_arg or va_start call EXP. Returns true if there was an error
743b0c6a 11901 produced. False otherwise. This is done so that we don't output the error
11902 or warning twice or three times. */
75a70cf9 11903
743b0c6a 11904bool
c2f47e15 11905fold_builtin_next_arg (tree exp, bool va_start_p)
4ee9c684 11906{
11907 tree fntype = TREE_TYPE (current_function_decl);
c2f47e15 11908 int nargs = call_expr_nargs (exp);
11909 tree arg;
4ee9c684 11910
11911 if (TYPE_ARG_TYPES (fntype) == 0
11912 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
11913 == void_type_node))
743b0c6a 11914 {
11915 error ("%<va_start%> used in function with fixed args");
11916 return true;
11917 }
c2f47e15 11918
11919 if (va_start_p)
79012a9d 11920 {
c2f47e15 11921 if (va_start_p && (nargs != 2))
11922 {
11923 error ("wrong number of arguments to function %<va_start%>");
11924 return true;
11925 }
11926 arg = CALL_EXPR_ARG (exp, 1);
79012a9d 11927 }
11928 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
11929 when we checked the arguments and if needed issued a warning. */
c2f47e15 11930 else
4ee9c684 11931 {
c2f47e15 11932 if (nargs == 0)
11933 {
11934 /* Evidently an out of date version of <stdarg.h>; can't validate
11935 va_start's second argument, but can still work as intended. */
11936 warning (0, "%<__builtin_next_arg%> called without an argument");
11937 return true;
11938 }
11939 else if (nargs > 1)
a0c938f0 11940 {
c2f47e15 11941 error ("wrong number of arguments to function %<__builtin_next_arg%>");
a0c938f0 11942 return true;
11943 }
c2f47e15 11944 arg = CALL_EXPR_ARG (exp, 0);
11945 }
11946
a8dd994c 11947 if (TREE_CODE (arg) == SSA_NAME)
11948 arg = SSA_NAME_VAR (arg);
11949
c2f47e15 11950 /* We destructively modify the call to be __builtin_va_start (ap, 0)
11951 or __builtin_next_arg (0) the first time we see it, after checking
11952 the arguments and if needed issuing a warning. */
11953 if (!integer_zerop (arg))
11954 {
11955 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
79012a9d 11956
4ee9c684 11957 /* Strip off all nops for the sake of the comparison. This
11958 is not quite the same as STRIP_NOPS. It does more.
11959 We must also strip off INDIRECT_EXPR for C++ reference
11960 parameters. */
72dd6141 11961 while (CONVERT_EXPR_P (arg)
4ee9c684 11962 || TREE_CODE (arg) == INDIRECT_REF)
11963 arg = TREE_OPERAND (arg, 0);
11964 if (arg != last_parm)
a0c938f0 11965 {
b08cf617 11966 /* FIXME: Sometimes with the tree optimizers we can get the
11967 not the last argument even though the user used the last
11968 argument. We just warn and set the arg to be the last
11969 argument so that we will get wrong-code because of
11970 it. */
c3ceba8e 11971 warning (0, "second parameter of %<va_start%> not last named argument");
743b0c6a 11972 }
24158ad7 11973
11974 /* Undefined by C99 7.15.1.4p4 (va_start):
11975 "If the parameter parmN is declared with the register storage
11976 class, with a function or array type, or with a type that is
11977 not compatible with the type that results after application of
11978 the default argument promotions, the behavior is undefined."
11979 */
11980 else if (DECL_REGISTER (arg))
11981 warning (0, "undefined behaviour when second parameter of "
11982 "%<va_start%> is declared with %<register%> storage");
11983
79012a9d 11984 /* We want to verify the second parameter just once before the tree
a0c938f0 11985 optimizers are run and then avoid keeping it in the tree,
11986 as otherwise we could warn even for correct code like:
11987 void foo (int i, ...)
11988 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
c2f47e15 11989 if (va_start_p)
11990 CALL_EXPR_ARG (exp, 1) = integer_zero_node;
11991 else
11992 CALL_EXPR_ARG (exp, 0) = integer_zero_node;
743b0c6a 11993 }
11994 return false;
4ee9c684 11995}
11996
11997
c2f47e15 11998/* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG.
11999 ORIG may be null if this is a 2-argument call. We don't attempt to
12000 simplify calls with more than 3 arguments.
4ee9c684 12001
c2f47e15 12002 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 12003 simplified form of the call as a tree. If IGNORED is true, it means that
12004 the caller does not use the returned value of the function. */
12005
12006static tree
c2f47e15 12007fold_builtin_sprintf (tree dest, tree fmt, tree orig, int ignored)
4ee9c684 12008{
c2f47e15 12009 tree call, retval;
4ee9c684 12010 const char *fmt_str = NULL;
12011
12012 /* Verify the required arguments in the original call. We deal with two
12013 types of sprintf() calls: 'sprintf (str, fmt)' and
12014 'sprintf (dest, "%s", orig)'. */
c2f47e15 12015 if (!validate_arg (dest, POINTER_TYPE)
12016 || !validate_arg (fmt, POINTER_TYPE))
12017 return NULL_TREE;
12018 if (orig && !validate_arg (orig, POINTER_TYPE))
4ee9c684 12019 return NULL_TREE;
4ee9c684 12020
12021 /* Check whether the format is a literal string constant. */
12022 fmt_str = c_getstr (fmt);
12023 if (fmt_str == NULL)
12024 return NULL_TREE;
12025
12026 call = NULL_TREE;
12027 retval = NULL_TREE;
12028
d4473c84 12029 if (!init_target_chars ())
c2f47e15 12030 return NULL_TREE;
99eabcc1 12031
4ee9c684 12032 /* If the format doesn't contain % args or %%, use strcpy. */
99eabcc1 12033 if (strchr (fmt_str, target_percent) == NULL)
4ee9c684 12034 {
12035 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
12036
12037 if (!fn)
12038 return NULL_TREE;
12039
72dfb3f2 12040 /* Don't optimize sprintf (buf, "abc", ptr++). */
c2f47e15 12041 if (orig)
72dfb3f2 12042 return NULL_TREE;
12043
4ee9c684 12044 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
12045 'format' is known to contain no % formats. */
c2f47e15 12046 call = build_call_expr (fn, 2, dest, fmt);
4ee9c684 12047 if (!ignored)
7016c612 12048 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
4ee9c684 12049 }
12050
12051 /* If the format is "%s", use strcpy if the result isn't used. */
99eabcc1 12052 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
4ee9c684 12053 {
c2f47e15 12054 tree fn;
4ee9c684 12055 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
12056
12057 if (!fn)
12058 return NULL_TREE;
12059
72dfb3f2 12060 /* Don't crash on sprintf (str1, "%s"). */
c2f47e15 12061 if (!orig)
72dfb3f2 12062 return NULL_TREE;
12063
4ee9c684 12064 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
4ee9c684 12065 if (!ignored)
12066 {
12067 retval = c_strlen (orig, 1);
12068 if (!retval || TREE_CODE (retval) != INTEGER_CST)
12069 return NULL_TREE;
12070 }
c2f47e15 12071 call = build_call_expr (fn, 2, dest, orig);
4ee9c684 12072 }
12073
12074 if (call && retval)
12075 {
e3b560a6 12076 retval = fold_convert
4ee9c684 12077 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
12078 retval);
05abc81b 12079 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
4ee9c684 12080 }
12081 else
12082 return call;
12083}
0a39fd54 12084
c2f47e15 12085/* Expand a call EXP to __builtin_object_size. */
0a39fd54 12086
12087rtx
12088expand_builtin_object_size (tree exp)
12089{
12090 tree ost;
12091 int object_size_type;
12092 tree fndecl = get_callee_fndecl (exp);
0a39fd54 12093
c2f47e15 12094 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
0a39fd54 12095 {
b8c23db3 12096 error ("%Kfirst argument of %D must be a pointer, second integer constant",
12097 exp, fndecl);
0a39fd54 12098 expand_builtin_trap ();
12099 return const0_rtx;
12100 }
12101
c2f47e15 12102 ost = CALL_EXPR_ARG (exp, 1);
0a39fd54 12103 STRIP_NOPS (ost);
12104
12105 if (TREE_CODE (ost) != INTEGER_CST
12106 || tree_int_cst_sgn (ost) < 0
12107 || compare_tree_int (ost, 3) > 0)
12108 {
b8c23db3 12109 error ("%Klast argument of %D is not integer constant between 0 and 3",
12110 exp, fndecl);
0a39fd54 12111 expand_builtin_trap ();
12112 return const0_rtx;
12113 }
12114
12115 object_size_type = tree_low_cst (ost, 0);
12116
12117 return object_size_type < 2 ? constm1_rtx : const0_rtx;
12118}
12119
12120/* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
12121 FCODE is the BUILT_IN_* to use.
c2f47e15 12122 Return NULL_RTX if we failed; the caller should emit a normal call,
0a39fd54 12123 otherwise try to get the result in TARGET, if convenient (and in
12124 mode MODE if that's convenient). */
12125
12126static rtx
12127expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
12128 enum built_in_function fcode)
12129{
0a39fd54 12130 tree dest, src, len, size;
12131
c2f47e15 12132 if (!validate_arglist (exp,
0a39fd54 12133 POINTER_TYPE,
12134 fcode == BUILT_IN_MEMSET_CHK
12135 ? INTEGER_TYPE : POINTER_TYPE,
12136 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
c2f47e15 12137 return NULL_RTX;
0a39fd54 12138
c2f47e15 12139 dest = CALL_EXPR_ARG (exp, 0);
12140 src = CALL_EXPR_ARG (exp, 1);
12141 len = CALL_EXPR_ARG (exp, 2);
12142 size = CALL_EXPR_ARG (exp, 3);
0a39fd54 12143
12144 if (! host_integerp (size, 1))
c2f47e15 12145 return NULL_RTX;
0a39fd54 12146
12147 if (host_integerp (len, 1) || integer_all_onesp (size))
12148 {
12149 tree fn;
12150
12151 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
12152 {
b430e8d9 12153 warning_at (tree_nonartificial_location (exp),
12154 0, "%Kcall to %D will always overflow destination buffer",
12155 exp, get_callee_fndecl (exp));
c2f47e15 12156 return NULL_RTX;
0a39fd54 12157 }
12158
0a39fd54 12159 fn = NULL_TREE;
12160 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12161 mem{cpy,pcpy,move,set} is available. */
12162 switch (fcode)
12163 {
12164 case BUILT_IN_MEMCPY_CHK:
12165 fn = built_in_decls[BUILT_IN_MEMCPY];
12166 break;
12167 case BUILT_IN_MEMPCPY_CHK:
12168 fn = built_in_decls[BUILT_IN_MEMPCPY];
12169 break;
12170 case BUILT_IN_MEMMOVE_CHK:
12171 fn = built_in_decls[BUILT_IN_MEMMOVE];
12172 break;
12173 case BUILT_IN_MEMSET_CHK:
12174 fn = built_in_decls[BUILT_IN_MEMSET];
12175 break;
12176 default:
12177 break;
12178 }
12179
12180 if (! fn)
c2f47e15 12181 return NULL_RTX;
0a39fd54 12182
c2f47e15 12183 fn = build_call_expr (fn, 3, dest, src, len);
6d54e886 12184 STRIP_TYPE_NOPS (fn);
12185 while (TREE_CODE (fn) == COMPOUND_EXPR)
12186 {
12187 expand_expr (TREE_OPERAND (fn, 0), const0_rtx, VOIDmode,
12188 EXPAND_NORMAL);
12189 fn = TREE_OPERAND (fn, 1);
12190 }
0a39fd54 12191 if (TREE_CODE (fn) == CALL_EXPR)
12192 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
12193 return expand_expr (fn, target, mode, EXPAND_NORMAL);
12194 }
12195 else if (fcode == BUILT_IN_MEMSET_CHK)
c2f47e15 12196 return NULL_RTX;
0a39fd54 12197 else
12198 {
12199 unsigned int dest_align
12200 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
12201
12202 /* If DEST is not a pointer type, call the normal function. */
12203 if (dest_align == 0)
c2f47e15 12204 return NULL_RTX;
0a39fd54 12205
12206 /* If SRC and DEST are the same (and not volatile), do nothing. */
12207 if (operand_equal_p (src, dest, 0))
12208 {
12209 tree expr;
12210
12211 if (fcode != BUILT_IN_MEMPCPY_CHK)
12212 {
12213 /* Evaluate and ignore LEN in case it has side-effects. */
12214 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
12215 return expand_expr (dest, target, mode, EXPAND_NORMAL);
12216 }
12217
0de36bdb 12218 expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
0a39fd54 12219 return expand_expr (expr, target, mode, EXPAND_NORMAL);
12220 }
12221
12222 /* __memmove_chk special case. */
12223 if (fcode == BUILT_IN_MEMMOVE_CHK)
12224 {
12225 unsigned int src_align
12226 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
12227
12228 if (src_align == 0)
c2f47e15 12229 return NULL_RTX;
0a39fd54 12230
12231 /* If src is categorized for a readonly section we can use
12232 normal __memcpy_chk. */
12233 if (readonly_data_expr (src))
12234 {
12235 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12236 if (!fn)
c2f47e15 12237 return NULL_RTX;
12238 fn = build_call_expr (fn, 4, dest, src, len, size);
6d54e886 12239 STRIP_TYPE_NOPS (fn);
12240 while (TREE_CODE (fn) == COMPOUND_EXPR)
12241 {
12242 expand_expr (TREE_OPERAND (fn, 0), const0_rtx, VOIDmode,
12243 EXPAND_NORMAL);
12244 fn = TREE_OPERAND (fn, 1);
12245 }
0a39fd54 12246 if (TREE_CODE (fn) == CALL_EXPR)
12247 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
12248 return expand_expr (fn, target, mode, EXPAND_NORMAL);
12249 }
12250 }
c2f47e15 12251 return NULL_RTX;
0a39fd54 12252 }
12253}
12254
12255/* Emit warning if a buffer overflow is detected at compile time. */
12256
12257static void
12258maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
12259{
c2f47e15 12260 int is_strlen = 0;
0a39fd54 12261 tree len, size;
b430e8d9 12262 location_t loc = tree_nonartificial_location (exp);
0a39fd54 12263
12264 switch (fcode)
12265 {
12266 case BUILT_IN_STRCPY_CHK:
12267 case BUILT_IN_STPCPY_CHK:
12268 /* For __strcat_chk the warning will be emitted only if overflowing
12269 by at least strlen (dest) + 1 bytes. */
12270 case BUILT_IN_STRCAT_CHK:
c2f47e15 12271 len = CALL_EXPR_ARG (exp, 1);
12272 size = CALL_EXPR_ARG (exp, 2);
0a39fd54 12273 is_strlen = 1;
12274 break;
b356dfef 12275 case BUILT_IN_STRNCAT_CHK:
0a39fd54 12276 case BUILT_IN_STRNCPY_CHK:
c2f47e15 12277 len = CALL_EXPR_ARG (exp, 2);
12278 size = CALL_EXPR_ARG (exp, 3);
0a39fd54 12279 break;
12280 case BUILT_IN_SNPRINTF_CHK:
12281 case BUILT_IN_VSNPRINTF_CHK:
c2f47e15 12282 len = CALL_EXPR_ARG (exp, 1);
12283 size = CALL_EXPR_ARG (exp, 3);
0a39fd54 12284 break;
12285 default:
12286 gcc_unreachable ();
12287 }
12288
0a39fd54 12289 if (!len || !size)
12290 return;
12291
0a39fd54 12292 if (! host_integerp (size, 1) || integer_all_onesp (size))
12293 return;
12294
12295 if (is_strlen)
12296 {
12297 len = c_strlen (len, 1);
12298 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12299 return;
12300 }
b356dfef 12301 else if (fcode == BUILT_IN_STRNCAT_CHK)
12302 {
c2f47e15 12303 tree src = CALL_EXPR_ARG (exp, 1);
b356dfef 12304 if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12305 return;
12306 src = c_strlen (src, 1);
12307 if (! src || ! host_integerp (src, 1))
12308 {
b430e8d9 12309 warning_at (loc, 0, "%Kcall to %D might overflow destination buffer",
12310 exp, get_callee_fndecl (exp));
b356dfef 12311 return;
12312 }
12313 else if (tree_int_cst_lt (src, size))
12314 return;
12315 }
0a39fd54 12316 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
12317 return;
12318
b430e8d9 12319 warning_at (loc, 0, "%Kcall to %D will always overflow destination buffer",
12320 exp, get_callee_fndecl (exp));
0a39fd54 12321}
12322
12323/* Emit warning if a buffer overflow is detected at compile time
12324 in __sprintf_chk/__vsprintf_chk calls. */
12325
12326static void
12327maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
12328{
0a39fd54 12329 tree dest, size, len, fmt, flag;
12330 const char *fmt_str;
c2f47e15 12331 int nargs = call_expr_nargs (exp);
0a39fd54 12332
12333 /* Verify the required arguments in the original call. */
c2f47e15 12334
12335 if (nargs < 4)
0a39fd54 12336 return;
c2f47e15 12337 dest = CALL_EXPR_ARG (exp, 0);
12338 flag = CALL_EXPR_ARG (exp, 1);
12339 size = CALL_EXPR_ARG (exp, 2);
12340 fmt = CALL_EXPR_ARG (exp, 3);
0a39fd54 12341
12342 if (! host_integerp (size, 1) || integer_all_onesp (size))
12343 return;
12344
12345 /* Check whether the format is a literal string constant. */
12346 fmt_str = c_getstr (fmt);
12347 if (fmt_str == NULL)
12348 return;
12349
d4473c84 12350 if (!init_target_chars ())
99eabcc1 12351 return;
12352
0a39fd54 12353 /* If the format doesn't contain % args or %%, we know its size. */
99eabcc1 12354 if (strchr (fmt_str, target_percent) == 0)
0a39fd54 12355 len = build_int_cstu (size_type_node, strlen (fmt_str));
12356 /* If the format is "%s" and first ... argument is a string literal,
12357 we know it too. */
c2f47e15 12358 else if (fcode == BUILT_IN_SPRINTF_CHK
12359 && strcmp (fmt_str, target_percent_s) == 0)
0a39fd54 12360 {
12361 tree arg;
12362
c2f47e15 12363 if (nargs < 5)
0a39fd54 12364 return;
c2f47e15 12365 arg = CALL_EXPR_ARG (exp, 4);
0a39fd54 12366 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
12367 return;
12368
12369 len = c_strlen (arg, 1);
12370 if (!len || ! host_integerp (len, 1))
12371 return;
12372 }
12373 else
12374 return;
12375
12376 if (! tree_int_cst_lt (len, size))
b430e8d9 12377 warning_at (tree_nonartificial_location (exp),
12378 0, "%Kcall to %D will always overflow destination buffer",
12379 exp, get_callee_fndecl (exp));
0a39fd54 12380}
12381
2c281b15 12382/* Emit warning if a free is called with address of a variable. */
12383
12384static void
12385maybe_emit_free_warning (tree exp)
12386{
12387 tree arg = CALL_EXPR_ARG (exp, 0);
12388
12389 STRIP_NOPS (arg);
12390 if (TREE_CODE (arg) != ADDR_EXPR)
12391 return;
12392
12393 arg = get_base_address (TREE_OPERAND (arg, 0));
12394 if (arg == NULL || INDIRECT_REF_P (arg))
12395 return;
12396
12397 if (SSA_VAR_P (arg))
b430e8d9 12398 warning_at (tree_nonartificial_location (exp),
12399 0, "%Kattempt to free a non-heap object %qD", exp, arg);
2c281b15 12400 else
b430e8d9 12401 warning_at (tree_nonartificial_location (exp),
12402 0, "%Kattempt to free a non-heap object", exp);
2c281b15 12403}
12404
c2f47e15 12405/* Fold a call to __builtin_object_size with arguments PTR and OST,
12406 if possible. */
0a39fd54 12407
12408tree
c2f47e15 12409fold_builtin_object_size (tree ptr, tree ost)
0a39fd54 12410{
c2f47e15 12411 tree ret = NULL_TREE;
0a39fd54 12412 int object_size_type;
12413
c2f47e15 12414 if (!validate_arg (ptr, POINTER_TYPE)
12415 || !validate_arg (ost, INTEGER_TYPE))
12416 return NULL_TREE;
0a39fd54 12417
0a39fd54 12418 STRIP_NOPS (ost);
12419
12420 if (TREE_CODE (ost) != INTEGER_CST
12421 || tree_int_cst_sgn (ost) < 0
12422 || compare_tree_int (ost, 3) > 0)
c2f47e15 12423 return NULL_TREE;
0a39fd54 12424
12425 object_size_type = tree_low_cst (ost, 0);
12426
12427 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
12428 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
12429 and (size_t) 0 for types 2 and 3. */
12430 if (TREE_SIDE_EFFECTS (ptr))
697bbc3f 12431 return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0);
0a39fd54 12432
12433 if (TREE_CODE (ptr) == ADDR_EXPR)
12434 ret = build_int_cstu (size_type_node,
697bbc3f 12435 compute_builtin_object_size (ptr, object_size_type));
0a39fd54 12436
12437 else if (TREE_CODE (ptr) == SSA_NAME)
12438 {
12439 unsigned HOST_WIDE_INT bytes;
12440
12441 /* If object size is not known yet, delay folding until
12442 later. Maybe subsequent passes will help determining
12443 it. */
12444 bytes = compute_builtin_object_size (ptr, object_size_type);
12445 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
12446 ? -1 : 0))
12447 ret = build_int_cstu (size_type_node, bytes);
12448 }
12449
12450 if (ret)
12451 {
697bbc3f 12452 unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (ret);
12453 HOST_WIDE_INT high = TREE_INT_CST_HIGH (ret);
12454 if (fit_double_type (low, high, &low, &high, TREE_TYPE (ret)))
12455 ret = NULL_TREE;
0a39fd54 12456 }
12457
12458 return ret;
12459}
12460
12461/* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
c2f47e15 12462 DEST, SRC, LEN, and SIZE are the arguments to the call.
0a39fd54 12463 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
12464 code of the builtin. If MAXLEN is not NULL, it is maximum length
12465 passed as third argument. */
12466
12467tree
c2f47e15 12468fold_builtin_memory_chk (tree fndecl,
12469 tree dest, tree src, tree len, tree size,
12470 tree maxlen, bool ignore,
0a39fd54 12471 enum built_in_function fcode)
12472{
c2f47e15 12473 tree fn;
0a39fd54 12474
c2f47e15 12475 if (!validate_arg (dest, POINTER_TYPE)
12476 || !validate_arg (src,
12477 (fcode == BUILT_IN_MEMSET_CHK
12478 ? INTEGER_TYPE : POINTER_TYPE))
12479 || !validate_arg (len, INTEGER_TYPE)
12480 || !validate_arg (size, INTEGER_TYPE))
12481 return NULL_TREE;
0a39fd54 12482
12483 /* If SRC and DEST are the same (and not volatile), return DEST
12484 (resp. DEST+LEN for __mempcpy_chk). */
12485 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
12486 {
12487 if (fcode != BUILT_IN_MEMPCPY_CHK)
12488 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
12489 else
12490 {
0de36bdb 12491 tree temp = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
0a39fd54 12492 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
12493 }
12494 }
12495
12496 if (! host_integerp (size, 1))
c2f47e15 12497 return NULL_TREE;
0a39fd54 12498
12499 if (! integer_all_onesp (size))
12500 {
12501 if (! host_integerp (len, 1))
12502 {
12503 /* If LEN is not constant, try MAXLEN too.
12504 For MAXLEN only allow optimizing into non-_ocs function
12505 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12506 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12507 {
12508 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
12509 {
12510 /* (void) __mempcpy_chk () can be optimized into
12511 (void) __memcpy_chk (). */
12512 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12513 if (!fn)
c2f47e15 12514 return NULL_TREE;
0a39fd54 12515
c2f47e15 12516 return build_call_expr (fn, 4, dest, src, len, size);
0a39fd54 12517 }
c2f47e15 12518 return NULL_TREE;
0a39fd54 12519 }
0a39fd54 12520 }
ad89623c 12521 else
12522 maxlen = len;
0a39fd54 12523
ad89623c 12524 if (tree_int_cst_lt (size, maxlen))
c2f47e15 12525 return NULL_TREE;
0a39fd54 12526 }
12527
0a39fd54 12528 fn = NULL_TREE;
12529 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12530 mem{cpy,pcpy,move,set} is available. */
12531 switch (fcode)
12532 {
12533 case BUILT_IN_MEMCPY_CHK:
12534 fn = built_in_decls[BUILT_IN_MEMCPY];
12535 break;
12536 case BUILT_IN_MEMPCPY_CHK:
12537 fn = built_in_decls[BUILT_IN_MEMPCPY];
12538 break;
12539 case BUILT_IN_MEMMOVE_CHK:
12540 fn = built_in_decls[BUILT_IN_MEMMOVE];
12541 break;
12542 case BUILT_IN_MEMSET_CHK:
12543 fn = built_in_decls[BUILT_IN_MEMSET];
12544 break;
12545 default:
12546 break;
12547 }
12548
12549 if (!fn)
c2f47e15 12550 return NULL_TREE;
0a39fd54 12551
c2f47e15 12552 return build_call_expr (fn, 3, dest, src, len);
0a39fd54 12553}
12554
12555/* Fold a call to the __st[rp]cpy_chk builtin.
c2f47e15 12556 DEST, SRC, and SIZE are the arguments to the call.
12557 IGNORE is true if return value can be ignored. FCODE is the BUILT_IN_*
0a39fd54 12558 code of the builtin. If MAXLEN is not NULL, it is maximum length of
12559 strings passed as second argument. */
12560
12561tree
c2f47e15 12562fold_builtin_stxcpy_chk (tree fndecl, tree dest, tree src, tree size,
12563 tree maxlen, bool ignore,
0a39fd54 12564 enum built_in_function fcode)
12565{
c2f47e15 12566 tree len, fn;
0a39fd54 12567
c2f47e15 12568 if (!validate_arg (dest, POINTER_TYPE)
12569 || !validate_arg (src, POINTER_TYPE)
12570 || !validate_arg (size, INTEGER_TYPE))
12571 return NULL_TREE;
0a39fd54 12572
12573 /* If SRC and DEST are the same (and not volatile), return DEST. */
12574 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
12575 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
a0c938f0 12576
0a39fd54 12577 if (! host_integerp (size, 1))
c2f47e15 12578 return NULL_TREE;
0a39fd54 12579
12580 if (! integer_all_onesp (size))
12581 {
12582 len = c_strlen (src, 1);
12583 if (! len || ! host_integerp (len, 1))
12584 {
12585 /* If LEN is not constant, try MAXLEN too.
12586 For MAXLEN only allow optimizing into non-_ocs function
12587 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12588 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12589 {
12590 if (fcode == BUILT_IN_STPCPY_CHK)
12591 {
12592 if (! ignore)
c2f47e15 12593 return NULL_TREE;
0a39fd54 12594
12595 /* If return value of __stpcpy_chk is ignored,
12596 optimize into __strcpy_chk. */
12597 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
12598 if (!fn)
c2f47e15 12599 return NULL_TREE;
0a39fd54 12600
c2f47e15 12601 return build_call_expr (fn, 3, dest, src, size);
0a39fd54 12602 }
12603
12604 if (! len || TREE_SIDE_EFFECTS (len))
c2f47e15 12605 return NULL_TREE;
0a39fd54 12606
12607 /* If c_strlen returned something, but not a constant,
12608 transform __strcpy_chk into __memcpy_chk. */
12609 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12610 if (!fn)
c2f47e15 12611 return NULL_TREE;
0a39fd54 12612
12613 len = size_binop (PLUS_EXPR, len, ssize_int (1));
0a39fd54 12614 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
c2f47e15 12615 build_call_expr (fn, 4,
12616 dest, src, len, size));
0a39fd54 12617 }
0a39fd54 12618 }
ad89623c 12619 else
12620 maxlen = len;
12621
12622 if (! tree_int_cst_lt (maxlen, size))
c2f47e15 12623 return NULL_TREE;
0a39fd54 12624 }
12625
0a39fd54 12626 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
12627 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
12628 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
12629 if (!fn)
c2f47e15 12630 return NULL_TREE;
0a39fd54 12631
c2f47e15 12632 return build_call_expr (fn, 2, dest, src);
0a39fd54 12633}
12634
c2f47e15 12635/* Fold a call to the __strncpy_chk builtin. DEST, SRC, LEN, and SIZE
12636 are the arguments to the call. If MAXLEN is not NULL, it is maximum
12637 length passed as third argument. */
0a39fd54 12638
12639tree
c2f47e15 12640fold_builtin_strncpy_chk (tree dest, tree src, tree len, tree size,
12641 tree maxlen)
0a39fd54 12642{
c2f47e15 12643 tree fn;
0a39fd54 12644
c2f47e15 12645 if (!validate_arg (dest, POINTER_TYPE)
12646 || !validate_arg (src, POINTER_TYPE)
12647 || !validate_arg (len, INTEGER_TYPE)
12648 || !validate_arg (size, INTEGER_TYPE))
12649 return NULL_TREE;
0a39fd54 12650
12651 if (! host_integerp (size, 1))
c2f47e15 12652 return NULL_TREE;
0a39fd54 12653
12654 if (! integer_all_onesp (size))
12655 {
12656 if (! host_integerp (len, 1))
12657 {
12658 /* If LEN is not constant, try MAXLEN too.
12659 For MAXLEN only allow optimizing into non-_ocs function
12660 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12661 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
c2f47e15 12662 return NULL_TREE;
0a39fd54 12663 }
ad89623c 12664 else
12665 maxlen = len;
0a39fd54 12666
ad89623c 12667 if (tree_int_cst_lt (size, maxlen))
c2f47e15 12668 return NULL_TREE;
0a39fd54 12669 }
12670
0a39fd54 12671 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
12672 fn = built_in_decls[BUILT_IN_STRNCPY];
12673 if (!fn)
c2f47e15 12674 return NULL_TREE;
0a39fd54 12675
c2f47e15 12676 return build_call_expr (fn, 3, dest, src, len);
0a39fd54 12677}
12678
c2f47e15 12679/* Fold a call to the __strcat_chk builtin FNDECL. DEST, SRC, and SIZE
12680 are the arguments to the call. */
0a39fd54 12681
12682static tree
c2f47e15 12683fold_builtin_strcat_chk (tree fndecl, tree dest, tree src, tree size)
0a39fd54 12684{
c2f47e15 12685 tree fn;
0a39fd54 12686 const char *p;
12687
c2f47e15 12688 if (!validate_arg (dest, POINTER_TYPE)
12689 || !validate_arg (src, POINTER_TYPE)
12690 || !validate_arg (size, INTEGER_TYPE))
12691 return NULL_TREE;
0a39fd54 12692
12693 p = c_getstr (src);
12694 /* If the SRC parameter is "", return DEST. */
12695 if (p && *p == '\0')
12696 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
12697
12698 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
c2f47e15 12699 return NULL_TREE;
0a39fd54 12700
12701 /* If __builtin_strcat_chk is used, assume strcat is available. */
12702 fn = built_in_decls[BUILT_IN_STRCAT];
12703 if (!fn)
c2f47e15 12704 return NULL_TREE;
0a39fd54 12705
c2f47e15 12706 return build_call_expr (fn, 2, dest, src);
0a39fd54 12707}
12708
c2f47e15 12709/* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
12710 LEN, and SIZE. */
0a39fd54 12711
12712static tree
c2f47e15 12713fold_builtin_strncat_chk (tree fndecl,
12714 tree dest, tree src, tree len, tree size)
0a39fd54 12715{
c2f47e15 12716 tree fn;
0a39fd54 12717 const char *p;
12718
c2f47e15 12719 if (!validate_arg (dest, POINTER_TYPE)
12720 || !validate_arg (src, POINTER_TYPE)
12721 || !validate_arg (size, INTEGER_TYPE)
12722 || !validate_arg (size, INTEGER_TYPE))
12723 return NULL_TREE;
0a39fd54 12724
12725 p = c_getstr (src);
12726 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
12727 if (p && *p == '\0')
12728 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
12729 else if (integer_zerop (len))
12730 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
12731
12732 if (! host_integerp (size, 1))
c2f47e15 12733 return NULL_TREE;
0a39fd54 12734
12735 if (! integer_all_onesp (size))
12736 {
12737 tree src_len = c_strlen (src, 1);
12738 if (src_len
12739 && host_integerp (src_len, 1)
12740 && host_integerp (len, 1)
12741 && ! tree_int_cst_lt (len, src_len))
12742 {
12743 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
12744 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
12745 if (!fn)
c2f47e15 12746 return NULL_TREE;
0a39fd54 12747
c2f47e15 12748 return build_call_expr (fn, 3, dest, src, size);
0a39fd54 12749 }
c2f47e15 12750 return NULL_TREE;
0a39fd54 12751 }
12752
0a39fd54 12753 /* If __builtin_strncat_chk is used, assume strncat is available. */
12754 fn = built_in_decls[BUILT_IN_STRNCAT];
12755 if (!fn)
c2f47e15 12756 return NULL_TREE;
0a39fd54 12757
c2f47e15 12758 return build_call_expr (fn, 3, dest, src, len);
0a39fd54 12759}
12760
c2f47e15 12761/* Fold a call EXP to __{,v}sprintf_chk. Return NULL_TREE if
0a39fd54 12762 a normal call should be emitted rather than expanding the function
12763 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
12764
12765static tree
c2f47e15 12766fold_builtin_sprintf_chk (tree exp, enum built_in_function fcode)
0a39fd54 12767{
12768 tree dest, size, len, fn, fmt, flag;
12769 const char *fmt_str;
c2f47e15 12770 int nargs = call_expr_nargs (exp);
0a39fd54 12771
12772 /* Verify the required arguments in the original call. */
c2f47e15 12773 if (nargs < 4)
12774 return NULL_TREE;
12775 dest = CALL_EXPR_ARG (exp, 0);
12776 if (!validate_arg (dest, POINTER_TYPE))
12777 return NULL_TREE;
12778 flag = CALL_EXPR_ARG (exp, 1);
12779 if (!validate_arg (flag, INTEGER_TYPE))
12780 return NULL_TREE;
12781 size = CALL_EXPR_ARG (exp, 2);
12782 if (!validate_arg (size, INTEGER_TYPE))
12783 return NULL_TREE;
12784 fmt = CALL_EXPR_ARG (exp, 3);
12785 if (!validate_arg (fmt, POINTER_TYPE))
12786 return NULL_TREE;
0a39fd54 12787
12788 if (! host_integerp (size, 1))
c2f47e15 12789 return NULL_TREE;
0a39fd54 12790
12791 len = NULL_TREE;
12792
d4473c84 12793 if (!init_target_chars ())
c2f47e15 12794 return NULL_TREE;
99eabcc1 12795
0a39fd54 12796 /* Check whether the format is a literal string constant. */
12797 fmt_str = c_getstr (fmt);
12798 if (fmt_str != NULL)
12799 {
12800 /* If the format doesn't contain % args or %%, we know the size. */
99eabcc1 12801 if (strchr (fmt_str, target_percent) == 0)
0a39fd54 12802 {
c2f47e15 12803 if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
0a39fd54 12804 len = build_int_cstu (size_type_node, strlen (fmt_str));
12805 }
12806 /* If the format is "%s" and first ... argument is a string literal,
12807 we know the size too. */
c2f47e15 12808 else if (fcode == BUILT_IN_SPRINTF_CHK
12809 && strcmp (fmt_str, target_percent_s) == 0)
0a39fd54 12810 {
12811 tree arg;
12812
c2f47e15 12813 if (nargs == 5)
0a39fd54 12814 {
c2f47e15 12815 arg = CALL_EXPR_ARG (exp, 4);
12816 if (validate_arg (arg, POINTER_TYPE))
0a39fd54 12817 {
12818 len = c_strlen (arg, 1);
12819 if (! len || ! host_integerp (len, 1))
12820 len = NULL_TREE;
12821 }
12822 }
12823 }
12824 }
12825
12826 if (! integer_all_onesp (size))
12827 {
12828 if (! len || ! tree_int_cst_lt (len, size))
c2f47e15 12829 return NULL_TREE;
0a39fd54 12830 }
12831
12832 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
12833 or if format doesn't contain % chars or is "%s". */
12834 if (! integer_zerop (flag))
12835 {
12836 if (fmt_str == NULL)
c2f47e15 12837 return NULL_TREE;
12838 if (strchr (fmt_str, target_percent) != NULL
12839 && strcmp (fmt_str, target_percent_s))
12840 return NULL_TREE;
0a39fd54 12841 }
12842
0a39fd54 12843 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
12844 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
12845 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
12846 if (!fn)
c2f47e15 12847 return NULL_TREE;
0a39fd54 12848
c2f47e15 12849 return rewrite_call_expr (exp, 4, fn, 2, dest, fmt);
0a39fd54 12850}
12851
c2f47e15 12852/* Fold a call EXP to {,v}snprintf. Return NULL_TREE if
0a39fd54 12853 a normal call should be emitted rather than expanding the function
12854 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
12855 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
12856 passed as second argument. */
12857
12858tree
c2f47e15 12859fold_builtin_snprintf_chk (tree exp, tree maxlen,
0a39fd54 12860 enum built_in_function fcode)
12861{
12862 tree dest, size, len, fn, fmt, flag;
12863 const char *fmt_str;
12864
12865 /* Verify the required arguments in the original call. */
c2f47e15 12866 if (call_expr_nargs (exp) < 5)
12867 return NULL_TREE;
12868 dest = CALL_EXPR_ARG (exp, 0);
12869 if (!validate_arg (dest, POINTER_TYPE))
12870 return NULL_TREE;
12871 len = CALL_EXPR_ARG (exp, 1);
12872 if (!validate_arg (len, INTEGER_TYPE))
12873 return NULL_TREE;
12874 flag = CALL_EXPR_ARG (exp, 2);
12875 if (!validate_arg (flag, INTEGER_TYPE))
12876 return NULL_TREE;
12877 size = CALL_EXPR_ARG (exp, 3);
12878 if (!validate_arg (size, INTEGER_TYPE))
12879 return NULL_TREE;
12880 fmt = CALL_EXPR_ARG (exp, 4);
12881 if (!validate_arg (fmt, POINTER_TYPE))
12882 return NULL_TREE;
0a39fd54 12883
12884 if (! host_integerp (size, 1))
c2f47e15 12885 return NULL_TREE;
0a39fd54 12886
12887 if (! integer_all_onesp (size))
12888 {
12889 if (! host_integerp (len, 1))
12890 {
12891 /* If LEN is not constant, try MAXLEN too.
12892 For MAXLEN only allow optimizing into non-_ocs function
12893 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12894 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
c2f47e15 12895 return NULL_TREE;
0a39fd54 12896 }
ad89623c 12897 else
12898 maxlen = len;
0a39fd54 12899
ad89623c 12900 if (tree_int_cst_lt (size, maxlen))
c2f47e15 12901 return NULL_TREE;
0a39fd54 12902 }
12903
d4473c84 12904 if (!init_target_chars ())
c2f47e15 12905 return NULL_TREE;
99eabcc1 12906
0a39fd54 12907 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
12908 or if format doesn't contain % chars or is "%s". */
12909 if (! integer_zerop (flag))
12910 {
12911 fmt_str = c_getstr (fmt);
12912 if (fmt_str == NULL)
c2f47e15 12913 return NULL_TREE;
12914 if (strchr (fmt_str, target_percent) != NULL
12915 && strcmp (fmt_str, target_percent_s))
12916 return NULL_TREE;
0a39fd54 12917 }
12918
0a39fd54 12919 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
12920 available. */
12921 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
12922 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
12923 if (!fn)
c2f47e15 12924 return NULL_TREE;
0a39fd54 12925
c2f47e15 12926 return rewrite_call_expr (exp, 5, fn, 3, dest, len, fmt);
0a39fd54 12927}
12928
12929/* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
c2f47e15 12930 FMT and ARG are the arguments to the call; we don't fold cases with
12931 more than 2 arguments, and ARG may be null if this is a 1-argument case.
0a39fd54 12932
c2f47e15 12933 Return NULL_TREE if no simplification was possible, otherwise return the
0a39fd54 12934 simplified form of the call as a tree. FCODE is the BUILT_IN_*
12935 code of the function to be simplified. */
12936
12937static tree
c2f47e15 12938fold_builtin_printf (tree fndecl, tree fmt, tree arg, bool ignore,
0a39fd54 12939 enum built_in_function fcode)
12940{
c2f47e15 12941 tree fn_putchar, fn_puts, newarg, call = NULL_TREE;
0a39fd54 12942 const char *fmt_str = NULL;
12943
12944 /* If the return value is used, don't do the transformation. */
12945 if (! ignore)
c2f47e15 12946 return NULL_TREE;
0a39fd54 12947
12948 /* Verify the required arguments in the original call. */
c2f47e15 12949 if (!validate_arg (fmt, POINTER_TYPE))
12950 return NULL_TREE;
0a39fd54 12951
12952 /* Check whether the format is a literal string constant. */
12953 fmt_str = c_getstr (fmt);
12954 if (fmt_str == NULL)
12955 return NULL_TREE;
12956
12957 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
12958 {
6d77ed92 12959 /* If we're using an unlocked function, assume the other
12960 unlocked functions exist explicitly. */
12961 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
12962 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
0a39fd54 12963 }
12964 else
12965 {
12966 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
12967 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
12968 }
12969
d4473c84 12970 if (!init_target_chars ())
c2f47e15 12971 return NULL_TREE;
a0c938f0 12972
c2f47e15 12973 if (strcmp (fmt_str, target_percent_s) == 0
12974 || strchr (fmt_str, target_percent) == NULL)
0a39fd54 12975 {
12976 const char *str;
12977
99eabcc1 12978 if (strcmp (fmt_str, target_percent_s) == 0)
0a39fd54 12979 {
12980 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
c2f47e15 12981 return NULL_TREE;
0a39fd54 12982
c2f47e15 12983 if (!arg || !validate_arg (arg, POINTER_TYPE))
12984 return NULL_TREE;
0a39fd54 12985
c2f47e15 12986 str = c_getstr (arg);
0a39fd54 12987 if (str == NULL)
c2f47e15 12988 return NULL_TREE;
0a39fd54 12989 }
12990 else
12991 {
12992 /* The format specifier doesn't contain any '%' characters. */
12993 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
c2f47e15 12994 && arg)
12995 return NULL_TREE;
0a39fd54 12996 str = fmt_str;
12997 }
12998
12999 /* If the string was "", printf does nothing. */
13000 if (str[0] == '\0')
13001 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
13002
13003 /* If the string has length of 1, call putchar. */
13004 if (str[1] == '\0')
13005 {
13006 /* Given printf("c"), (where c is any one character,)
13007 convert "c"[0] to an int and pass that to the replacement
13008 function. */
c2f47e15 13009 newarg = build_int_cst (NULL_TREE, str[0]);
13010 if (fn_putchar)
13011 call = build_call_expr (fn_putchar, 1, newarg);
0a39fd54 13012 }
13013 else
13014 {
13015 /* If the string was "string\n", call puts("string"). */
13016 size_t len = strlen (str);
99eabcc1 13017 if ((unsigned char)str[len - 1] == target_newline)
0a39fd54 13018 {
13019 /* Create a NUL-terminated string that's one char shorter
13020 than the original, stripping off the trailing '\n'. */
364c0c59 13021 char *newstr = XALLOCAVEC (char, len);
0a39fd54 13022 memcpy (newstr, str, len - 1);
13023 newstr[len - 1] = 0;
13024
c2f47e15 13025 newarg = build_string_literal (len, newstr);
13026 if (fn_puts)
13027 call = build_call_expr (fn_puts, 1, newarg);
0a39fd54 13028 }
13029 else
13030 /* We'd like to arrange to call fputs(string,stdout) here,
13031 but we need stdout and don't have a way to get it yet. */
c2f47e15 13032 return NULL_TREE;
0a39fd54 13033 }
13034 }
13035
13036 /* The other optimizations can be done only on the non-va_list variants. */
13037 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
c2f47e15 13038 return NULL_TREE;
0a39fd54 13039
13040 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
99eabcc1 13041 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
0a39fd54 13042 {
c2f47e15 13043 if (!arg || !validate_arg (arg, POINTER_TYPE))
13044 return NULL_TREE;
13045 if (fn_puts)
13046 call = build_call_expr (fn_puts, 1, arg);
0a39fd54 13047 }
13048
13049 /* If the format specifier was "%c", call __builtin_putchar(arg). */
99eabcc1 13050 else if (strcmp (fmt_str, target_percent_c) == 0)
0a39fd54 13051 {
c2f47e15 13052 if (!arg || !validate_arg (arg, INTEGER_TYPE))
13053 return NULL_TREE;
13054 if (fn_putchar)
13055 call = build_call_expr (fn_putchar, 1, arg);
0a39fd54 13056 }
13057
c2f47e15 13058 if (!call)
13059 return NULL_TREE;
0a39fd54 13060
0a39fd54 13061 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
13062}
13063
13064/* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
c2f47e15 13065 FP, FMT, and ARG are the arguments to the call. We don't fold calls with
13066 more than 3 arguments, and ARG may be null in the 2-argument case.
0a39fd54 13067
c2f47e15 13068 Return NULL_TREE if no simplification was possible, otherwise return the
0a39fd54 13069 simplified form of the call as a tree. FCODE is the BUILT_IN_*
13070 code of the function to be simplified. */
13071
13072static tree
c2f47e15 13073fold_builtin_fprintf (tree fndecl, tree fp, tree fmt, tree arg, bool ignore,
0a39fd54 13074 enum built_in_function fcode)
13075{
c2f47e15 13076 tree fn_fputc, fn_fputs, call = NULL_TREE;
0a39fd54 13077 const char *fmt_str = NULL;
13078
13079 /* If the return value is used, don't do the transformation. */
13080 if (! ignore)
c2f47e15 13081 return NULL_TREE;
0a39fd54 13082
13083 /* Verify the required arguments in the original call. */
c2f47e15 13084 if (!validate_arg (fp, POINTER_TYPE))
13085 return NULL_TREE;
13086 if (!validate_arg (fmt, POINTER_TYPE))
13087 return NULL_TREE;
0a39fd54 13088
13089 /* Check whether the format is a literal string constant. */
13090 fmt_str = c_getstr (fmt);
13091 if (fmt_str == NULL)
13092 return NULL_TREE;
13093
13094 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
13095 {
6d77ed92 13096 /* If we're using an unlocked function, assume the other
13097 unlocked functions exist explicitly. */
13098 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
13099 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
0a39fd54 13100 }
13101 else
13102 {
13103 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
13104 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
13105 }
13106
d4473c84 13107 if (!init_target_chars ())
c2f47e15 13108 return NULL_TREE;
a0c938f0 13109
0a39fd54 13110 /* If the format doesn't contain % args or %%, use strcpy. */
99eabcc1 13111 if (strchr (fmt_str, target_percent) == NULL)
0a39fd54 13112 {
13113 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
c2f47e15 13114 && arg)
13115 return NULL_TREE;
0a39fd54 13116
13117 /* If the format specifier was "", fprintf does nothing. */
13118 if (fmt_str[0] == '\0')
13119 {
13120 /* If FP has side-effects, just wait until gimplification is
13121 done. */
13122 if (TREE_SIDE_EFFECTS (fp))
c2f47e15 13123 return NULL_TREE;
0a39fd54 13124
13125 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
13126 }
13127
13128 /* When "string" doesn't contain %, replace all cases of
13129 fprintf (fp, string) with fputs (string, fp). The fputs
13130 builtin will take care of special cases like length == 1. */
c2f47e15 13131 if (fn_fputs)
13132 call = build_call_expr (fn_fputs, 2, fmt, fp);
0a39fd54 13133 }
13134
13135 /* The other optimizations can be done only on the non-va_list variants. */
13136 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
c2f47e15 13137 return NULL_TREE;
0a39fd54 13138
13139 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
99eabcc1 13140 else if (strcmp (fmt_str, target_percent_s) == 0)
0a39fd54 13141 {
c2f47e15 13142 if (!arg || !validate_arg (arg, POINTER_TYPE))
13143 return NULL_TREE;
13144 if (fn_fputs)
13145 call = build_call_expr (fn_fputs, 2, arg, fp);
0a39fd54 13146 }
13147
13148 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
99eabcc1 13149 else if (strcmp (fmt_str, target_percent_c) == 0)
0a39fd54 13150 {
c2f47e15 13151 if (!arg || !validate_arg (arg, INTEGER_TYPE))
13152 return NULL_TREE;
13153 if (fn_fputc)
13154 call = build_call_expr (fn_fputc, 2, arg, fp);
0a39fd54 13155 }
13156
c2f47e15 13157 if (!call)
13158 return NULL_TREE;
0a39fd54 13159 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
13160}
99eabcc1 13161
13162/* Initialize format string characters in the target charset. */
13163
13164static bool
13165init_target_chars (void)
13166{
13167 static bool init;
13168 if (!init)
13169 {
13170 target_newline = lang_hooks.to_target_charset ('\n');
13171 target_percent = lang_hooks.to_target_charset ('%');
13172 target_c = lang_hooks.to_target_charset ('c');
13173 target_s = lang_hooks.to_target_charset ('s');
13174 if (target_newline == 0 || target_percent == 0 || target_c == 0
13175 || target_s == 0)
13176 return false;
13177
13178 target_percent_c[0] = target_percent;
13179 target_percent_c[1] = target_c;
13180 target_percent_c[2] = '\0';
13181
13182 target_percent_s[0] = target_percent;
13183 target_percent_s[1] = target_s;
13184 target_percent_s[2] = '\0';
13185
13186 target_percent_s_newline[0] = target_percent;
13187 target_percent_s_newline[1] = target_s;
13188 target_percent_s_newline[2] = target_newline;
13189 target_percent_s_newline[3] = '\0';
a0c938f0 13190
99eabcc1 13191 init = true;
13192 }
13193 return true;
13194}
bffb7645 13195
f0c477f2 13196/* Helper function for do_mpfr_arg*(). Ensure M is a normal number
13197 and no overflow/underflow occurred. INEXACT is true if M was not
fa7637bd 13198 exactly calculated. TYPE is the tree type for the result. This
f0c477f2 13199 function assumes that you cleared the MPFR flags and then
13200 calculated M to see if anything subsequently set a flag prior to
13201 entering this function. Return NULL_TREE if any checks fail. */
13202
13203static tree
d4473c84 13204do_mpfr_ckconv (mpfr_srcptr m, tree type, int inexact)
f0c477f2 13205{
13206 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13207 overflow/underflow occurred. If -frounding-math, proceed iff the
13208 result of calling FUNC was exact. */
d4473c84 13209 if (mpfr_number_p (m) && !mpfr_overflow_p () && !mpfr_underflow_p ()
f0c477f2 13210 && (!flag_rounding_math || !inexact))
13211 {
13212 REAL_VALUE_TYPE rr;
13213
66fa16e6 13214 real_from_mpfr (&rr, m, type, GMP_RNDN);
f0c477f2 13215 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
13216 check for overflow/underflow. If the REAL_VALUE_TYPE is zero
13217 but the mpft_t is not, then we underflowed in the
13218 conversion. */
776a7bab 13219 if (real_isfinite (&rr)
f0c477f2 13220 && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
13221 {
13222 REAL_VALUE_TYPE rmode;
13223
13224 real_convert (&rmode, TYPE_MODE (type), &rr);
13225 /* Proceed iff the specified mode can hold the value. */
13226 if (real_identical (&rmode, &rr))
13227 return build_real (type, rmode);
13228 }
13229 }
13230 return NULL_TREE;
13231}
13232
239d491a 13233#ifdef HAVE_mpc
13234/* Helper function for do_mpc_arg*(). Ensure M is a normal complex
13235 number and no overflow/underflow occurred. INEXACT is true if M
13236 was not exactly calculated. TYPE is the tree type for the result.
13237 This function assumes that you cleared the MPFR flags and then
13238 calculated M to see if anything subsequently set a flag prior to
13239 entering this function. Return NULL_TREE if any checks fail. */
13240
13241static tree
13242do_mpc_ckconv (mpc_srcptr m, tree type, int inexact)
13243{
13244 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13245 overflow/underflow occurred. If -frounding-math, proceed iff the
13246 result of calling FUNC was exact. */
c3cfad90 13247 if (mpfr_number_p (mpc_realref (m)) && mpfr_number_p (mpc_imagref (m))
239d491a 13248 && !mpfr_overflow_p () && !mpfr_underflow_p ()
13249 && (!flag_rounding_math || !inexact))
13250 {
13251 REAL_VALUE_TYPE re, im;
13252
c3cfad90 13253 real_from_mpfr (&re, mpc_realref (m), type, GMP_RNDN);
13254 real_from_mpfr (&im, mpc_imagref (m), type, GMP_RNDN);
239d491a 13255 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR values,
13256 check for overflow/underflow. If the REAL_VALUE_TYPE is zero
13257 but the mpft_t is not, then we underflowed in the
13258 conversion. */
13259 if (real_isfinite (&re) && real_isfinite (&im)
c3cfad90 13260 && (re.cl == rvc_zero) == (mpfr_zero_p (mpc_realref (m)) != 0)
13261 && (im.cl == rvc_zero) == (mpfr_zero_p (mpc_imagref (m)) != 0))
239d491a 13262 {
13263 REAL_VALUE_TYPE re_mode, im_mode;
13264
13265 real_convert (&re_mode, TYPE_MODE (TREE_TYPE (type)), &re);
13266 real_convert (&im_mode, TYPE_MODE (TREE_TYPE (type)), &im);
13267 /* Proceed iff the specified mode can hold the value. */
13268 if (real_identical (&re_mode, &re) && real_identical (&im_mode, &im))
13269 return build_complex (type, build_real (TREE_TYPE (type), re_mode),
13270 build_real (TREE_TYPE (type), im_mode));
13271 }
13272 }
13273 return NULL_TREE;
13274}
13275#endif /* HAVE_mpc */
13276
bffb7645 13277/* If argument ARG is a REAL_CST, call the one-argument mpfr function
13278 FUNC on it and return the resulting value as a tree with type TYPE.
728bac60 13279 If MIN and/or MAX are not NULL, then the supplied ARG must be
13280 within those bounds. If INCLUSIVE is true, then MIN/MAX are
13281 acceptable values, otherwise they are not. The mpfr precision is
13282 set to the precision of TYPE. We assume that function FUNC returns
13283 zero if the result could be calculated exactly within the requested
13284 precision. */
bffb7645 13285
13286static tree
728bac60 13287do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
13288 const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
13289 bool inclusive)
bffb7645 13290{
13291 tree result = NULL_TREE;
13292
13293 STRIP_NOPS (arg);
13294
bd7d6fa4 13295 /* To proceed, MPFR must exactly represent the target floating point
13296 format, which only happens when the target base equals two. */
13297 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
f96bd2bf 13298 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
bffb7645 13299 {
f0c477f2 13300 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
bffb7645 13301
776a7bab 13302 if (real_isfinite (ra)
f0c477f2 13303 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
13304 && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
bffb7645 13305 {
e2eb2b7f 13306 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13307 const int prec = fmt->p;
13308 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
debf9994 13309 int inexact;
bffb7645 13310 mpfr_t m;
13311
13312 mpfr_init2 (m, prec);
66fa16e6 13313 mpfr_from_real (m, ra, GMP_RNDN);
d4473c84 13314 mpfr_clear_flags ();
e2eb2b7f 13315 inexact = func (m, m, rnd);
f0c477f2 13316 result = do_mpfr_ckconv (m, type, inexact);
bffb7645 13317 mpfr_clear (m);
13318 }
13319 }
13320
13321 return result;
13322}
f0c477f2 13323
13324/* If argument ARG is a REAL_CST, call the two-argument mpfr function
13325 FUNC on it and return the resulting value as a tree with type TYPE.
13326 The mpfr precision is set to the precision of TYPE. We assume that
13327 function FUNC returns zero if the result could be calculated
13328 exactly within the requested precision. */
13329
13330static tree
13331do_mpfr_arg2 (tree arg1, tree arg2, tree type,
13332 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13333{
13334 tree result = NULL_TREE;
13335
13336 STRIP_NOPS (arg1);
13337 STRIP_NOPS (arg2);
13338
bd7d6fa4 13339 /* To proceed, MPFR must exactly represent the target floating point
13340 format, which only happens when the target base equals two. */
13341 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
f96bd2bf 13342 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13343 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
f0c477f2 13344 {
13345 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13346 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13347
776a7bab 13348 if (real_isfinite (ra1) && real_isfinite (ra2))
f0c477f2 13349 {
e2eb2b7f 13350 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13351 const int prec = fmt->p;
13352 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
f0c477f2 13353 int inexact;
13354 mpfr_t m1, m2;
13355
13356 mpfr_inits2 (prec, m1, m2, NULL);
66fa16e6 13357 mpfr_from_real (m1, ra1, GMP_RNDN);
13358 mpfr_from_real (m2, ra2, GMP_RNDN);
d4473c84 13359 mpfr_clear_flags ();
e2eb2b7f 13360 inexact = func (m1, m1, m2, rnd);
f0c477f2 13361 result = do_mpfr_ckconv (m1, type, inexact);
13362 mpfr_clears (m1, m2, NULL);
13363 }
13364 }
13365
13366 return result;
13367}
d92f994c 13368
9917422b 13369/* If argument ARG is a REAL_CST, call the three-argument mpfr function
13370 FUNC on it and return the resulting value as a tree with type TYPE.
13371 The mpfr precision is set to the precision of TYPE. We assume that
13372 function FUNC returns zero if the result could be calculated
13373 exactly within the requested precision. */
13374
13375static tree
13376do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
13377 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13378{
13379 tree result = NULL_TREE;
13380
13381 STRIP_NOPS (arg1);
13382 STRIP_NOPS (arg2);
13383 STRIP_NOPS (arg3);
13384
bd7d6fa4 13385 /* To proceed, MPFR must exactly represent the target floating point
13386 format, which only happens when the target base equals two. */
13387 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
f96bd2bf 13388 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13389 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)
13390 && TREE_CODE (arg3) == REAL_CST && !TREE_OVERFLOW (arg3))
9917422b 13391 {
13392 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13393 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13394 const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
13395
776a7bab 13396 if (real_isfinite (ra1) && real_isfinite (ra2) && real_isfinite (ra3))
9917422b 13397 {
e2eb2b7f 13398 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13399 const int prec = fmt->p;
13400 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
9917422b 13401 int inexact;
13402 mpfr_t m1, m2, m3;
13403
13404 mpfr_inits2 (prec, m1, m2, m3, NULL);
66fa16e6 13405 mpfr_from_real (m1, ra1, GMP_RNDN);
13406 mpfr_from_real (m2, ra2, GMP_RNDN);
13407 mpfr_from_real (m3, ra3, GMP_RNDN);
d4473c84 13408 mpfr_clear_flags ();
e2eb2b7f 13409 inexact = func (m1, m1, m2, m3, rnd);
9917422b 13410 result = do_mpfr_ckconv (m1, type, inexact);
13411 mpfr_clears (m1, m2, m3, NULL);
13412 }
13413 }
13414
13415 return result;
13416}
13417
d92f994c 13418/* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
13419 the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
d735c391 13420 If ARG_SINP and ARG_COSP are NULL then the result is returned
13421 as a complex value.
d92f994c 13422 The type is taken from the type of ARG and is used for setting the
13423 precision of the calculation and results. */
13424
13425static tree
13426do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
13427{
bd7d6fa4 13428 tree const type = TREE_TYPE (arg);
d92f994c 13429 tree result = NULL_TREE;
13430
13431 STRIP_NOPS (arg);
13432
bd7d6fa4 13433 /* To proceed, MPFR must exactly represent the target floating point
13434 format, which only happens when the target base equals two. */
13435 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
f96bd2bf 13436 && TREE_CODE (arg) == REAL_CST
13437 && !TREE_OVERFLOW (arg))
d92f994c 13438 {
13439 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
13440
776a7bab 13441 if (real_isfinite (ra))
d92f994c 13442 {
e2eb2b7f 13443 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13444 const int prec = fmt->p;
13445 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
d92f994c 13446 tree result_s, result_c;
13447 int inexact;
13448 mpfr_t m, ms, mc;
13449
13450 mpfr_inits2 (prec, m, ms, mc, NULL);
66fa16e6 13451 mpfr_from_real (m, ra, GMP_RNDN);
d4473c84 13452 mpfr_clear_flags ();
e2eb2b7f 13453 inexact = mpfr_sin_cos (ms, mc, m, rnd);
d92f994c 13454 result_s = do_mpfr_ckconv (ms, type, inexact);
13455 result_c = do_mpfr_ckconv (mc, type, inexact);
13456 mpfr_clears (m, ms, mc, NULL);
13457 if (result_s && result_c)
13458 {
d735c391 13459 /* If we are to return in a complex value do so. */
13460 if (!arg_sinp && !arg_cosp)
13461 return build_complex (build_complex_type (type),
13462 result_c, result_s);
13463
d92f994c 13464 /* Dereference the sin/cos pointer arguments. */
13465 arg_sinp = build_fold_indirect_ref (arg_sinp);
13466 arg_cosp = build_fold_indirect_ref (arg_cosp);
13467 /* Proceed if valid pointer type were passed in. */
13468 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
13469 && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
13470 {
13471 /* Set the values. */
41076ef6 13472 result_s = fold_build2 (MODIFY_EXPR, type, arg_sinp,
35cc02b5 13473 result_s);
d92f994c 13474 TREE_SIDE_EFFECTS (result_s) = 1;
41076ef6 13475 result_c = fold_build2 (MODIFY_EXPR, type, arg_cosp,
35cc02b5 13476 result_c);
d92f994c 13477 TREE_SIDE_EFFECTS (result_c) = 1;
13478 /* Combine the assignments into a compound expr. */
13479 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13480 result_s, result_c));
13481 }
13482 }
13483 }
13484 }
13485 return result;
13486}
65dd1378 13487
65dd1378 13488/* If argument ARG1 is an INTEGER_CST and ARG2 is a REAL_CST, call the
13489 two-argument mpfr order N Bessel function FUNC on them and return
13490 the resulting value as a tree with type TYPE. The mpfr precision
13491 is set to the precision of TYPE. We assume that function FUNC
13492 returns zero if the result could be calculated exactly within the
13493 requested precision. */
13494static tree
13495do_mpfr_bessel_n (tree arg1, tree arg2, tree type,
13496 int (*func)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
13497 const REAL_VALUE_TYPE *min, bool inclusive)
13498{
13499 tree result = NULL_TREE;
13500
13501 STRIP_NOPS (arg1);
13502 STRIP_NOPS (arg2);
13503
13504 /* To proceed, MPFR must exactly represent the target floating point
13505 format, which only happens when the target base equals two. */
13506 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13507 && host_integerp (arg1, 0)
13508 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
13509 {
13510 const HOST_WIDE_INT n = tree_low_cst(arg1, 0);
13511 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg2);
13512
13513 if (n == (long)n
776a7bab 13514 && real_isfinite (ra)
65dd1378 13515 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min)))
13516 {
e2eb2b7f 13517 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13518 const int prec = fmt->p;
13519 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
65dd1378 13520 int inexact;
13521 mpfr_t m;
13522
13523 mpfr_init2 (m, prec);
13524 mpfr_from_real (m, ra, GMP_RNDN);
13525 mpfr_clear_flags ();
e2eb2b7f 13526 inexact = func (m, n, m, rnd);
65dd1378 13527 result = do_mpfr_ckconv (m, type, inexact);
13528 mpfr_clear (m);
13529 }
13530 }
13531
13532 return result;
13533}
e5407ca6 13534
13535/* If arguments ARG0 and ARG1 are REAL_CSTs, call mpfr_remquo() to set
13536 the pointer *(ARG_QUO) and return the result. The type is taken
13537 from the type of ARG0 and is used for setting the precision of the
13538 calculation and results. */
13539
13540static tree
13541do_mpfr_remquo (tree arg0, tree arg1, tree arg_quo)
13542{
13543 tree const type = TREE_TYPE (arg0);
13544 tree result = NULL_TREE;
13545
13546 STRIP_NOPS (arg0);
13547 STRIP_NOPS (arg1);
13548
13549 /* To proceed, MPFR must exactly represent the target floating point
13550 format, which only happens when the target base equals two. */
13551 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13552 && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
13553 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1))
13554 {
13555 const REAL_VALUE_TYPE *const ra0 = TREE_REAL_CST_PTR (arg0);
13556 const REAL_VALUE_TYPE *const ra1 = TREE_REAL_CST_PTR (arg1);
13557
776a7bab 13558 if (real_isfinite (ra0) && real_isfinite (ra1))
e5407ca6 13559 {
e2eb2b7f 13560 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13561 const int prec = fmt->p;
13562 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
e5407ca6 13563 tree result_rem;
13564 long integer_quo;
13565 mpfr_t m0, m1;
13566
13567 mpfr_inits2 (prec, m0, m1, NULL);
13568 mpfr_from_real (m0, ra0, GMP_RNDN);
13569 mpfr_from_real (m1, ra1, GMP_RNDN);
13570 mpfr_clear_flags ();
e2eb2b7f 13571 mpfr_remquo (m0, &integer_quo, m0, m1, rnd);
e5407ca6 13572 /* Remquo is independent of the rounding mode, so pass
13573 inexact=0 to do_mpfr_ckconv(). */
13574 result_rem = do_mpfr_ckconv (m0, type, /*inexact=*/ 0);
13575 mpfr_clears (m0, m1, NULL);
13576 if (result_rem)
13577 {
13578 /* MPFR calculates quo in the host's long so it may
13579 return more bits in quo than the target int can hold
13580 if sizeof(host long) > sizeof(target int). This can
13581 happen even for native compilers in LP64 mode. In
13582 these cases, modulo the quo value with the largest
13583 number that the target int can hold while leaving one
13584 bit for the sign. */
13585 if (sizeof (integer_quo) * CHAR_BIT > INT_TYPE_SIZE)
13586 integer_quo %= (long)(1UL << (INT_TYPE_SIZE - 1));
13587
13588 /* Dereference the quo pointer argument. */
13589 arg_quo = build_fold_indirect_ref (arg_quo);
13590 /* Proceed iff a valid pointer type was passed in. */
13591 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_quo)) == integer_type_node)
13592 {
13593 /* Set the value. */
13594 tree result_quo = fold_build2 (MODIFY_EXPR,
13595 TREE_TYPE (arg_quo), arg_quo,
13596 build_int_cst (NULL, integer_quo));
13597 TREE_SIDE_EFFECTS (result_quo) = 1;
13598 /* Combine the quo assignment with the rem. */
13599 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13600 result_quo, result_rem));
13601 }
13602 }
13603 }
13604 }
13605 return result;
13606}
e84da7c1 13607
13608/* If ARG is a REAL_CST, call mpfr_lgamma() on it and return the
13609 resulting value as a tree with type TYPE. The mpfr precision is
13610 set to the precision of TYPE. We assume that this mpfr function
13611 returns zero if the result could be calculated exactly within the
13612 requested precision. In addition, the integer pointer represented
13613 by ARG_SG will be dereferenced and set to the appropriate signgam
13614 (-1,1) value. */
13615
13616static tree
13617do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type)
13618{
13619 tree result = NULL_TREE;
13620
13621 STRIP_NOPS (arg);
13622
13623 /* To proceed, MPFR must exactly represent the target floating point
13624 format, which only happens when the target base equals two. Also
13625 verify ARG is a constant and that ARG_SG is an int pointer. */
13626 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13627 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)
13628 && TREE_CODE (TREE_TYPE (arg_sg)) == POINTER_TYPE
13629 && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg_sg))) == integer_type_node)
13630 {
13631 const REAL_VALUE_TYPE *const ra = TREE_REAL_CST_PTR (arg);
13632
13633 /* In addition to NaN and Inf, the argument cannot be zero or a
13634 negative integer. */
776a7bab 13635 if (real_isfinite (ra)
e84da7c1 13636 && ra->cl != rvc_zero
13637 && !(real_isneg(ra) && real_isinteger(ra, TYPE_MODE (type))))
13638 {
e2eb2b7f 13639 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13640 const int prec = fmt->p;
13641 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
e84da7c1 13642 int inexact, sg;
13643 mpfr_t m;
13644 tree result_lg;
13645
13646 mpfr_init2 (m, prec);
13647 mpfr_from_real (m, ra, GMP_RNDN);
13648 mpfr_clear_flags ();
e2eb2b7f 13649 inexact = mpfr_lgamma (m, &sg, m, rnd);
e84da7c1 13650 result_lg = do_mpfr_ckconv (m, type, inexact);
13651 mpfr_clear (m);
13652 if (result_lg)
13653 {
13654 tree result_sg;
13655
13656 /* Dereference the arg_sg pointer argument. */
13657 arg_sg = build_fold_indirect_ref (arg_sg);
13658 /* Assign the signgam value into *arg_sg. */
13659 result_sg = fold_build2 (MODIFY_EXPR,
13660 TREE_TYPE (arg_sg), arg_sg,
13661 build_int_cst (NULL, sg));
13662 TREE_SIDE_EFFECTS (result_sg) = 1;
13663 /* Combine the signgam assignment with the lgamma result. */
13664 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13665 result_sg, result_lg));
13666 }
13667 }
13668 }
13669
13670 return result;
13671}
75a70cf9 13672
239d491a 13673#ifdef HAVE_mpc
13674/* If argument ARG is a COMPLEX_CST, call the one-argument mpc
13675 function FUNC on it and return the resulting value as a tree with
13676 type TYPE. The mpfr precision is set to the precision of TYPE. We
13677 assume that function FUNC returns zero if the result could be
13678 calculated exactly within the requested precision. */
13679
13680static tree
13681do_mpc_arg1 (tree arg, tree type, int (*func)(mpc_ptr, mpc_srcptr, mpc_rnd_t))
13682{
13683 tree result = NULL_TREE;
13684
13685 STRIP_NOPS (arg);
13686
13687 /* To proceed, MPFR must exactly represent the target floating point
13688 format, which only happens when the target base equals two. */
13689 if (TREE_CODE (arg) == COMPLEX_CST && !TREE_OVERFLOW (arg)
13690 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE
13691 && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg))))->b == 2)
13692 {
13693 const REAL_VALUE_TYPE *const re = TREE_REAL_CST_PTR (TREE_REALPART (arg));
13694 const REAL_VALUE_TYPE *const im = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
13695
13696 if (real_isfinite (re) && real_isfinite (im))
13697 {
13698 const struct real_format *const fmt =
13699 REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
13700 const int prec = fmt->p;
13701 const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
44d89feb 13702 const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
239d491a 13703 int inexact;
13704 mpc_t m;
13705
13706 mpc_init2 (m, prec);
c3cfad90 13707 mpfr_from_real (mpc_realref(m), re, rnd);
13708 mpfr_from_real (mpc_imagref(m), im, rnd);
239d491a 13709 mpfr_clear_flags ();
44d89feb 13710 inexact = func (m, m, crnd);
239d491a 13711 result = do_mpc_ckconv (m, type, inexact);
13712 mpc_clear (m);
13713 }
13714 }
13715
13716 return result;
13717}
13718#endif /* HAVE_mpc */
13719
75a70cf9 13720/* FIXME tuples.
13721 The functions below provide an alternate interface for folding
13722 builtin function calls presented as GIMPLE_CALL statements rather
13723 than as CALL_EXPRs. The folded result is still expressed as a
13724 tree. There is too much code duplication in the handling of
13725 varargs functions, and a more intrusive re-factoring would permit
13726 better sharing of code between the tree and statement-based
13727 versions of these functions. */
13728
13729/* Construct a new CALL_EXPR using the tail of the argument list of STMT
13730 along with N new arguments specified as the "..." parameters. SKIP
13731 is the number of arguments in STMT to be omitted. This function is used
13732 to do varargs-to-varargs transformations. */
13733
13734static tree
13735gimple_rewrite_call_expr (gimple stmt, int skip, tree fndecl, int n, ...)
13736{
13737 int oldnargs = gimple_call_num_args (stmt);
13738 int nargs = oldnargs - skip + n;
13739 tree fntype = TREE_TYPE (fndecl);
13740 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
13741 tree *buffer;
13742 int i, j;
13743 va_list ap;
13744
13745 buffer = XALLOCAVEC (tree, nargs);
13746 va_start (ap, n);
13747 for (i = 0; i < n; i++)
13748 buffer[i] = va_arg (ap, tree);
13749 va_end (ap);
13750 for (j = skip; j < oldnargs; j++, i++)
13751 buffer[i] = gimple_call_arg (stmt, j);
13752
13753 return fold (build_call_array (TREE_TYPE (fntype), fn, nargs, buffer));
13754}
13755
13756/* Fold a call STMT to __{,v}sprintf_chk. Return NULL_TREE if
13757 a normal call should be emitted rather than expanding the function
13758 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
13759
13760static tree
13761gimple_fold_builtin_sprintf_chk (gimple stmt, enum built_in_function fcode)
13762{
13763 tree dest, size, len, fn, fmt, flag;
13764 const char *fmt_str;
13765 int nargs = gimple_call_num_args (stmt);
13766
13767 /* Verify the required arguments in the original call. */
13768 if (nargs < 4)
13769 return NULL_TREE;
13770 dest = gimple_call_arg (stmt, 0);
13771 if (!validate_arg (dest, POINTER_TYPE))
13772 return NULL_TREE;
13773 flag = gimple_call_arg (stmt, 1);
13774 if (!validate_arg (flag, INTEGER_TYPE))
13775 return NULL_TREE;
13776 size = gimple_call_arg (stmt, 2);
13777 if (!validate_arg (size, INTEGER_TYPE))
13778 return NULL_TREE;
13779 fmt = gimple_call_arg (stmt, 3);
13780 if (!validate_arg (fmt, POINTER_TYPE))
13781 return NULL_TREE;
13782
13783 if (! host_integerp (size, 1))
13784 return NULL_TREE;
13785
13786 len = NULL_TREE;
13787
13788 if (!init_target_chars ())
13789 return NULL_TREE;
13790
13791 /* Check whether the format is a literal string constant. */
13792 fmt_str = c_getstr (fmt);
13793 if (fmt_str != NULL)
13794 {
13795 /* If the format doesn't contain % args or %%, we know the size. */
13796 if (strchr (fmt_str, target_percent) == 0)
13797 {
13798 if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
13799 len = build_int_cstu (size_type_node, strlen (fmt_str));
13800 }
13801 /* If the format is "%s" and first ... argument is a string literal,
13802 we know the size too. */
13803 else if (fcode == BUILT_IN_SPRINTF_CHK
13804 && strcmp (fmt_str, target_percent_s) == 0)
13805 {
13806 tree arg;
13807
13808 if (nargs == 5)
13809 {
13810 arg = gimple_call_arg (stmt, 4);
13811 if (validate_arg (arg, POINTER_TYPE))
13812 {
13813 len = c_strlen (arg, 1);
13814 if (! len || ! host_integerp (len, 1))
13815 len = NULL_TREE;
13816 }
13817 }
13818 }
13819 }
13820
13821 if (! integer_all_onesp (size))
13822 {
13823 if (! len || ! tree_int_cst_lt (len, size))
13824 return NULL_TREE;
13825 }
13826
13827 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
13828 or if format doesn't contain % chars or is "%s". */
13829 if (! integer_zerop (flag))
13830 {
13831 if (fmt_str == NULL)
13832 return NULL_TREE;
13833 if (strchr (fmt_str, target_percent) != NULL
13834 && strcmp (fmt_str, target_percent_s))
13835 return NULL_TREE;
13836 }
13837
13838 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
13839 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
13840 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
13841 if (!fn)
13842 return NULL_TREE;
13843
13844 return gimple_rewrite_call_expr (stmt, 4, fn, 2, dest, fmt);
13845}
13846
13847/* Fold a call STMT to {,v}snprintf. Return NULL_TREE if
13848 a normal call should be emitted rather than expanding the function
13849 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
13850 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
13851 passed as second argument. */
13852
13853tree
13854gimple_fold_builtin_snprintf_chk (gimple stmt, tree maxlen,
13855 enum built_in_function fcode)
13856{
13857 tree dest, size, len, fn, fmt, flag;
13858 const char *fmt_str;
13859
13860 /* Verify the required arguments in the original call. */
13861 if (gimple_call_num_args (stmt) < 5)
13862 return NULL_TREE;
13863 dest = gimple_call_arg (stmt, 0);
13864 if (!validate_arg (dest, POINTER_TYPE))
13865 return NULL_TREE;
13866 len = gimple_call_arg (stmt, 1);
13867 if (!validate_arg (len, INTEGER_TYPE))
13868 return NULL_TREE;
13869 flag = gimple_call_arg (stmt, 2);
13870 if (!validate_arg (flag, INTEGER_TYPE))
13871 return NULL_TREE;
13872 size = gimple_call_arg (stmt, 3);
13873 if (!validate_arg (size, INTEGER_TYPE))
13874 return NULL_TREE;
13875 fmt = gimple_call_arg (stmt, 4);
13876 if (!validate_arg (fmt, POINTER_TYPE))
13877 return NULL_TREE;
13878
13879 if (! host_integerp (size, 1))
13880 return NULL_TREE;
13881
13882 if (! integer_all_onesp (size))
13883 {
13884 if (! host_integerp (len, 1))
13885 {
13886 /* If LEN is not constant, try MAXLEN too.
13887 For MAXLEN only allow optimizing into non-_ocs function
13888 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
13889 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
13890 return NULL_TREE;
13891 }
13892 else
13893 maxlen = len;
13894
13895 if (tree_int_cst_lt (size, maxlen))
13896 return NULL_TREE;
13897 }
13898
13899 if (!init_target_chars ())
13900 return NULL_TREE;
13901
13902 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
13903 or if format doesn't contain % chars or is "%s". */
13904 if (! integer_zerop (flag))
13905 {
13906 fmt_str = c_getstr (fmt);
13907 if (fmt_str == NULL)
13908 return NULL_TREE;
13909 if (strchr (fmt_str, target_percent) != NULL
13910 && strcmp (fmt_str, target_percent_s))
13911 return NULL_TREE;
13912 }
13913
13914 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
13915 available. */
13916 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
13917 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
13918 if (!fn)
13919 return NULL_TREE;
13920
13921 return gimple_rewrite_call_expr (stmt, 5, fn, 3, dest, len, fmt);
13922}
13923
13924/* Builtins with folding operations that operate on "..." arguments
13925 need special handling; we need to store the arguments in a convenient
13926 data structure before attempting any folding. Fortunately there are
13927 only a few builtins that fall into this category. FNDECL is the
13928 function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
13929 result of the function call is ignored. */
13930
13931static tree
13932gimple_fold_builtin_varargs (tree fndecl, gimple stmt, bool ignore ATTRIBUTE_UNUSED)
13933{
13934 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
13935 tree ret = NULL_TREE;
13936
13937 switch (fcode)
13938 {
13939 case BUILT_IN_SPRINTF_CHK:
13940 case BUILT_IN_VSPRINTF_CHK:
13941 ret = gimple_fold_builtin_sprintf_chk (stmt, fcode);
13942 break;
13943
13944 case BUILT_IN_SNPRINTF_CHK:
13945 case BUILT_IN_VSNPRINTF_CHK:
13946 ret = gimple_fold_builtin_snprintf_chk (stmt, NULL_TREE, fcode);
13947
13948 default:
13949 break;
13950 }
13951 if (ret)
13952 {
13953 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
13954 TREE_NO_WARNING (ret) = 1;
13955 return ret;
13956 }
13957 return NULL_TREE;
13958}
13959
13960/* A wrapper function for builtin folding that prevents warnings for
13961 "statement without effect" and the like, caused by removing the
13962 call node earlier than the warning is generated. */
13963
13964tree
13965fold_call_stmt (gimple stmt, bool ignore)
13966{
13967 tree ret = NULL_TREE;
13968 tree fndecl = gimple_call_fndecl (stmt);
13969 if (fndecl
13970 && TREE_CODE (fndecl) == FUNCTION_DECL
13971 && DECL_BUILT_IN (fndecl)
13972 && !gimple_call_va_arg_pack_p (stmt))
13973 {
13974 int nargs = gimple_call_num_args (stmt);
13975
198622c0 13976 if (avoid_folding_inline_builtin (fndecl))
13977 return NULL_TREE;
75a70cf9 13978 /* FIXME: Don't use a list in this interface. */
13979 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
13980 {
13981 tree arglist = NULL_TREE;
13982 int i;
13983 for (i = nargs - 1; i >= 0; i--)
13984 arglist = tree_cons (NULL_TREE, gimple_call_arg (stmt, i), arglist);
13985 return targetm.fold_builtin (fndecl, arglist, ignore);
13986 }
13987 else
13988 {
13989 if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
13990 {
13991 tree args[MAX_ARGS_TO_FOLD_BUILTIN];
13992 int i;
13993 for (i = 0; i < nargs; i++)
13994 args[i] = gimple_call_arg (stmt, i);
13995 ret = fold_builtin_n (fndecl, args, nargs, ignore);
13996 }
13997 if (!ret)
13998 ret = gimple_fold_builtin_varargs (fndecl, stmt, ignore);
13999 if (ret)
14000 {
14001 /* Propagate location information from original call to
14002 expansion of builtin. Otherwise things like
14003 maybe_emit_chk_warning, that operate on the expansion
14004 of a builtin, will use the wrong location information. */
14005 if (gimple_has_location (stmt))
14006 {
14007 tree realret = ret;
14008 if (TREE_CODE (ret) == NOP_EXPR)
14009 realret = TREE_OPERAND (ret, 0);
14010 if (CAN_HAVE_LOCATION_P (realret)
14011 && !EXPR_HAS_LOCATION (realret))
14012 SET_EXPR_LOCATION (realret, gimple_location (stmt));
14013 return realret;
14014 }
14015 return ret;
14016 }
14017 }
14018 }
14019 return NULL_TREE;
14020}