]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/builtins.c
PR libstdc++/37907
[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));
c699fab8 63#ifdef HAVE_mpc_pow
64static tree do_mpc_arg2 (tree, tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t));
65#endif
239d491a 66#endif
726e2588 67
ab7943b9 68/* Define the names of the builtin function types and codes. */
8934cb0c 69const char *const built_in_class_names[4]
ab7943b9 70 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
71
9cfddb70 72#define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
0dfc45b5 73const char * built_in_names[(int) END_BUILTINS] =
4e9d90c7 74{
75#include "builtins.def"
76};
77#undef DEF_BUILTIN
ab7943b9 78
df94cd3b 79/* Setup an array of _DECL trees, make sure each element is
80 initialized to NULL_TREE. */
d2d4bdde 81tree built_in_decls[(int) END_BUILTINS];
0a68165a 82/* Declarations used when constructing the builtin implicitly in the compiler.
83 It may be NULL_TREE when this is invalid (for instance runtime is not
4ee9c684 84 required to implement the function call in all cases). */
0a68165a 85tree implicit_built_in_decls[(int) END_BUILTINS];
df94cd3b 86
aecda0d6 87static const char *c_getstr (tree);
88static rtx c_readstr (const char *, enum machine_mode);
89static int target_char_cast (tree, char *);
d8ae1baa 90static rtx get_memory_rtx (tree, tree);
aecda0d6 91static int apply_args_size (void);
92static int apply_result_size (void);
d8c9779c 93#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
aecda0d6 94static rtx result_vector (int, rtx);
d8c9779c 95#endif
843d08a9 96static void expand_builtin_update_setjmp_buf (rtx);
aecda0d6 97static void expand_builtin_prefetch (tree);
98static rtx expand_builtin_apply_args (void);
99static rtx expand_builtin_apply_args_1 (void);
100static rtx expand_builtin_apply (rtx, rtx, rtx);
101static void expand_builtin_return (rtx);
102static enum type_class type_to_class (tree);
103static rtx expand_builtin_classify_type (tree);
104static void expand_errno_check (tree, rtx);
105static rtx expand_builtin_mathfn (tree, rtx, rtx);
106static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
6b43bae4 107static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
a67a90e5 108static rtx expand_builtin_interclass_mathfn (tree, rtx, rtx);
c3147c1a 109static rtx expand_builtin_sincos (tree);
d735c391 110static rtx expand_builtin_cexpi (tree, rtx, rtx);
ff1b14e4 111static rtx expand_builtin_int_roundingfn (tree, rtx);
112static rtx expand_builtin_int_roundingfn_2 (tree, rtx);
aecda0d6 113static rtx expand_builtin_args_info (tree);
79012a9d 114static rtx expand_builtin_next_arg (void);
aecda0d6 115static rtx expand_builtin_va_start (tree);
116static rtx expand_builtin_va_end (tree);
117static rtx expand_builtin_va_copy (tree);
7959b13b 118static rtx expand_builtin_memchr (tree, rtx, enum machine_mode);
c2f47e15 119static rtx expand_builtin_memcmp (tree, rtx, enum machine_mode);
aecda0d6 120static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
121static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
122static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
7da1412b 123static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
aecda0d6 124static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
125static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
126static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
127static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
c2f47e15 128static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode);
129static rtx expand_builtin_mempcpy_args (tree, tree, tree, tree, rtx,
130 enum machine_mode, int);
131static rtx expand_builtin_memmove (tree, rtx, enum machine_mode, int);
132static rtx expand_builtin_memmove_args (tree, tree, tree, tree, rtx,
133 enum machine_mode, int);
134static rtx expand_builtin_bcopy (tree, int);
1d89860b 135static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
c2f47e15 136static rtx expand_builtin_strcpy_args (tree, tree, tree, rtx, enum machine_mode);
aecda0d6 137static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
aecda0d6 138static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
aecda0d6 139static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
c2f47e15 140static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
141static rtx expand_builtin_memset_args (tree, tree, tree, rtx, enum machine_mode, tree);
aecda0d6 142static rtx expand_builtin_bzero (tree);
143static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
c2f47e15 144static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
145static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
146static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
147static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
aecda0d6 148static rtx expand_builtin_alloca (tree, rtx);
149static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
150static rtx expand_builtin_frame_address (tree, tree);
19bf118a 151static rtx expand_builtin_fputs (tree, rtx, bool);
152static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
153static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
6411575e 154static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
aecda0d6 155static tree stabilize_va_list (tree, int);
156static rtx expand_builtin_expect (tree, rtx);
157static tree fold_builtin_constant_p (tree);
76f5a783 158static tree fold_builtin_expect (tree, tree);
aecda0d6 159static tree fold_builtin_classify_type (tree);
e6e27594 160static tree fold_builtin_strlen (tree);
aecda0d6 161static tree fold_builtin_inf (tree, int);
162static tree fold_builtin_nan (tree, tree, int);
c2f47e15 163static tree rewrite_call_expr (tree, int, tree, int, ...);
b7bf20db 164static bool validate_arg (const_tree, enum tree_code code);
277f8dd2 165static bool integer_valued_real_p (tree);
76b9b24b 166static tree fold_trunc_transparent_mathfn (tree, tree);
aecda0d6 167static bool readonly_data_expr (tree);
168static rtx expand_builtin_fabs (tree, rtx, rtx);
27f261ef 169static rtx expand_builtin_signbit (tree, rtx);
e6e27594 170static tree fold_builtin_sqrt (tree, tree);
171static tree fold_builtin_cbrt (tree, tree);
c2f47e15 172static tree fold_builtin_pow (tree, tree, tree, tree);
173static tree fold_builtin_powi (tree, tree, tree, tree);
e6e27594 174static tree fold_builtin_cos (tree, tree, tree);
cacdc1af 175static tree fold_builtin_cosh (tree, tree, tree);
bffb7645 176static tree fold_builtin_tan (tree, tree);
7169af54 177static tree fold_builtin_trunc (tree, tree);
178static tree fold_builtin_floor (tree, tree);
179static tree fold_builtin_ceil (tree, tree);
180static tree fold_builtin_round (tree, tree);
ad52b9b7 181static tree fold_builtin_int_roundingfn (tree, tree);
10b9666f 182static tree fold_builtin_bitop (tree, tree);
c2f47e15 183static tree fold_builtin_memory_op (tree, tree, tree, tree, bool, int);
184static tree fold_builtin_strchr (tree, tree, tree);
7959b13b 185static tree fold_builtin_memchr (tree, tree, tree, tree);
c2f47e15 186static tree fold_builtin_memcmp (tree, tree, tree);
187static tree fold_builtin_strcmp (tree, tree);
188static tree fold_builtin_strncmp (tree, tree, tree);
64c18e8d 189static tree fold_builtin_signbit (tree, tree);
c2f47e15 190static tree fold_builtin_copysign (tree, tree, tree, tree);
467214fd 191static tree fold_builtin_isascii (tree);
192static tree fold_builtin_toascii (tree);
193static tree fold_builtin_isdigit (tree);
d1aade50 194static tree fold_builtin_fabs (tree, tree);
195static tree fold_builtin_abs (tree, tree);
c2f47e15 196static tree fold_builtin_unordered_cmp (tree, tree, tree, enum tree_code,
d5019fe8 197 enum tree_code);
c2f47e15 198static tree fold_builtin_n (tree, tree *, int, bool);
199static tree fold_builtin_0 (tree, bool);
3d3d84b8 200static tree fold_builtin_1 (tree, tree, bool);
c2f47e15 201static tree fold_builtin_2 (tree, tree, tree, bool);
202static tree fold_builtin_3 (tree, tree, tree, tree, bool);
203static tree fold_builtin_4 (tree, tree, tree, tree, tree, bool);
204static tree fold_builtin_varargs (tree, tree, bool);
205
206static tree fold_builtin_strpbrk (tree, tree, tree);
207static tree fold_builtin_strstr (tree, tree, tree);
208static tree fold_builtin_strrchr (tree, tree, tree);
209static tree fold_builtin_strcat (tree, tree);
210static tree fold_builtin_strncat (tree, tree, tree);
211static tree fold_builtin_strspn (tree, tree);
212static tree fold_builtin_strcspn (tree, tree);
213static tree fold_builtin_sprintf (tree, tree, tree, int);
4ee9c684 214
0a39fd54 215static rtx expand_builtin_object_size (tree);
216static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
217 enum built_in_function);
218static void maybe_emit_chk_warning (tree, enum built_in_function);
219static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
2c281b15 220static void maybe_emit_free_warning (tree);
c2f47e15 221static tree fold_builtin_object_size (tree, tree);
222static tree fold_builtin_strcat_chk (tree, tree, tree, tree);
223static tree fold_builtin_strncat_chk (tree, tree, tree, tree, tree);
0a39fd54 224static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
c2f47e15 225static tree fold_builtin_printf (tree, tree, tree, bool, enum built_in_function);
226static tree fold_builtin_fprintf (tree, tree, tree, tree, bool,
227 enum built_in_function);
99eabcc1 228static bool init_target_chars (void);
229
230static unsigned HOST_WIDE_INT target_newline;
231static unsigned HOST_WIDE_INT target_percent;
232static unsigned HOST_WIDE_INT target_c;
233static unsigned HOST_WIDE_INT target_s;
234static char target_percent_c[3];
235static char target_percent_s[3];
236static char target_percent_s_newline[4];
728bac60 237static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
238 const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool);
f0c477f2 239static tree do_mpfr_arg2 (tree, tree, tree,
240 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
9917422b 241static tree do_mpfr_arg3 (tree, tree, tree, tree,
242 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
d92f994c 243static tree do_mpfr_sincos (tree, tree, tree);
65dd1378 244static tree do_mpfr_bessel_n (tree, tree, tree,
245 int (*)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
246 const REAL_VALUE_TYPE *, bool);
e5407ca6 247static tree do_mpfr_remquo (tree, tree, tree);
e84da7c1 248static tree do_mpfr_lgamma_r (tree, tree, tree);
0a39fd54 249
1c47b3e8 250bool
251is_builtin_name (const char *name)
b6a5fc45 252{
b6a5fc45 253 if (strncmp (name, "__builtin_", 10) == 0)
254 return true;
255 if (strncmp (name, "__sync_", 7) == 0)
256 return true;
257 return false;
258}
4ee9c684 259
1c47b3e8 260/* Return true if NODE should be considered for inline expansion regardless
261 of the optimization level. This means whenever a function is invoked with
262 its "internal" name, which normally contains the prefix "__builtin". */
263
264static bool
265called_as_built_in (tree node)
266{
267 /* Note that we must use DECL_NAME, not DECL_ASSEMBLER_NAME_SET_P since
268 we want the name used to call the function, not the name it
269 will have. */
270 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
271 return is_builtin_name (name);
272}
273
698537d1 274/* Return the alignment in bits of EXP, an object.
275 Don't return more than MAX_ALIGN no matter what, ALIGN is the inital
276 guessed alignment e.g. from type alignment. */
277
278int
279get_object_alignment (tree exp, unsigned int align, unsigned int max_align)
280{
281 unsigned int inner;
282
283 inner = max_align;
284 if (handled_component_p (exp))
285 {
286 HOST_WIDE_INT bitsize, bitpos;
287 tree offset;
288 enum machine_mode mode;
289 int unsignedp, volatilep;
290
291 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
292 &mode, &unsignedp, &volatilep, true);
293 if (bitpos)
294 inner = MIN (inner, (unsigned) (bitpos & -bitpos));
295 while (offset)
296 {
297 tree next_offset;
298
299 if (TREE_CODE (offset) == PLUS_EXPR)
300 {
301 next_offset = TREE_OPERAND (offset, 0);
302 offset = TREE_OPERAND (offset, 1);
303 }
304 else
305 next_offset = NULL;
306 if (host_integerp (offset, 1))
307 {
308 /* Any overflow in calculating offset_bits won't change
309 the alignment. */
310 unsigned offset_bits
311 = ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT);
312
313 if (offset_bits)
314 inner = MIN (inner, (offset_bits & -offset_bits));
315 }
316 else if (TREE_CODE (offset) == MULT_EXPR
317 && host_integerp (TREE_OPERAND (offset, 1), 1))
318 {
319 /* Any overflow in calculating offset_factor won't change
320 the alignment. */
321 unsigned offset_factor
322 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
323 * BITS_PER_UNIT);
324
325 if (offset_factor)
326 inner = MIN (inner, (offset_factor & -offset_factor));
327 }
328 else
329 {
330 inner = MIN (inner, BITS_PER_UNIT);
331 break;
332 }
333 offset = next_offset;
334 }
335 }
336 if (DECL_P (exp))
337 align = MIN (inner, DECL_ALIGN (exp));
338#ifdef CONSTANT_ALIGNMENT
339 else if (CONSTANT_CLASS_P (exp))
340 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
341#endif
342 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
343 || TREE_CODE (exp) == INDIRECT_REF)
344 align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
345 else
346 align = MIN (align, inner);
347 return MIN (align, max_align);
348}
349
7abca321 350/* Returns true iff we can trust that alignment information has been
351 calculated properly. */
352
353bool
354can_trust_pointer_alignment (void)
355{
356 /* We rely on TER to compute accurate alignment information. */
357 return (optimize && flag_tree_ter);
358}
359
53800dbe 360/* Return the alignment in bits of EXP, a pointer valued expression.
361 But don't return more than MAX_ALIGN no matter what.
362 The alignment returned is, by default, the alignment of the thing that
27d0c333 363 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
53800dbe 364
365 Otherwise, look at the expression to see if we can do better, i.e., if the
366 expression is actually pointing at an object whose alignment is tighter. */
367
f656b751 368int
aecda0d6 369get_pointer_alignment (tree exp, unsigned int max_align)
53800dbe 370{
27d0c333 371 unsigned int align, inner;
53800dbe 372
7abca321 373 if (!can_trust_pointer_alignment ())
189575ff 374 return 0;
375
535e2026 376 if (!POINTER_TYPE_P (TREE_TYPE (exp)))
377 return 0;
378
53800dbe 379 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
380 align = MIN (align, max_align);
381
382 while (1)
383 {
384 switch (TREE_CODE (exp))
385 {
72dd6141 386 CASE_CONVERT:
53800dbe 387 exp = TREE_OPERAND (exp, 0);
552752f7 388 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
53800dbe 389 return align;
325d1c45 390
53800dbe 391 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
392 align = MIN (inner, max_align);
393 break;
394
0de36bdb 395 case POINTER_PLUS_EXPR:
53800dbe 396 /* If sum of pointer + int, restrict our maximum alignment to that
397 imposed by the integer. If not, we can't do any better than
398 ALIGN. */
325d1c45 399 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
53800dbe 400 return align;
401
0994d2ed 402 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
403 & (max_align / BITS_PER_UNIT - 1))
53800dbe 404 != 0)
405 max_align >>= 1;
406
407 exp = TREE_OPERAND (exp, 0);
408 break;
409
410 case ADDR_EXPR:
411 /* See what we are pointing at and look at its alignment. */
698537d1 412 return get_object_alignment (TREE_OPERAND (exp, 0), align, max_align);
53800dbe 413
414 default:
415 return align;
416 }
417 }
418}
419
420/* Compute the length of a C string. TREE_STRING_LENGTH is not the right
421 way, because it could contain a zero byte in the middle.
422 TREE_STRING_LENGTH is the size of the character array, not the string.
423
4172d65e 424 ONLY_VALUE should be nonzero if the result is not going to be emitted
c09841f6 425 into the instruction stream and zero if it is going to be expanded.
4172d65e 426 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
681fab1e 427 is returned, otherwise NULL, since
428 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
429 evaluate the side-effects.
430
902de8ed 431 The value returned is of type `ssizetype'.
432
53800dbe 433 Unfortunately, string_constant can't access the values of const char
434 arrays with initializers, so neither can we do so here. */
435
4ee9c684 436tree
681fab1e 437c_strlen (tree src, int only_value)
53800dbe 438{
439 tree offset_node;
27d0c333 440 HOST_WIDE_INT offset;
441 int max;
44acf429 442 const char *ptr;
53800dbe 443
681fab1e 444 STRIP_NOPS (src);
445 if (TREE_CODE (src) == COND_EXPR
446 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
447 {
448 tree len1, len2;
449
450 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
451 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
0862b7e9 452 if (tree_int_cst_equal (len1, len2))
681fab1e 453 return len1;
454 }
455
456 if (TREE_CODE (src) == COMPOUND_EXPR
457 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
458 return c_strlen (TREE_OPERAND (src, 1), only_value);
459
53800dbe 460 src = string_constant (src, &offset_node);
461 if (src == 0)
c2f47e15 462 return NULL_TREE;
902de8ed 463
83d79705 464 max = TREE_STRING_LENGTH (src) - 1;
53800dbe 465 ptr = TREE_STRING_POINTER (src);
902de8ed 466
53800dbe 467 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
468 {
469 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
470 compute the offset to the following null if we don't know where to
471 start searching for it. */
472 int i;
902de8ed 473
53800dbe 474 for (i = 0; i < max; i++)
475 if (ptr[i] == 0)
c2f47e15 476 return NULL_TREE;
902de8ed 477
53800dbe 478 /* We don't know the starting offset, but we do know that the string
479 has no internal zero bytes. We can assume that the offset falls
480 within the bounds of the string; otherwise, the programmer deserves
481 what he gets. Subtract the offset from the length of the string,
902de8ed 482 and return that. This would perhaps not be valid if we were dealing
483 with named arrays in addition to literal string constants. */
484
485 return size_diffop (size_int (max), offset_node);
53800dbe 486 }
487
488 /* We have a known offset into the string. Start searching there for
27d0c333 489 a null character if we can represent it as a single HOST_WIDE_INT. */
dabc4084 490 if (offset_node == 0)
53800dbe 491 offset = 0;
dabc4084 492 else if (! host_integerp (offset_node, 0))
493 offset = -1;
53800dbe 494 else
27d0c333 495 offset = tree_low_cst (offset_node, 0);
902de8ed 496
1f63a7d6 497 /* If the offset is known to be out of bounds, warn, and call strlen at
498 runtime. */
53800dbe 499 if (offset < 0 || offset > max)
500 {
1f63a7d6 501 /* Suppress multiple warnings for propagated constant strings. */
502 if (! TREE_NO_WARNING (src))
503 {
504 warning (0, "offset outside bounds of constant string");
505 TREE_NO_WARNING (src) = 1;
506 }
c2f47e15 507 return NULL_TREE;
53800dbe 508 }
902de8ed 509
53800dbe 510 /* Use strlen to search for the first zero byte. Since any strings
511 constructed with build_string will have nulls appended, we win even
512 if we get handed something like (char[4])"abcd".
513
514 Since OFFSET is our starting index into the string, no further
515 calculation is needed. */
902de8ed 516 return ssize_int (strlen (ptr + offset));
53800dbe 517}
518
83d79705 519/* Return a char pointer for a C string if it is a string constant
520 or sum of string constant and integer constant. */
521
522static const char *
aecda0d6 523c_getstr (tree src)
83d79705 524{
525 tree offset_node;
83d79705 526
527 src = string_constant (src, &offset_node);
528 if (src == 0)
529 return 0;
530
8c85fcb7 531 if (offset_node == 0)
532 return TREE_STRING_POINTER (src);
533 else if (!host_integerp (offset_node, 1)
534 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
83d79705 535 return 0;
83d79705 536
8c85fcb7 537 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
83d79705 538}
539
8c85fcb7 540/* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
541 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
ecc318ff 542
6840589f 543static rtx
aecda0d6 544c_readstr (const char *str, enum machine_mode mode)
6840589f 545{
546 HOST_WIDE_INT c[2];
547 HOST_WIDE_INT ch;
548 unsigned int i, j;
549
64db345d 550 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
7d3f6cc7 551
6840589f 552 c[0] = 0;
553 c[1] = 0;
554 ch = 1;
555 for (i = 0; i < GET_MODE_SIZE (mode); i++)
556 {
557 j = i;
558 if (WORDS_BIG_ENDIAN)
559 j = GET_MODE_SIZE (mode) - i - 1;
560 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
561 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
562 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
563 j *= BITS_PER_UNIT;
64db345d 564 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
7d3f6cc7 565
6840589f 566 if (ch)
567 ch = (unsigned char) str[i];
568 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
569 }
570 return immed_double_const (c[0], c[1], mode);
571}
572
ecc318ff 573/* Cast a target constant CST to target CHAR and if that value fits into
5206b159 574 host char type, return zero and put that value into variable pointed to by
ecc318ff 575 P. */
576
577static int
aecda0d6 578target_char_cast (tree cst, char *p)
ecc318ff 579{
580 unsigned HOST_WIDE_INT val, hostval;
581
27d0c333 582 if (!host_integerp (cst, 1)
ecc318ff 583 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
584 return 1;
585
27d0c333 586 val = tree_low_cst (cst, 1);
ecc318ff 587 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
588 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
589
590 hostval = val;
591 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
592 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
593
594 if (val != hostval)
595 return 1;
596
597 *p = hostval;
598 return 0;
599}
600
4ee9c684 601/* Similar to save_expr, but assumes that arbitrary code is not executed
602 in between the multiple evaluations. In particular, we assume that a
603 non-addressable local variable will not be modified. */
604
605static tree
606builtin_save_expr (tree exp)
607{
608 if (TREE_ADDRESSABLE (exp) == 0
609 && (TREE_CODE (exp) == PARM_DECL
610 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
611 return exp;
612
613 return save_expr (exp);
614}
615
53800dbe 616/* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
617 times to get the address of either a higher stack frame, or a return
618 address located within it (depending on FNDECL_CODE). */
902de8ed 619
c626df3d 620static rtx
869d0ef0 621expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
53800dbe 622{
623 int i;
624
869d0ef0 625#ifdef INITIAL_FRAME_ADDRESS_RTX
626 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
627#else
e3e15c50 628 rtx tem;
629
1b74fde7 630 /* For a zero count with __builtin_return_address, we don't care what
631 frame address we return, because target-specific definitions will
632 override us. Therefore frame pointer elimination is OK, and using
633 the soft frame pointer is OK.
634
fa7637bd 635 For a nonzero count, or a zero count with __builtin_frame_address,
1b74fde7 636 we require a stable offset from the current frame pointer to the
637 previous one, so we must use the hard frame pointer, and
e3e15c50 638 we must disable frame pointer elimination. */
1b74fde7 639 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
e3e15c50 640 tem = frame_pointer_rtx;
a0c938f0 641 else
e3e15c50 642 {
643 tem = hard_frame_pointer_rtx;
644
645 /* Tell reload not to eliminate the frame pointer. */
18d50ae6 646 crtl->accesses_prior_frames = 1;
e3e15c50 647 }
869d0ef0 648#endif
649
53800dbe 650 /* Some machines need special handling before we can access
3a69c60c 651 arbitrary frames. For example, on the SPARC, we must first flush
53800dbe 652 all register windows to the stack. */
653#ifdef SETUP_FRAME_ADDRESSES
654 if (count > 0)
655 SETUP_FRAME_ADDRESSES ();
656#endif
657
3a69c60c 658 /* On the SPARC, the return address is not in the frame, it is in a
53800dbe 659 register. There is no way to access it off of the current frame
660 pointer, but it can be accessed off the previous frame pointer by
661 reading the value from the register window save area. */
662#ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
663 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
664 count--;
665#endif
666
667 /* Scan back COUNT frames to the specified frame. */
668 for (i = 0; i < count; i++)
669 {
670 /* Assume the dynamic chain pointer is in the word that the
671 frame address points to, unless otherwise specified. */
672#ifdef DYNAMIC_CHAIN_ADDRESS
673 tem = DYNAMIC_CHAIN_ADDRESS (tem);
674#endif
675 tem = memory_address (Pmode, tem);
00060fc2 676 tem = gen_frame_mem (Pmode, tem);
83fc1478 677 tem = copy_to_reg (tem);
53800dbe 678 }
679
3a69c60c 680 /* For __builtin_frame_address, return what we've got. But, on
681 the SPARC for example, we may have to add a bias. */
53800dbe 682 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
3a69c60c 683#ifdef FRAME_ADDR_RTX
684 return FRAME_ADDR_RTX (tem);
685#else
53800dbe 686 return tem;
3a69c60c 687#endif
53800dbe 688
3a69c60c 689 /* For __builtin_return_address, get the return address from that frame. */
53800dbe 690#ifdef RETURN_ADDR_RTX
691 tem = RETURN_ADDR_RTX (count, tem);
692#else
693 tem = memory_address (Pmode,
694 plus_constant (tem, GET_MODE_SIZE (Pmode)));
00060fc2 695 tem = gen_frame_mem (Pmode, tem);
53800dbe 696#endif
697 return tem;
698}
699
f7c44134 700/* Alias set used for setjmp buffer. */
32c2fdea 701static alias_set_type setjmp_alias_set = -1;
f7c44134 702
6b7f6858 703/* Construct the leading half of a __builtin_setjmp call. Control will
2c8a1497 704 return to RECEIVER_LABEL. This is also called directly by the SJLJ
705 exception handling code. */
53800dbe 706
6b7f6858 707void
aecda0d6 708expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
53800dbe 709{
53800dbe 710 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
53800dbe 711 rtx stack_save;
f7c44134 712 rtx mem;
53800dbe 713
f7c44134 714 if (setjmp_alias_set == -1)
715 setjmp_alias_set = new_alias_set ();
716
85d654dd 717 buf_addr = convert_memory_address (Pmode, buf_addr);
53800dbe 718
37ae8504 719 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
53800dbe 720
6b7f6858 721 /* We store the frame pointer and the address of receiver_label in
722 the buffer and use the rest of it for the stack save area, which
723 is machine-dependent. */
53800dbe 724
f7c44134 725 mem = gen_rtx_MEM (Pmode, buf_addr);
ab6ab77e 726 set_mem_alias_set (mem, setjmp_alias_set);
e3e026e8 727 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
f7c44134 728
729 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
ab6ab77e 730 set_mem_alias_set (mem, setjmp_alias_set);
f7c44134 731
732 emit_move_insn (validize_mem (mem),
6b7f6858 733 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
53800dbe 734
735 stack_save = gen_rtx_MEM (sa_mode,
736 plus_constant (buf_addr,
737 2 * GET_MODE_SIZE (Pmode)));
ab6ab77e 738 set_mem_alias_set (stack_save, setjmp_alias_set);
53800dbe 739 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
740
741 /* If there is further processing to do, do it. */
742#ifdef HAVE_builtin_setjmp_setup
743 if (HAVE_builtin_setjmp_setup)
744 emit_insn (gen_builtin_setjmp_setup (buf_addr));
745#endif
746
6b7f6858 747 /* Tell optimize_save_area_alloca that extra work is going to
748 need to go on during alloca. */
18d50ae6 749 cfun->calls_setjmp = 1;
80ab81b9 750
29f09705 751 /* We have a nonlocal label. */
18d50ae6 752 cfun->has_nonlocal_label = 1;
6b7f6858 753}
53800dbe 754
2c8a1497 755/* Construct the trailing part of a __builtin_setjmp call. This is
756 also called directly by the SJLJ exception handling code. */
6b7f6858 757
758void
aecda0d6 759expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
6b7f6858 760{
53800dbe 761 /* Clobber the FP when we get here, so we have to make sure it's
762 marked as used by this function. */
18b42941 763 emit_use (hard_frame_pointer_rtx);
53800dbe 764
765 /* Mark the static chain as clobbered here so life information
766 doesn't get messed up for it. */
18b42941 767 emit_clobber (static_chain_rtx);
53800dbe 768
769 /* Now put in the code to restore the frame pointer, and argument
491e04ef 770 pointer, if needed. */
53800dbe 771#ifdef HAVE_nonlocal_goto
772 if (! HAVE_nonlocal_goto)
773#endif
5a1c3f40 774 {
775 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
776 /* This might change the hard frame pointer in ways that aren't
777 apparent to early optimization passes, so force a clobber. */
18b42941 778 emit_clobber (hard_frame_pointer_rtx);
5a1c3f40 779 }
53800dbe 780
781#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
782 if (fixed_regs[ARG_POINTER_REGNUM])
783 {
784#ifdef ELIMINABLE_REGS
785 size_t i;
e99c3a1d 786 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
53800dbe 787
3098b2d3 788 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
53800dbe 789 if (elim_regs[i].from == ARG_POINTER_REGNUM
790 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
791 break;
792
3098b2d3 793 if (i == ARRAY_SIZE (elim_regs))
53800dbe 794#endif
795 {
796 /* Now restore our arg pointer from the address at which it
05927e40 797 was saved in our stack frame. */
27a7a23a 798 emit_move_insn (crtl->args.internal_arg_pointer,
b079a207 799 copy_to_reg (get_arg_pointer_save_area ()));
53800dbe 800 }
801 }
802#endif
803
804#ifdef HAVE_builtin_setjmp_receiver
805 if (HAVE_builtin_setjmp_receiver)
6b7f6858 806 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
53800dbe 807 else
808#endif
809#ifdef HAVE_nonlocal_goto_receiver
810 if (HAVE_nonlocal_goto_receiver)
811 emit_insn (gen_nonlocal_goto_receiver ());
812 else
813#endif
6b7f6858 814 { /* Nothing */ }
57f6bb94 815
3072d30e 816 /* We must not allow the code we just generated to be reordered by
817 scheduling. Specifically, the update of the frame pointer must
818 happen immediately, not later. */
819 emit_insn (gen_blockage ());
6b7f6858 820}
53800dbe 821
53800dbe 822/* __builtin_longjmp is passed a pointer to an array of five words (not
823 all will be used on all machines). It operates similarly to the C
824 library function of the same name, but is more efficient. Much of
2c8a1497 825 the code below is copied from the handling of non-local gotos. */
53800dbe 826
c626df3d 827static void
aecda0d6 828expand_builtin_longjmp (rtx buf_addr, rtx value)
53800dbe 829{
4712c7d6 830 rtx fp, lab, stack, insn, last;
53800dbe 831 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
832
27a7a23a 833 /* DRAP is needed for stack realign if longjmp is expanded to current
834 function */
835 if (SUPPORTS_STACK_ALIGNMENT)
836 crtl->need_drap = true;
837
f7c44134 838 if (setjmp_alias_set == -1)
839 setjmp_alias_set = new_alias_set ();
840
85d654dd 841 buf_addr = convert_memory_address (Pmode, buf_addr);
479e4d5e 842
53800dbe 843 buf_addr = force_reg (Pmode, buf_addr);
844
845 /* We used to store value in static_chain_rtx, but that fails if pointers
846 are smaller than integers. We instead require that the user must pass
847 a second argument of 1, because that is what builtin_setjmp will
848 return. This also makes EH slightly more efficient, since we are no
849 longer copying around a value that we don't care about. */
64db345d 850 gcc_assert (value == const1_rtx);
53800dbe 851
4712c7d6 852 last = get_last_insn ();
53800dbe 853#ifdef HAVE_builtin_longjmp
854 if (HAVE_builtin_longjmp)
855 emit_insn (gen_builtin_longjmp (buf_addr));
856 else
857#endif
858 {
859 fp = gen_rtx_MEM (Pmode, buf_addr);
860 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
861 GET_MODE_SIZE (Pmode)));
862
863 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
864 2 * GET_MODE_SIZE (Pmode)));
ab6ab77e 865 set_mem_alias_set (fp, setjmp_alias_set);
866 set_mem_alias_set (lab, setjmp_alias_set);
867 set_mem_alias_set (stack, setjmp_alias_set);
53800dbe 868
869 /* Pick up FP, label, and SP from the block and jump. This code is
870 from expand_goto in stmt.c; see there for detailed comments. */
03fd9d2c 871#ifdef HAVE_nonlocal_goto
53800dbe 872 if (HAVE_nonlocal_goto)
873 /* We have to pass a value to the nonlocal_goto pattern that will
874 get copied into the static_chain pointer, but it does not matter
875 what that value is, because builtin_setjmp does not use it. */
28d202a8 876 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
53800dbe 877 else
878#endif
879 {
880 lab = copy_to_reg (lab);
881
18b42941 882 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
883 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
2a871ad1 884
53800dbe 885 emit_move_insn (hard_frame_pointer_rtx, fp);
886 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
887
18b42941 888 emit_use (hard_frame_pointer_rtx);
889 emit_use (stack_pointer_rtx);
53800dbe 890 emit_indirect_jump (lab);
891 }
892 }
615166bb 893
894 /* Search backwards and mark the jump insn as a non-local goto.
895 Note that this precludes the use of __builtin_longjmp to a
896 __builtin_setjmp target in the same function. However, we've
897 already cautioned the user that these functions are for
898 internal exception handling use only. */
449c0509 899 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
900 {
64db345d 901 gcc_assert (insn != last);
7d3f6cc7 902
6d7dc5b9 903 if (JUMP_P (insn))
449c0509 904 {
a1ddb869 905 add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
449c0509 906 break;
907 }
6d7dc5b9 908 else if (CALL_P (insn))
9342ee68 909 break;
449c0509 910 }
53800dbe 911}
912
4ee9c684 913/* Expand a call to __builtin_nonlocal_goto. We're passed the target label
914 and the address of the save area. */
915
916static rtx
c2f47e15 917expand_builtin_nonlocal_goto (tree exp)
4ee9c684 918{
919 tree t_label, t_save_area;
920 rtx r_label, r_save_area, r_fp, r_sp, insn;
921
c2f47e15 922 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4ee9c684 923 return NULL_RTX;
924
c2f47e15 925 t_label = CALL_EXPR_ARG (exp, 0);
926 t_save_area = CALL_EXPR_ARG (exp, 1);
4ee9c684 927
8ec3c5c2 928 r_label = expand_normal (t_label);
3dce56cc 929 r_label = convert_memory_address (Pmode, r_label);
8ec3c5c2 930 r_save_area = expand_normal (t_save_area);
3dce56cc 931 r_save_area = convert_memory_address (Pmode, r_save_area);
51adbc8a 932 /* Copy the address of the save location to a register just in case it was based
933 on the frame pointer. */
934 r_save_area = copy_to_reg (r_save_area);
4ee9c684 935 r_fp = gen_rtx_MEM (Pmode, r_save_area);
936 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
937 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
938
18d50ae6 939 crtl->has_nonlocal_goto = 1;
4ee9c684 940
03fd9d2c 941#ifdef HAVE_nonlocal_goto
4ee9c684 942 /* ??? We no longer need to pass the static chain value, afaik. */
943 if (HAVE_nonlocal_goto)
944 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
945 else
946#endif
947 {
948 r_label = copy_to_reg (r_label);
949
18b42941 950 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
951 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
491e04ef 952
4ee9c684 953 /* Restore frame pointer for containing function.
954 This sets the actual hard register used for the frame pointer
955 to the location of the function's incoming static chain info.
956 The non-local goto handler will then adjust it to contain the
957 proper value and reload the argument pointer, if needed. */
958 emit_move_insn (hard_frame_pointer_rtx, r_fp);
959 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
491e04ef 960
4ee9c684 961 /* USE of hard_frame_pointer_rtx added for consistency;
962 not clear if really needed. */
18b42941 963 emit_use (hard_frame_pointer_rtx);
964 emit_use (stack_pointer_rtx);
ad0d0af8 965
966 /* If the architecture is using a GP register, we must
967 conservatively assume that the target function makes use of it.
968 The prologue of functions with nonlocal gotos must therefore
969 initialize the GP register to the appropriate value, and we
970 must then make sure that this value is live at the point
971 of the jump. (Note that this doesn't necessarily apply
972 to targets with a nonlocal_goto pattern; they are free
973 to implement it in their own way. Note also that this is
974 a no-op if the GP register is a global invariant.) */
975 if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
976 && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
18b42941 977 emit_use (pic_offset_table_rtx);
ad0d0af8 978
4ee9c684 979 emit_indirect_jump (r_label);
980 }
491e04ef 981
4ee9c684 982 /* Search backwards to the jump insn and mark it as a
983 non-local goto. */
984 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
985 {
6d7dc5b9 986 if (JUMP_P (insn))
4ee9c684 987 {
a1ddb869 988 add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
4ee9c684 989 break;
990 }
6d7dc5b9 991 else if (CALL_P (insn))
4ee9c684 992 break;
993 }
994
995 return const0_rtx;
996}
997
843d08a9 998/* __builtin_update_setjmp_buf is passed a pointer to an array of five words
999 (not all will be used on all machines) that was passed to __builtin_setjmp.
1000 It updates the stack pointer in that block to correspond to the current
1001 stack pointer. */
1002
1003static void
1004expand_builtin_update_setjmp_buf (rtx buf_addr)
1005{
1006 enum machine_mode sa_mode = Pmode;
1007 rtx stack_save;
1008
1009
1010#ifdef HAVE_save_stack_nonlocal
1011 if (HAVE_save_stack_nonlocal)
1012 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
1013#endif
1014#ifdef STACK_SAVEAREA_MODE
1015 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
1016#endif
1017
1018 stack_save
1019 = gen_rtx_MEM (sa_mode,
1020 memory_address
1021 (sa_mode,
1022 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
1023
1024#ifdef HAVE_setjmp
1025 if (HAVE_setjmp)
1026 emit_insn (gen_setjmp ());
1027#endif
1028
1029 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
1030}
1031
5e3608d8 1032/* Expand a call to __builtin_prefetch. For a target that does not support
1033 data prefetch, evaluate the memory address argument in case it has side
1034 effects. */
1035
1036static void
c2f47e15 1037expand_builtin_prefetch (tree exp)
5e3608d8 1038{
1039 tree arg0, arg1, arg2;
c2f47e15 1040 int nargs;
5e3608d8 1041 rtx op0, op1, op2;
1042
c2f47e15 1043 if (!validate_arglist (exp, POINTER_TYPE, 0))
26a5cadb 1044 return;
1045
c2f47e15 1046 arg0 = CALL_EXPR_ARG (exp, 0);
1047
26a5cadb 1048 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
1049 zero (read) and argument 2 (locality) defaults to 3 (high degree of
1050 locality). */
c2f47e15 1051 nargs = call_expr_nargs (exp);
1052 if (nargs > 1)
1053 arg1 = CALL_EXPR_ARG (exp, 1);
26a5cadb 1054 else
c2f47e15 1055 arg1 = integer_zero_node;
1056 if (nargs > 2)
1057 arg2 = CALL_EXPR_ARG (exp, 2);
1058 else
1059 arg2 = build_int_cst (NULL_TREE, 3);
5e3608d8 1060
1061 /* Argument 0 is an address. */
1062 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
1063
1064 /* Argument 1 (read/write flag) must be a compile-time constant int. */
1065 if (TREE_CODE (arg1) != INTEGER_CST)
1066 {
07e3a3d2 1067 error ("second argument to %<__builtin_prefetch%> must be a constant");
9342ee68 1068 arg1 = integer_zero_node;
5e3608d8 1069 }
8ec3c5c2 1070 op1 = expand_normal (arg1);
5e3608d8 1071 /* Argument 1 must be either zero or one. */
1072 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
1073 {
c3ceba8e 1074 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
07e3a3d2 1075 " using zero");
5e3608d8 1076 op1 = const0_rtx;
1077 }
1078
1079 /* Argument 2 (locality) must be a compile-time constant int. */
1080 if (TREE_CODE (arg2) != INTEGER_CST)
1081 {
07e3a3d2 1082 error ("third argument to %<__builtin_prefetch%> must be a constant");
5e3608d8 1083 arg2 = integer_zero_node;
1084 }
8ec3c5c2 1085 op2 = expand_normal (arg2);
5e3608d8 1086 /* Argument 2 must be 0, 1, 2, or 3. */
1087 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1088 {
c3ceba8e 1089 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
5e3608d8 1090 op2 = const0_rtx;
1091 }
1092
1093#ifdef HAVE_prefetch
1094 if (HAVE_prefetch)
1095 {
f0ce3b1f 1096 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
4cd21437 1097 (op0,
f0ce3b1f 1098 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
19bf118a 1099 || (GET_MODE (op0) != Pmode))
9342ee68 1100 {
85d654dd 1101 op0 = convert_memory_address (Pmode, op0);
9342ee68 1102 op0 = force_reg (Pmode, op0);
1103 }
5e3608d8 1104 emit_insn (gen_prefetch (op0, op1, op2));
1105 }
5e3608d8 1106#endif
0a534ba7 1107
f0ce3b1f 1108 /* Don't do anything with direct references to volatile memory, but
1109 generate code to handle other side effects. */
e16ceb8e 1110 if (!MEM_P (op0) && side_effects_p (op0))
f0ce3b1f 1111 emit_insn (op0);
5e3608d8 1112}
1113
f7c44134 1114/* Get a MEM rtx for expression EXP which is the address of an operand
d8ae1baa 1115 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1116 the maximum length of the block of memory that might be accessed or
1117 NULL if unknown. */
f7c44134 1118
53800dbe 1119static rtx
d8ae1baa 1120get_memory_rtx (tree exp, tree len)
53800dbe 1121{
ad0a178f 1122 tree orig_exp = exp;
1123 rtx addr, mem;
1124 HOST_WIDE_INT off;
1125
1126 /* When EXP is not resolved SAVE_EXPR, MEM_ATTRS can be still derived
1127 from its expression, for expr->a.b only <variable>.a.b is recorded. */
1128 if (TREE_CODE (exp) == SAVE_EXPR && !SAVE_EXPR_RESOLVED_P (exp))
1129 exp = TREE_OPERAND (exp, 0);
1130
1131 addr = expand_expr (orig_exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1132 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
2a631e19 1133
f7c44134 1134 /* Get an expression we can use to find the attributes to assign to MEM.
1135 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1136 we can. First remove any nops. */
72dd6141 1137 while (CONVERT_EXPR_P (exp)
f7c44134 1138 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1139 exp = TREE_OPERAND (exp, 0);
1140
ad0a178f 1141 off = 0;
1142 if (TREE_CODE (exp) == POINTER_PLUS_EXPR
1143 && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
1144 && host_integerp (TREE_OPERAND (exp, 1), 0)
1145 && (off = tree_low_cst (TREE_OPERAND (exp, 1), 0)) > 0)
1146 exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1147 else if (TREE_CODE (exp) == ADDR_EXPR)
a1a25d19 1148 exp = TREE_OPERAND (exp, 0);
f7c44134 1149 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
a1a25d19 1150 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1151 else
1152 exp = NULL;
1153
1154 /* Honor attributes derived from exp, except for the alias set
1155 (as builtin stringops may alias with anything) and the size
1156 (as stringops may access multiple array elements). */
1157 if (exp)
eec8e941 1158 {
a1a25d19 1159 set_mem_attributes (mem, exp, 0);
d8ae1baa 1160
ad0a178f 1161 if (off)
1162 mem = adjust_automodify_address_nv (mem, BLKmode, NULL, off);
1163
d8ae1baa 1164 /* Allow the string and memory builtins to overflow from one
1165 field into another, see http://gcc.gnu.org/PR23561.
1166 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1167 memory accessed by the string or memory builtin will fit
1168 within the field. */
1169 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1170 {
1171 tree mem_expr = MEM_EXPR (mem);
1172 HOST_WIDE_INT offset = -1, length = -1;
1173 tree inner = exp;
1174
1175 while (TREE_CODE (inner) == ARRAY_REF
72dd6141 1176 || CONVERT_EXPR_P (inner)
d8ae1baa 1177 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1178 || TREE_CODE (inner) == SAVE_EXPR)
1179 inner = TREE_OPERAND (inner, 0);
1180
1181 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1182
1183 if (MEM_OFFSET (mem)
971ba038 1184 && CONST_INT_P (MEM_OFFSET (mem)))
d8ae1baa 1185 offset = INTVAL (MEM_OFFSET (mem));
1186
1187 if (offset >= 0 && len && host_integerp (len, 0))
1188 length = tree_low_cst (len, 0);
1189
1190 while (TREE_CODE (inner) == COMPONENT_REF)
1191 {
1192 tree field = TREE_OPERAND (inner, 1);
d8ae1baa 1193 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1194 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1195
6933ebec 1196 /* Bitfields are generally not byte-addressable. */
1197 gcc_assert (!DECL_BIT_FIELD (field)
1198 || ((tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1199 % BITS_PER_UNIT) == 0
1200 && host_integerp (DECL_SIZE (field), 0)
1201 && (TREE_INT_CST_LOW (DECL_SIZE (field))
1202 % BITS_PER_UNIT) == 0));
1203
b2f0b2a3 1204 /* If we can prove that the memory starting at XEXP (mem, 0) and
1205 ending at XEXP (mem, 0) + LENGTH will fit into this field, we
1206 can keep the COMPONENT_REF in MEM_EXPR. But be careful with
1207 fields without DECL_SIZE_UNIT like flexible array members. */
d8ae1baa 1208 if (length >= 0
b2f0b2a3 1209 && DECL_SIZE_UNIT (field)
6933ebec 1210 && host_integerp (DECL_SIZE_UNIT (field), 0))
d8ae1baa 1211 {
1212 HOST_WIDE_INT size
6933ebec 1213 = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field));
d8ae1baa 1214 if (offset <= size
1215 && length <= size
1216 && offset + length <= size)
1217 break;
1218 }
1219
1220 if (offset >= 0
1221 && host_integerp (DECL_FIELD_OFFSET (field), 0))
6933ebec 1222 offset += TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field))
d8ae1baa 1223 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1224 / BITS_PER_UNIT;
1225 else
1226 {
1227 offset = -1;
1228 length = -1;
1229 }
1230
1231 mem_expr = TREE_OPERAND (mem_expr, 0);
1232 inner = TREE_OPERAND (inner, 0);
d8ae1baa 1233 }
1234
1235 if (mem_expr == NULL)
1236 offset = -1;
1237 if (mem_expr != MEM_EXPR (mem))
1238 {
1239 set_mem_expr (mem, mem_expr);
1240 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1241 }
1242 }
eec8e941 1243 set_mem_alias_set (mem, 0);
a1a25d19 1244 set_mem_size (mem, NULL_RTX);
eec8e941 1245 }
53800dbe 1246
53800dbe 1247 return mem;
1248}
1249\f
1250/* Built-in functions to perform an untyped call and return. */
1251
1252/* For each register that may be used for calling a function, this
1253 gives a mode used to copy the register's value. VOIDmode indicates
1254 the register is not used for calling a function. If the machine
1255 has register windows, this gives only the outbound registers.
1256 INCOMING_REGNO gives the corresponding inbound register. */
1257static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1258
1259/* For each register that may be used for returning values, this gives
1260 a mode used to copy the register's value. VOIDmode indicates the
1261 register is not used for returning values. If the machine has
1262 register windows, this gives only the outbound registers.
1263 INCOMING_REGNO gives the corresponding inbound register. */
1264static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1265
1266/* For each register that may be used for calling a function, this
1267 gives the offset of that register into the block returned by
1268 __builtin_apply_args. 0 indicates that the register is not
1269 used for calling a function. */
1270static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1271
53800dbe 1272/* Return the size required for the block returned by __builtin_apply_args,
1273 and initialize apply_args_mode. */
1274
1275static int
aecda0d6 1276apply_args_size (void)
53800dbe 1277{
1278 static int size = -1;
58e9ce8f 1279 int align;
1280 unsigned int regno;
53800dbe 1281 enum machine_mode mode;
1282
1283 /* The values computed by this function never change. */
1284 if (size < 0)
1285 {
1286 /* The first value is the incoming arg-pointer. */
1287 size = GET_MODE_SIZE (Pmode);
1288
1289 /* The second value is the structure value address unless this is
1290 passed as an "invisible" first argument. */
6812c89e 1291 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
53800dbe 1292 size += GET_MODE_SIZE (Pmode);
1293
1294 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1295 if (FUNCTION_ARG_REGNO_P (regno))
1296 {
0862b7e9 1297 mode = reg_raw_mode[regno];
1298
64db345d 1299 gcc_assert (mode != VOIDmode);
53800dbe 1300
1301 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1302 if (size % align != 0)
1303 size = CEIL (size, align) * align;
1304 apply_args_reg_offset[regno] = size;
1305 size += GET_MODE_SIZE (mode);
1306 apply_args_mode[regno] = mode;
1307 }
1308 else
1309 {
1310 apply_args_mode[regno] = VOIDmode;
1311 apply_args_reg_offset[regno] = 0;
1312 }
1313 }
1314 return size;
1315}
1316
1317/* Return the size required for the block returned by __builtin_apply,
1318 and initialize apply_result_mode. */
1319
1320static int
aecda0d6 1321apply_result_size (void)
53800dbe 1322{
1323 static int size = -1;
1324 int align, regno;
1325 enum machine_mode mode;
1326
1327 /* The values computed by this function never change. */
1328 if (size < 0)
1329 {
1330 size = 0;
1331
1332 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1333 if (FUNCTION_VALUE_REGNO_P (regno))
1334 {
0862b7e9 1335 mode = reg_raw_mode[regno];
1336
64db345d 1337 gcc_assert (mode != VOIDmode);
53800dbe 1338
1339 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1340 if (size % align != 0)
1341 size = CEIL (size, align) * align;
1342 size += GET_MODE_SIZE (mode);
1343 apply_result_mode[regno] = mode;
1344 }
1345 else
1346 apply_result_mode[regno] = VOIDmode;
1347
1348 /* Allow targets that use untyped_call and untyped_return to override
1349 the size so that machine-specific information can be stored here. */
1350#ifdef APPLY_RESULT_SIZE
1351 size = APPLY_RESULT_SIZE;
1352#endif
1353 }
1354 return size;
1355}
1356
1357#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1358/* Create a vector describing the result block RESULT. If SAVEP is true,
1359 the result block is used to save the values; otherwise it is used to
1360 restore the values. */
1361
1362static rtx
aecda0d6 1363result_vector (int savep, rtx result)
53800dbe 1364{
1365 int regno, size, align, nelts;
1366 enum machine_mode mode;
1367 rtx reg, mem;
364c0c59 1368 rtx *savevec = XALLOCAVEC (rtx, FIRST_PSEUDO_REGISTER);
bf8e3599 1369
53800dbe 1370 size = nelts = 0;
1371 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1372 if ((mode = apply_result_mode[regno]) != VOIDmode)
1373 {
1374 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1375 if (size % align != 0)
1376 size = CEIL (size, align) * align;
1377 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
e513d163 1378 mem = adjust_address (result, mode, size);
53800dbe 1379 savevec[nelts++] = (savep
1380 ? gen_rtx_SET (VOIDmode, mem, reg)
1381 : gen_rtx_SET (VOIDmode, reg, mem));
1382 size += GET_MODE_SIZE (mode);
1383 }
1384 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1385}
1386#endif /* HAVE_untyped_call or HAVE_untyped_return */
1387
1388/* Save the state required to perform an untyped call with the same
1389 arguments as were passed to the current function. */
1390
1391static rtx
aecda0d6 1392expand_builtin_apply_args_1 (void)
53800dbe 1393{
1c7e61a7 1394 rtx registers, tem;
53800dbe 1395 int size, align, regno;
1396 enum machine_mode mode;
6812c89e 1397 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
53800dbe 1398
1399 /* Create a block where the arg-pointer, structure value address,
1400 and argument registers can be saved. */
1401 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1402
1403 /* Walk past the arg-pointer and structure value address. */
1404 size = GET_MODE_SIZE (Pmode);
6812c89e 1405 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
53800dbe 1406 size += GET_MODE_SIZE (Pmode);
1407
1408 /* Save each register used in calling a function to the block. */
1409 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1410 if ((mode = apply_args_mode[regno]) != VOIDmode)
1411 {
53800dbe 1412 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1413 if (size % align != 0)
1414 size = CEIL (size, align) * align;
1415
1416 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1417
e513d163 1418 emit_move_insn (adjust_address (registers, mode, size), tem);
53800dbe 1419 size += GET_MODE_SIZE (mode);
1420 }
1421
1422 /* Save the arg pointer to the block. */
27a7a23a 1423 tem = copy_to_reg (crtl->args.internal_arg_pointer);
f083a92b 1424#ifdef STACK_GROWS_DOWNWARD
1c7e61a7 1425 /* We need the pointer as the caller actually passed them to us, not
9d4b544c 1426 as we might have pretended they were passed. Make sure it's a valid
1427 operand, as emit_move_insn isn't expected to handle a PLUS. */
1428 tem
abe32cce 1429 = force_operand (plus_constant (tem, crtl->args.pretend_args_size),
9d4b544c 1430 NULL_RTX);
1c7e61a7 1431#endif
1432 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
0862b7e9 1433
53800dbe 1434 size = GET_MODE_SIZE (Pmode);
1435
1436 /* Save the structure value address unless this is passed as an
1437 "invisible" first argument. */
45550790 1438 if (struct_incoming_value)
53800dbe 1439 {
e513d163 1440 emit_move_insn (adjust_address (registers, Pmode, size),
45550790 1441 copy_to_reg (struct_incoming_value));
53800dbe 1442 size += GET_MODE_SIZE (Pmode);
1443 }
1444
1445 /* Return the address of the block. */
1446 return copy_addr_to_reg (XEXP (registers, 0));
1447}
1448
1449/* __builtin_apply_args returns block of memory allocated on
1450 the stack into which is stored the arg pointer, structure
1451 value address, static chain, and all the registers that might
1452 possibly be used in performing a function call. The code is
1453 moved to the start of the function so the incoming values are
1454 saved. */
27d0c333 1455
53800dbe 1456static rtx
aecda0d6 1457expand_builtin_apply_args (void)
53800dbe 1458{
1459 /* Don't do __builtin_apply_args more than once in a function.
1460 Save the result of the first call and reuse it. */
1461 if (apply_args_value != 0)
1462 return apply_args_value;
1463 {
1464 /* When this function is called, it means that registers must be
1465 saved on entry to this function. So we migrate the
1466 call to the first insn of this function. */
1467 rtx temp;
1468 rtx seq;
1469
1470 start_sequence ();
1471 temp = expand_builtin_apply_args_1 ();
1472 seq = get_insns ();
1473 end_sequence ();
1474
1475 apply_args_value = temp;
1476
31d3e01c 1477 /* Put the insns after the NOTE that starts the function.
1478 If this is inside a start_sequence, make the outer-level insn
53800dbe 1479 chain current, so the code is placed at the start of the
0ef1a651 1480 function. If internal_arg_pointer is a non-virtual pseudo,
1481 it needs to be placed after the function that initializes
1482 that pseudo. */
53800dbe 1483 push_topmost_sequence ();
0ef1a651 1484 if (REG_P (crtl->args.internal_arg_pointer)
1485 && REGNO (crtl->args.internal_arg_pointer) > LAST_VIRTUAL_REGISTER)
1486 emit_insn_before (seq, parm_birth_insn);
1487 else
1488 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
53800dbe 1489 pop_topmost_sequence ();
1490 return temp;
1491 }
1492}
1493
1494/* Perform an untyped call and save the state required to perform an
1495 untyped return of whatever value was returned by the given function. */
1496
1497static rtx
aecda0d6 1498expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
53800dbe 1499{
1500 int size, align, regno;
1501 enum machine_mode mode;
2a631e19 1502 rtx incoming_args, result, reg, dest, src, call_insn;
53800dbe 1503 rtx old_stack_level = 0;
1504 rtx call_fusage = 0;
6812c89e 1505 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
53800dbe 1506
85d654dd 1507 arguments = convert_memory_address (Pmode, arguments);
726ec87c 1508
53800dbe 1509 /* Create a block where the return registers can be saved. */
1510 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1511
53800dbe 1512 /* Fetch the arg pointer from the ARGUMENTS block. */
1513 incoming_args = gen_reg_rtx (Pmode);
726ec87c 1514 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
53800dbe 1515#ifndef STACK_GROWS_DOWNWARD
ad99e708 1516 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1517 incoming_args, 0, OPTAB_LIB_WIDEN);
53800dbe 1518#endif
1519
04a46d40 1520 /* Push a new argument block and copy the arguments. Do not allow
1521 the (potential) memcpy call below to interfere with our stack
1522 manipulations. */
53800dbe 1523 do_pending_stack_adjust ();
04a46d40 1524 NO_DEFER_POP;
53800dbe 1525
2358393e 1526 /* Save the stack with nonlocal if available. */
53800dbe 1527#ifdef HAVE_save_stack_nonlocal
1528 if (HAVE_save_stack_nonlocal)
1529 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1530 else
1531#endif
1532 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1533
59647703 1534 /* Allocate a block of memory onto the stack and copy the memory
1535 arguments to the outgoing arguments address. */
1536 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
27a7a23a 1537
1538 /* Set DRAP flag to true, even though allocate_dynamic_stack_space
1539 may have already set current_function_calls_alloca to true.
1540 current_function_calls_alloca won't be set if argsize is zero,
1541 so we have to guarantee need_drap is true here. */
1542 if (SUPPORTS_STACK_ALIGNMENT)
1543 crtl->need_drap = true;
1544
59647703 1545 dest = virtual_outgoing_args_rtx;
1546#ifndef STACK_GROWS_DOWNWARD
971ba038 1547 if (CONST_INT_P (argsize))
59647703 1548 dest = plus_constant (dest, -INTVAL (argsize));
1549 else
1550 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1551#endif
2a631e19 1552 dest = gen_rtx_MEM (BLKmode, dest);
1553 set_mem_align (dest, PARM_BOUNDARY);
1554 src = gen_rtx_MEM (BLKmode, incoming_args);
1555 set_mem_align (src, PARM_BOUNDARY);
0378dbdc 1556 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
53800dbe 1557
1558 /* Refer to the argument block. */
1559 apply_args_size ();
1560 arguments = gen_rtx_MEM (BLKmode, arguments);
2a631e19 1561 set_mem_align (arguments, PARM_BOUNDARY);
53800dbe 1562
1563 /* Walk past the arg-pointer and structure value address. */
1564 size = GET_MODE_SIZE (Pmode);
45550790 1565 if (struct_value)
53800dbe 1566 size += GET_MODE_SIZE (Pmode);
1567
1568 /* Restore each of the registers previously saved. Make USE insns
1569 for each of these registers for use in making the call. */
1570 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1571 if ((mode = apply_args_mode[regno]) != VOIDmode)
1572 {
1573 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1574 if (size % align != 0)
1575 size = CEIL (size, align) * align;
1576 reg = gen_rtx_REG (mode, regno);
e513d163 1577 emit_move_insn (reg, adjust_address (arguments, mode, size));
53800dbe 1578 use_reg (&call_fusage, reg);
1579 size += GET_MODE_SIZE (mode);
1580 }
1581
1582 /* Restore the structure value address unless this is passed as an
1583 "invisible" first argument. */
1584 size = GET_MODE_SIZE (Pmode);
45550790 1585 if (struct_value)
53800dbe 1586 {
1587 rtx value = gen_reg_rtx (Pmode);
e513d163 1588 emit_move_insn (value, adjust_address (arguments, Pmode, size));
45550790 1589 emit_move_insn (struct_value, value);
8ad4c111 1590 if (REG_P (struct_value))
45550790 1591 use_reg (&call_fusage, struct_value);
53800dbe 1592 size += GET_MODE_SIZE (Pmode);
1593 }
1594
1595 /* All arguments and registers used for the call are set up by now! */
4ee9c684 1596 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
53800dbe 1597
1598 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1599 and we don't want to load it into a register as an optimization,
1600 because prepare_call_address already did it if it should be done. */
1601 if (GET_CODE (function) != SYMBOL_REF)
1602 function = memory_address (FUNCTION_MODE, function);
1603
1604 /* Generate the actual call instruction and save the return value. */
1605#ifdef HAVE_untyped_call
1606 if (HAVE_untyped_call)
1607 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1608 result, result_vector (1, result)));
1609 else
1610#endif
1611#ifdef HAVE_call_value
1612 if (HAVE_call_value)
1613 {
1614 rtx valreg = 0;
1615
1616 /* Locate the unique return register. It is not possible to
1617 express a call that sets more than one return register using
1618 call_value; use untyped_call for that. In fact, untyped_call
1619 only needs to save the return registers in the given block. */
1620 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1621 if ((mode = apply_result_mode[regno]) != VOIDmode)
1622 {
64db345d 1623 gcc_assert (!valreg); /* HAVE_untyped_call required. */
7d3f6cc7 1624
53800dbe 1625 valreg = gen_rtx_REG (mode, regno);
1626 }
1627
2ed6c343 1628 emit_call_insn (GEN_CALL_VALUE (valreg,
53800dbe 1629 gen_rtx_MEM (FUNCTION_MODE, function),
1630 const0_rtx, NULL_RTX, const0_rtx));
1631
e513d163 1632 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
53800dbe 1633 }
1634 else
1635#endif
64db345d 1636 gcc_unreachable ();
53800dbe 1637
d5f9786f 1638 /* Find the CALL insn we just emitted, and attach the register usage
1639 information. */
1640 call_insn = last_call_insn ();
1641 add_function_usage_to (call_insn, call_fusage);
53800dbe 1642
1643 /* Restore the stack. */
1644#ifdef HAVE_save_stack_nonlocal
1645 if (HAVE_save_stack_nonlocal)
1646 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1647 else
1648#endif
1649 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1650
04a46d40 1651 OK_DEFER_POP;
1652
53800dbe 1653 /* Return the address of the result block. */
85d654dd 1654 result = copy_addr_to_reg (XEXP (result, 0));
1655 return convert_memory_address (ptr_mode, result);
53800dbe 1656}
1657
1658/* Perform an untyped return. */
1659
1660static void
aecda0d6 1661expand_builtin_return (rtx result)
53800dbe 1662{
1663 int size, align, regno;
1664 enum machine_mode mode;
1665 rtx reg;
1666 rtx call_fusage = 0;
1667
85d654dd 1668 result = convert_memory_address (Pmode, result);
726ec87c 1669
53800dbe 1670 apply_result_size ();
1671 result = gen_rtx_MEM (BLKmode, result);
1672
1673#ifdef HAVE_untyped_return
1674 if (HAVE_untyped_return)
1675 {
1676 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1677 emit_barrier ();
1678 return;
1679 }
1680#endif
1681
1682 /* Restore the return value and note that each value is used. */
1683 size = 0;
1684 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1685 if ((mode = apply_result_mode[regno]) != VOIDmode)
1686 {
1687 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1688 if (size % align != 0)
1689 size = CEIL (size, align) * align;
1690 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
e513d163 1691 emit_move_insn (reg, adjust_address (result, mode, size));
53800dbe 1692
1693 push_to_sequence (call_fusage);
18b42941 1694 emit_use (reg);
53800dbe 1695 call_fusage = get_insns ();
1696 end_sequence ();
1697 size += GET_MODE_SIZE (mode);
1698 }
1699
1700 /* Put the USE insns before the return. */
31d3e01c 1701 emit_insn (call_fusage);
53800dbe 1702
1703 /* Return whatever values was restored by jumping directly to the end
1704 of the function. */
62380d2d 1705 expand_naked_return ();
53800dbe 1706}
1707
539a3a92 1708/* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
27d0c333 1709
539a3a92 1710static enum type_class
aecda0d6 1711type_to_class (tree type)
539a3a92 1712{
1713 switch (TREE_CODE (type))
1714 {
1715 case VOID_TYPE: return void_type_class;
1716 case INTEGER_TYPE: return integer_type_class;
539a3a92 1717 case ENUMERAL_TYPE: return enumeral_type_class;
1718 case BOOLEAN_TYPE: return boolean_type_class;
1719 case POINTER_TYPE: return pointer_type_class;
1720 case REFERENCE_TYPE: return reference_type_class;
1721 case OFFSET_TYPE: return offset_type_class;
1722 case REAL_TYPE: return real_type_class;
1723 case COMPLEX_TYPE: return complex_type_class;
1724 case FUNCTION_TYPE: return function_type_class;
1725 case METHOD_TYPE: return method_type_class;
1726 case RECORD_TYPE: return record_type_class;
1727 case UNION_TYPE:
1728 case QUAL_UNION_TYPE: return union_type_class;
1729 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1730 ? string_type_class : array_type_class);
539a3a92 1731 case LANG_TYPE: return lang_type_class;
1732 default: return no_type_class;
1733 }
1734}
bf8e3599 1735
c2f47e15 1736/* Expand a call EXP to __builtin_classify_type. */
27d0c333 1737
53800dbe 1738static rtx
c2f47e15 1739expand_builtin_classify_type (tree exp)
53800dbe 1740{
c2f47e15 1741 if (call_expr_nargs (exp))
1742 return GEN_INT (type_to_class (TREE_TYPE (CALL_EXPR_ARG (exp, 0))));
53800dbe 1743 return GEN_INT (no_type_class);
1744}
1745
07976da7 1746/* This helper macro, meant to be used in mathfn_built_in below,
1747 determines which among a set of three builtin math functions is
1748 appropriate for a given type mode. The `F' and `L' cases are
1749 automatically generated from the `double' case. */
1750#define CASE_MATHFN(BUILT_IN_MATHFN) \
1751 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1752 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1753 fcodel = BUILT_IN_MATHFN##L ; break;
cd2656b0 1754/* Similar to above, but appends _R after any F/L suffix. */
1755#define CASE_MATHFN_REENT(BUILT_IN_MATHFN) \
1756 case BUILT_IN_MATHFN##_R: case BUILT_IN_MATHFN##F_R: case BUILT_IN_MATHFN##L_R: \
1757 fcode = BUILT_IN_MATHFN##_R; fcodef = BUILT_IN_MATHFN##F_R ; \
1758 fcodel = BUILT_IN_MATHFN##L_R ; break;
07976da7 1759
1760/* Return mathematic function equivalent to FN but operating directly
c319d56a 1761 on TYPE, if available. If IMPLICIT is true find the function in
1762 implicit_built_in_decls[], otherwise use built_in_decls[]. If we
1763 can't do the conversion, return zero. */
1764
1765static tree
1766mathfn_built_in_1 (tree type, enum built_in_function fn, bool implicit)
0a68165a 1767{
c319d56a 1768 tree const *const fn_arr
1769 = implicit ? implicit_built_in_decls : built_in_decls;
07976da7 1770 enum built_in_function fcode, fcodef, fcodel;
1771
1772 switch (fn)
1773 {
746114e8 1774 CASE_MATHFN (BUILT_IN_ACOS)
1775 CASE_MATHFN (BUILT_IN_ACOSH)
1776 CASE_MATHFN (BUILT_IN_ASIN)
1777 CASE_MATHFN (BUILT_IN_ASINH)
07976da7 1778 CASE_MATHFN (BUILT_IN_ATAN)
746114e8 1779 CASE_MATHFN (BUILT_IN_ATAN2)
1780 CASE_MATHFN (BUILT_IN_ATANH)
1781 CASE_MATHFN (BUILT_IN_CBRT)
07976da7 1782 CASE_MATHFN (BUILT_IN_CEIL)
d735c391 1783 CASE_MATHFN (BUILT_IN_CEXPI)
746114e8 1784 CASE_MATHFN (BUILT_IN_COPYSIGN)
07976da7 1785 CASE_MATHFN (BUILT_IN_COS)
746114e8 1786 CASE_MATHFN (BUILT_IN_COSH)
1787 CASE_MATHFN (BUILT_IN_DREM)
1788 CASE_MATHFN (BUILT_IN_ERF)
1789 CASE_MATHFN (BUILT_IN_ERFC)
07976da7 1790 CASE_MATHFN (BUILT_IN_EXP)
746114e8 1791 CASE_MATHFN (BUILT_IN_EXP10)
1792 CASE_MATHFN (BUILT_IN_EXP2)
1793 CASE_MATHFN (BUILT_IN_EXPM1)
1794 CASE_MATHFN (BUILT_IN_FABS)
1795 CASE_MATHFN (BUILT_IN_FDIM)
07976da7 1796 CASE_MATHFN (BUILT_IN_FLOOR)
746114e8 1797 CASE_MATHFN (BUILT_IN_FMA)
1798 CASE_MATHFN (BUILT_IN_FMAX)
1799 CASE_MATHFN (BUILT_IN_FMIN)
1800 CASE_MATHFN (BUILT_IN_FMOD)
1801 CASE_MATHFN (BUILT_IN_FREXP)
1802 CASE_MATHFN (BUILT_IN_GAMMA)
cd2656b0 1803 CASE_MATHFN_REENT (BUILT_IN_GAMMA) /* GAMMA_R */
746114e8 1804 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1805 CASE_MATHFN (BUILT_IN_HYPOT)
1806 CASE_MATHFN (BUILT_IN_ILOGB)
1807 CASE_MATHFN (BUILT_IN_INF)
69b779ea 1808 CASE_MATHFN (BUILT_IN_ISINF)
746114e8 1809 CASE_MATHFN (BUILT_IN_J0)
1810 CASE_MATHFN (BUILT_IN_J1)
1811 CASE_MATHFN (BUILT_IN_JN)
ac148751 1812 CASE_MATHFN (BUILT_IN_LCEIL)
746114e8 1813 CASE_MATHFN (BUILT_IN_LDEXP)
ad52b9b7 1814 CASE_MATHFN (BUILT_IN_LFLOOR)
746114e8 1815 CASE_MATHFN (BUILT_IN_LGAMMA)
cd2656b0 1816 CASE_MATHFN_REENT (BUILT_IN_LGAMMA) /* LGAMMA_R */
ac148751 1817 CASE_MATHFN (BUILT_IN_LLCEIL)
ad52b9b7 1818 CASE_MATHFN (BUILT_IN_LLFLOOR)
746114e8 1819 CASE_MATHFN (BUILT_IN_LLRINT)
1820 CASE_MATHFN (BUILT_IN_LLROUND)
07976da7 1821 CASE_MATHFN (BUILT_IN_LOG)
746114e8 1822 CASE_MATHFN (BUILT_IN_LOG10)
1823 CASE_MATHFN (BUILT_IN_LOG1P)
1824 CASE_MATHFN (BUILT_IN_LOG2)
1825 CASE_MATHFN (BUILT_IN_LOGB)
1826 CASE_MATHFN (BUILT_IN_LRINT)
1827 CASE_MATHFN (BUILT_IN_LROUND)
1828 CASE_MATHFN (BUILT_IN_MODF)
1829 CASE_MATHFN (BUILT_IN_NAN)
1830 CASE_MATHFN (BUILT_IN_NANS)
07976da7 1831 CASE_MATHFN (BUILT_IN_NEARBYINT)
746114e8 1832 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1833 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1834 CASE_MATHFN (BUILT_IN_POW)
757c219d 1835 CASE_MATHFN (BUILT_IN_POWI)
746114e8 1836 CASE_MATHFN (BUILT_IN_POW10)
1837 CASE_MATHFN (BUILT_IN_REMAINDER)
1838 CASE_MATHFN (BUILT_IN_REMQUO)
1839 CASE_MATHFN (BUILT_IN_RINT)
07976da7 1840 CASE_MATHFN (BUILT_IN_ROUND)
746114e8 1841 CASE_MATHFN (BUILT_IN_SCALB)
1842 CASE_MATHFN (BUILT_IN_SCALBLN)
1843 CASE_MATHFN (BUILT_IN_SCALBN)
c319d56a 1844 CASE_MATHFN (BUILT_IN_SIGNBIT)
746114e8 1845 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
07976da7 1846 CASE_MATHFN (BUILT_IN_SIN)
746114e8 1847 CASE_MATHFN (BUILT_IN_SINCOS)
1848 CASE_MATHFN (BUILT_IN_SINH)
07976da7 1849 CASE_MATHFN (BUILT_IN_SQRT)
1850 CASE_MATHFN (BUILT_IN_TAN)
746114e8 1851 CASE_MATHFN (BUILT_IN_TANH)
1852 CASE_MATHFN (BUILT_IN_TGAMMA)
07976da7 1853 CASE_MATHFN (BUILT_IN_TRUNC)
746114e8 1854 CASE_MATHFN (BUILT_IN_Y0)
1855 CASE_MATHFN (BUILT_IN_Y1)
1856 CASE_MATHFN (BUILT_IN_YN)
07976da7 1857
0a68165a 1858 default:
c2f47e15 1859 return NULL_TREE;
0a68165a 1860 }
07976da7 1861
96b9f485 1862 if (TYPE_MAIN_VARIANT (type) == double_type_node)
c319d56a 1863 return fn_arr[fcode];
96b9f485 1864 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
c319d56a 1865 return fn_arr[fcodef];
96b9f485 1866 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
c319d56a 1867 return fn_arr[fcodel];
07976da7 1868 else
c2f47e15 1869 return NULL_TREE;
0a68165a 1870}
1871
c319d56a 1872/* Like mathfn_built_in_1(), but always use the implicit array. */
1873
1874tree
1875mathfn_built_in (tree type, enum built_in_function fn)
1876{
1877 return mathfn_built_in_1 (type, fn, /*implicit=*/ 1);
1878}
1879
0fd605a5 1880/* If errno must be maintained, expand the RTL to check if the result,
1881 TARGET, of a built-in function call, EXP, is NaN, and if so set
1882 errno to EDOM. */
1883
1884static void
aecda0d6 1885expand_errno_check (tree exp, rtx target)
0fd605a5 1886{
7f05340e 1887 rtx lab = gen_label_rtx ();
0fd605a5 1888
7f05340e 1889 /* Test the result; if it is NaN, set errno=EDOM because
1890 the argument was not in the domain. */
3fcf767f 1891 do_compare_rtx_and_jump (target, target, EQ, 0, GET_MODE (target),
1892 NULL_RTX, NULL_RTX, lab);
0fd605a5 1893
1894#ifdef TARGET_EDOM
7f05340e 1895 /* If this built-in doesn't throw an exception, set errno directly. */
c2f47e15 1896 if (TREE_NOTHROW (TREE_OPERAND (CALL_EXPR_FN (exp), 0)))
7f05340e 1897 {
0fd605a5 1898#ifdef GEN_ERRNO_RTX
7f05340e 1899 rtx errno_rtx = GEN_ERRNO_RTX;
0fd605a5 1900#else
7f05340e 1901 rtx errno_rtx
0fd605a5 1902 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1903#endif
7f05340e 1904 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
0fd605a5 1905 emit_label (lab);
7f05340e 1906 return;
0fd605a5 1907 }
7f05340e 1908#endif
1909
08491912 1910 /* Make sure the library call isn't expanded as a tail call. */
1911 CALL_EXPR_TAILCALL (exp) = 0;
1912
7f05340e 1913 /* We can't set errno=EDOM directly; let the library call do it.
1914 Pop the arguments right away in case the call gets deleted. */
1915 NO_DEFER_POP;
1916 expand_call (exp, target, 0);
1917 OK_DEFER_POP;
1918 emit_label (lab);
0fd605a5 1919}
1920
6b43bae4 1921/* Expand a call to one of the builtin math functions (sqrt, exp, or log).
c2f47e15 1922 Return NULL_RTX if a normal call should be emitted rather than expanding
1923 the function in-line. EXP is the expression that is a call to the builtin
53800dbe 1924 function; if convenient, the result should be placed in TARGET.
1925 SUBTARGET may be used as the target for computing one of EXP's operands. */
27d0c333 1926
53800dbe 1927static rtx
aecda0d6 1928expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
53800dbe 1929{
bf8e3599 1930 optab builtin_optab;
bd421108 1931 rtx op0, insns, before_call;
c6e6ecb1 1932 tree fndecl = get_callee_fndecl (exp);
7f05340e 1933 enum machine_mode mode;
528ee710 1934 bool errno_set = false;
abfea505 1935 tree arg;
53800dbe 1936
c2f47e15 1937 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
1938 return NULL_RTX;
53800dbe 1939
c2f47e15 1940 arg = CALL_EXPR_ARG (exp, 0);
53800dbe 1941
1942 switch (DECL_FUNCTION_CODE (fndecl))
1943 {
4f35b1fc 1944 CASE_FLT_FN (BUILT_IN_SQRT):
7f05340e 1945 errno_set = ! tree_expr_nonnegative_p (arg);
1946 builtin_optab = sqrt_optab;
1947 break;
4f35b1fc 1948 CASE_FLT_FN (BUILT_IN_EXP):
528ee710 1949 errno_set = true; builtin_optab = exp_optab; break;
4f35b1fc 1950 CASE_FLT_FN (BUILT_IN_EXP10):
1951 CASE_FLT_FN (BUILT_IN_POW10):
750ef9f5 1952 errno_set = true; builtin_optab = exp10_optab; break;
4f35b1fc 1953 CASE_FLT_FN (BUILT_IN_EXP2):
750ef9f5 1954 errno_set = true; builtin_optab = exp2_optab; break;
4f35b1fc 1955 CASE_FLT_FN (BUILT_IN_EXPM1):
a6b4eed2 1956 errno_set = true; builtin_optab = expm1_optab; break;
4f35b1fc 1957 CASE_FLT_FN (BUILT_IN_LOGB):
4efbc641 1958 errno_set = true; builtin_optab = logb_optab; break;
4f35b1fc 1959 CASE_FLT_FN (BUILT_IN_LOG):
528ee710 1960 errno_set = true; builtin_optab = log_optab; break;
4f35b1fc 1961 CASE_FLT_FN (BUILT_IN_LOG10):
d3cd9bde 1962 errno_set = true; builtin_optab = log10_optab; break;
4f35b1fc 1963 CASE_FLT_FN (BUILT_IN_LOG2):
d3cd9bde 1964 errno_set = true; builtin_optab = log2_optab; break;
4f35b1fc 1965 CASE_FLT_FN (BUILT_IN_LOG1P):
f474cd93 1966 errno_set = true; builtin_optab = log1p_optab; break;
4f35b1fc 1967 CASE_FLT_FN (BUILT_IN_ASIN):
8de2f465 1968 builtin_optab = asin_optab; break;
4f35b1fc 1969 CASE_FLT_FN (BUILT_IN_ACOS):
8de2f465 1970 builtin_optab = acos_optab; break;
4f35b1fc 1971 CASE_FLT_FN (BUILT_IN_TAN):
528ee710 1972 builtin_optab = tan_optab; break;
4f35b1fc 1973 CASE_FLT_FN (BUILT_IN_ATAN):
528ee710 1974 builtin_optab = atan_optab; break;
4f35b1fc 1975 CASE_FLT_FN (BUILT_IN_FLOOR):
528ee710 1976 builtin_optab = floor_optab; break;
4f35b1fc 1977 CASE_FLT_FN (BUILT_IN_CEIL):
528ee710 1978 builtin_optab = ceil_optab; break;
4f35b1fc 1979 CASE_FLT_FN (BUILT_IN_TRUNC):
a7cc195f 1980 builtin_optab = btrunc_optab; break;
4f35b1fc 1981 CASE_FLT_FN (BUILT_IN_ROUND):
528ee710 1982 builtin_optab = round_optab; break;
4f35b1fc 1983 CASE_FLT_FN (BUILT_IN_NEARBYINT):
0ddf4ad9 1984 builtin_optab = nearbyint_optab;
1985 if (flag_trapping_math)
1986 break;
1987 /* Else fallthrough and expand as rint. */
4f35b1fc 1988 CASE_FLT_FN (BUILT_IN_RINT):
aef94a0f 1989 builtin_optab = rint_optab; break;
b3154a1f 1990 CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
1991 builtin_optab = significand_optab; break;
42721db0 1992 default:
64db345d 1993 gcc_unreachable ();
53800dbe 1994 }
1995
7f05340e 1996 /* Make a suitable register to place result in. */
1997 mode = TYPE_MODE (TREE_TYPE (exp));
fc4eef90 1998
7f05340e 1999 if (! flag_errno_math || ! HONOR_NANS (mode))
2000 errno_set = false;
2001
bd421108 2002 /* Before working hard, check whether the instruction is available. */
99bdde56 2003 if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing)
68e6cb9d 2004 {
bd421108 2005 target = gen_reg_rtx (mode);
7f05340e 2006
bd421108 2007 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2008 need to expand the argument again. This way, we will not perform
2009 side-effects more the once. */
abfea505 2010 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
7f05340e 2011
1db6d067 2012 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
7f05340e 2013
bd421108 2014 start_sequence ();
53800dbe 2015
bd421108 2016 /* Compute into TARGET.
2017 Set TARGET to wherever the result comes back. */
2018 target = expand_unop (mode, builtin_optab, op0, target, 0);
2019
2020 if (target != 0)
2021 {
2022 if (errno_set)
2023 expand_errno_check (exp, target);
2024
2025 /* Output the entire sequence. */
2026 insns = get_insns ();
2027 end_sequence ();
2028 emit_insn (insns);
2029 return target;
2030 }
2031
2032 /* If we were unable to expand via the builtin, stop the sequence
2033 (without outputting the insns) and call to the library function
2034 with the stabilized argument list. */
53800dbe 2035 end_sequence ();
53800dbe 2036 }
2037
bd421108 2038 before_call = get_last_insn ();
2039
1e5b92fa 2040 return expand_call (exp, target, target == const0_rtx);
0fd605a5 2041}
2042
2043/* Expand a call to the builtin binary math functions (pow and atan2).
c2f47e15 2044 Return NULL_RTX if a normal call should be emitted rather than expanding the
0fd605a5 2045 function in-line. EXP is the expression that is a call to the builtin
2046 function; if convenient, the result should be placed in TARGET.
2047 SUBTARGET may be used as the target for computing one of EXP's
2048 operands. */
2049
2050static rtx
aecda0d6 2051expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
0fd605a5 2052{
2053 optab builtin_optab;
2054 rtx op0, op1, insns;
4737caf2 2055 int op1_type = REAL_TYPE;
c6e6ecb1 2056 tree fndecl = get_callee_fndecl (exp);
abfea505 2057 tree arg0, arg1;
7f05340e 2058 enum machine_mode mode;
0fd605a5 2059 bool errno_set = true;
0fd605a5 2060
73a954a1 2061 switch (DECL_FUNCTION_CODE (fndecl))
2062 {
2063 CASE_FLT_FN (BUILT_IN_SCALBN):
2064 CASE_FLT_FN (BUILT_IN_SCALBLN):
2065 CASE_FLT_FN (BUILT_IN_LDEXP):
2066 op1_type = INTEGER_TYPE;
2067 default:
2068 break;
2069 }
4737caf2 2070
c2f47e15 2071 if (!validate_arglist (exp, REAL_TYPE, op1_type, VOID_TYPE))
2072 return NULL_RTX;
0fd605a5 2073
c2f47e15 2074 arg0 = CALL_EXPR_ARG (exp, 0);
2075 arg1 = CALL_EXPR_ARG (exp, 1);
0fd605a5 2076
0fd605a5 2077 switch (DECL_FUNCTION_CODE (fndecl))
2078 {
4f35b1fc 2079 CASE_FLT_FN (BUILT_IN_POW):
0fd605a5 2080 builtin_optab = pow_optab; break;
4f35b1fc 2081 CASE_FLT_FN (BUILT_IN_ATAN2):
0fd605a5 2082 builtin_optab = atan2_optab; break;
73a954a1 2083 CASE_FLT_FN (BUILT_IN_SCALB):
2084 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2085 return 0;
2086 builtin_optab = scalb_optab; break;
2087 CASE_FLT_FN (BUILT_IN_SCALBN):
2088 CASE_FLT_FN (BUILT_IN_SCALBLN):
2089 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2090 return 0;
2091 /* Fall through... */
4f35b1fc 2092 CASE_FLT_FN (BUILT_IN_LDEXP):
4737caf2 2093 builtin_optab = ldexp_optab; break;
4f35b1fc 2094 CASE_FLT_FN (BUILT_IN_FMOD):
80ed5c06 2095 builtin_optab = fmod_optab; break;
ef722005 2096 CASE_FLT_FN (BUILT_IN_REMAINDER):
4f35b1fc 2097 CASE_FLT_FN (BUILT_IN_DREM):
ef722005 2098 builtin_optab = remainder_optab; break;
0fd605a5 2099 default:
64db345d 2100 gcc_unreachable ();
0fd605a5 2101 }
2102
7f05340e 2103 /* Make a suitable register to place result in. */
2104 mode = TYPE_MODE (TREE_TYPE (exp));
fc4eef90 2105
2106 /* Before working hard, check whether the instruction is available. */
99bdde56 2107 if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing)
c2f47e15 2108 return NULL_RTX;
fc4eef90 2109
7f05340e 2110 target = gen_reg_rtx (mode);
2111
2112 if (! flag_errno_math || ! HONOR_NANS (mode))
2113 errno_set = false;
2114
4ee9c684 2115 /* Always stabilize the argument list. */
abfea505 2116 CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
2117 CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1);
7f05340e 2118
8ec3c5c2 2119 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2120 op1 = expand_normal (arg1);
7f05340e 2121
7f05340e 2122 start_sequence ();
2123
0fd605a5 2124 /* Compute into TARGET.
2125 Set TARGET to wherever the result comes back. */
7f05340e 2126 target = expand_binop (mode, builtin_optab, op0, op1,
0fd605a5 2127 target, 0, OPTAB_DIRECT);
53800dbe 2128
68e6cb9d 2129 /* If we were unable to expand via the builtin, stop the sequence
2130 (without outputting the insns) and call to the library function
2131 with the stabilized argument list. */
0fd605a5 2132 if (target == 0)
2133 {
2134 end_sequence ();
68e6cb9d 2135 return expand_call (exp, target, target == const0_rtx);
53800dbe 2136 }
2137
a4356fb9 2138 if (errno_set)
2139 expand_errno_check (exp, target);
0fd605a5 2140
53800dbe 2141 /* Output the entire sequence. */
2142 insns = get_insns ();
2143 end_sequence ();
31d3e01c 2144 emit_insn (insns);
bf8e3599 2145
53800dbe 2146 return target;
2147}
2148
6b43bae4 2149/* Expand a call to the builtin sin and cos math functions.
c2f47e15 2150 Return NULL_RTX if a normal call should be emitted rather than expanding the
6b43bae4 2151 function in-line. EXP is the expression that is a call to the builtin
2152 function; if convenient, the result should be placed in TARGET.
2153 SUBTARGET may be used as the target for computing one of EXP's
2154 operands. */
2155
2156static rtx
2157expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2158{
2159 optab builtin_optab;
7511b819 2160 rtx op0, insns;
6b43bae4 2161 tree fndecl = get_callee_fndecl (exp);
6b43bae4 2162 enum machine_mode mode;
abfea505 2163 tree arg;
6b43bae4 2164
c2f47e15 2165 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2166 return NULL_RTX;
6b43bae4 2167
c2f47e15 2168 arg = CALL_EXPR_ARG (exp, 0);
6b43bae4 2169
2170 switch (DECL_FUNCTION_CODE (fndecl))
2171 {
4f35b1fc 2172 CASE_FLT_FN (BUILT_IN_SIN):
2173 CASE_FLT_FN (BUILT_IN_COS):
6b43bae4 2174 builtin_optab = sincos_optab; break;
2175 default:
64db345d 2176 gcc_unreachable ();
6b43bae4 2177 }
2178
2179 /* Make a suitable register to place result in. */
2180 mode = TYPE_MODE (TREE_TYPE (exp));
2181
6b43bae4 2182 /* Check if sincos insn is available, otherwise fallback
0bed3869 2183 to sin or cos insn. */
99bdde56 2184 if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing)
6b43bae4 2185 switch (DECL_FUNCTION_CODE (fndecl))
2186 {
4f35b1fc 2187 CASE_FLT_FN (BUILT_IN_SIN):
6b43bae4 2188 builtin_optab = sin_optab; break;
4f35b1fc 2189 CASE_FLT_FN (BUILT_IN_COS):
6b43bae4 2190 builtin_optab = cos_optab; break;
2191 default:
64db345d 2192 gcc_unreachable ();
6b43bae4 2193 }
6b43bae4 2194
2195 /* Before working hard, check whether the instruction is available. */
99bdde56 2196 if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing)
6b43bae4 2197 {
2198 target = gen_reg_rtx (mode);
2199
2200 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2201 need to expand the argument again. This way, we will not perform
2202 side-effects more the once. */
abfea505 2203 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
6b43bae4 2204
1db6d067 2205 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
6b43bae4 2206
6b43bae4 2207 start_sequence ();
2208
2209 /* Compute into TARGET.
2210 Set TARGET to wherever the result comes back. */
2211 if (builtin_optab == sincos_optab)
2212 {
64db345d 2213 int result;
7d3f6cc7 2214
6b43bae4 2215 switch (DECL_FUNCTION_CODE (fndecl))
2216 {
4f35b1fc 2217 CASE_FLT_FN (BUILT_IN_SIN):
64db345d 2218 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
6b43bae4 2219 break;
4f35b1fc 2220 CASE_FLT_FN (BUILT_IN_COS):
64db345d 2221 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
6b43bae4 2222 break;
2223 default:
64db345d 2224 gcc_unreachable ();
6b43bae4 2225 }
64db345d 2226 gcc_assert (result);
6b43bae4 2227 }
2228 else
2229 {
2230 target = expand_unop (mode, builtin_optab, op0, target, 0);
2231 }
2232
2233 if (target != 0)
2234 {
6b43bae4 2235 /* Output the entire sequence. */
2236 insns = get_insns ();
2237 end_sequence ();
2238 emit_insn (insns);
2239 return target;
2240 }
2241
2242 /* If we were unable to expand via the builtin, stop the sequence
2243 (without outputting the insns) and call to the library function
2244 with the stabilized argument list. */
2245 end_sequence ();
2246 }
2247
6b43bae4 2248 target = expand_call (exp, target, target == const0_rtx);
2249
2250 return target;
2251}
2252
a67a90e5 2253/* Expand a call to one of the builtin math functions that operate on
2254 floating point argument and output an integer result (ilogb, isinf,
2255 isnan, etc).
2256 Return 0 if a normal call should be emitted rather than expanding the
2257 function in-line. EXP is the expression that is a call to the builtin
2258 function; if convenient, the result should be placed in TARGET.
2259 SUBTARGET may be used as the target for computing one of EXP's operands. */
2260
2261static rtx
2262expand_builtin_interclass_mathfn (tree exp, rtx target, rtx subtarget)
2263{
cde061c1 2264 optab builtin_optab = 0;
2265 enum insn_code icode = CODE_FOR_nothing;
a67a90e5 2266 rtx op0;
2267 tree fndecl = get_callee_fndecl (exp);
a67a90e5 2268 enum machine_mode mode;
2269 bool errno_set = false;
abfea505 2270 tree arg;
a67a90e5 2271
c2f47e15 2272 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2273 return NULL_RTX;
a67a90e5 2274
c2f47e15 2275 arg = CALL_EXPR_ARG (exp, 0);
a67a90e5 2276
2277 switch (DECL_FUNCTION_CODE (fndecl))
2278 {
2279 CASE_FLT_FN (BUILT_IN_ILOGB):
2280 errno_set = true; builtin_optab = ilogb_optab; break;
69b779ea 2281 CASE_FLT_FN (BUILT_IN_ISINF):
2282 builtin_optab = isinf_optab; break;
8a1a9cb7 2283 case BUILT_IN_ISNORMAL:
cde061c1 2284 case BUILT_IN_ISFINITE:
2285 CASE_FLT_FN (BUILT_IN_FINITE):
2286 /* These builtins have no optabs (yet). */
2287 break;
a67a90e5 2288 default:
2289 gcc_unreachable ();
2290 }
2291
2292 /* There's no easy way to detect the case we need to set EDOM. */
2293 if (flag_errno_math && errno_set)
2294 return NULL_RTX;
2295
2296 /* Optab mode depends on the mode of the input argument. */
2297 mode = TYPE_MODE (TREE_TYPE (arg));
2298
cde061c1 2299 if (builtin_optab)
99bdde56 2300 icode = optab_handler (builtin_optab, mode)->insn_code;
a67a90e5 2301
2302 /* Before working hard, check whether the instruction is available. */
2303 if (icode != CODE_FOR_nothing)
2304 {
2305 /* Make a suitable register to place result in. */
2306 if (!target
2307 || GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
2308 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
2309
2310 gcc_assert (insn_data[icode].operand[0].predicate
2311 (target, GET_MODE (target)));
2312
2313 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2314 need to expand the argument again. This way, we will not perform
2315 side-effects more the once. */
abfea505 2316 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
a67a90e5 2317
1db6d067 2318 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
a67a90e5 2319
2320 if (mode != GET_MODE (op0))
2321 op0 = convert_to_mode (mode, op0, 0);
2322
2323 /* Compute into TARGET.
2324 Set TARGET to wherever the result comes back. */
2325 emit_unop_insn (icode, target, op0, UNKNOWN);
2326 return target;
2327 }
2328
06f7a99d 2329 /* If there is no optab, try generic code. */
2330 switch (DECL_FUNCTION_CODE (fndecl))
2331 {
2332 tree result;
2333
2334 CASE_FLT_FN (BUILT_IN_ISINF):
2335 {
2336 /* isinf(x) -> isgreater(fabs(x),DBL_MAX). */
2337 tree const isgr_fn = built_in_decls[BUILT_IN_ISGREATER];
2338 tree const type = TREE_TYPE (arg);
2339 REAL_VALUE_TYPE r;
2340 char buf[128];
2341
2342 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2343 real_from_string (&r, buf);
2344 result = build_call_expr (isgr_fn, 2,
2345 fold_build1 (ABS_EXPR, type, arg),
2346 build_real (type, r));
2347 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2348 }
cde061c1 2349 CASE_FLT_FN (BUILT_IN_FINITE):
2350 case BUILT_IN_ISFINITE:
2351 {
2352 /* isfinite(x) -> islessequal(fabs(x),DBL_MAX). */
2353 tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
2354 tree const type = TREE_TYPE (arg);
2355 REAL_VALUE_TYPE r;
2356 char buf[128];
2357
2358 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2359 real_from_string (&r, buf);
2360 result = build_call_expr (isle_fn, 2,
2361 fold_build1 (ABS_EXPR, type, arg),
2362 build_real (type, r));
2363 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2364 }
8a1a9cb7 2365 case BUILT_IN_ISNORMAL:
2366 {
2367 /* isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) &
2368 islessequal(fabs(x),DBL_MAX). */
2369 tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
2370 tree const isge_fn = built_in_decls[BUILT_IN_ISGREATEREQUAL];
2371 tree const type = TREE_TYPE (arg);
2372 REAL_VALUE_TYPE rmax, rmin;
2373 char buf[128];
2374
2375 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2376 real_from_string (&rmax, buf);
2377 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
2378 real_from_string (&rmin, buf);
2379 arg = builtin_save_expr (fold_build1 (ABS_EXPR, type, arg));
2380 result = build_call_expr (isle_fn, 2, arg,
2381 build_real (type, rmax));
2382 result = fold_build2 (BIT_AND_EXPR, integer_type_node, result,
2383 build_call_expr (isge_fn, 2, arg,
2384 build_real (type, rmin)));
2385 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2386 }
06f7a99d 2387 default:
2388 break;
2389 }
2390
a67a90e5 2391 target = expand_call (exp, target, target == const0_rtx);
2392
2393 return target;
2394}
2395
c3147c1a 2396/* Expand a call to the builtin sincos math function.
c2f47e15 2397 Return NULL_RTX if a normal call should be emitted rather than expanding the
c3147c1a 2398 function in-line. EXP is the expression that is a call to the builtin
2399 function. */
2400
2401static rtx
2402expand_builtin_sincos (tree exp)
2403{
2404 rtx op0, op1, op2, target1, target2;
c3147c1a 2405 enum machine_mode mode;
2406 tree arg, sinp, cosp;
2407 int result;
2408
c2f47e15 2409 if (!validate_arglist (exp, REAL_TYPE,
2410 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2411 return NULL_RTX;
c3147c1a 2412
c2f47e15 2413 arg = CALL_EXPR_ARG (exp, 0);
2414 sinp = CALL_EXPR_ARG (exp, 1);
2415 cosp = CALL_EXPR_ARG (exp, 2);
c3147c1a 2416
2417 /* Make a suitable register to place result in. */
2418 mode = TYPE_MODE (TREE_TYPE (arg));
2419
2420 /* Check if sincos insn is available, otherwise emit the call. */
99bdde56 2421 if (optab_handler (sincos_optab, mode)->insn_code == CODE_FOR_nothing)
c3147c1a 2422 return NULL_RTX;
2423
2424 target1 = gen_reg_rtx (mode);
2425 target2 = gen_reg_rtx (mode);
2426
8ec3c5c2 2427 op0 = expand_normal (arg);
2428 op1 = expand_normal (build_fold_indirect_ref (sinp));
2429 op2 = expand_normal (build_fold_indirect_ref (cosp));
c3147c1a 2430
2431 /* Compute into target1 and target2.
2432 Set TARGET to wherever the result comes back. */
2433 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2434 gcc_assert (result);
2435
2436 /* Move target1 and target2 to the memory locations indicated
2437 by op1 and op2. */
2438 emit_move_insn (op1, target1);
2439 emit_move_insn (op2, target2);
2440
2441 return const0_rtx;
2442}
2443
d735c391 2444/* Expand a call to the internal cexpi builtin to the sincos math function.
2445 EXP is the expression that is a call to the builtin function; if convenient,
2446 the result should be placed in TARGET. SUBTARGET may be used as the target
2447 for computing one of EXP's operands. */
2448
2449static rtx
2450expand_builtin_cexpi (tree exp, rtx target, rtx subtarget)
2451{
2452 tree fndecl = get_callee_fndecl (exp);
d735c391 2453 tree arg, type;
c2f47e15 2454 enum machine_mode mode;
d735c391 2455 rtx op0, op1, op2;
2456
c2f47e15 2457 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2458 return NULL_RTX;
d735c391 2459
c2f47e15 2460 arg = CALL_EXPR_ARG (exp, 0);
d735c391 2461 type = TREE_TYPE (arg);
2462 mode = TYPE_MODE (TREE_TYPE (arg));
2463
2464 /* Try expanding via a sincos optab, fall back to emitting a libcall
18b8d8ae 2465 to sincos or cexp. We are sure we have sincos or cexp because cexpi
2466 is only generated from sincos, cexp or if we have either of them. */
99bdde56 2467 if (optab_handler (sincos_optab, mode)->insn_code != CODE_FOR_nothing)
d735c391 2468 {
2469 op1 = gen_reg_rtx (mode);
2470 op2 = gen_reg_rtx (mode);
2471
1db6d067 2472 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
d735c391 2473
2474 /* Compute into op1 and op2. */
2475 expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
2476 }
18b8d8ae 2477 else if (TARGET_HAS_SINCOS)
d735c391 2478 {
c2f47e15 2479 tree call, fn = NULL_TREE;
d735c391 2480 tree top1, top2;
2481 rtx op1a, op2a;
2482
2483 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2484 fn = built_in_decls[BUILT_IN_SINCOSF];
2485 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2486 fn = built_in_decls[BUILT_IN_SINCOS];
2487 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2488 fn = built_in_decls[BUILT_IN_SINCOSL];
c2f47e15 2489 else
2490 gcc_unreachable ();
d735c391 2491
2492 op1 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2493 op2 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2494 op1a = copy_to_mode_reg (Pmode, XEXP (op1, 0));
2495 op2a = copy_to_mode_reg (Pmode, XEXP (op2, 0));
2496 top1 = make_tree (build_pointer_type (TREE_TYPE (arg)), op1a);
2497 top2 = make_tree (build_pointer_type (TREE_TYPE (arg)), op2a);
2498
d735c391 2499 /* Make sure not to fold the sincos call again. */
2500 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
c2f47e15 2501 expand_normal (build_call_nary (TREE_TYPE (TREE_TYPE (fn)),
2502 call, 3, arg, top1, top2));
d735c391 2503 }
18b8d8ae 2504 else
2505 {
0ecbc158 2506 tree call, fn = NULL_TREE, narg;
18b8d8ae 2507 tree ctype = build_complex_type (type);
2508
0ecbc158 2509 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2510 fn = built_in_decls[BUILT_IN_CEXPF];
2511 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2512 fn = built_in_decls[BUILT_IN_CEXP];
2513 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2514 fn = built_in_decls[BUILT_IN_CEXPL];
c2f47e15 2515 else
2516 gcc_unreachable ();
fc0dfa6e 2517
2518 /* If we don't have a decl for cexp create one. This is the
2519 friendliest fallback if the user calls __builtin_cexpi
2520 without full target C99 function support. */
2521 if (fn == NULL_TREE)
2522 {
2523 tree fntype;
2524 const char *name = NULL;
2525
2526 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2527 name = "cexpf";
2528 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2529 name = "cexp";
2530 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2531 name = "cexpl";
2532
2533 fntype = build_function_type_list (ctype, ctype, NULL_TREE);
2534 fn = build_fn_decl (name, fntype);
2535 }
2536
18b8d8ae 2537 narg = fold_build2 (COMPLEX_EXPR, ctype,
2538 build_real (type, dconst0), arg);
2539
2540 /* Make sure not to fold the cexp call again. */
2541 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
3737e769 2542 return expand_expr (build_call_nary (ctype, call, 1, narg),
1db6d067 2543 target, VOIDmode, EXPAND_NORMAL);
18b8d8ae 2544 }
d735c391 2545
2546 /* Now build the proper return type. */
2547 return expand_expr (build2 (COMPLEX_EXPR, build_complex_type (type),
2548 make_tree (TREE_TYPE (arg), op2),
2549 make_tree (TREE_TYPE (arg), op1)),
1db6d067 2550 target, VOIDmode, EXPAND_NORMAL);
d735c391 2551}
2552
7d3afc77 2553/* Expand a call to one of the builtin rounding functions gcc defines
2554 as an extension (lfloor and lceil). As these are gcc extensions we
2555 do not need to worry about setting errno to EDOM.
ad52b9b7 2556 If expanding via optab fails, lower expression to (int)(floor(x)).
2557 EXP is the expression that is a call to the builtin function;
ff1b14e4 2558 if convenient, the result should be placed in TARGET. */
ad52b9b7 2559
2560static rtx
ff1b14e4 2561expand_builtin_int_roundingfn (tree exp, rtx target)
ad52b9b7 2562{
9c42dd28 2563 convert_optab builtin_optab;
ad52b9b7 2564 rtx op0, insns, tmp;
2565 tree fndecl = get_callee_fndecl (exp);
ad52b9b7 2566 enum built_in_function fallback_fn;
2567 tree fallback_fndecl;
2568 enum machine_mode mode;
4de0924f 2569 tree arg;
ad52b9b7 2570
c2f47e15 2571 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
ad52b9b7 2572 gcc_unreachable ();
2573
c2f47e15 2574 arg = CALL_EXPR_ARG (exp, 0);
ad52b9b7 2575
2576 switch (DECL_FUNCTION_CODE (fndecl))
2577 {
4f35b1fc 2578 CASE_FLT_FN (BUILT_IN_LCEIL):
2579 CASE_FLT_FN (BUILT_IN_LLCEIL):
ac148751 2580 builtin_optab = lceil_optab;
2581 fallback_fn = BUILT_IN_CEIL;
2582 break;
2583
4f35b1fc 2584 CASE_FLT_FN (BUILT_IN_LFLOOR):
2585 CASE_FLT_FN (BUILT_IN_LLFLOOR):
ad52b9b7 2586 builtin_optab = lfloor_optab;
2587 fallback_fn = BUILT_IN_FLOOR;
2588 break;
2589
2590 default:
2591 gcc_unreachable ();
2592 }
2593
2594 /* Make a suitable register to place result in. */
2595 mode = TYPE_MODE (TREE_TYPE (exp));
2596
9c42dd28 2597 target = gen_reg_rtx (mode);
ad52b9b7 2598
9c42dd28 2599 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2600 need to expand the argument again. This way, we will not perform
2601 side-effects more the once. */
abfea505 2602 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
ad52b9b7 2603
ff1b14e4 2604 op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
ad52b9b7 2605
9c42dd28 2606 start_sequence ();
ad52b9b7 2607
9c42dd28 2608 /* Compute into TARGET. */
2609 if (expand_sfix_optab (target, op0, builtin_optab))
2610 {
2611 /* Output the entire sequence. */
2612 insns = get_insns ();
ad52b9b7 2613 end_sequence ();
9c42dd28 2614 emit_insn (insns);
2615 return target;
ad52b9b7 2616 }
2617
9c42dd28 2618 /* If we were unable to expand via the builtin, stop the sequence
2619 (without outputting the insns). */
2620 end_sequence ();
2621
ad52b9b7 2622 /* Fall back to floating point rounding optab. */
2623 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
fc0dfa6e 2624
2625 /* For non-C99 targets we may end up without a fallback fndecl here
2626 if the user called __builtin_lfloor directly. In this case emit
2627 a call to the floor/ceil variants nevertheless. This should result
2628 in the best user experience for not full C99 targets. */
2629 if (fallback_fndecl == NULL_TREE)
2630 {
2631 tree fntype;
2632 const char *name = NULL;
2633
2634 switch (DECL_FUNCTION_CODE (fndecl))
2635 {
2636 case BUILT_IN_LCEIL:
2637 case BUILT_IN_LLCEIL:
2638 name = "ceil";
2639 break;
2640 case BUILT_IN_LCEILF:
2641 case BUILT_IN_LLCEILF:
2642 name = "ceilf";
2643 break;
2644 case BUILT_IN_LCEILL:
2645 case BUILT_IN_LLCEILL:
2646 name = "ceill";
2647 break;
2648 case BUILT_IN_LFLOOR:
2649 case BUILT_IN_LLFLOOR:
2650 name = "floor";
2651 break;
2652 case BUILT_IN_LFLOORF:
2653 case BUILT_IN_LLFLOORF:
2654 name = "floorf";
2655 break;
2656 case BUILT_IN_LFLOORL:
2657 case BUILT_IN_LLFLOORL:
2658 name = "floorl";
2659 break;
2660 default:
2661 gcc_unreachable ();
2662 }
2663
2664 fntype = build_function_type_list (TREE_TYPE (arg),
2665 TREE_TYPE (arg), NULL_TREE);
2666 fallback_fndecl = build_fn_decl (name, fntype);
2667 }
2668
c2f47e15 2669 exp = build_call_expr (fallback_fndecl, 1, arg);
ad52b9b7 2670
d4c690af 2671 tmp = expand_normal (exp);
ad52b9b7 2672
2673 /* Truncate the result of floating point optab to integer
2674 via expand_fix (). */
2675 target = gen_reg_rtx (mode);
2676 expand_fix (target, tmp, 0);
2677
2678 return target;
2679}
2680
7d3afc77 2681/* Expand a call to one of the builtin math functions doing integer
2682 conversion (lrint).
2683 Return 0 if a normal call should be emitted rather than expanding the
2684 function in-line. EXP is the expression that is a call to the builtin
ff1b14e4 2685 function; if convenient, the result should be placed in TARGET. */
7d3afc77 2686
2687static rtx
ff1b14e4 2688expand_builtin_int_roundingfn_2 (tree exp, rtx target)
7d3afc77 2689{
5f51ee59 2690 convert_optab builtin_optab;
7d3afc77 2691 rtx op0, insns;
2692 tree fndecl = get_callee_fndecl (exp);
4de0924f 2693 tree arg;
c2f47e15 2694 enum machine_mode mode;
7d3afc77 2695
2696 /* There's no easy way to detect the case we need to set EDOM. */
2697 if (flag_errno_math)
2698 return NULL_RTX;
2699
c2f47e15 2700 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2701 gcc_unreachable ();
2702
2703 arg = CALL_EXPR_ARG (exp, 0);
7d3afc77 2704
2705 switch (DECL_FUNCTION_CODE (fndecl))
2706 {
2707 CASE_FLT_FN (BUILT_IN_LRINT):
2708 CASE_FLT_FN (BUILT_IN_LLRINT):
2709 builtin_optab = lrint_optab; break;
ef2f1a10 2710 CASE_FLT_FN (BUILT_IN_LROUND):
2711 CASE_FLT_FN (BUILT_IN_LLROUND):
2712 builtin_optab = lround_optab; break;
7d3afc77 2713 default:
2714 gcc_unreachable ();
2715 }
2716
2717 /* Make a suitable register to place result in. */
2718 mode = TYPE_MODE (TREE_TYPE (exp));
2719
5f51ee59 2720 target = gen_reg_rtx (mode);
7d3afc77 2721
5f51ee59 2722 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2723 need to expand the argument again. This way, we will not perform
2724 side-effects more the once. */
abfea505 2725 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
7d3afc77 2726
ff1b14e4 2727 op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
7d3afc77 2728
5f51ee59 2729 start_sequence ();
7d3afc77 2730
5f51ee59 2731 if (expand_sfix_optab (target, op0, builtin_optab))
2732 {
2733 /* Output the entire sequence. */
2734 insns = get_insns ();
7d3afc77 2735 end_sequence ();
5f51ee59 2736 emit_insn (insns);
2737 return target;
7d3afc77 2738 }
2739
5f51ee59 2740 /* If we were unable to expand via the builtin, stop the sequence
2741 (without outputting the insns) and call to the library function
2742 with the stabilized argument list. */
2743 end_sequence ();
2744
7d3afc77 2745 target = expand_call (exp, target, target == const0_rtx);
2746
2747 return target;
2748}
2749
f1b844c6 2750/* To evaluate powi(x,n), the floating point value x raised to the
2751 constant integer exponent n, we use a hybrid algorithm that
2752 combines the "window method" with look-up tables. For an
2753 introduction to exponentiation algorithms and "addition chains",
2754 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2755 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2756 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2757 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2758
2759/* Provide a default value for POWI_MAX_MULTS, the maximum number of
2760 multiplications to inline before calling the system library's pow
2761 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2762 so this default never requires calling pow, powf or powl. */
0862b7e9 2763
f1b844c6 2764#ifndef POWI_MAX_MULTS
2765#define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2766#endif
2767
2768/* The size of the "optimal power tree" lookup table. All
2769 exponents less than this value are simply looked up in the
2770 powi_table below. This threshold is also used to size the
2771 cache of pseudo registers that hold intermediate results. */
2772#define POWI_TABLE_SIZE 256
2773
2774/* The size, in bits of the window, used in the "window method"
2775 exponentiation algorithm. This is equivalent to a radix of
2776 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2777#define POWI_WINDOW_SIZE 3
2778
2779/* The following table is an efficient representation of an
2780 "optimal power tree". For each value, i, the corresponding
2781 value, j, in the table states than an optimal evaluation
2782 sequence for calculating pow(x,i) can be found by evaluating
2783 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2784 100 integers is given in Knuth's "Seminumerical algorithms". */
2785
2786static const unsigned char powi_table[POWI_TABLE_SIZE] =
2787 {
2788 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2789 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2790 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2791 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2792 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2793 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2794 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2795 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2796 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2797 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2798 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2799 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2800 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2801 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2802 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2803 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2804 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2805 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2806 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2807 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2808 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2809 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2810 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2811 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2812 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2813 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2814 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2815 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2816 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2817 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2818 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2819 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2820 };
2821
2822
2823/* Return the number of multiplications required to calculate
2824 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2825 subroutine of powi_cost. CACHE is an array indicating
2826 which exponents have already been calculated. */
2827
2828static int
2829powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2830{
2831 /* If we've already calculated this exponent, then this evaluation
2832 doesn't require any additional multiplications. */
2833 if (cache[n])
2834 return 0;
2835
2836 cache[n] = true;
2837 return powi_lookup_cost (n - powi_table[n], cache)
2838 + powi_lookup_cost (powi_table[n], cache) + 1;
2839}
2840
2841/* Return the number of multiplications required to calculate
2842 powi(x,n) for an arbitrary x, given the exponent N. This
2843 function needs to be kept in sync with expand_powi below. */
2844
2845static int
2846powi_cost (HOST_WIDE_INT n)
2847{
2848 bool cache[POWI_TABLE_SIZE];
2849 unsigned HOST_WIDE_INT digit;
2850 unsigned HOST_WIDE_INT val;
2851 int result;
2852
2853 if (n == 0)
2854 return 0;
2855
2856 /* Ignore the reciprocal when calculating the cost. */
2857 val = (n < 0) ? -n : n;
2858
2859 /* Initialize the exponent cache. */
2860 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2861 cache[1] = true;
2862
2863 result = 0;
2864
2865 while (val >= POWI_TABLE_SIZE)
2866 {
2867 if (val & 1)
2868 {
2869 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2870 result += powi_lookup_cost (digit, cache)
2871 + POWI_WINDOW_SIZE + 1;
2872 val >>= POWI_WINDOW_SIZE;
2873 }
2874 else
2875 {
2876 val >>= 1;
2877 result++;
2878 }
2879 }
0862b7e9 2880
6881dbab 2881 return result + powi_lookup_cost (val, cache);
f1b844c6 2882}
2883
2884/* Recursive subroutine of expand_powi. This function takes the array,
2885 CACHE, of already calculated exponents and an exponent N and returns
2886 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2887
2888static rtx
2889expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2890{
2891 unsigned HOST_WIDE_INT digit;
2892 rtx target, result;
2893 rtx op0, op1;
2894
2895 if (n < POWI_TABLE_SIZE)
2896 {
2897 if (cache[n])
a0c938f0 2898 return cache[n];
f1b844c6 2899
2900 target = gen_reg_rtx (mode);
2901 cache[n] = target;
2902
2903 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2904 op1 = expand_powi_1 (mode, powi_table[n], cache);
2905 }
2906 else if (n & 1)
2907 {
2908 target = gen_reg_rtx (mode);
2909 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2910 op0 = expand_powi_1 (mode, n - digit, cache);
2911 op1 = expand_powi_1 (mode, digit, cache);
2912 }
2913 else
2914 {
2915 target = gen_reg_rtx (mode);
2916 op0 = expand_powi_1 (mode, n >> 1, cache);
2917 op1 = op0;
2918 }
2919
2920 result = expand_mult (mode, op0, op1, target, 0);
2921 if (result != target)
2922 emit_move_insn (target, result);
2923 return target;
2924}
2925
2926/* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2927 floating point operand in mode MODE, and N is the exponent. This
2928 function needs to be kept in sync with powi_cost above. */
0862b7e9 2929
f1b844c6 2930static rtx
2931expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2932{
2933 unsigned HOST_WIDE_INT val;
2934 rtx cache[POWI_TABLE_SIZE];
2935 rtx result;
2936
2937 if (n == 0)
2938 return CONST1_RTX (mode);
2939
2940 val = (n < 0) ? -n : n;
2941
19bf118a 2942 memset (cache, 0, sizeof (cache));
f1b844c6 2943 cache[1] = x;
2944
2945 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2946
2947 /* If the original exponent was negative, reciprocate the result. */
2948 if (n < 0)
2949 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2950 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2951
2952 return result;
2953}
2954
c2f47e15 2955/* Expand a call to the pow built-in mathematical function. Return NULL_RTX if
f1b844c6 2956 a normal call should be emitted rather than expanding the function
2957 in-line. EXP is the expression that is a call to the builtin
2958 function; if convenient, the result should be placed in TARGET. */
2959
2960static rtx
2961expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2962{
c2f47e15 2963 tree arg0, arg1;
2964 tree fn, narg0;
1c4709b4 2965 tree type = TREE_TYPE (exp);
2966 REAL_VALUE_TYPE cint, c, c2;
2967 HOST_WIDE_INT n;
2968 rtx op, op2;
2969 enum machine_mode mode = TYPE_MODE (type);
f1b844c6 2970
c2f47e15 2971 if (! validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2972 return NULL_RTX;
f1b844c6 2973
c2f47e15 2974 arg0 = CALL_EXPR_ARG (exp, 0);
2975 arg1 = CALL_EXPR_ARG (exp, 1);
f1b844c6 2976
1c4709b4 2977 if (TREE_CODE (arg1) != REAL_CST
f96bd2bf 2978 || TREE_OVERFLOW (arg1))
1c4709b4 2979 return expand_builtin_mathfn_2 (exp, target, subtarget);
2980
2981 /* Handle constant exponents. */
2982
2983 /* For integer valued exponents we can expand to an optimal multiplication
2984 sequence using expand_powi. */
2985 c = TREE_REAL_CST (arg1);
2986 n = real_to_integer (&c);
2987 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2988 if (real_identical (&c, &cint)
2989 && ((n >= -1 && n <= 2)
2990 || (flag_unsafe_math_optimizations
a0d18cec 2991 && optimize_insn_for_speed_p ()
1c4709b4 2992 && powi_cost (n) <= POWI_MAX_MULTS)))
f1b844c6 2993 {
1db6d067 2994 op = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
1c4709b4 2995 if (n != 1)
2996 {
2997 op = force_reg (mode, op);
2998 op = expand_powi (op, mode, n);
2999 }
3000 return op;
3001 }
3002
3003 narg0 = builtin_save_expr (arg0);
f1b844c6 3004
1c4709b4 3005 /* If the exponent is not integer valued, check if it is half of an integer.
3006 In this case we can expand to sqrt (x) * x**(n/2). */
3007 fn = mathfn_built_in (type, BUILT_IN_SQRT);
3008 if (fn != NULL_TREE)
3009 {
3010 real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
3011 n = real_to_integer (&c2);
f1b844c6 3012 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
1c4709b4 3013 if (real_identical (&c2, &cint)
3014 && ((flag_unsafe_math_optimizations
a0d18cec 3015 && optimize_insn_for_speed_p ()
1c4709b4 3016 && powi_cost (n/2) <= POWI_MAX_MULTS)
3017 || n == 1))
f1b844c6 3018 {
c2f47e15 3019 tree call_expr = build_call_expr (fn, 1, narg0);
8697cf4d 3020 /* Use expand_expr in case the newly built call expression
3021 was folded to a non-call. */
3022 op = expand_expr (call_expr, subtarget, mode, EXPAND_NORMAL);
1c4709b4 3023 if (n != 1)
8c5cac78 3024 {
1db6d067 3025 op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL);
1c4709b4 3026 op2 = force_reg (mode, op2);
3027 op2 = expand_powi (op2, mode, abs (n / 2));
3028 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
3029 0, OPTAB_LIB_WIDEN);
3030 /* If the original exponent was negative, reciprocate the
3031 result. */
3032 if (n < 0)
3033 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
3034 op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
8c5cac78 3035 }
1c4709b4 3036 return op;
f1b844c6 3037 }
3038 }
b613c2a6 3039
1c4709b4 3040 /* Try if the exponent is a third of an integer. In this case
5a84ba55 3041 we can expand to x**(n/3) * cbrt(x)**(n%3). As cbrt (x) is
3042 different from pow (x, 1./3.) due to rounding and behavior
3043 with negative x we need to constrain this transformation to
3044 unsafe math and positive x or finite math. */
1c4709b4 3045 fn = mathfn_built_in (type, BUILT_IN_CBRT);
5a84ba55 3046 if (fn != NULL_TREE
3047 && flag_unsafe_math_optimizations
3048 && (tree_expr_nonnegative_p (arg0)
3049 || !HONOR_NANS (mode)))
1c4709b4 3050 {
3fa759a9 3051 REAL_VALUE_TYPE dconst3;
3052 real_from_integer (&dconst3, VOIDmode, 3, 0, 0);
1c4709b4 3053 real_arithmetic (&c2, MULT_EXPR, &c, &dconst3);
3054 real_round (&c2, mode, &c2);
3055 n = real_to_integer (&c2);
3056 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
3057 real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
3058 real_convert (&c2, mode, &c2);
3059 if (real_identical (&c2, &c)
a0d18cec 3060 && ((optimize_insn_for_speed_p ()
1c4709b4 3061 && powi_cost (n/3) <= POWI_MAX_MULTS)
3062 || n == 1))
3063 {
c2f47e15 3064 tree call_expr = build_call_expr (fn, 1,narg0);
1c4709b4 3065 op = expand_builtin (call_expr, NULL_RTX, subtarget, mode, 0);
3066 if (abs (n) % 3 == 2)
3067 op = expand_simple_binop (mode, MULT, op, op, op,
3068 0, OPTAB_LIB_WIDEN);
3069 if (n != 1)
3070 {
1db6d067 3071 op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL);
1c4709b4 3072 op2 = force_reg (mode, op2);
3073 op2 = expand_powi (op2, mode, abs (n / 3));
3074 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
3075 0, OPTAB_LIB_WIDEN);
3076 /* If the original exponent was negative, reciprocate the
3077 result. */
3078 if (n < 0)
3079 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
3080 op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
3081 }
3082 return op;
3083 }
3084 }
3085
3086 /* Fall back to optab expansion. */
b613c2a6 3087 return expand_builtin_mathfn_2 (exp, target, subtarget);
f1b844c6 3088}
3089
c2f47e15 3090/* Expand a call to the powi built-in mathematical function. Return NULL_RTX if
757c219d 3091 a normal call should be emitted rather than expanding the function
3092 in-line. EXP is the expression that is a call to the builtin
3093 function; if convenient, the result should be placed in TARGET. */
3094
3095static rtx
3096expand_builtin_powi (tree exp, rtx target, rtx subtarget)
3097{
757c219d 3098 tree arg0, arg1;
3099 rtx op0, op1;
3100 enum machine_mode mode;
d0405f40 3101 enum machine_mode mode2;
757c219d 3102
c2f47e15 3103 if (! validate_arglist (exp, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
3104 return NULL_RTX;
757c219d 3105
c2f47e15 3106 arg0 = CALL_EXPR_ARG (exp, 0);
3107 arg1 = CALL_EXPR_ARG (exp, 1);
757c219d 3108 mode = TYPE_MODE (TREE_TYPE (exp));
3109
3110 /* Handle constant power. */
3111
3112 if (TREE_CODE (arg1) == INTEGER_CST
f96bd2bf 3113 && !TREE_OVERFLOW (arg1))
757c219d 3114 {
3115 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
3116
3117 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
3118 Otherwise, check the number of multiplications required. */
3119 if ((TREE_INT_CST_HIGH (arg1) == 0
3120 || TREE_INT_CST_HIGH (arg1) == -1)
3121 && ((n >= -1 && n <= 2)
a0d18cec 3122 || (optimize_insn_for_speed_p ()
757c219d 3123 && powi_cost (n) <= POWI_MAX_MULTS)))
3124 {
1db6d067 3125 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
757c219d 3126 op0 = force_reg (mode, op0);
3127 return expand_powi (op0, mode, n);
3128 }
3129 }
3130
3131 /* Emit a libcall to libgcc. */
3132
c2f47e15 3133 /* Mode of the 2nd argument must match that of an int. */
d0405f40 3134 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
3135
757c219d 3136 if (target == NULL_RTX)
3137 target = gen_reg_rtx (mode);
3138
1db6d067 3139 op0 = expand_expr (arg0, subtarget, mode, EXPAND_NORMAL);
757c219d 3140 if (GET_MODE (op0) != mode)
3141 op0 = convert_to_mode (mode, op0, 0);
1db6d067 3142 op1 = expand_expr (arg1, NULL_RTX, mode2, EXPAND_NORMAL);
d0405f40 3143 if (GET_MODE (op1) != mode2)
3144 op1 = convert_to_mode (mode2, op1, 0);
757c219d 3145
f36b9f69 3146 target = emit_library_call_value (optab_libfunc (powi_optab, mode),
2dd6f9ed 3147 target, LCT_CONST, mode, 2,
d0405f40 3148 op0, mode, op1, mode2);
757c219d 3149
3150 return target;
3151}
3152
c2f47e15 3153/* Expand expression EXP which is a call to the strlen builtin. Return
3154 NULL_RTX if we failed the caller should emit a normal call, otherwise
aed0bd19 3155 try to get the result in TARGET, if convenient. */
f7c44134 3156
53800dbe 3157static rtx
c2f47e15 3158expand_builtin_strlen (tree exp, rtx target,
aecda0d6 3159 enum machine_mode target_mode)
53800dbe 3160{
c2f47e15 3161 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
3162 return NULL_RTX;
53800dbe 3163 else
3164 {
911c0150 3165 rtx pat;
c2f47e15 3166 tree len;
3167 tree src = CALL_EXPR_ARG (exp, 0);
911c0150 3168 rtx result, src_reg, char_rtx, before_strlen;
80cd7a5e 3169 enum machine_mode insn_mode = target_mode, char_mode;
ef2c4a29 3170 enum insn_code icode = CODE_FOR_nothing;
6248e345 3171 int align;
3172
3173 /* If the length can be computed at compile-time, return it. */
681fab1e 3174 len = c_strlen (src, 0);
6248e345 3175 if (len)
80cd7a5e 3176 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
6248e345 3177
681fab1e 3178 /* If the length can be computed at compile-time and is constant
3179 integer, but there are side-effects in src, evaluate
3180 src for side-effects, then return len.
3181 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
3182 can be optimized into: i++; x = 3; */
3183 len = c_strlen (src, 1);
3184 if (len && TREE_CODE (len) == INTEGER_CST)
3185 {
3186 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3187 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
3188 }
3189
6248e345 3190 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
53800dbe 3191
53800dbe 3192 /* If SRC is not a pointer type, don't do this operation inline. */
3193 if (align == 0)
c2f47e15 3194 return NULL_RTX;
53800dbe 3195
911c0150 3196 /* Bail out if we can't compute strlen in the right mode. */
53800dbe 3197 while (insn_mode != VOIDmode)
3198 {
99bdde56 3199 icode = optab_handler (strlen_optab, insn_mode)->insn_code;
53800dbe 3200 if (icode != CODE_FOR_nothing)
c28ae87f 3201 break;
53800dbe 3202
3203 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
3204 }
3205 if (insn_mode == VOIDmode)
c2f47e15 3206 return NULL_RTX;
53800dbe 3207
3208 /* Make a place to write the result of the instruction. */
3209 result = target;
3210 if (! (result != 0
8ad4c111 3211 && REG_P (result)
53800dbe 3212 && GET_MODE (result) == insn_mode
3213 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3214 result = gen_reg_rtx (insn_mode);
3215
911c0150 3216 /* Make a place to hold the source address. We will not expand
3217 the actual source until we are sure that the expansion will
3218 not fail -- there are trees that cannot be expanded twice. */
3219 src_reg = gen_reg_rtx (Pmode);
53800dbe 3220
911c0150 3221 /* Mark the beginning of the strlen sequence so we can emit the
3222 source operand later. */
f0ce3b1f 3223 before_strlen = get_last_insn ();
53800dbe 3224
53800dbe 3225 char_rtx = const0_rtx;
f7c44134 3226 char_mode = insn_data[(int) icode].operand[2].mode;
3227 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
3228 char_mode))
53800dbe 3229 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
3230
911c0150 3231 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
3232 char_rtx, GEN_INT (align));
3233 if (! pat)
c2f47e15 3234 return NULL_RTX;
911c0150 3235 emit_insn (pat);
3236
3237 /* Now that we are assured of success, expand the source. */
3238 start_sequence ();
c5aba89c 3239 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
911c0150 3240 if (pat != src_reg)
3241 emit_move_insn (src_reg, pat);
31d3e01c 3242 pat = get_insns ();
911c0150 3243 end_sequence ();
bceb0d1f 3244
3245 if (before_strlen)
3246 emit_insn_after (pat, before_strlen);
3247 else
3248 emit_insn_before (pat, get_insns ());
53800dbe 3249
3250 /* Return the value in the proper mode for this function. */
80cd7a5e 3251 if (GET_MODE (result) == target_mode)
911c0150 3252 target = result;
53800dbe 3253 else if (target != 0)
911c0150 3254 convert_move (target, result, 0);
53800dbe 3255 else
80cd7a5e 3256 target = convert_to_mode (target_mode, result, 0);
911c0150 3257
3258 return target;
53800dbe 3259 }
3260}
3261
c2f47e15 3262/* Expand a call to the strstr builtin. Return NULL_RTX if we failed the
17f5ea87 3263 caller should emit a normal call, otherwise try to get the result
3264 in TARGET, if convenient (and in mode MODE if that's convenient). */
3265
3266static rtx
c2f47e15 3267expand_builtin_strstr (tree exp, rtx target, enum machine_mode mode)
17f5ea87 3268{
c2f47e15 3269 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
17f5ea87 3270 {
c2f47e15 3271 tree type = TREE_TYPE (exp);
3272 tree result = fold_builtin_strstr (CALL_EXPR_ARG (exp, 0),
3273 CALL_EXPR_ARG (exp, 1), type);
2c84ee37 3274 if (result)
3275 return expand_expr (result, target, mode, EXPAND_NORMAL);
17f5ea87 3276 }
c2f47e15 3277 return NULL_RTX;
17f5ea87 3278}
3279
c2f47e15 3280/* Expand a call to the strchr builtin. Return NULL_RTX if we failed the
46f3a74a 3281 caller should emit a normal call, otherwise try to get the result
3282 in TARGET, if convenient (and in mode MODE if that's convenient). */
3283
3284static rtx
c2f47e15 3285expand_builtin_strchr (tree exp, rtx target, enum machine_mode mode)
46f3a74a 3286{
c2f47e15 3287 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
46f3a74a 3288 {
c2f47e15 3289 tree type = TREE_TYPE (exp);
3290 tree result = fold_builtin_strchr (CALL_EXPR_ARG (exp, 0),
3291 CALL_EXPR_ARG (exp, 1), type);
2c84ee37 3292 if (result)
3293 return expand_expr (result, target, mode, EXPAND_NORMAL);
83d79705 3294
2c84ee37 3295 /* FIXME: Should use strchrM optab so that ports can optimize this. */
83d79705 3296 }
c2f47e15 3297 return NULL_RTX;
83d79705 3298}
3299
c2f47e15 3300/* Expand a call to the strrchr builtin. Return NULL_RTX if we failed the
83d79705 3301 caller should emit a normal call, otherwise try to get the result
3302 in TARGET, if convenient (and in mode MODE if that's convenient). */
3303
3304static rtx
c2f47e15 3305expand_builtin_strrchr (tree exp, rtx target, enum machine_mode mode)
83d79705 3306{
c2f47e15 3307 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
83d79705 3308 {
c2f47e15 3309 tree type = TREE_TYPE (exp);
3310 tree result = fold_builtin_strrchr (CALL_EXPR_ARG (exp, 0),
3311 CALL_EXPR_ARG (exp, 1), type);
2c84ee37 3312 if (result)
3313 return expand_expr (result, target, mode, EXPAND_NORMAL);
83d79705 3314 }
c2f47e15 3315 return NULL_RTX;
83d79705 3316}
3317
c2f47e15 3318/* Expand a call to the strpbrk builtin. Return NULL_RTX if we failed the
83d79705 3319 caller should emit a normal call, otherwise try to get the result
3320 in TARGET, if convenient (and in mode MODE if that's convenient). */
3321
3322static rtx
c2f47e15 3323expand_builtin_strpbrk (tree exp, rtx target, enum machine_mode mode)
83d79705 3324{
c2f47e15 3325 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
83d79705 3326 {
c2f47e15 3327 tree type = TREE_TYPE (exp);
3328 tree result = fold_builtin_strpbrk (CALL_EXPR_ARG (exp, 0),
3329 CALL_EXPR_ARG (exp, 1), type);
2c84ee37 3330 if (result)
3331 return expand_expr (result, target, mode, EXPAND_NORMAL);
46f3a74a 3332 }
c2f47e15 3333 return NULL_RTX;
46f3a74a 3334}
3335
6840589f 3336/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3337 bytes from constant string DATA + OFFSET and return it as target
3338 constant. */
3339
3340static rtx
aecda0d6 3341builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
3342 enum machine_mode mode)
6840589f 3343{
3344 const char *str = (const char *) data;
3345
64db345d 3346 gcc_assert (offset >= 0
3347 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
3348 <= strlen (str) + 1));
6840589f 3349
3350 return c_readstr (str + offset, mode);
3351}
3352
c2f47e15 3353/* Expand a call EXP to the memcpy builtin.
3354 Return NULL_RTX if we failed, the caller should emit a normal call,
3b824fa6 3355 otherwise try to get the result in TARGET, if convenient (and in
9fe0e1b8 3356 mode MODE if that's convenient). */
c2f47e15 3357
53800dbe 3358static rtx
5a0de151 3359expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
53800dbe 3360{
8e76ec06 3361 tree fndecl = get_callee_fndecl (exp);
c2f47e15 3362
3363 if (!validate_arglist (exp,
3364 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3365 return NULL_RTX;
53800dbe 3366 else
3367 {
c2f47e15 3368 tree dest = CALL_EXPR_ARG (exp, 0);
3369 tree src = CALL_EXPR_ARG (exp, 1);
3370 tree len = CALL_EXPR_ARG (exp, 2);
6840589f 3371 const char *src_str;
27d0c333 3372 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3373 unsigned int dest_align
3374 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
53800dbe 3375 rtx dest_mem, src_mem, dest_addr, len_rtx;
c2f47e15 3376 tree result = fold_builtin_memory_op (dest, src, len,
3377 TREE_TYPE (TREE_TYPE (fndecl)),
4f46f2b9 3378 false, /*endp=*/0);
162719b3 3379 HOST_WIDE_INT expected_size = -1;
3380 unsigned int expected_align = 0;
75a70cf9 3381 tree_ann_common_t ann;
5a0de151 3382
3383 if (result)
4f46f2b9 3384 {
3385 while (TREE_CODE (result) == COMPOUND_EXPR)
3386 {
3387 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3388 EXPAND_NORMAL);
3389 result = TREE_OPERAND (result, 1);
3390 }
3391 return expand_expr (result, target, mode, EXPAND_NORMAL);
3392 }
53800dbe 3393
6f428e8b 3394 /* If DEST is not a pointer type, call the normal function. */
3395 if (dest_align == 0)
c2f47e15 3396 return NULL_RTX;
6f428e8b 3397
6f428e8b 3398 /* If either SRC is not a pointer type, don't do this
a0c938f0 3399 operation in-line. */
6f428e8b 3400 if (src_align == 0)
c2f47e15 3401 return NULL_RTX;
162719b3 3402
75a70cf9 3403 ann = tree_common_ann (exp);
3404 if (ann)
3405 stringop_block_profile (ann->stmt, &expected_align, &expected_size);
3406
162719b3 3407 if (expected_align < dest_align)
3408 expected_align = dest_align;
d8ae1baa 3409 dest_mem = get_memory_rtx (dest, len);
2a631e19 3410 set_mem_align (dest_mem, dest_align);
8ec3c5c2 3411 len_rtx = expand_normal (len);
6840589f 3412 src_str = c_getstr (src);
3413
3414 /* If SRC is a string constant and block move would be done
3415 by pieces, we can avoid loading the string from memory
3416 and only stored the computed constants. */
3417 if (src_str
971ba038 3418 && CONST_INT_P (len_rtx)
6840589f 3419 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3420 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
364c0c59 3421 CONST_CAST (char *, src_str),
3422 dest_align, false))
6840589f 3423 {
9fe0e1b8 3424 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3425 builtin_memcpy_read_str,
364c0c59 3426 CONST_CAST (char *, src_str),
3427 dest_align, false, 0);
e5716f7e 3428 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3429 dest_mem = convert_memory_address (ptr_mode, dest_mem);
9fe0e1b8 3430 return dest_mem;
6840589f 3431 }
3432
d8ae1baa 3433 src_mem = get_memory_rtx (src, len);
2a631e19 3434 set_mem_align (src_mem, src_align);
53800dbe 3435
53800dbe 3436 /* Copy word part most expediently. */
162719b3 3437 dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx,
3438 CALL_EXPR_TAILCALL (exp)
3439 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3440 expected_align, expected_size);
53800dbe 3441
3442 if (dest_addr == 0)
e5716f7e 3443 {
3444 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3445 dest_addr = convert_memory_address (ptr_mode, dest_addr);
e5716f7e 3446 }
9fe0e1b8 3447 return dest_addr;
53800dbe 3448 }
3449}
3450
c2f47e15 3451/* Expand a call EXP to the mempcpy builtin.
3452 Return NULL_RTX if we failed; the caller should emit a normal call,
647661c6 3453 otherwise try to get the result in TARGET, if convenient (and in
9fe0e1b8 3454 mode MODE if that's convenient). If ENDP is 0 return the
3455 destination pointer, if ENDP is 1 return the end pointer ala
3456 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3457 stpcpy. */
647661c6 3458
3459static rtx
c8b17b2e 3460expand_builtin_mempcpy (tree exp, rtx target, enum machine_mode mode)
647661c6 3461{
c2f47e15 3462 if (!validate_arglist (exp,
3463 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3464 return NULL_RTX;
3465 else
3466 {
3467 tree dest = CALL_EXPR_ARG (exp, 0);
3468 tree src = CALL_EXPR_ARG (exp, 1);
3469 tree len = CALL_EXPR_ARG (exp, 2);
3470 return expand_builtin_mempcpy_args (dest, src, len,
3471 TREE_TYPE (exp),
3472 target, mode, /*endp=*/ 1);
3473 }
3474}
3475
3476/* Helper function to do the actual work for expand_builtin_mempcpy. The
3477 arguments to the builtin_mempcpy call DEST, SRC, and LEN are broken out
3478 so that this can also be called without constructing an actual CALL_EXPR.
3479 TYPE is the return type of the call. The other arguments and return value
3480 are the same as for expand_builtin_mempcpy. */
3481
3482static rtx
3483expand_builtin_mempcpy_args (tree dest, tree src, tree len, tree type,
3484 rtx target, enum machine_mode mode, int endp)
3485{
3486 /* If return value is ignored, transform mempcpy into memcpy. */
c8b17b2e 3487 if (target == const0_rtx && implicit_built_in_decls[BUILT_IN_MEMCPY])
9fe0e1b8 3488 {
3489 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
c8b17b2e 3490 tree result = build_call_expr (fn, 3, dest, src, len);
9fe0e1b8 3491
c8b17b2e 3492 while (TREE_CODE (result) == COMPOUND_EXPR)
3493 {
3494 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3495 EXPAND_NORMAL);
3496 result = TREE_OPERAND (result, 1);
3497 }
3498 return expand_expr (result, target, mode, EXPAND_NORMAL);
9fe0e1b8 3499 }
647661c6 3500 else
3501 {
9fe0e1b8 3502 const char *src_str;
3503 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3504 unsigned int dest_align
3505 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3506 rtx dest_mem, src_mem, len_rtx;
c2f47e15 3507 tree result = fold_builtin_memory_op (dest, src, len, type, false, endp);
9fe0e1b8 3508
7da1412b 3509 if (result)
4f46f2b9 3510 {
3511 while (TREE_CODE (result) == COMPOUND_EXPR)
3512 {
3513 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3514 EXPAND_NORMAL);
3515 result = TREE_OPERAND (result, 1);
3516 }
3517 return expand_expr (result, target, mode, EXPAND_NORMAL);
3518 }
a0c938f0 3519
7da1412b 3520 /* If either SRC or DEST is not a pointer type, don't do this
a0c938f0 3521 operation in-line. */
7da1412b 3522 if (dest_align == 0 || src_align == 0)
c2f47e15 3523 return NULL_RTX;
9fe0e1b8 3524
6217c238 3525 /* If LEN is not constant, call the normal function. */
3526 if (! host_integerp (len, 1))
c2f47e15 3527 return NULL_RTX;
0862b7e9 3528
8ec3c5c2 3529 len_rtx = expand_normal (len);
9fe0e1b8 3530 src_str = c_getstr (src);
647661c6 3531
9fe0e1b8 3532 /* If SRC is a string constant and block move would be done
3533 by pieces, we can avoid loading the string from memory
3534 and only stored the computed constants. */
3535 if (src_str
971ba038 3536 && CONST_INT_P (len_rtx)
9fe0e1b8 3537 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3538 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
364c0c59 3539 CONST_CAST (char *, src_str),
3540 dest_align, false))
9fe0e1b8 3541 {
d8ae1baa 3542 dest_mem = get_memory_rtx (dest, len);
9fe0e1b8 3543 set_mem_align (dest_mem, dest_align);
3544 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3545 builtin_memcpy_read_str,
364c0c59 3546 CONST_CAST (char *, src_str),
3547 dest_align, false, endp);
9fe0e1b8 3548 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3549 dest_mem = convert_memory_address (ptr_mode, dest_mem);
9fe0e1b8 3550 return dest_mem;
647661c6 3551 }
3552
971ba038 3553 if (CONST_INT_P (len_rtx)
9fe0e1b8 3554 && can_move_by_pieces (INTVAL (len_rtx),
3555 MIN (dest_align, src_align)))
3556 {
d8ae1baa 3557 dest_mem = get_memory_rtx (dest, len);
9fe0e1b8 3558 set_mem_align (dest_mem, dest_align);
d8ae1baa 3559 src_mem = get_memory_rtx (src, len);
9fe0e1b8 3560 set_mem_align (src_mem, src_align);
3561 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3562 MIN (dest_align, src_align), endp);
3563 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3564 dest_mem = convert_memory_address (ptr_mode, dest_mem);
9fe0e1b8 3565 return dest_mem;
3566 }
3567
c2f47e15 3568 return NULL_RTX;
647661c6 3569 }
3570}
3571
c2f47e15 3572/* Expand expression EXP, which is a call to the memmove builtin. Return
3573 NULL_RTX if we failed; the caller should emit a normal call. */
c4950093 3574
3575static rtx
c2f47e15 3576expand_builtin_memmove (tree exp, rtx target, enum machine_mode mode, int ignore)
c4950093 3577{
c2f47e15 3578 if (!validate_arglist (exp,
3579 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3580 return NULL_RTX;
c4950093 3581 else
3582 {
c2f47e15 3583 tree dest = CALL_EXPR_ARG (exp, 0);
3584 tree src = CALL_EXPR_ARG (exp, 1);
3585 tree len = CALL_EXPR_ARG (exp, 2);
3586 return expand_builtin_memmove_args (dest, src, len, TREE_TYPE (exp),
3587 target, mode, ignore);
3588 }
3589}
7e72af53 3590
c2f47e15 3591/* Helper function to do the actual work for expand_builtin_memmove. The
3592 arguments to the builtin_memmove call DEST, SRC, and LEN are broken out
3593 so that this can also be called without constructing an actual CALL_EXPR.
3594 TYPE is the return type of the call. The other arguments and return value
3595 are the same as for expand_builtin_memmove. */
3596
3597static rtx
3598expand_builtin_memmove_args (tree dest, tree src, tree len,
3599 tree type, rtx target, enum machine_mode mode,
3600 int ignore)
3601{
3602 tree result = fold_builtin_memory_op (dest, src, len, type, ignore, /*endp=*/3);
3603
3604 if (result)
3605 {
05be68f3 3606 STRIP_TYPE_NOPS (result);
c2f47e15 3607 while (TREE_CODE (result) == COMPOUND_EXPR)
4f46f2b9 3608 {
c2f47e15 3609 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3610 EXPAND_NORMAL);
3611 result = TREE_OPERAND (result, 1);
4f46f2b9 3612 }
c2f47e15 3613 return expand_expr (result, target, mode, EXPAND_NORMAL);
3614 }
3615
3616 /* Otherwise, call the normal function. */
3617 return NULL_RTX;
c4950093 3618}
3619
c2f47e15 3620/* Expand expression EXP, which is a call to the bcopy builtin. Return
3621 NULL_RTX if we failed the caller should emit a normal call. */
c4950093 3622
3623static rtx
c2f47e15 3624expand_builtin_bcopy (tree exp, int ignore)
c4950093 3625{
0b25db21 3626 tree type = TREE_TYPE (exp);
c2f47e15 3627 tree src, dest, size;
c4950093 3628
c2f47e15 3629 if (!validate_arglist (exp,
3630 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
c4950093 3631 return NULL_RTX;
3632
c2f47e15 3633 src = CALL_EXPR_ARG (exp, 0);
3634 dest = CALL_EXPR_ARG (exp, 1);
3635 size = CALL_EXPR_ARG (exp, 2);
c4950093 3636
c2f47e15 3637 /* Transform bcopy(ptr x, ptr y, int z) to memmove(ptr y, ptr x, size_t z).
3638 This is done this way so that if it isn't expanded inline, we fall
3639 back to calling bcopy instead of memmove. */
3640 return expand_builtin_memmove_args (dest, src,
3641 fold_convert (sizetype, size),
3642 type, const0_rtx, VOIDmode,
3643 ignore);
c4950093 3644}
3645
727c62dd 3646#ifndef HAVE_movstr
3647# define HAVE_movstr 0
3648# define CODE_FOR_movstr CODE_FOR_nothing
3649#endif
3650
c2f47e15 3651/* Expand into a movstr instruction, if one is available. Return NULL_RTX if
727c62dd 3652 we failed, the caller should emit a normal call, otherwise try to
3653 get the result in TARGET, if convenient. If ENDP is 0 return the
3654 destination pointer, if ENDP is 1 return the end pointer ala
3655 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3656 stpcpy. */
3657
3658static rtx
3659expand_movstr (tree dest, tree src, rtx target, int endp)
3660{
3661 rtx end;
3662 rtx dest_mem;
3663 rtx src_mem;
3664 rtx insn;
3665 const struct insn_data * data;
3666
3667 if (!HAVE_movstr)
c2f47e15 3668 return NULL_RTX;
727c62dd 3669
d8ae1baa 3670 dest_mem = get_memory_rtx (dest, NULL);
3671 src_mem = get_memory_rtx (src, NULL);
727c62dd 3672 if (!endp)
3673 {
3674 target = force_reg (Pmode, XEXP (dest_mem, 0));
3675 dest_mem = replace_equiv_address (dest_mem, target);
3676 end = gen_reg_rtx (Pmode);
3677 }
3678 else
3679 {
3680 if (target == 0 || target == const0_rtx)
3681 {
3682 end = gen_reg_rtx (Pmode);
3683 if (target == 0)
3684 target = end;
3685 }
3686 else
3687 end = target;
3688 }
3689
3690 data = insn_data + CODE_FOR_movstr;
3691
3692 if (data->operand[0].mode != VOIDmode)
3693 end = gen_lowpart (data->operand[0].mode, end);
3694
3695 insn = data->genfun (end, dest_mem, src_mem);
3696
64db345d 3697 gcc_assert (insn);
727c62dd 3698
3699 emit_insn (insn);
3700
3701 /* movstr is supposed to set end to the address of the NUL
3702 terminator. If the caller requested a mempcpy-like return value,
3703 adjust it. */
3704 if (endp == 1 && target != const0_rtx)
c5aba89c 3705 {
3706 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3707 emit_move_insn (target, force_operand (tem, NULL_RTX));
3708 }
727c62dd 3709
3710 return target;
3711}
3712
c2f47e15 3713/* Expand expression EXP, which is a call to the strcpy builtin. Return
3714 NULL_RTX if we failed the caller should emit a normal call, otherwise
3715 try to get the result in TARGET, if convenient (and in mode MODE if that's
6f428e8b 3716 convenient). */
902de8ed 3717
53800dbe 3718static rtx
c2f47e15 3719expand_builtin_strcpy (tree fndecl, tree exp, rtx target, enum machine_mode mode)
53800dbe 3720{
c2f47e15 3721 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3722 {
3723 tree dest = CALL_EXPR_ARG (exp, 0);
3724 tree src = CALL_EXPR_ARG (exp, 1);
3725 return expand_builtin_strcpy_args (fndecl, dest, src, target, mode);
3726 }
3727 return NULL_RTX;
3728}
3729
3730/* Helper function to do the actual work for expand_builtin_strcpy. The
3731 arguments to the builtin_strcpy call DEST and SRC are broken out
3732 so that this can also be called without constructing an actual CALL_EXPR.
3733 The other arguments and return value are the same as for
3734 expand_builtin_strcpy. */
3735
3736static rtx
3737expand_builtin_strcpy_args (tree fndecl, tree dest, tree src,
3738 rtx target, enum machine_mode mode)
3739{
3740 tree result = fold_builtin_strcpy (fndecl, dest, src, 0);
3741 if (result)
3742 return expand_expr (result, target, mode, EXPAND_NORMAL);
3743 return expand_movstr (dest, src, target, /*endp=*/0);
902de8ed 3744
53800dbe 3745}
3746
c2f47e15 3747/* Expand a call EXP to the stpcpy builtin.
3748 Return NULL_RTX if we failed the caller should emit a normal call,
3b824fa6 3749 otherwise try to get the result in TARGET, if convenient (and in
3750 mode MODE if that's convenient). */
3751
3752static rtx
dc369150 3753expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3b824fa6 3754{
c2f47e15 3755 tree dst, src;
3756
3757 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3758 return NULL_RTX;
3759
3760 dst = CALL_EXPR_ARG (exp, 0);
3761 src = CALL_EXPR_ARG (exp, 1);
3762
727c62dd 3763 /* If return value is ignored, transform stpcpy into strcpy. */
c8b17b2e 3764 if (target == const0_rtx && implicit_built_in_decls[BUILT_IN_STRCPY])
978836e5 3765 {
3766 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
c8b17b2e 3767 tree result = build_call_expr (fn, 2, dst, src);
978836e5 3768
c8b17b2e 3769 STRIP_NOPS (result);
3770 while (TREE_CODE (result) == COMPOUND_EXPR)
3771 {
3772 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3773 EXPAND_NORMAL);
3774 result = TREE_OPERAND (result, 1);
3775 }
3776 return expand_expr (result, target, mode, EXPAND_NORMAL);
978836e5 3777 }
3b824fa6 3778 else
3779 {
c2f47e15 3780 tree len, lenp1;
727c62dd 3781 rtx ret;
647661c6 3782
9fe0e1b8 3783 /* Ensure we get an actual string whose length can be evaluated at
a0c938f0 3784 compile-time, not an expression containing a string. This is
3785 because the latter will potentially produce pessimized code
3786 when used to produce the return value. */
681fab1e 3787 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
c2f47e15 3788 return expand_movstr (dst, src, target, /*endp=*/2);
3b824fa6 3789
7d705727 3790 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
c2f47e15 3791 ret = expand_builtin_mempcpy_args (dst, src, lenp1, TREE_TYPE (exp),
3792 target, mode, /*endp=*/2);
727c62dd 3793
3794 if (ret)
3795 return ret;
3796
3797 if (TREE_CODE (len) == INTEGER_CST)
3798 {
8ec3c5c2 3799 rtx len_rtx = expand_normal (len);
727c62dd 3800
971ba038 3801 if (CONST_INT_P (len_rtx))
727c62dd 3802 {
c2f47e15 3803 ret = expand_builtin_strcpy_args (get_callee_fndecl (exp),
3804 dst, src, target, mode);
727c62dd 3805
3806 if (ret)
3807 {
3808 if (! target)
7ac87324 3809 {
3810 if (mode != VOIDmode)
3811 target = gen_reg_rtx (mode);
3812 else
3813 target = gen_reg_rtx (GET_MODE (ret));
3814 }
727c62dd 3815 if (GET_MODE (target) != GET_MODE (ret))
3816 ret = gen_lowpart (GET_MODE (target), ret);
3817
c5aba89c 3818 ret = plus_constant (ret, INTVAL (len_rtx));
3819 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
64db345d 3820 gcc_assert (ret);
727c62dd 3821
3822 return target;
3823 }
3824 }
3825 }
3826
c2f47e15 3827 return expand_movstr (dst, src, target, /*endp=*/2);
3b824fa6 3828 }
3829}
3830
6840589f 3831/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3832 bytes from constant string DATA + OFFSET and return it as target
3833 constant. */
3834
09879952 3835rtx
aecda0d6 3836builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3837 enum machine_mode mode)
6840589f 3838{
3839 const char *str = (const char *) data;
3840
3841 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3842 return const0_rtx;
3843
3844 return c_readstr (str + offset, mode);
3845}
3846
c2f47e15 3847/* Expand expression EXP, which is a call to the strncpy builtin. Return
3848 NULL_RTX if we failed the caller should emit a normal call. */
ed09096d 3849
3850static rtx
8ff6a5cd 3851expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
ed09096d 3852{
ea726109 3853 tree fndecl = get_callee_fndecl (exp);
c2f47e15 3854
3855 if (validate_arglist (exp,
3856 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
ed09096d 3857 {
c2f47e15 3858 tree dest = CALL_EXPR_ARG (exp, 0);
3859 tree src = CALL_EXPR_ARG (exp, 1);
3860 tree len = CALL_EXPR_ARG (exp, 2);
3861 tree slen = c_strlen (src, 1);
3862 tree result = fold_builtin_strncpy (fndecl, dest, src, len, slen);
a0c938f0 3863
8ff6a5cd 3864 if (result)
4f46f2b9 3865 {
3866 while (TREE_CODE (result) == COMPOUND_EXPR)
3867 {
3868 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3869 EXPAND_NORMAL);
3870 result = TREE_OPERAND (result, 1);
3871 }
3872 return expand_expr (result, target, mode, EXPAND_NORMAL);
3873 }
6840589f 3874
8ff6a5cd 3875 /* We must be passed a constant len and src parameter. */
3876 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
c2f47e15 3877 return NULL_RTX;
ed09096d 3878
3879 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3880
3881 /* We're required to pad with trailing zeros if the requested
a0c938f0 3882 len is greater than strlen(s2)+1. In that case try to
6840589f 3883 use store_by_pieces, if it fails, punt. */
ed09096d 3884 if (tree_int_cst_lt (slen, len))
6840589f 3885 {
27d0c333 3886 unsigned int dest_align
3887 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
c2f47e15 3888 const char *p = c_getstr (src);
6840589f 3889 rtx dest_mem;
3890
27d0c333 3891 if (!p || dest_align == 0 || !host_integerp (len, 1)
3892 || !can_store_by_pieces (tree_low_cst (len, 1),
6840589f 3893 builtin_strncpy_read_str,
364c0c59 3894 CONST_CAST (char *, p),
3895 dest_align, false))
c2f47e15 3896 return NULL_RTX;
6840589f 3897
d8ae1baa 3898 dest_mem = get_memory_rtx (dest, len);
27d0c333 3899 store_by_pieces (dest_mem, tree_low_cst (len, 1),
6840589f 3900 builtin_strncpy_read_str,
364c0c59 3901 CONST_CAST (char *, p), dest_align, false, 0);
e5716f7e 3902 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3903 dest_mem = convert_memory_address (ptr_mode, dest_mem);
e5716f7e 3904 return dest_mem;
6840589f 3905 }
ed09096d 3906 }
c2f47e15 3907 return NULL_RTX;
ed09096d 3908}
3909
ecc318ff 3910/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3911 bytes from constant string DATA + OFFSET and return it as target
3912 constant. */
3913
f656b751 3914rtx
aecda0d6 3915builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3916 enum machine_mode mode)
ecc318ff 3917{
3918 const char *c = (const char *) data;
364c0c59 3919 char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
ecc318ff 3920
3921 memset (p, *c, GET_MODE_SIZE (mode));
3922
3923 return c_readstr (p, mode);
3924}
3925
a7ec6974 3926/* Callback routine for store_by_pieces. Return the RTL of a register
3927 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3928 char value given in the RTL register data. For example, if mode is
3929 4 bytes wide, return the RTL for 0x01010101*data. */
3930
3931static rtx
aecda0d6 3932builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3933 enum machine_mode mode)
a7ec6974 3934{
3935 rtx target, coeff;
3936 size_t size;
3937 char *p;
3938
3939 size = GET_MODE_SIZE (mode);
f0ce3b1f 3940 if (size == 1)
3941 return (rtx) data;
a7ec6974 3942
364c0c59 3943 p = XALLOCAVEC (char, size);
a7ec6974 3944 memset (p, 1, size);
3945 coeff = c_readstr (p, mode);
3946
f0ce3b1f 3947 target = convert_to_mode (mode, (rtx) data, 1);
a7ec6974 3948 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3949 return force_reg (mode, target);
3950}
3951
c2f47e15 3952/* Expand expression EXP, which is a call to the memset builtin. Return
3953 NULL_RTX if we failed the caller should emit a normal call, otherwise
3954 try to get the result in TARGET, if convenient (and in mode MODE if that's
6f428e8b 3955 convenient). */
902de8ed 3956
53800dbe 3957static rtx
c2f47e15 3958expand_builtin_memset (tree exp, rtx target, enum machine_mode mode)
53800dbe 3959{
c2f47e15 3960 if (!validate_arglist (exp,
3961 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3962 return NULL_RTX;
53800dbe 3963 else
3964 {
c2f47e15 3965 tree dest = CALL_EXPR_ARG (exp, 0);
3966 tree val = CALL_EXPR_ARG (exp, 1);
3967 tree len = CALL_EXPR_ARG (exp, 2);
3968 return expand_builtin_memset_args (dest, val, len, target, mode, exp);
3969 }
3970}
53800dbe 3971
c2f47e15 3972/* Helper function to do the actual work for expand_builtin_memset. The
3973 arguments to the builtin_memset call DEST, VAL, and LEN are broken out
3974 so that this can also be called without constructing an actual CALL_EXPR.
3975 The other arguments and return value are the same as for
3976 expand_builtin_memset. */
6b961939 3977
c2f47e15 3978static rtx
3979expand_builtin_memset_args (tree dest, tree val, tree len,
3980 rtx target, enum machine_mode mode, tree orig_exp)
3981{
3982 tree fndecl, fn;
3983 enum built_in_function fcode;
3984 char c;
3985 unsigned int dest_align;
3986 rtx dest_mem, dest_addr, len_rtx;
3987 HOST_WIDE_INT expected_size = -1;
3988 unsigned int expected_align = 0;
75a70cf9 3989 tree_ann_common_t ann;
53800dbe 3990
c2f47e15 3991 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
162719b3 3992
c2f47e15 3993 /* If DEST is not a pointer type, don't do this operation in-line. */
3994 if (dest_align == 0)
3995 return NULL_RTX;
6f428e8b 3996
75a70cf9 3997 ann = tree_common_ann (orig_exp);
3998 if (ann)
3999 stringop_block_profile (ann->stmt, &expected_align, &expected_size);
4000
c2f47e15 4001 if (expected_align < dest_align)
4002 expected_align = dest_align;
6b961939 4003
c2f47e15 4004 /* If the LEN parameter is zero, return DEST. */
4005 if (integer_zerop (len))
4006 {
4007 /* Evaluate and ignore VAL in case it has side-effects. */
4008 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
4009 return expand_expr (dest, target, mode, EXPAND_NORMAL);
4010 }
7a3e5564 4011
c2f47e15 4012 /* Stabilize the arguments in case we fail. */
4013 dest = builtin_save_expr (dest);
4014 val = builtin_save_expr (val);
4015 len = builtin_save_expr (len);
a7ec6974 4016
c2f47e15 4017 len_rtx = expand_normal (len);
4018 dest_mem = get_memory_rtx (dest, len);
a7ec6974 4019
c2f47e15 4020 if (TREE_CODE (val) != INTEGER_CST)
4021 {
4022 rtx val_rtx;
a7ec6974 4023
c2f47e15 4024 val_rtx = expand_normal (val);
4025 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
4026 val_rtx, 0);
53800dbe 4027
c2f47e15 4028 /* Assume that we can memset by pieces if we can store
4029 * the coefficients by pieces (in the required modes).
4030 * We can't pass builtin_memset_gen_str as that emits RTL. */
4031 c = 1;
4032 if (host_integerp (len, 1)
c2f47e15 4033 && can_store_by_pieces (tree_low_cst (len, 1),
4b297e2e 4034 builtin_memset_read_str, &c, dest_align,
4035 true))
c2f47e15 4036 {
4037 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
4038 val_rtx);
4039 store_by_pieces (dest_mem, tree_low_cst (len, 1),
4b297e2e 4040 builtin_memset_gen_str, val_rtx, dest_align,
4041 true, 0);
c2f47e15 4042 }
4043 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
4044 dest_align, expected_align,
4045 expected_size))
6b961939 4046 goto do_libcall;
c2f47e15 4047
4048 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
4049 dest_mem = convert_memory_address (ptr_mode, dest_mem);
4050 return dest_mem;
4051 }
53800dbe 4052
c2f47e15 4053 if (target_char_cast (val, &c))
4054 goto do_libcall;
ecc318ff 4055
c2f47e15 4056 if (c)
4057 {
4058 if (host_integerp (len, 1)
c2f47e15 4059 && can_store_by_pieces (tree_low_cst (len, 1),
4b297e2e 4060 builtin_memset_read_str, &c, dest_align,
4061 true))
c2f47e15 4062 store_by_pieces (dest_mem, tree_low_cst (len, 1),
4b297e2e 4063 builtin_memset_read_str, &c, dest_align, true, 0);
c2f47e15 4064 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
4065 dest_align, expected_align,
4066 expected_size))
4067 goto do_libcall;
4068
4069 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
4070 dest_mem = convert_memory_address (ptr_mode, dest_mem);
4071 return dest_mem;
4072 }
ecc318ff 4073
c2f47e15 4074 set_mem_align (dest_mem, dest_align);
4075 dest_addr = clear_storage_hints (dest_mem, len_rtx,
4076 CALL_EXPR_TAILCALL (orig_exp)
4077 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
4078 expected_align, expected_size);
53800dbe 4079
c2f47e15 4080 if (dest_addr == 0)
4081 {
4082 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
4083 dest_addr = convert_memory_address (ptr_mode, dest_addr);
4084 }
53800dbe 4085
c2f47e15 4086 return dest_addr;
6b961939 4087
c2f47e15 4088 do_libcall:
4089 fndecl = get_callee_fndecl (orig_exp);
4090 fcode = DECL_FUNCTION_CODE (fndecl);
4091 if (fcode == BUILT_IN_MEMSET)
4092 fn = build_call_expr (fndecl, 3, dest, val, len);
4093 else if (fcode == BUILT_IN_BZERO)
4094 fn = build_call_expr (fndecl, 2, dest, len);
4095 else
4096 gcc_unreachable ();
4097 if (TREE_CODE (fn) == CALL_EXPR)
4098 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
4099 return expand_call (fn, target, target == const0_rtx);
53800dbe 4100}
4101
c2f47e15 4102/* Expand expression EXP, which is a call to the bzero builtin. Return
4103 NULL_RTX if we failed the caller should emit a normal call. */
27d0c333 4104
ffc83088 4105static rtx
0b25db21 4106expand_builtin_bzero (tree exp)
ffc83088 4107{
c2f47e15 4108 tree dest, size;
ffc83088 4109
c2f47e15 4110 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7369e7ba 4111 return NULL_RTX;
ffc83088 4112
c2f47e15 4113 dest = CALL_EXPR_ARG (exp, 0);
4114 size = CALL_EXPR_ARG (exp, 1);
bf8e3599 4115
7369e7ba 4116 /* New argument list transforming bzero(ptr x, int y) to
6f428e8b 4117 memset(ptr x, int 0, size_t y). This is done this way
4118 so that if it isn't expanded inline, we fallback to
4119 calling bzero instead of memset. */
bf8e3599 4120
c2f47e15 4121 return expand_builtin_memset_args (dest, integer_zero_node,
4122 fold_convert (sizetype, size),
4123 const0_rtx, VOIDmode, exp);
ffc83088 4124}
4125
7959b13b 4126/* Expand a call to the memchr builtin. Return NULL_RTX if we failed the
4127 caller should emit a normal call, otherwise try to get the result
4128 in TARGET, if convenient (and in mode MODE if that's convenient). */
4129
4130static rtx
4131expand_builtin_memchr (tree exp, rtx target, enum machine_mode mode)
4132{
4133 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE,
4134 INTEGER_TYPE, VOID_TYPE))
4135 {
4136 tree type = TREE_TYPE (exp);
4137 tree result = fold_builtin_memchr (CALL_EXPR_ARG (exp, 0),
4138 CALL_EXPR_ARG (exp, 1),
4139 CALL_EXPR_ARG (exp, 2), type);
4140 if (result)
4141 return expand_expr (result, target, mode, EXPAND_NORMAL);
4142 }
4143 return NULL_RTX;
4144}
4145
7a3f89b5 4146/* Expand expression EXP, which is a call to the memcmp built-in function.
c2f47e15 4147 Return NULL_RTX if we failed and the
53800dbe 4148 caller should emit a normal call, otherwise try to get the result in
6f428e8b 4149 TARGET, if convenient (and in mode MODE, if that's convenient). */
27d0c333 4150
53800dbe 4151static rtx
c2f47e15 4152expand_builtin_memcmp (tree exp, rtx target, enum machine_mode mode)
53800dbe 4153{
c2f47e15 4154 if (!validate_arglist (exp,
4155 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4156 return NULL_RTX;
218bc19e 4157 else
6f428e8b 4158 {
c2f47e15 4159 tree result = fold_builtin_memcmp (CALL_EXPR_ARG (exp, 0),
4160 CALL_EXPR_ARG (exp, 1),
4161 CALL_EXPR_ARG (exp, 2));
218bc19e 4162 if (result)
4163 return expand_expr (result, target, mode, EXPAND_NORMAL);
6f428e8b 4164 }
4165
6ac5504b 4166#if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
53800dbe 4167 {
0cd832f0 4168 rtx arg1_rtx, arg2_rtx, arg3_rtx;
53800dbe 4169 rtx result;
0cd832f0 4170 rtx insn;
c2f47e15 4171 tree arg1 = CALL_EXPR_ARG (exp, 0);
4172 tree arg2 = CALL_EXPR_ARG (exp, 1);
4173 tree len = CALL_EXPR_ARG (exp, 2);
53800dbe 4174
4175 int arg1_align
4176 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4177 int arg2_align
4178 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
b428c0a5 4179 enum machine_mode insn_mode;
4180
4181#ifdef HAVE_cmpmemsi
4182 if (HAVE_cmpmemsi)
4183 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
4184 else
4185#endif
6ac5504b 4186#ifdef HAVE_cmpstrnsi
4187 if (HAVE_cmpstrnsi)
4188 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
b428c0a5 4189 else
4190#endif
c2f47e15 4191 return NULL_RTX;
53800dbe 4192
4193 /* If we don't have POINTER_TYPE, call the function. */
4194 if (arg1_align == 0 || arg2_align == 0)
c2f47e15 4195 return NULL_RTX;
53800dbe 4196
4197 /* Make a place to write the result of the instruction. */
4198 result = target;
4199 if (! (result != 0
8ad4c111 4200 && REG_P (result) && GET_MODE (result) == insn_mode
53800dbe 4201 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4202 result = gen_reg_rtx (insn_mode);
4203
d8ae1baa 4204 arg1_rtx = get_memory_rtx (arg1, len);
4205 arg2_rtx = get_memory_rtx (arg2, len);
7c1ab261 4206 arg3_rtx = expand_normal (fold_convert (sizetype, len));
83f88f8e 4207
4208 /* Set MEM_SIZE as appropriate. */
971ba038 4209 if (CONST_INT_P (arg3_rtx))
83f88f8e 4210 {
4211 set_mem_size (arg1_rtx, arg3_rtx);
4212 set_mem_size (arg2_rtx, arg3_rtx);
4213 }
4214
b428c0a5 4215#ifdef HAVE_cmpmemsi
4216 if (HAVE_cmpmemsi)
4217 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4218 GEN_INT (MIN (arg1_align, arg2_align)));
0cd832f0 4219 else
b428c0a5 4220#endif
6ac5504b 4221#ifdef HAVE_cmpstrnsi
4222 if (HAVE_cmpstrnsi)
4223 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4224 GEN_INT (MIN (arg1_align, arg2_align)));
b428c0a5 4225 else
4226#endif
64db345d 4227 gcc_unreachable ();
0cd832f0 4228
4229 if (insn)
4230 emit_insn (insn);
4231 else
2dd6f9ed 4232 emit_library_call_value (memcmp_libfunc, result, LCT_PURE,
0cd832f0 4233 TYPE_MODE (integer_type_node), 3,
4234 XEXP (arg1_rtx, 0), Pmode,
4235 XEXP (arg2_rtx, 0), Pmode,
4236 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
78a8ed03 4237 TYPE_UNSIGNED (sizetype)),
0cd832f0 4238 TYPE_MODE (sizetype));
53800dbe 4239
4240 /* Return the value in the proper mode for this function. */
4241 mode = TYPE_MODE (TREE_TYPE (exp));
4242 if (GET_MODE (result) == mode)
4243 return result;
4244 else if (target != 0)
4245 {
4246 convert_move (target, result, 0);
4247 return target;
4248 }
4249 else
4250 return convert_to_mode (mode, result, 0);
4251 }
83d79705 4252#endif
53800dbe 4253
c2f47e15 4254 return NULL_RTX;
6f428e8b 4255}
4256
c2f47e15 4257/* Expand expression EXP, which is a call to the strcmp builtin. Return NULL_RTX
53800dbe 4258 if we failed the caller should emit a normal call, otherwise try to get
4259 the result in TARGET, if convenient. */
902de8ed 4260
53800dbe 4261static rtx
aecda0d6 4262expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
53800dbe 4263{
c2f47e15 4264 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4265 return NULL_RTX;
218bc19e 4266 else
ef6c187e 4267 {
c2f47e15 4268 tree result = fold_builtin_strcmp (CALL_EXPR_ARG (exp, 0),
4269 CALL_EXPR_ARG (exp, 1));
218bc19e 4270 if (result)
4271 return expand_expr (result, target, mode, EXPAND_NORMAL);
ef6c187e 4272 }
bf8e3599 4273
6ac5504b 4274#if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
4275 if (cmpstr_optab[SImode] != CODE_FOR_nothing
4276 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
4277 {
4278 rtx arg1_rtx, arg2_rtx;
4279 rtx result, insn = NULL_RTX;
4280 tree fndecl, fn;
c2f47e15 4281 tree arg1 = CALL_EXPR_ARG (exp, 0);
4282 tree arg2 = CALL_EXPR_ARG (exp, 1);
a0c938f0 4283
6ac5504b 4284 int arg1_align
4285 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4286 int arg2_align
4287 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4288
4289 /* If we don't have POINTER_TYPE, call the function. */
4290 if (arg1_align == 0 || arg2_align == 0)
c2f47e15 4291 return NULL_RTX;
7a3f89b5 4292
6ac5504b 4293 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
4294 arg1 = builtin_save_expr (arg1);
4295 arg2 = builtin_save_expr (arg2);
7a3f89b5 4296
d8ae1baa 4297 arg1_rtx = get_memory_rtx (arg1, NULL);
4298 arg2_rtx = get_memory_rtx (arg2, NULL);
53800dbe 4299
6ac5504b 4300#ifdef HAVE_cmpstrsi
4301 /* Try to call cmpstrsi. */
4302 if (HAVE_cmpstrsi)
4303 {
a0c938f0 4304 enum machine_mode insn_mode
6ac5504b 4305 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
4306
4307 /* Make a place to write the result of the instruction. */
4308 result = target;
4309 if (! (result != 0
4310 && REG_P (result) && GET_MODE (result) == insn_mode
4311 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4312 result = gen_reg_rtx (insn_mode);
4313
4314 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
4315 GEN_INT (MIN (arg1_align, arg2_align)));
4316 }
4317#endif
03fd9d2c 4318#ifdef HAVE_cmpstrnsi
6ac5504b 4319 /* Try to determine at least one length and call cmpstrnsi. */
a0c938f0 4320 if (!insn && HAVE_cmpstrnsi)
6ac5504b 4321 {
4322 tree len;
4323 rtx arg3_rtx;
4324
a0c938f0 4325 enum machine_mode insn_mode
6ac5504b 4326 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
4327 tree len1 = c_strlen (arg1, 1);
4328 tree len2 = c_strlen (arg2, 1);
4329
4330 if (len1)
4331 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
4332 if (len2)
4333 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
4334
4335 /* If we don't have a constant length for the first, use the length
4336 of the second, if we know it. We don't require a constant for
4337 this case; some cost analysis could be done if both are available
4338 but neither is constant. For now, assume they're equally cheap,
4339 unless one has side effects. If both strings have constant lengths,
4340 use the smaller. */
4341
4342 if (!len1)
4343 len = len2;
4344 else if (!len2)
4345 len = len1;
4346 else if (TREE_SIDE_EFFECTS (len1))
4347 len = len2;
4348 else if (TREE_SIDE_EFFECTS (len2))
4349 len = len1;
4350 else if (TREE_CODE (len1) != INTEGER_CST)
4351 len = len2;
4352 else if (TREE_CODE (len2) != INTEGER_CST)
4353 len = len1;
4354 else if (tree_int_cst_lt (len1, len2))
4355 len = len1;
4356 else
4357 len = len2;
4358
4359 /* If both arguments have side effects, we cannot optimize. */
4360 if (!len || TREE_SIDE_EFFECTS (len))
6b961939 4361 goto do_libcall;
53800dbe 4362
8ec3c5c2 4363 arg3_rtx = expand_normal (len);
902de8ed 4364
6ac5504b 4365 /* Make a place to write the result of the instruction. */
4366 result = target;
4367 if (! (result != 0
4368 && REG_P (result) && GET_MODE (result) == insn_mode
4369 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4370 result = gen_reg_rtx (insn_mode);
53800dbe 4371
6ac5504b 4372 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4373 GEN_INT (MIN (arg1_align, arg2_align)));
4374 }
4375#endif
3f8aefe2 4376
6ac5504b 4377 if (insn)
4378 {
4379 emit_insn (insn);
3f8aefe2 4380
6ac5504b 4381 /* Return the value in the proper mode for this function. */
4382 mode = TYPE_MODE (TREE_TYPE (exp));
4383 if (GET_MODE (result) == mode)
4384 return result;
4385 if (target == 0)
4386 return convert_to_mode (mode, result, 0);
4387 convert_move (target, result, 0);
4388 return target;
4389 }
902de8ed 4390
6ac5504b 4391 /* Expand the library call ourselves using a stabilized argument
4392 list to avoid re-evaluating the function's arguments twice. */
2694880e 4393#ifdef HAVE_cmpstrnsi
6b961939 4394 do_libcall:
2694880e 4395#endif
6ac5504b 4396 fndecl = get_callee_fndecl (exp);
c2f47e15 4397 fn = build_call_expr (fndecl, 2, arg1, arg2);
6ac5504b 4398 if (TREE_CODE (fn) == CALL_EXPR)
4399 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4400 return expand_call (fn, target, target == const0_rtx);
4401 }
7a3f89b5 4402#endif
c2f47e15 4403 return NULL_RTX;
83d79705 4404}
53800dbe 4405
c2f47e15 4406/* Expand expression EXP, which is a call to the strncmp builtin. Return
4407 NULL_RTX if we failed the caller should emit a normal call, otherwise try to get
ed09096d 4408 the result in TARGET, if convenient. */
27d0c333 4409
ed09096d 4410static rtx
aecda0d6 4411expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
ed09096d 4412{
c2f47e15 4413 if (!validate_arglist (exp,
4414 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4415 return NULL_RTX;
218bc19e 4416 else
ef6c187e 4417 {
c2f47e15 4418 tree result = fold_builtin_strncmp (CALL_EXPR_ARG (exp, 0),
4419 CALL_EXPR_ARG (exp, 1),
4420 CALL_EXPR_ARG (exp, 2));
218bc19e 4421 if (result)
4422 return expand_expr (result, target, mode, EXPAND_NORMAL);
ef6c187e 4423 }
ed09096d 4424
6e34e617 4425 /* If c_strlen can determine an expression for one of the string
6ac5504b 4426 lengths, and it doesn't have side effects, then emit cmpstrnsi
7a3f89b5 4427 using length MIN(strlen(string)+1, arg3). */
6ac5504b 4428#ifdef HAVE_cmpstrnsi
4429 if (HAVE_cmpstrnsi)
7a3f89b5 4430 {
4431 tree len, len1, len2;
4432 rtx arg1_rtx, arg2_rtx, arg3_rtx;
4433 rtx result, insn;
0b25db21 4434 tree fndecl, fn;
c2f47e15 4435 tree arg1 = CALL_EXPR_ARG (exp, 0);
4436 tree arg2 = CALL_EXPR_ARG (exp, 1);
4437 tree arg3 = CALL_EXPR_ARG (exp, 2);
6f428e8b 4438
7a3f89b5 4439 int arg1_align
4440 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4441 int arg2_align
4442 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4443 enum machine_mode insn_mode
6ac5504b 4444 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
bf8e3599 4445
681fab1e 4446 len1 = c_strlen (arg1, 1);
4447 len2 = c_strlen (arg2, 1);
7a3f89b5 4448
4449 if (len1)
4450 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
4451 if (len2)
4452 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
4453
4454 /* If we don't have a constant length for the first, use the length
4455 of the second, if we know it. We don't require a constant for
4456 this case; some cost analysis could be done if both are available
4457 but neither is constant. For now, assume they're equally cheap,
4458 unless one has side effects. If both strings have constant lengths,
4459 use the smaller. */
4460
4461 if (!len1)
4462 len = len2;
4463 else if (!len2)
4464 len = len1;
4465 else if (TREE_SIDE_EFFECTS (len1))
4466 len = len2;
4467 else if (TREE_SIDE_EFFECTS (len2))
4468 len = len1;
4469 else if (TREE_CODE (len1) != INTEGER_CST)
4470 len = len2;
4471 else if (TREE_CODE (len2) != INTEGER_CST)
4472 len = len1;
4473 else if (tree_int_cst_lt (len1, len2))
4474 len = len1;
4475 else
4476 len = len2;
6e34e617 4477
7a3f89b5 4478 /* If both arguments have side effects, we cannot optimize. */
4479 if (!len || TREE_SIDE_EFFECTS (len))
c2f47e15 4480 return NULL_RTX;
bf8e3599 4481
7a3f89b5 4482 /* The actual new length parameter is MIN(len,arg3). */
49d00087 4483 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
4484 fold_convert (TREE_TYPE (len), arg3));
7a3f89b5 4485
4486 /* If we don't have POINTER_TYPE, call the function. */
4487 if (arg1_align == 0 || arg2_align == 0)
c2f47e15 4488 return NULL_RTX;
7a3f89b5 4489
4490 /* Make a place to write the result of the instruction. */
4491 result = target;
4492 if (! (result != 0
8ad4c111 4493 && REG_P (result) && GET_MODE (result) == insn_mode
7a3f89b5 4494 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4495 result = gen_reg_rtx (insn_mode);
4496
6ac5504b 4497 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
4ee9c684 4498 arg1 = builtin_save_expr (arg1);
4499 arg2 = builtin_save_expr (arg2);
4500 len = builtin_save_expr (len);
3f8aefe2 4501
d8ae1baa 4502 arg1_rtx = get_memory_rtx (arg1, len);
4503 arg2_rtx = get_memory_rtx (arg2, len);
8ec3c5c2 4504 arg3_rtx = expand_normal (len);
6ac5504b 4505 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4506 GEN_INT (MIN (arg1_align, arg2_align)));
3f8aefe2 4507 if (insn)
4508 {
4509 emit_insn (insn);
4510
4511 /* Return the value in the proper mode for this function. */
4512 mode = TYPE_MODE (TREE_TYPE (exp));
4513 if (GET_MODE (result) == mode)
4514 return result;
4515 if (target == 0)
4516 return convert_to_mode (mode, result, 0);
4517 convert_move (target, result, 0);
4518 return target;
4519 }
7a3f89b5 4520
3f8aefe2 4521 /* Expand the library call ourselves using a stabilized argument
4522 list to avoid re-evaluating the function's arguments twice. */
3f8aefe2 4523 fndecl = get_callee_fndecl (exp);
c2f47e15 4524 fn = build_call_expr (fndecl, 3, arg1, arg2, len);
0b25db21 4525 if (TREE_CODE (fn) == CALL_EXPR)
4526 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4527 return expand_call (fn, target, target == const0_rtx);
7a3f89b5 4528 }
4529#endif
c2f47e15 4530 return NULL_RTX;
ed09096d 4531}
4532
49f0327b 4533/* Expand expression EXP, which is a call to the strcat builtin.
c2f47e15 4534 Return NULL_RTX if we failed the caller should emit a normal call,
49f0327b 4535 otherwise try to get the result in TARGET, if convenient. */
27d0c333 4536
49f0327b 4537static rtx
c2f47e15 4538expand_builtin_strcat (tree fndecl, tree exp, rtx target, enum machine_mode mode)
49f0327b 4539{
c2f47e15 4540 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4541 return NULL_RTX;
49f0327b 4542 else
4543 {
c2f47e15 4544 tree dst = CALL_EXPR_ARG (exp, 0);
4545 tree src = CALL_EXPR_ARG (exp, 1);
49f0327b 4546 const char *p = c_getstr (src);
4547
1d89860b 4548 /* If the string length is zero, return the dst parameter. */
a0c938f0 4549 if (p && *p == '\0')
1d89860b 4550 return expand_expr (dst, target, mode, EXPAND_NORMAL);
a0c938f0 4551
a0d18cec 4552 if (optimize_insn_for_speed_p ())
ca71f89b 4553 {
1d89860b 4554 /* See if we can store by pieces into (dst + strlen(dst)). */
4555 tree newsrc, newdst,
4556 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4557 rtx insns;
4558
4559 /* Stabilize the argument list. */
4560 newsrc = builtin_save_expr (src);
1d89860b 4561 dst = builtin_save_expr (dst);
4562
4563 start_sequence ();
4564
4565 /* Create strlen (dst). */
c2f47e15 4566 newdst = build_call_expr (strlen_fn, 1, dst);
0de36bdb 4567 /* Create (dst p+ strlen (dst)). */
1d89860b 4568
0de36bdb 4569 newdst = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
1d89860b 4570 newdst = builtin_save_expr (newdst);
1d89860b 4571
c2f47e15 4572 if (!expand_builtin_strcpy_args (fndecl, newdst, newsrc, target, mode))
ca71f89b 4573 {
1d89860b 4574 end_sequence (); /* Stop sequence. */
c2f47e15 4575 return NULL_RTX;
ca71f89b 4576 }
a0c938f0 4577
1d89860b 4578 /* Output the entire sequence. */
4579 insns = get_insns ();
4580 end_sequence ();
4581 emit_insn (insns);
a0c938f0 4582
1d89860b 4583 return expand_expr (dst, target, mode, EXPAND_NORMAL);
ca71f89b 4584 }
49f0327b 4585
c2f47e15 4586 return NULL_RTX;
49f0327b 4587 }
4588}
4589
4590/* Expand expression EXP, which is a call to the strncat builtin.
c2f47e15 4591 Return NULL_RTX if we failed the caller should emit a normal call,
49f0327b 4592 otherwise try to get the result in TARGET, if convenient. */
27d0c333 4593
49f0327b 4594static rtx
c2f47e15 4595expand_builtin_strncat (tree exp, rtx target, enum machine_mode mode)
49f0327b 4596{
c2f47e15 4597 if (validate_arglist (exp,
4598 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
49f0327b 4599 {
c2f47e15 4600 tree result = fold_builtin_strncat (CALL_EXPR_ARG (exp, 0),
4601 CALL_EXPR_ARG (exp, 1),
4602 CALL_EXPR_ARG (exp, 2));
2c84ee37 4603 if (result)
4604 return expand_expr (result, target, mode, EXPAND_NORMAL);
49f0327b 4605 }
c2f47e15 4606 return NULL_RTX;
49f0327b 4607}
4608
4609/* Expand expression EXP, which is a call to the strspn builtin.
c2f47e15 4610 Return NULL_RTX if we failed the caller should emit a normal call,
49f0327b 4611 otherwise try to get the result in TARGET, if convenient. */
27d0c333 4612
49f0327b 4613static rtx
c2f47e15 4614expand_builtin_strspn (tree exp, rtx target, enum machine_mode mode)
49f0327b 4615{
c2f47e15 4616 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
49f0327b 4617 {
c2f47e15 4618 tree result = fold_builtin_strspn (CALL_EXPR_ARG (exp, 0),
4619 CALL_EXPR_ARG (exp, 1));
2c84ee37 4620 if (result)
4621 return expand_expr (result, target, mode, EXPAND_NORMAL);
49f0327b 4622 }
c2f47e15 4623 return NULL_RTX;
49f0327b 4624}
4625
4626/* Expand expression EXP, which is a call to the strcspn builtin.
c2f47e15 4627 Return NULL_RTX if we failed the caller should emit a normal call,
49f0327b 4628 otherwise try to get the result in TARGET, if convenient. */
27d0c333 4629
49f0327b 4630static rtx
c2f47e15 4631expand_builtin_strcspn (tree exp, rtx target, enum machine_mode mode)
49f0327b 4632{
c2f47e15 4633 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
49f0327b 4634 {
c2f47e15 4635 tree result = fold_builtin_strcspn (CALL_EXPR_ARG (exp, 0),
4636 CALL_EXPR_ARG (exp, 1));
2c84ee37 4637 if (result)
4638 return expand_expr (result, target, mode, EXPAND_NORMAL);
49f0327b 4639 }
c2f47e15 4640 return NULL_RTX;
49f0327b 4641}
4642
a66c9326 4643/* Expand a call to __builtin_saveregs, generating the result in TARGET,
4644 if that's convenient. */
902de8ed 4645
a66c9326 4646rtx
aecda0d6 4647expand_builtin_saveregs (void)
53800dbe 4648{
a66c9326 4649 rtx val, seq;
53800dbe 4650
4651 /* Don't do __builtin_saveregs more than once in a function.
4652 Save the result of the first call and reuse it. */
4653 if (saveregs_value != 0)
4654 return saveregs_value;
53800dbe 4655
a66c9326 4656 /* When this function is called, it means that registers must be
4657 saved on entry to this function. So we migrate the call to the
4658 first insn of this function. */
4659
4660 start_sequence ();
53800dbe 4661
a66c9326 4662 /* Do whatever the machine needs done in this case. */
45550790 4663 val = targetm.calls.expand_builtin_saveregs ();
53800dbe 4664
a66c9326 4665 seq = get_insns ();
4666 end_sequence ();
53800dbe 4667
a66c9326 4668 saveregs_value = val;
53800dbe 4669
31d3e01c 4670 /* Put the insns after the NOTE that starts the function. If this
4671 is inside a start_sequence, make the outer-level insn chain current, so
a66c9326 4672 the code is placed at the start of the function. */
4673 push_topmost_sequence ();
0ec80471 4674 emit_insn_after (seq, entry_of_function ());
a66c9326 4675 pop_topmost_sequence ();
4676
4677 return val;
53800dbe 4678}
4679
4680/* __builtin_args_info (N) returns word N of the arg space info
4681 for the current function. The number and meanings of words
4682 is controlled by the definition of CUMULATIVE_ARGS. */
f7c44134 4683
53800dbe 4684static rtx
c2f47e15 4685expand_builtin_args_info (tree exp)
53800dbe 4686{
53800dbe 4687 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
abe32cce 4688 int *word_ptr = (int *) &crtl->args.info;
53800dbe 4689
64db345d 4690 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
53800dbe 4691
c2f47e15 4692 if (call_expr_nargs (exp) != 0)
53800dbe 4693 {
c2f47e15 4694 if (!host_integerp (CALL_EXPR_ARG (exp, 0), 0))
eb586f2c 4695 error ("argument of %<__builtin_args_info%> must be constant");
53800dbe 4696 else
4697 {
c2f47e15 4698 HOST_WIDE_INT wordnum = tree_low_cst (CALL_EXPR_ARG (exp, 0), 0);
53800dbe 4699
27d0c333 4700 if (wordnum < 0 || wordnum >= nwords)
eb586f2c 4701 error ("argument of %<__builtin_args_info%> out of range");
53800dbe 4702 else
4703 return GEN_INT (word_ptr[wordnum]);
4704 }
4705 }
4706 else
eb586f2c 4707 error ("missing argument in %<__builtin_args_info%>");
53800dbe 4708
4709 return const0_rtx;
53800dbe 4710}
4711
79012a9d 4712/* Expand a call to __builtin_next_arg. */
27d0c333 4713
53800dbe 4714static rtx
79012a9d 4715expand_builtin_next_arg (void)
53800dbe 4716{
79012a9d 4717 /* Checking arguments is already done in fold_builtin_next_arg
4718 that must be called before this function. */
940ddc5c 4719 return expand_binop (ptr_mode, add_optab,
abe32cce 4720 crtl->args.internal_arg_pointer,
4721 crtl->args.arg_offset_rtx,
53800dbe 4722 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4723}
4724
a66c9326 4725/* Make it easier for the backends by protecting the valist argument
4726 from multiple evaluations. */
4727
4728static tree
aecda0d6 4729stabilize_va_list (tree valist, int needs_lvalue)
a66c9326 4730{
5f57a8b1 4731 tree vatype = targetm.canonical_va_list_type (TREE_TYPE (valist));
4732
4733 gcc_assert (vatype != NULL_TREE);
4734
4735 if (TREE_CODE (vatype) == ARRAY_TYPE)
a66c9326 4736 {
2d47cc32 4737 if (TREE_SIDE_EFFECTS (valist))
4738 valist = save_expr (valist);
11a61dea 4739
2d47cc32 4740 /* For this case, the backends will be expecting a pointer to
5f57a8b1 4741 vatype, but it's possible we've actually been given an array
4742 (an actual TARGET_CANONICAL_VA_LIST_TYPE (valist)).
2d47cc32 4743 So fix it. */
4744 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
8a15c04a 4745 {
5f57a8b1 4746 tree p1 = build_pointer_type (TREE_TYPE (vatype));
fcdd3ab3 4747 valist = build_fold_addr_expr_with_type (valist, p1);
8a15c04a 4748 }
a66c9326 4749 }
11a61dea 4750 else
a66c9326 4751 {
2d47cc32 4752 tree pt;
11a61dea 4753
2d47cc32 4754 if (! needs_lvalue)
4755 {
11a61dea 4756 if (! TREE_SIDE_EFFECTS (valist))
4757 return valist;
bf8e3599 4758
5f57a8b1 4759 pt = build_pointer_type (vatype);
49d00087 4760 valist = fold_build1 (ADDR_EXPR, pt, valist);
a66c9326 4761 TREE_SIDE_EFFECTS (valist) = 1;
a66c9326 4762 }
2d47cc32 4763
11a61dea 4764 if (TREE_SIDE_EFFECTS (valist))
2d47cc32 4765 valist = save_expr (valist);
fcdd3ab3 4766 valist = build_fold_indirect_ref (valist);
a66c9326 4767 }
4768
4769 return valist;
4770}
4771
2e15d750 4772/* The "standard" definition of va_list is void*. */
4773
4774tree
4775std_build_builtin_va_list (void)
4776{
4777 return ptr_type_node;
4778}
4779
5f57a8b1 4780/* The "standard" abi va_list is va_list_type_node. */
4781
4782tree
4783std_fn_abi_va_list (tree fndecl ATTRIBUTE_UNUSED)
4784{
4785 return va_list_type_node;
4786}
4787
4788/* The "standard" type of va_list is va_list_type_node. */
4789
4790tree
4791std_canonical_va_list_type (tree type)
4792{
4793 tree wtype, htype;
4794
4795 if (INDIRECT_REF_P (type))
4796 type = TREE_TYPE (type);
4797 else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE(type)))
4798 type = TREE_TYPE (type);
5f57a8b1 4799 wtype = va_list_type_node;
4800 htype = type;
7b36f9ab 4801 /* Treat structure va_list types. */
4802 if (TREE_CODE (wtype) == RECORD_TYPE && POINTER_TYPE_P (htype))
4803 htype = TREE_TYPE (htype);
4804 else if (TREE_CODE (wtype) == ARRAY_TYPE)
5f57a8b1 4805 {
4806 /* If va_list is an array type, the argument may have decayed
4807 to a pointer type, e.g. by being passed to another function.
4808 In that case, unwrap both types so that we can compare the
4809 underlying records. */
4810 if (TREE_CODE (htype) == ARRAY_TYPE
4811 || POINTER_TYPE_P (htype))
4812 {
4813 wtype = TREE_TYPE (wtype);
4814 htype = TREE_TYPE (htype);
4815 }
4816 }
4817 if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
4818 return va_list_type_node;
4819
4820 return NULL_TREE;
4821}
4822
a66c9326 4823/* The "standard" implementation of va_start: just assign `nextarg' to
4824 the variable. */
27d0c333 4825
a66c9326 4826void
aecda0d6 4827std_expand_builtin_va_start (tree valist, rtx nextarg)
a66c9326 4828{
f03c17bc 4829 rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
4830 convert_move (va_r, nextarg, 0);
a66c9326 4831}
4832
c2f47e15 4833/* Expand EXP, a call to __builtin_va_start. */
27d0c333 4834
a66c9326 4835static rtx
c2f47e15 4836expand_builtin_va_start (tree exp)
a66c9326 4837{
4838 rtx nextarg;
c2f47e15 4839 tree valist;
a66c9326 4840
c2f47e15 4841 if (call_expr_nargs (exp) < 2)
cb166087 4842 {
4843 error ("too few arguments to function %<va_start%>");
4844 return const0_rtx;
4845 }
a66c9326 4846
c2f47e15 4847 if (fold_builtin_next_arg (exp, true))
79012a9d 4848 return const0_rtx;
7c2f0500 4849
79012a9d 4850 nextarg = expand_builtin_next_arg ();
c2f47e15 4851 valist = stabilize_va_list (CALL_EXPR_ARG (exp, 0), 1);
a66c9326 4852
8a58ed0a 4853 if (targetm.expand_builtin_va_start)
4854 targetm.expand_builtin_va_start (valist, nextarg);
4855 else
4856 std_expand_builtin_va_start (valist, nextarg);
a66c9326 4857
4858 return const0_rtx;
4859}
4860
a66c9326 4861/* The "standard" implementation of va_arg: read the value from the
4862 current (padded) address and increment by the (padded) size. */
f7c44134 4863
e0eca1fa 4864tree
75a70cf9 4865std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
4866 gimple_seq *post_p)
fcdd3ab3 4867{
52cc2eeb 4868 tree addr, t, type_size, rounded_size, valist_tmp;
b8e8e485 4869 unsigned HOST_WIDE_INT align, boundary;
bef380a4 4870 bool indirect;
52cc2eeb 4871
4872#ifdef ARGS_GROW_DOWNWARD
4873 /* All of the alignment and movement below is for args-grow-up machines.
4874 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4875 implement their own specialized gimplify_va_arg_expr routines. */
64db345d 4876 gcc_unreachable ();
52cc2eeb 4877#endif
fcdd3ab3 4878
bef380a4 4879 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4880 if (indirect)
4881 type = build_pointer_type (type);
4882
52cc2eeb 4883 align = PARM_BOUNDARY / BITS_PER_UNIT;
c8b779eb 4884 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
4885
4886 /* When we align parameter on stack for caller, if the parameter
befa808c 4887 alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
4888 aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
c8b779eb 4889 here with caller. */
befa808c 4890 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
4891 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
c8b779eb 4892
4893 boundary /= BITS_PER_UNIT;
fcdd3ab3 4894
52cc2eeb 4895 /* Hoist the valist value into a temporary for the moment. */
ecdeeb37 4896 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4897
fcdd3ab3 4898 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4899 requires greater alignment, we must perform dynamic alignment. */
85c1f587 4900 if (boundary > align
4901 && !integer_zerop (TYPE_SIZE (type)))
fcdd3ab3 4902 {
41076ef6 4903 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
0de36bdb 4904 fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (valist),
4905 valist_tmp, size_int (boundary - 1)));
52cc2eeb 4906 gimplify_and_add (t, pre_p);
4907
0de36bdb 4908 t = fold_convert (sizetype, valist_tmp);
41076ef6 4909 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
0de36bdb 4910 fold_convert (TREE_TYPE (valist),
4911 fold_build2 (BIT_AND_EXPR, sizetype, t,
4912 size_int (-boundary))));
ecdeeb37 4913 gimplify_and_add (t, pre_p);
fcdd3ab3 4914 }
c5dc0c32 4915 else
4916 boundary = align;
4917
4918 /* If the actual alignment is less than the alignment of the type,
4919 adjust the type accordingly so that we don't assume strict alignment
f0b5f617 4920 when dereferencing the pointer. */
c5dc0c32 4921 boundary *= BITS_PER_UNIT;
4922 if (boundary < TYPE_ALIGN (type))
4923 {
4924 type = build_variant_type_copy (type);
4925 TYPE_ALIGN (type) = boundary;
4926 }
fcdd3ab3 4927
bcff3604 4928 /* Compute the rounded size of the type. */
52cc2eeb 4929 type_size = size_in_bytes (type);
4930 rounded_size = round_up (type_size, align);
4931
fcdd3ab3 4932 /* Reduce rounded_size so it's sharable with the postqueue. */
4933 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4934
4935 /* Get AP. */
ecdeeb37 4936 addr = valist_tmp;
52cc2eeb 4937 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
fcdd3ab3 4938 {
4939 /* Small args are padded downward. */
49d00087 4940 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4941 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4942 size_binop (MINUS_EXPR, rounded_size, type_size));
0de36bdb 4943 addr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (addr), addr, t);
fcdd3ab3 4944 }
4945
fcdd3ab3 4946 /* Compute new value for AP. */
0de36bdb 4947 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (valist), valist_tmp, rounded_size);
41076ef6 4948 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
ecdeeb37 4949 gimplify_and_add (t, pre_p);
e0eca1fa 4950
4951 addr = fold_convert (build_pointer_type (type), addr);
fcdd3ab3 4952
bef380a4 4953 if (indirect)
f2462d6c 4954 addr = build_va_arg_indirect_ref (addr);
4955
4956 return build_va_arg_indirect_ref (addr);
4957}
a0930a69 4958
f2462d6c 4959/* Build an indirect-ref expression over the given TREE, which represents a
4960 piece of a va_arg() expansion. */
4961tree
4962build_va_arg_indirect_ref (tree addr)
4963{
a0930a69 4964 addr = build_fold_indirect_ref (addr);
f2462d6c 4965
a0930a69 4966 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4967 mf_mark (addr);
bef380a4 4968
a0930a69 4969 return addr;
433006a9 4970}
4971
fcdd3ab3 4972/* Return a dummy expression of type TYPE in order to keep going after an
4973 error. */
4974
4975static tree
4976dummy_object (tree type)
4977{
535664e3 4978 tree t = build_int_cst (build_pointer_type (type), 0);
fcdd3ab3 4979 return build1 (INDIRECT_REF, type, t);
4980}
4981
2799a2b7 4982/* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4983 builtin function, but a very special sort of operator. */
fcdd3ab3 4984
4985enum gimplify_status
75a70cf9 4986gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
fcdd3ab3 4987{
5f57a8b1 4988 tree promoted_type, have_va_type;
fcdd3ab3 4989 tree valist = TREE_OPERAND (*expr_p, 0);
4990 tree type = TREE_TYPE (*expr_p);
4991 tree t;
e60a6f7b 4992 location_t loc = EXPR_HAS_LOCATION (*expr_p) ? EXPR_LOCATION (*expr_p) :
4993 UNKNOWN_LOCATION;
fcdd3ab3 4994
4995 /* Verify that valist is of the proper type. */
fcdd3ab3 4996 have_va_type = TREE_TYPE (valist);
f43dda35 4997 if (have_va_type == error_mark_node)
4998 return GS_ERROR;
5f57a8b1 4999 have_va_type = targetm.canonical_va_list_type (have_va_type);
f43dda35 5000
5f57a8b1 5001 if (have_va_type == NULL_TREE)
fcdd3ab3 5002 {
e60a6f7b 5003 error_at (loc, "first argument to %<va_arg%> not of type %<va_list%>");
e0eca1fa 5004 return GS_ERROR;
fcdd3ab3 5005 }
5006
5007 /* Generate a diagnostic for requesting data of a type that cannot
5008 be passed through `...' due to type promotion at the call site. */
5f57a8b1 5009 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
fcdd3ab3 5010 != type)
5011 {
5012 static bool gave_help;
a52d5726 5013 bool warned;
fcdd3ab3 5014
5015 /* Unfortunately, this is merely undefined, rather than a constraint
5016 violation, so we cannot make this an error. If this call is never
5017 executed, the program is still strictly conforming. */
e60a6f7b 5018 warned = warning_at (loc, 0,
5019 "%qT is promoted to %qT when passed through %<...%>",
5020 type, promoted_type);
a52d5726 5021 if (!gave_help && warned)
fcdd3ab3 5022 {
5023 gave_help = true;
e60a6f7b 5024 inform (loc, "(so you should pass %qT not %qT to %<va_arg%>)",
5025 promoted_type, type);
fcdd3ab3 5026 }
5027
5028 /* We can, however, treat "undefined" any way we please.
5029 Call abort to encourage the user to fix the program. */
a52d5726 5030 if (warned)
e60a6f7b 5031 inform (loc, "if this code is reached, the program will abort");
ad0e7a06 5032 /* Before the abort, allow the evaluation of the va_list
5033 expression to exit or longjmp. */
5034 gimplify_and_add (valist, pre_p);
c2f47e15 5035 t = build_call_expr (implicit_built_in_decls[BUILT_IN_TRAP], 0);
75a70cf9 5036 gimplify_and_add (t, pre_p);
fcdd3ab3 5037
5038 /* This is dead code, but go ahead and finish so that the
5039 mode of the result comes out right. */
5040 *expr_p = dummy_object (type);
5041 return GS_ALL_DONE;
5042 }
5043 else
5044 {
5045 /* Make it easier for the backends by protecting the valist argument
a0c938f0 5046 from multiple evaluations. */
5f57a8b1 5047 if (TREE_CODE (have_va_type) == ARRAY_TYPE)
e0eca1fa 5048 {
5049 /* For this case, the backends will be expecting a pointer to
5f57a8b1 5050 TREE_TYPE (abi), but it's possible we've
5051 actually been given an array (an actual TARGET_FN_ABI_VA_LIST).
e0eca1fa 5052 So fix it. */
5053 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
5054 {
5f57a8b1 5055 tree p1 = build_pointer_type (TREE_TYPE (have_va_type));
bab5904e 5056 valist = fold_convert (p1, build_fold_addr_expr (valist));
e0eca1fa 5057 }
75a70cf9 5058
e0eca1fa 5059 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
5060 }
5061 else
5062 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
fcdd3ab3 5063
17a6380d 5064 if (!targetm.gimplify_va_arg_expr)
75a70cf9 5065 /* FIXME: Once most targets are converted we should merely
89f18f73 5066 assert this is non-null. */
fcdd3ab3 5067 return GS_ALL_DONE;
5068
17a6380d 5069 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
fcdd3ab3 5070 return GS_OK;
5071 }
5072}
5073
c2f47e15 5074/* Expand EXP, a call to __builtin_va_end. */
f7c44134 5075
a66c9326 5076static rtx
c2f47e15 5077expand_builtin_va_end (tree exp)
a66c9326 5078{
c2f47e15 5079 tree valist = CALL_EXPR_ARG (exp, 0);
8a15c04a 5080
8a15c04a 5081 /* Evaluate for side effects, if needed. I hate macros that don't
5082 do that. */
5083 if (TREE_SIDE_EFFECTS (valist))
5084 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
a66c9326 5085
5086 return const0_rtx;
5087}
5088
c2f47e15 5089/* Expand EXP, a call to __builtin_va_copy. We do this as a
a66c9326 5090 builtin rather than just as an assignment in stdarg.h because of the
5091 nastiness of array-type va_list types. */
f7c44134 5092
a66c9326 5093static rtx
c2f47e15 5094expand_builtin_va_copy (tree exp)
a66c9326 5095{
5096 tree dst, src, t;
5097
c2f47e15 5098 dst = CALL_EXPR_ARG (exp, 0);
5099 src = CALL_EXPR_ARG (exp, 1);
a66c9326 5100
5101 dst = stabilize_va_list (dst, 1);
5102 src = stabilize_va_list (src, 0);
5103
5f57a8b1 5104 gcc_assert (cfun != NULL && cfun->decl != NULL_TREE);
5105
5106 if (TREE_CODE (targetm.fn_abi_va_list (cfun->decl)) != ARRAY_TYPE)
a66c9326 5107 {
5f57a8b1 5108 t = build2 (MODIFY_EXPR, targetm.fn_abi_va_list (cfun->decl), dst, src);
a66c9326 5109 TREE_SIDE_EFFECTS (t) = 1;
5110 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5111 }
5112 else
5113 {
11a61dea 5114 rtx dstb, srcb, size;
5115
5116 /* Evaluate to pointers. */
5117 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
5118 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
5f57a8b1 5119 size = expand_expr (TYPE_SIZE_UNIT (targetm.fn_abi_va_list (cfun->decl)),
5120 NULL_RTX, VOIDmode, EXPAND_NORMAL);
11a61dea 5121
85d654dd 5122 dstb = convert_memory_address (Pmode, dstb);
5123 srcb = convert_memory_address (Pmode, srcb);
726ec87c 5124
11a61dea 5125 /* "Dereference" to BLKmode memories. */
5126 dstb = gen_rtx_MEM (BLKmode, dstb);
ab6ab77e 5127 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
5f57a8b1 5128 set_mem_align (dstb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
11a61dea 5129 srcb = gen_rtx_MEM (BLKmode, srcb);
ab6ab77e 5130 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
5f57a8b1 5131 set_mem_align (srcb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
11a61dea 5132
5133 /* Copy. */
0378dbdc 5134 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
a66c9326 5135 }
5136
5137 return const0_rtx;
5138}
5139
53800dbe 5140/* Expand a call to one of the builtin functions __builtin_frame_address or
5141 __builtin_return_address. */
27d0c333 5142
53800dbe 5143static rtx
c2f47e15 5144expand_builtin_frame_address (tree fndecl, tree exp)
53800dbe 5145{
53800dbe 5146 /* The argument must be a nonnegative integer constant.
5147 It counts the number of frames to scan up the stack.
5148 The value is the return address saved in that frame. */
c2f47e15 5149 if (call_expr_nargs (exp) == 0)
53800dbe 5150 /* Warning about missing arg was already issued. */
5151 return const0_rtx;
c2f47e15 5152 else if (! host_integerp (CALL_EXPR_ARG (exp, 0), 1))
53800dbe 5153 {
5154 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
07e3a3d2 5155 error ("invalid argument to %<__builtin_frame_address%>");
53800dbe 5156 else
07e3a3d2 5157 error ("invalid argument to %<__builtin_return_address%>");
53800dbe 5158 return const0_rtx;
5159 }
5160 else
5161 {
27d0c333 5162 rtx tem
5163 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
c2f47e15 5164 tree_low_cst (CALL_EXPR_ARG (exp, 0), 1));
53800dbe 5165
5166 /* Some ports cannot access arbitrary stack frames. */
5167 if (tem == NULL)
5168 {
5169 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
c3ceba8e 5170 warning (0, "unsupported argument to %<__builtin_frame_address%>");
53800dbe 5171 else
c3ceba8e 5172 warning (0, "unsupported argument to %<__builtin_return_address%>");
53800dbe 5173 return const0_rtx;
5174 }
5175
5176 /* For __builtin_frame_address, return what we've got. */
5177 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
5178 return tem;
5179
8ad4c111 5180 if (!REG_P (tem)
53800dbe 5181 && ! CONSTANT_P (tem))
5182 tem = copy_to_mode_reg (Pmode, tem);
5183 return tem;
5184 }
5185}
5186
c2f47e15 5187/* Expand EXP, a call to the alloca builtin. Return NULL_RTX if
53800dbe 5188 we failed and the caller should emit a normal call, otherwise try to get
5189 the result in TARGET, if convenient. */
15c6cf6b 5190
53800dbe 5191static rtx
c2f47e15 5192expand_builtin_alloca (tree exp, rtx target)
53800dbe 5193{
5194 rtx op0;
15c6cf6b 5195 rtx result;
53800dbe 5196
f9fa0459 5197 /* Emit normal call if marked not-inlineable. */
5198 if (CALL_CANNOT_INLINE_P (exp))
c2f47e15 5199 return NULL_RTX;
4ee9c684 5200
c2f47e15 5201 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5202 return NULL_RTX;
53800dbe 5203
5204 /* Compute the argument. */
c2f47e15 5205 op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
53800dbe 5206
5207 /* Allocate the desired space. */
15c6cf6b 5208 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
85d654dd 5209 result = convert_memory_address (ptr_mode, result);
15c6cf6b 5210
5211 return result;
53800dbe 5212}
5213
c2f47e15 5214/* Expand a call to a bswap builtin with argument ARG0. MODE
42791117 5215 is the mode to expand with. */
5216
5217static rtx
c2f47e15 5218expand_builtin_bswap (tree exp, rtx target, rtx subtarget)
42791117 5219{
5220 enum machine_mode mode;
5221 tree arg;
5222 rtx op0;
5223
c2f47e15 5224 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5225 return NULL_RTX;
42791117 5226
c2f47e15 5227 arg = CALL_EXPR_ARG (exp, 0);
42791117 5228 mode = TYPE_MODE (TREE_TYPE (arg));
1db6d067 5229 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
42791117 5230
5231 target = expand_unop (mode, bswap_optab, op0, target, 1);
5232
5233 gcc_assert (target);
5234
5235 return convert_to_mode (mode, target, 0);
5236}
5237
c2f47e15 5238/* Expand a call to a unary builtin in EXP.
5239 Return NULL_RTX if a normal call should be emitted rather than expanding the
53800dbe 5240 function in-line. If convenient, the result should be placed in TARGET.
5241 SUBTARGET may be used as the target for computing one of EXP's operands. */
15c6cf6b 5242
53800dbe 5243static rtx
c2f47e15 5244expand_builtin_unop (enum machine_mode target_mode, tree exp, rtx target,
aecda0d6 5245 rtx subtarget, optab op_optab)
53800dbe 5246{
5247 rtx op0;
c2f47e15 5248
5249 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5250 return NULL_RTX;
53800dbe 5251
5252 /* Compute the argument. */
1db6d067 5253 op0 = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
5254 VOIDmode, EXPAND_NORMAL);
6a08d0ab 5255 /* Compute op, into TARGET if possible.
53800dbe 5256 Set TARGET to wherever the result comes back. */
c2f47e15 5257 target = expand_unop (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0))),
6a08d0ab 5258 op_optab, op0, target, 1);
64db345d 5259 gcc_assert (target);
7d3f6cc7 5260
efb070c8 5261 return convert_to_mode (target_mode, target, 0);
53800dbe 5262}
89cfe6e5 5263
df94cd3b 5264/* If the string passed to fputs is a constant and is one character
2c0e001b 5265 long, we attempt to transform this call into __builtin_fputc(). */
15c6cf6b 5266
df94cd3b 5267static rtx
c2f47e15 5268expand_builtin_fputs (tree exp, rtx target, bool unlocked)
df94cd3b 5269{
2c0e001b 5270 /* Verify the arguments in the original call. */
c2f47e15 5271 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
ce1b14f4 5272 {
c2f47e15 5273 tree result = fold_builtin_fputs (CALL_EXPR_ARG (exp, 0),
5274 CALL_EXPR_ARG (exp, 1),
5275 (target == const0_rtx),
2c84ee37 5276 unlocked, NULL_TREE);
5277 if (result)
5278 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
ce1b14f4 5279 }
c2f47e15 5280 return NULL_RTX;
3311f67b 5281}
5282
5a74f77e 5283/* Expand a call to __builtin_expect. We just return our argument
5284 as the builtin_expect semantic should've been already executed by
5285 tree branch prediction pass. */
89cfe6e5 5286
5287static rtx
c2f47e15 5288expand_builtin_expect (tree exp, rtx target)
89cfe6e5 5289{
c2f47e15 5290 tree arg, c;
89cfe6e5 5291
c2f47e15 5292 if (call_expr_nargs (exp) < 2)
89cfe6e5 5293 return const0_rtx;
c2f47e15 5294 arg = CALL_EXPR_ARG (exp, 0);
5295 c = CALL_EXPR_ARG (exp, 1);
89cfe6e5 5296
c2f47e15 5297 target = expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5a74f77e 5298 /* When guessing was done, the hints should be already stripped away. */
07311427 5299 gcc_assert (!flag_guess_branch_prob
5300 || optimize == 0 || errorcount || sorrycount);
89cfe6e5 5301 return target;
5302}
689df48e 5303
c22de3f0 5304void
aecda0d6 5305expand_builtin_trap (void)
a0ef1725 5306{
5307#ifdef HAVE_trap
5308 if (HAVE_trap)
5309 emit_insn (gen_trap ());
5310 else
5311#endif
5312 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
5313 emit_barrier ();
5314}
78a74442 5315
d2b48f0c 5316/* Expand a call to __builtin_unreachable. We do nothing except emit
5317 a barrier saying that control flow will not pass here.
5318
5319 It is the responsibility of the program being compiled to ensure
5320 that control flow does never reach __builtin_unreachable. */
5321static void
5322expand_builtin_unreachable (void)
5323{
5324 emit_barrier ();
5325}
5326
c2f47e15 5327/* Expand EXP, a call to fabs, fabsf or fabsl.
5328 Return NULL_RTX if a normal call should be emitted rather than expanding
78a74442 5329 the function inline. If convenient, the result should be placed
5330 in TARGET. SUBTARGET may be used as the target for computing
5331 the operand. */
5332
5333static rtx
c2f47e15 5334expand_builtin_fabs (tree exp, rtx target, rtx subtarget)
78a74442 5335{
5336 enum machine_mode mode;
5337 tree arg;
5338 rtx op0;
5339
c2f47e15 5340 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
5341 return NULL_RTX;
78a74442 5342
c2f47e15 5343 arg = CALL_EXPR_ARG (exp, 0);
c7f617c2 5344 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
78a74442 5345 mode = TYPE_MODE (TREE_TYPE (arg));
1db6d067 5346 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
78a74442 5347 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
5348}
5349
c2f47e15 5350/* Expand EXP, a call to copysign, copysignf, or copysignl.
270436f3 5351 Return NULL is a normal call should be emitted rather than expanding the
5352 function inline. If convenient, the result should be placed in TARGET.
5353 SUBTARGET may be used as the target for computing the operand. */
5354
5355static rtx
c2f47e15 5356expand_builtin_copysign (tree exp, rtx target, rtx subtarget)
270436f3 5357{
5358 rtx op0, op1;
5359 tree arg;
5360
c2f47e15 5361 if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
5362 return NULL_RTX;
270436f3 5363
c2f47e15 5364 arg = CALL_EXPR_ARG (exp, 0);
8ec3c5c2 5365 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
270436f3 5366
c2f47e15 5367 arg = CALL_EXPR_ARG (exp, 1);
8ec3c5c2 5368 op1 = expand_normal (arg);
270436f3 5369
5370 return expand_copysign (op0, op1, target);
5371}
5372
19bf118a 5373/* Create a new constant string literal and return a char* pointer to it.
5374 The STRING_CST value is the LEN characters at STR. */
1e8e9920 5375tree
19bf118a 5376build_string_literal (int len, const char *str)
5377{
5378 tree t, elem, index, type;
5379
5380 t = build_string (len, str);
5381 elem = build_type_variant (char_type_node, 1, 0);
40238f64 5382 index = build_index_type (size_int (len - 1));
19bf118a 5383 type = build_array_type (elem, index);
5384 TREE_TYPE (t) = type;
5385 TREE_CONSTANT (t) = 1;
5386 TREE_READONLY (t) = 1;
5387 TREE_STATIC (t) = 1;
5388
19bf118a 5389 type = build_pointer_type (elem);
40238f64 5390 t = build1 (ADDR_EXPR, type,
5391 build4 (ARRAY_REF, elem,
5392 t, integer_zero_node, NULL_TREE, NULL_TREE));
19bf118a 5393 return t;
5394}
5395
0b25db21 5396/* Expand EXP, a call to printf or printf_unlocked.
c2f47e15 5397 Return NULL_RTX if a normal call should be emitted rather than transforming
19bf118a 5398 the function inline. If convenient, the result should be placed in
0862b7e9 5399 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
19bf118a 5400 call. */
5401static rtx
0b25db21 5402expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
19bf118a 5403 bool unlocked)
5404{
6d77ed92 5405 /* If we're using an unlocked function, assume the other unlocked
5406 functions exist explicitly. */
5407 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
5408 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
5409 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
5410 : implicit_built_in_decls[BUILT_IN_PUTS];
19bf118a 5411 const char *fmt_str;
c2f47e15 5412 tree fn = 0;
5413 tree fmt, arg;
5414 int nargs = call_expr_nargs (exp);
19bf118a 5415
5416 /* If the return value is used, don't do the transformation. */
5417 if (target != const0_rtx)
c2f47e15 5418 return NULL_RTX;
19bf118a 5419
5420 /* Verify the required arguments in the original call. */
c2f47e15 5421 if (nargs == 0)
5422 return NULL_RTX;
5423 fmt = CALL_EXPR_ARG (exp, 0);
552752f7 5424 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
c2f47e15 5425 return NULL_RTX;
19bf118a 5426
5427 /* Check whether the format is a literal string constant. */
5428 fmt_str = c_getstr (fmt);
5429 if (fmt_str == NULL)
c2f47e15 5430 return NULL_RTX;
19bf118a 5431
d4473c84 5432 if (!init_target_chars ())
c2f47e15 5433 return NULL_RTX;
a0c938f0 5434
19bf118a 5435 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
99eabcc1 5436 if (strcmp (fmt_str, target_percent_s_newline) == 0)
19bf118a 5437 {
c2f47e15 5438 if ((nargs != 2)
5439 || ! POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (exp, 1))))
5440 return NULL_RTX;
5441 if (fn_puts)
5442 fn = build_call_expr (fn_puts, 1, CALL_EXPR_ARG (exp, 1));
19bf118a 5443 }
5444 /* If the format specifier was "%c", call __builtin_putchar(arg). */
99eabcc1 5445 else if (strcmp (fmt_str, target_percent_c) == 0)
19bf118a 5446 {
c2f47e15 5447 if ((nargs != 2)
5448 || TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1))) != INTEGER_TYPE)
5449 return NULL_RTX;
5450 if (fn_putchar)
5451 fn = build_call_expr (fn_putchar, 1, CALL_EXPR_ARG (exp, 1));
19bf118a 5452 }
5453 else
5454 {
5455 /* We can't handle anything else with % args or %% ... yet. */
99eabcc1 5456 if (strchr (fmt_str, target_percent))
c2f47e15 5457 return NULL_RTX;
19bf118a 5458
c2f47e15 5459 if (nargs > 1)
5460 return NULL_RTX;
19bf118a 5461
5462 /* If the format specifier was "", printf does nothing. */
5463 if (fmt_str[0] == '\0')
5464 return const0_rtx;
5465 /* If the format specifier has length of 1, call putchar. */
5466 if (fmt_str[1] == '\0')
5467 {
5468 /* Given printf("c"), (where c is any one character,)
5469 convert "c"[0] to an int and pass that to the replacement
5470 function. */
7016c612 5471 arg = build_int_cst (NULL_TREE, fmt_str[0]);
c2f47e15 5472 if (fn_putchar)
5473 fn = build_call_expr (fn_putchar, 1, arg);
19bf118a 5474 }
5475 else
5476 {
5477 /* If the format specifier was "string\n", call puts("string"). */
5478 size_t len = strlen (fmt_str);
99eabcc1 5479 if ((unsigned char)fmt_str[len - 1] == target_newline)
19bf118a 5480 {
91c82c20 5481 /* Create a NUL-terminated string that's one char shorter
19bf118a 5482 than the original, stripping off the trailing '\n'. */
364c0c59 5483 char *newstr = XALLOCAVEC (char, len);
19bf118a 5484 memcpy (newstr, fmt_str, len - 1);
5485 newstr[len - 1] = 0;
19bf118a 5486 arg = build_string_literal (len, newstr);
c2f47e15 5487 if (fn_puts)
5488 fn = build_call_expr (fn_puts, 1, arg);
19bf118a 5489 }
5490 else
5491 /* We'd like to arrange to call fputs(string,stdout) here,
5492 but we need stdout and don't have a way to get it yet. */
c2f47e15 5493 return NULL_RTX;
19bf118a 5494 }
5495 }
5496
5497 if (!fn)
c2f47e15 5498 return NULL_RTX;
0b25db21 5499 if (TREE_CODE (fn) == CALL_EXPR)
5500 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5501 return expand_expr (fn, target, mode, EXPAND_NORMAL);
19bf118a 5502}
5503
0b25db21 5504/* Expand EXP, a call to fprintf or fprintf_unlocked.
c2f47e15 5505 Return NULL_RTX if a normal call should be emitted rather than transforming
19bf118a 5506 the function inline. If convenient, the result should be placed in
0862b7e9 5507 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
19bf118a 5508 call. */
5509static rtx
0b25db21 5510expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
a0c938f0 5511 bool unlocked)
19bf118a 5512{
6d77ed92 5513 /* If we're using an unlocked function, assume the other unlocked
5514 functions exist explicitly. */
5515 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5516 : implicit_built_in_decls[BUILT_IN_FPUTC];
5517 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5518 : implicit_built_in_decls[BUILT_IN_FPUTS];
19bf118a 5519 const char *fmt_str;
c2f47e15 5520 tree fn = 0;
5521 tree fmt, fp, arg;
5522 int nargs = call_expr_nargs (exp);
19bf118a 5523
5524 /* If the return value is used, don't do the transformation. */
5525 if (target != const0_rtx)
c2f47e15 5526 return NULL_RTX;
19bf118a 5527
5528 /* Verify the required arguments in the original call. */
c2f47e15 5529 if (nargs < 2)
5530 return NULL_RTX;
5531 fp = CALL_EXPR_ARG (exp, 0);
552752f7 5532 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
c2f47e15 5533 return NULL_RTX;
5534 fmt = CALL_EXPR_ARG (exp, 1);
552752f7 5535 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
c2f47e15 5536 return NULL_RTX;
19bf118a 5537
5538 /* Check whether the format is a literal string constant. */
5539 fmt_str = c_getstr (fmt);
5540 if (fmt_str == NULL)
c2f47e15 5541 return NULL_RTX;
19bf118a 5542
d4473c84 5543 if (!init_target_chars ())
c2f47e15 5544 return NULL_RTX;
a0c938f0 5545
19bf118a 5546 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
99eabcc1 5547 if (strcmp (fmt_str, target_percent_s) == 0)
19bf118a 5548 {
c2f47e15 5549 if ((nargs != 3)
5550 || ! POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (exp, 2))))
5551 return NULL_RTX;
5552 arg = CALL_EXPR_ARG (exp, 2);
5553 if (fn_fputs)
5554 fn = build_call_expr (fn_fputs, 2, arg, fp);
19bf118a 5555 }
5556 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
99eabcc1 5557 else if (strcmp (fmt_str, target_percent_c) == 0)
19bf118a 5558 {
c2f47e15 5559 if ((nargs != 3)
5560 || TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2))) != INTEGER_TYPE)
5561 return NULL_RTX;
5562 arg = CALL_EXPR_ARG (exp, 2);
5563 if (fn_fputc)
5564 fn = build_call_expr (fn_fputc, 2, arg, fp);
19bf118a 5565 }
5566 else
5567 {
5568 /* We can't handle anything else with % args or %% ... yet. */
99eabcc1 5569 if (strchr (fmt_str, target_percent))
c2f47e15 5570 return NULL_RTX;
19bf118a 5571
c2f47e15 5572 if (nargs > 2)
5573 return NULL_RTX;
19bf118a 5574
5575 /* If the format specifier was "", fprintf does nothing. */
5576 if (fmt_str[0] == '\0')
5577 {
5578 /* Evaluate and ignore FILE* argument for side-effects. */
5579 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5580 return const0_rtx;
5581 }
5582
5583 /* When "string" doesn't contain %, replace all cases of
5584 fprintf(stream,string) with fputs(string,stream). The fputs
5585 builtin will take care of special cases like length == 1. */
c2f47e15 5586 if (fn_fputs)
5587 fn = build_call_expr (fn_fputs, 2, fmt, fp);
19bf118a 5588 }
5589
5590 if (!fn)
c2f47e15 5591 return NULL_RTX;
0b25db21 5592 if (TREE_CODE (fn) == CALL_EXPR)
5593 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5594 return expand_expr (fn, target, mode, EXPAND_NORMAL);
19bf118a 5595}
5596
c2f47e15 5597/* Expand a call EXP to sprintf. Return NULL_RTX if
6411575e 5598 a normal call should be emitted rather than expanding the function
5599 inline. If convenient, the result should be placed in TARGET with
5600 mode MODE. */
5601
5602static rtx
c2f47e15 5603expand_builtin_sprintf (tree exp, rtx target, enum machine_mode mode)
6411575e 5604{
c2f47e15 5605 tree dest, fmt;
a7a723f0 5606 const char *fmt_str;
c2f47e15 5607 int nargs = call_expr_nargs (exp);
6411575e 5608
5609 /* Verify the required arguments in the original call. */
c2f47e15 5610 if (nargs < 2)
5611 return NULL_RTX;
5612 dest = CALL_EXPR_ARG (exp, 0);
552752f7 5613 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
c2f47e15 5614 return NULL_RTX;
5615 fmt = CALL_EXPR_ARG (exp, 0);
552752f7 5616 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
c2f47e15 5617 return NULL_RTX;
6411575e 5618
5619 /* Check whether the format is a literal string constant. */
a7a723f0 5620 fmt_str = c_getstr (fmt);
5621 if (fmt_str == NULL)
c2f47e15 5622 return NULL_RTX;
6411575e 5623
d4473c84 5624 if (!init_target_chars ())
c2f47e15 5625 return NULL_RTX;
99eabcc1 5626
6411575e 5627 /* If the format doesn't contain % args or %%, use strcpy. */
99eabcc1 5628 if (strchr (fmt_str, target_percent) == 0)
6411575e 5629 {
5630 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5631 tree exp;
5632
c2f47e15 5633 if ((nargs > 2) || ! fn)
5634 return NULL_RTX;
5635 expand_expr (build_call_expr (fn, 2, dest, fmt),
6411575e 5636 const0_rtx, VOIDmode, EXPAND_NORMAL);
5637 if (target == const0_rtx)
5638 return const0_rtx;
7016c612 5639 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
6411575e 5640 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5641 }
a7a723f0 5642 /* If the format is "%s", use strcpy if the result isn't used. */
99eabcc1 5643 else if (strcmp (fmt_str, target_percent_s) == 0)
6411575e 5644 {
a7a723f0 5645 tree fn, arg, len;
5646 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
6411575e 5647
a7a723f0 5648 if (! fn)
c2f47e15 5649 return NULL_RTX;
5650 if (nargs != 3)
5651 return NULL_RTX;
5652 arg = CALL_EXPR_ARG (exp, 2);
552752f7 5653 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
c2f47e15 5654 return NULL_RTX;
6411575e 5655
5656 if (target != const0_rtx)
5657 {
681fab1e 5658 len = c_strlen (arg, 1);
a7a723f0 5659 if (! len || TREE_CODE (len) != INTEGER_CST)
c2f47e15 5660 return NULL_RTX;
6411575e 5661 }
5662 else
a7a723f0 5663 len = NULL_TREE;
6411575e 5664
c2f47e15 5665 expand_expr (build_call_expr (fn, 2, dest, arg),
6411575e 5666 const0_rtx, VOIDmode, EXPAND_NORMAL);
5667
5668 if (target == const0_rtx)
5669 return const0_rtx;
a7a723f0 5670 return expand_expr (len, target, mode, EXPAND_NORMAL);
6411575e 5671 }
5672
c2f47e15 5673 return NULL_RTX;
6411575e 5674}
27f261ef 5675
4ee9c684 5676/* Expand a call to either the entry or exit function profiler. */
5677
5678static rtx
5679expand_builtin_profile_func (bool exitp)
5680{
f4e36c33 5681 rtx this_rtx, which;
4ee9c684 5682
f4e36c33 5683 this_rtx = DECL_RTL (current_function_decl);
5684 gcc_assert (MEM_P (this_rtx));
5685 this_rtx = XEXP (this_rtx, 0);
4ee9c684 5686
5687 if (exitp)
5688 which = profile_function_exit_libfunc;
5689 else
5690 which = profile_function_entry_libfunc;
5691
f4e36c33 5692 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this_rtx, Pmode,
4ee9c684 5693 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
869d0ef0 5694 0),
4ee9c684 5695 Pmode);
5696
5697 return const0_rtx;
5698}
5699
ac8fb6db 5700/* Expand a call to __builtin___clear_cache. */
5701
5702static rtx
5703expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED)
5704{
5705#ifndef HAVE_clear_cache
5706#ifdef CLEAR_INSN_CACHE
5707 /* There is no "clear_cache" insn, and __clear_cache() in libgcc
5708 does something. Just do the default expansion to a call to
5709 __clear_cache(). */
5710 return NULL_RTX;
5711#else
5712 /* There is no "clear_cache" insn, and __clear_cache() in libgcc
5713 does nothing. There is no need to call it. Do nothing. */
5714 return const0_rtx;
5715#endif /* CLEAR_INSN_CACHE */
5716#else
5717 /* We have a "clear_cache" insn, and it will handle everything. */
5718 tree begin, end;
5719 rtx begin_rtx, end_rtx;
5720 enum insn_code icode;
5721
5722 /* We must not expand to a library call. If we did, any
5723 fallback library function in libgcc that might contain a call to
5724 __builtin___clear_cache() would recurse infinitely. */
5725 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
5726 {
5727 error ("both arguments to %<__builtin___clear_cache%> must be pointers");
5728 return const0_rtx;
5729 }
5730
5731 if (HAVE_clear_cache)
5732 {
5733 icode = CODE_FOR_clear_cache;
5734
5735 begin = CALL_EXPR_ARG (exp, 0);
5736 begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL);
5737 begin_rtx = convert_memory_address (Pmode, begin_rtx);
5738 if (!insn_data[icode].operand[0].predicate (begin_rtx, Pmode))
5739 begin_rtx = copy_to_mode_reg (Pmode, begin_rtx);
5740
5741 end = CALL_EXPR_ARG (exp, 1);
5742 end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL);
5743 end_rtx = convert_memory_address (Pmode, end_rtx);
5744 if (!insn_data[icode].operand[1].predicate (end_rtx, Pmode))
5745 end_rtx = copy_to_mode_reg (Pmode, end_rtx);
5746
5747 emit_insn (gen_clear_cache (begin_rtx, end_rtx));
5748 }
5749 return const0_rtx;
5750#endif /* HAVE_clear_cache */
5751}
5752
4ee9c684 5753/* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5754
5755static rtx
5756round_trampoline_addr (rtx tramp)
5757{
5758 rtx temp, addend, mask;
5759
5760 /* If we don't need too much alignment, we'll have been guaranteed
5761 proper alignment by get_trampoline_type. */
5762 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5763 return tramp;
5764
5765 /* Round address up to desired boundary. */
5766 temp = gen_reg_rtx (Pmode);
5767 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5768 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5769
5770 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5771 temp, 0, OPTAB_LIB_WIDEN);
5772 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5773 temp, 0, OPTAB_LIB_WIDEN);
5774
5775 return tramp;
5776}
5777
5778static rtx
c2f47e15 5779expand_builtin_init_trampoline (tree exp)
4ee9c684 5780{
5781 tree t_tramp, t_func, t_chain;
5782 rtx r_tramp, r_func, r_chain;
5783#ifdef TRAMPOLINE_TEMPLATE
5784 rtx blktramp;
5785#endif
5786
c2f47e15 5787 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE,
4ee9c684 5788 POINTER_TYPE, VOID_TYPE))
5789 return NULL_RTX;
5790
c2f47e15 5791 t_tramp = CALL_EXPR_ARG (exp, 0);
5792 t_func = CALL_EXPR_ARG (exp, 1);
5793 t_chain = CALL_EXPR_ARG (exp, 2);
4ee9c684 5794
8ec3c5c2 5795 r_tramp = expand_normal (t_tramp);
5796 r_func = expand_normal (t_func);
5797 r_chain = expand_normal (t_chain);
4ee9c684 5798
5799 /* Generate insns to initialize the trampoline. */
5800 r_tramp = round_trampoline_addr (r_tramp);
5801#ifdef TRAMPOLINE_TEMPLATE
5802 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5803 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5804 emit_block_move (blktramp, assemble_trampoline_template (),
5805 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5806#endif
5807 trampolines_created = 1;
5808 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5809
5810 return const0_rtx;
5811}
5812
5813static rtx
c2f47e15 5814expand_builtin_adjust_trampoline (tree exp)
4ee9c684 5815{
5816 rtx tramp;
5817
c2f47e15 5818 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
4ee9c684 5819 return NULL_RTX;
5820
c2f47e15 5821 tramp = expand_normal (CALL_EXPR_ARG (exp, 0));
4ee9c684 5822 tramp = round_trampoline_addr (tramp);
5823#ifdef TRAMPOLINE_ADJUST_ADDRESS
5824 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5825#endif
5826
5827 return tramp;
5828}
5829
93f564d6 5830/* Expand the call EXP to the built-in signbit, signbitf or signbitl
5831 function. The function first checks whether the back end provides
5832 an insn to implement signbit for the respective mode. If not, it
5833 checks whether the floating point format of the value is such that
5834 the sign bit can be extracted. If that is not the case, the
5835 function returns NULL_RTX to indicate that a normal call should be
5836 emitted rather than expanding the function in-line. EXP is the
5837 expression that is a call to the builtin function; if convenient,
5838 the result should be placed in TARGET. */
27f261ef 5839static rtx
5840expand_builtin_signbit (tree exp, rtx target)
5841{
5842 const struct real_format *fmt;
5843 enum machine_mode fmode, imode, rmode;
5844 HOST_WIDE_INT hi, lo;
c2f47e15 5845 tree arg;
ca4f1f5b 5846 int word, bitpos;
27eda240 5847 enum insn_code icode;
27f261ef 5848 rtx temp;
5849
c2f47e15 5850 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
5851 return NULL_RTX;
27f261ef 5852
c2f47e15 5853 arg = CALL_EXPR_ARG (exp, 0);
27f261ef 5854 fmode = TYPE_MODE (TREE_TYPE (arg));
5855 rmode = TYPE_MODE (TREE_TYPE (exp));
5856 fmt = REAL_MODE_FORMAT (fmode);
5857
93f564d6 5858 arg = builtin_save_expr (arg);
5859
5860 /* Expand the argument yielding a RTX expression. */
5861 temp = expand_normal (arg);
5862
5863 /* Check if the back end provides an insn that handles signbit for the
5864 argument's mode. */
27eda240 5865 icode = signbit_optab->handlers [(int) fmode].insn_code;
5866 if (icode != CODE_FOR_nothing)
93f564d6 5867 {
5868 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
27eda240 5869 emit_unop_insn (icode, target, temp, UNKNOWN);
93f564d6 5870 return target;
5871 }
5872
27f261ef 5873 /* For floating point formats without a sign bit, implement signbit
5874 as "ARG < 0.0". */
8d564692 5875 bitpos = fmt->signbit_ro;
ca4f1f5b 5876 if (bitpos < 0)
27f261ef 5877 {
5878 /* But we can't do this if the format supports signed zero. */
5879 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
c2f47e15 5880 return NULL_RTX;
27f261ef 5881
49d00087 5882 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5883 build_real (TREE_TYPE (arg), dconst0));
27f261ef 5884 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5885 }
5886
ca4f1f5b 5887 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
27f261ef 5888 {
ca4f1f5b 5889 imode = int_mode_for_mode (fmode);
5890 if (imode == BLKmode)
c2f47e15 5891 return NULL_RTX;
ca4f1f5b 5892 temp = gen_lowpart (imode, temp);
24fd4260 5893 }
5894 else
5895 {
ca4f1f5b 5896 imode = word_mode;
5897 /* Handle targets with different FP word orders. */
5898 if (FLOAT_WORDS_BIG_ENDIAN)
a0c938f0 5899 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
ca4f1f5b 5900 else
a0c938f0 5901 word = bitpos / BITS_PER_WORD;
ca4f1f5b 5902 temp = operand_subword_force (temp, word, fmode);
5903 bitpos = bitpos % BITS_PER_WORD;
5904 }
5905
44b0f1d0 5906 /* Force the intermediate word_mode (or narrower) result into a
5907 register. This avoids attempting to create paradoxical SUBREGs
5908 of floating point modes below. */
5909 temp = force_reg (imode, temp);
5910
ca4f1f5b 5911 /* If the bitpos is within the "result mode" lowpart, the operation
5912 can be implement with a single bitwise AND. Otherwise, we need
5913 a right shift and an AND. */
5914
5915 if (bitpos < GET_MODE_BITSIZE (rmode))
5916 {
24fd4260 5917 if (bitpos < HOST_BITS_PER_WIDE_INT)
27f261ef 5918 {
24fd4260 5919 hi = 0;
5920 lo = (HOST_WIDE_INT) 1 << bitpos;
27f261ef 5921 }
5922 else
24fd4260 5923 {
5924 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5925 lo = 0;
5926 }
27f261ef 5927
4a46f016 5928 if (GET_MODE_SIZE (imode) > GET_MODE_SIZE (rmode))
ca4f1f5b 5929 temp = gen_lowpart (rmode, temp);
24fd4260 5930 temp = expand_binop (rmode, and_optab, temp,
5931 immed_double_const (lo, hi, rmode),
ca4f1f5b 5932 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27f261ef 5933 }
ca4f1f5b 5934 else
5935 {
5936 /* Perform a logical right shift to place the signbit in the least
a0c938f0 5937 significant bit, then truncate the result to the desired mode
ca4f1f5b 5938 and mask just this bit. */
5939 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5940 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5941 temp = gen_lowpart (rmode, temp);
5942 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5943 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5944 }
5945
27f261ef 5946 return temp;
5947}
73673831 5948
5949/* Expand fork or exec calls. TARGET is the desired target of the
c2f47e15 5950 call. EXP is the call. FN is the
73673831 5951 identificator of the actual function. IGNORE is nonzero if the
5952 value is to be ignored. */
5953
5954static rtx
c2f47e15 5955expand_builtin_fork_or_exec (tree fn, tree exp, rtx target, int ignore)
73673831 5956{
5957 tree id, decl;
5958 tree call;
5959
5960 /* If we are not profiling, just call the function. */
5961 if (!profile_arc_flag)
5962 return NULL_RTX;
5963
5964 /* Otherwise call the wrapper. This should be equivalent for the rest of
5965 compiler, so the code does not diverge, and the wrapper may run the
9c9bad97 5966 code necessary for keeping the profiling sane. */
73673831 5967
5968 switch (DECL_FUNCTION_CODE (fn))
5969 {
5970 case BUILT_IN_FORK:
5971 id = get_identifier ("__gcov_fork");
5972 break;
5973
5974 case BUILT_IN_EXECL:
5975 id = get_identifier ("__gcov_execl");
5976 break;
5977
5978 case BUILT_IN_EXECV:
5979 id = get_identifier ("__gcov_execv");
5980 break;
5981
5982 case BUILT_IN_EXECLP:
5983 id = get_identifier ("__gcov_execlp");
5984 break;
5985
5986 case BUILT_IN_EXECLE:
5987 id = get_identifier ("__gcov_execle");
5988 break;
5989
5990 case BUILT_IN_EXECVP:
5991 id = get_identifier ("__gcov_execvp");
5992 break;
5993
5994 case BUILT_IN_EXECVE:
5995 id = get_identifier ("__gcov_execve");
5996 break;
5997
5998 default:
64db345d 5999 gcc_unreachable ();
73673831 6000 }
6001
e60a6f7b 6002 decl = build_decl (DECL_SOURCE_LOCATION (fn),
6003 FUNCTION_DECL, id, TREE_TYPE (fn));
73673831 6004 DECL_EXTERNAL (decl) = 1;
6005 TREE_PUBLIC (decl) = 1;
6006 DECL_ARTIFICIAL (decl) = 1;
6007 TREE_NOTHROW (decl) = 1;
e82d310b 6008 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
6009 DECL_VISIBILITY_SPECIFIED (decl) = 1;
c2f47e15 6010 call = rewrite_call_expr (exp, 0, decl, 0);
73673831 6011 return expand_call (call, target, ignore);
c2f47e15 6012 }
6013
b6a5fc45 6014
6015\f
3e272de8 6016/* Reconstitute a mode for a __sync intrinsic operation. Since the type of
6017 the pointer in these functions is void*, the tree optimizers may remove
6018 casts. The mode computed in expand_builtin isn't reliable either, due
6019 to __sync_bool_compare_and_swap.
6020
6021 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
6022 group of builtins. This gives us log2 of the mode size. */
6023
6024static inline enum machine_mode
6025get_builtin_sync_mode (int fcode_diff)
6026{
ad3a13b5 6027 /* The size is not negotiable, so ask not to get BLKmode in return
6028 if the target indicates that a smaller size would be better. */
6029 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
3e272de8 6030}
6031
041e0215 6032/* Expand the memory expression LOC and return the appropriate memory operand
6033 for the builtin_sync operations. */
6034
6035static rtx
6036get_builtin_sync_mem (tree loc, enum machine_mode mode)
6037{
6038 rtx addr, mem;
6039
1db6d067 6040 addr = expand_expr (loc, NULL_RTX, Pmode, EXPAND_SUM);
041e0215 6041
6042 /* Note that we explicitly do not want any alias information for this
6043 memory, so that we kill all other live memories. Otherwise we don't
6044 satisfy the full barrier semantics of the intrinsic. */
6045 mem = validize_mem (gen_rtx_MEM (mode, addr));
6046
6047 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
c94cfd1c 6048 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
041e0215 6049 MEM_VOLATILE_P (mem) = 1;
6050
6051 return mem;
6052}
6053
b6a5fc45 6054/* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
c2f47e15 6055 EXP is the CALL_EXPR. CODE is the rtx code
b6a5fc45 6056 that corresponds to the arithmetic or logical operation from the name;
6057 an exception here is that NOT actually means NAND. TARGET is an optional
6058 place for us to store the results; AFTER is true if this is the
6059 fetch_and_xxx form. IGNORE is true if we don't actually care about
6060 the result of the operation at all. */
6061
6062static rtx
c2f47e15 6063expand_builtin_sync_operation (enum machine_mode mode, tree exp,
3e272de8 6064 enum rtx_code code, bool after,
b6a5fc45 6065 rtx target, bool ignore)
6066{
041e0215 6067 rtx val, mem;
a8bb7059 6068 enum machine_mode old_mode;
e60a6f7b 6069 location_t loc = EXPR_LOCATION (exp);
b6a5fc45 6070
cf73e559 6071 if (code == NOT && warn_sync_nand)
6072 {
6073 tree fndecl = get_callee_fndecl (exp);
6074 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6075
6076 static bool warned_f_a_n, warned_n_a_f;
6077
6078 switch (fcode)
6079 {
6080 case BUILT_IN_FETCH_AND_NAND_1:
6081 case BUILT_IN_FETCH_AND_NAND_2:
6082 case BUILT_IN_FETCH_AND_NAND_4:
6083 case BUILT_IN_FETCH_AND_NAND_8:
6084 case BUILT_IN_FETCH_AND_NAND_16:
6085
6086 if (warned_f_a_n)
6087 break;
6088
6089 fndecl = implicit_built_in_decls[BUILT_IN_FETCH_AND_NAND_N];
e60a6f7b 6090 inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
cf73e559 6091 warned_f_a_n = true;
6092 break;
6093
6094 case BUILT_IN_NAND_AND_FETCH_1:
6095 case BUILT_IN_NAND_AND_FETCH_2:
6096 case BUILT_IN_NAND_AND_FETCH_4:
6097 case BUILT_IN_NAND_AND_FETCH_8:
6098 case BUILT_IN_NAND_AND_FETCH_16:
6099
6100 if (warned_n_a_f)
6101 break;
6102
6103 fndecl = implicit_built_in_decls[BUILT_IN_NAND_AND_FETCH_N];
e60a6f7b 6104 inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
cf73e559 6105 warned_n_a_f = true;
6106 break;
6107
6108 default:
6109 gcc_unreachable ();
6110 }
6111 }
6112
b6a5fc45 6113 /* Expand the operands. */
c2f47e15 6114 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
b6a5fc45 6115
1db6d067 6116 val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
a8bb7059 6117 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
6118 of CONST_INTs, where we know the old_mode only from the call argument. */
6119 old_mode = GET_MODE (val);
6120 if (old_mode == VOIDmode)
6121 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
6122 val = convert_modes (mode, old_mode, val, 1);
b6a5fc45 6123
b6a5fc45 6124 if (ignore)
6125 return expand_sync_operation (mem, val, code);
6126 else
6127 return expand_sync_fetch_operation (mem, val, code, after, target);
6128}
6129
6130/* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
c2f47e15 6131 intrinsics. EXP is the CALL_EXPR. IS_BOOL is
b6a5fc45 6132 true if this is the boolean form. TARGET is a place for us to store the
6133 results; this is NOT optional if IS_BOOL is true. */
6134
6135static rtx
c2f47e15 6136expand_builtin_compare_and_swap (enum machine_mode mode, tree exp,
3e272de8 6137 bool is_bool, rtx target)
b6a5fc45 6138{
041e0215 6139 rtx old_val, new_val, mem;
a8bb7059 6140 enum machine_mode old_mode;
b6a5fc45 6141
6142 /* Expand the operands. */
c2f47e15 6143 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
b6a5fc45 6144
c2f47e15 6145
1db6d067 6146 old_val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX,
6147 mode, EXPAND_NORMAL);
a8bb7059 6148 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
6149 of CONST_INTs, where we know the old_mode only from the call argument. */
6150 old_mode = GET_MODE (old_val);
6151 if (old_mode == VOIDmode)
6152 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
6153 old_val = convert_modes (mode, old_mode, old_val, 1);
b6a5fc45 6154
1db6d067 6155 new_val = expand_expr (CALL_EXPR_ARG (exp, 2), NULL_RTX,
6156 mode, EXPAND_NORMAL);
a8bb7059 6157 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
6158 of CONST_INTs, where we know the old_mode only from the call argument. */
6159 old_mode = GET_MODE (new_val);
6160 if (old_mode == VOIDmode)
6161 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2)));
6162 new_val = convert_modes (mode, old_mode, new_val, 1);
b6a5fc45 6163
b6a5fc45 6164 if (is_bool)
6165 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
6166 else
6167 return expand_val_compare_and_swap (mem, old_val, new_val, target);
6168}
6169
6170/* Expand the __sync_lock_test_and_set intrinsic. Note that the most
6171 general form is actually an atomic exchange, and some targets only
6172 support a reduced form with the second argument being a constant 1.
c2f47e15 6173 EXP is the CALL_EXPR; TARGET is an optional place for us to store
6174 the results. */
b6a5fc45 6175
6176static rtx
c2f47e15 6177expand_builtin_lock_test_and_set (enum machine_mode mode, tree exp,
3e272de8 6178 rtx target)
b6a5fc45 6179{
041e0215 6180 rtx val, mem;
a8bb7059 6181 enum machine_mode old_mode;
b6a5fc45 6182
6183 /* Expand the operands. */
c2f47e15 6184 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
1db6d067 6185 val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
a8bb7059 6186 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
6187 of CONST_INTs, where we know the old_mode only from the call argument. */
6188 old_mode = GET_MODE (val);
6189 if (old_mode == VOIDmode)
6190 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
6191 val = convert_modes (mode, old_mode, val, 1);
b6a5fc45 6192
b6a5fc45 6193 return expand_sync_lock_test_and_set (mem, val, target);
6194}
6195
6196/* Expand the __sync_synchronize intrinsic. */
6197
6198static void
6199expand_builtin_synchronize (void)
6200{
82e58396 6201 tree x;
b6a5fc45 6202
6203#ifdef HAVE_memory_barrier
6204 if (HAVE_memory_barrier)
6205 {
6206 emit_insn (gen_memory_barrier ());
6207 return;
6208 }
6209#endif
6210
047a7e40 6211 if (synchronize_libfunc != NULL_RTX)
6212 {
6213 emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
6214 return;
6215 }
6216
82e58396 6217 /* If no explicit memory barrier instruction is available, create an
6218 empty asm stmt with a memory clobber. */
6219 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
6220 tree_cons (NULL, build_string (6, "memory"), NULL));
6221 ASM_VOLATILE_P (x) = 1;
6222 expand_asm_expr (x);
b6a5fc45 6223}
6224
c2f47e15 6225/* Expand the __sync_lock_release intrinsic. EXP is the CALL_EXPR. */
b6a5fc45 6226
6227static void
c2f47e15 6228expand_builtin_lock_release (enum machine_mode mode, tree exp)
b6a5fc45 6229{
b6a5fc45 6230 enum insn_code icode;
041e0215 6231 rtx mem, insn;
3e272de8 6232 rtx val = const0_rtx;
b6a5fc45 6233
6234 /* Expand the operands. */
c2f47e15 6235 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
b6a5fc45 6236
6237 /* If there is an explicit operation in the md file, use it. */
6238 icode = sync_lock_release[mode];
6239 if (icode != CODE_FOR_nothing)
6240 {
6241 if (!insn_data[icode].operand[1].predicate (val, mode))
6242 val = force_reg (mode, val);
6243
6244 insn = GEN_FCN (icode) (mem, val);
6245 if (insn)
6246 {
6247 emit_insn (insn);
6248 return;
6249 }
6250 }
6251
6252 /* Otherwise we can implement this operation by emitting a barrier
6253 followed by a store of zero. */
6254 expand_builtin_synchronize ();
6255 emit_move_insn (mem, val);
6256}
53800dbe 6257\f
6258/* Expand an expression EXP that calls a built-in function,
6259 with result going to TARGET if that's convenient
6260 (and in mode MODE if that's convenient).
6261 SUBTARGET may be used as the target for computing one of EXP's operands.
6262 IGNORE is nonzero if the value is to be ignored. */
6263
6264rtx
aecda0d6 6265expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
6266 int ignore)
53800dbe 6267{
c6e6ecb1 6268 tree fndecl = get_callee_fndecl (exp);
53800dbe 6269 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
efb070c8 6270 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
53800dbe 6271
8305149e 6272 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
883b2e73 6273 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
bf8e3599 6274
53800dbe 6275 /* When not optimizing, generate calls to library functions for a certain
6276 set of builtins. */
cd9ff771 6277 if (!optimize
b6a5fc45 6278 && !called_as_built_in (fndecl)
cd9ff771 6279 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
2c281b15 6280 && fcode != BUILT_IN_ALLOCA
6281 && fcode != BUILT_IN_FREE)
cd9ff771 6282 return expand_call (exp, target, ignore);
53800dbe 6283
8d6d7930 6284 /* The built-in function expanders test for target == const0_rtx
6285 to determine whether the function's result will be ignored. */
6286 if (ignore)
6287 target = const0_rtx;
6288
6289 /* If the result of a pure or const built-in function is ignored, and
6290 none of its arguments are volatile, we can avoid expanding the
6291 built-in call and just evaluate the arguments for side-effects. */
6292 if (target == const0_rtx
9c2a0c05 6293 && (DECL_PURE_P (fndecl) || TREE_READONLY (fndecl)))
8d6d7930 6294 {
6295 bool volatilep = false;
6296 tree arg;
c2f47e15 6297 call_expr_arg_iterator iter;
8d6d7930 6298
c2f47e15 6299 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
6300 if (TREE_THIS_VOLATILE (arg))
8d6d7930 6301 {
6302 volatilep = true;
6303 break;
6304 }
6305
6306 if (! volatilep)
6307 {
c2f47e15 6308 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
6309 expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL);
8d6d7930 6310 return const0_rtx;
6311 }
6312 }
6313
53800dbe 6314 switch (fcode)
6315 {
4f35b1fc 6316 CASE_FLT_FN (BUILT_IN_FABS):
c2f47e15 6317 target = expand_builtin_fabs (exp, target, subtarget);
78a74442 6318 if (target)
a0c938f0 6319 return target;
78a74442 6320 break;
6321
4f35b1fc 6322 CASE_FLT_FN (BUILT_IN_COPYSIGN):
c2f47e15 6323 target = expand_builtin_copysign (exp, target, subtarget);
270436f3 6324 if (target)
6325 return target;
6326 break;
6327
7d3f6cc7 6328 /* Just do a normal library call if we were unable to fold
6329 the values. */
4f35b1fc 6330 CASE_FLT_FN (BUILT_IN_CABS):
78a74442 6331 break;
53800dbe 6332
4f35b1fc 6333 CASE_FLT_FN (BUILT_IN_EXP):
6334 CASE_FLT_FN (BUILT_IN_EXP10):
6335 CASE_FLT_FN (BUILT_IN_POW10):
6336 CASE_FLT_FN (BUILT_IN_EXP2):
6337 CASE_FLT_FN (BUILT_IN_EXPM1):
6338 CASE_FLT_FN (BUILT_IN_LOGB):
4f35b1fc 6339 CASE_FLT_FN (BUILT_IN_LOG):
6340 CASE_FLT_FN (BUILT_IN_LOG10):
6341 CASE_FLT_FN (BUILT_IN_LOG2):
6342 CASE_FLT_FN (BUILT_IN_LOG1P):
6343 CASE_FLT_FN (BUILT_IN_TAN):
6344 CASE_FLT_FN (BUILT_IN_ASIN):
6345 CASE_FLT_FN (BUILT_IN_ACOS):
6346 CASE_FLT_FN (BUILT_IN_ATAN):
b3154a1f 6347 CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
7f3be425 6348 /* Treat these like sqrt only if unsafe math optimizations are allowed,
6349 because of possible accuracy problems. */
6350 if (! flag_unsafe_math_optimizations)
53800dbe 6351 break;
4f35b1fc 6352 CASE_FLT_FN (BUILT_IN_SQRT):
6353 CASE_FLT_FN (BUILT_IN_FLOOR):
6354 CASE_FLT_FN (BUILT_IN_CEIL):
6355 CASE_FLT_FN (BUILT_IN_TRUNC):
6356 CASE_FLT_FN (BUILT_IN_ROUND):
6357 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6358 CASE_FLT_FN (BUILT_IN_RINT):
53800dbe 6359 target = expand_builtin_mathfn (exp, target, subtarget);
6360 if (target)
6361 return target;
6362 break;
6363
a67a90e5 6364 CASE_FLT_FN (BUILT_IN_ILOGB):
6365 if (! flag_unsafe_math_optimizations)
6366 break;
69b779ea 6367 CASE_FLT_FN (BUILT_IN_ISINF):
cde061c1 6368 CASE_FLT_FN (BUILT_IN_FINITE):
6369 case BUILT_IN_ISFINITE:
8a1a9cb7 6370 case BUILT_IN_ISNORMAL:
a67a90e5 6371 target = expand_builtin_interclass_mathfn (exp, target, subtarget);
6372 if (target)
6373 return target;
6374 break;
6375
4f35b1fc 6376 CASE_FLT_FN (BUILT_IN_LCEIL):
6377 CASE_FLT_FN (BUILT_IN_LLCEIL):
6378 CASE_FLT_FN (BUILT_IN_LFLOOR):
6379 CASE_FLT_FN (BUILT_IN_LLFLOOR):
ff1b14e4 6380 target = expand_builtin_int_roundingfn (exp, target);
ad52b9b7 6381 if (target)
6382 return target;
6383 break;
6384
7d3afc77 6385 CASE_FLT_FN (BUILT_IN_LRINT):
6386 CASE_FLT_FN (BUILT_IN_LLRINT):
ef2f1a10 6387 CASE_FLT_FN (BUILT_IN_LROUND):
6388 CASE_FLT_FN (BUILT_IN_LLROUND):
ff1b14e4 6389 target = expand_builtin_int_roundingfn_2 (exp, target);
7d3afc77 6390 if (target)
6391 return target;
6392 break;
6393
4f35b1fc 6394 CASE_FLT_FN (BUILT_IN_POW):
f1b844c6 6395 target = expand_builtin_pow (exp, target, subtarget);
6396 if (target)
6397 return target;
6398 break;
6399
4f35b1fc 6400 CASE_FLT_FN (BUILT_IN_POWI):
757c219d 6401 target = expand_builtin_powi (exp, target, subtarget);
6402 if (target)
6403 return target;
6404 break;
6405
4f35b1fc 6406 CASE_FLT_FN (BUILT_IN_ATAN2):
6407 CASE_FLT_FN (BUILT_IN_LDEXP):
73a954a1 6408 CASE_FLT_FN (BUILT_IN_SCALB):
6409 CASE_FLT_FN (BUILT_IN_SCALBN):
6410 CASE_FLT_FN (BUILT_IN_SCALBLN):
0fd605a5 6411 if (! flag_unsafe_math_optimizations)
6412 break;
ef722005 6413
6414 CASE_FLT_FN (BUILT_IN_FMOD):
6415 CASE_FLT_FN (BUILT_IN_REMAINDER):
6416 CASE_FLT_FN (BUILT_IN_DREM):
0fd605a5 6417 target = expand_builtin_mathfn_2 (exp, target, subtarget);
6418 if (target)
6419 return target;
6420 break;
6421
d735c391 6422 CASE_FLT_FN (BUILT_IN_CEXPI):
6423 target = expand_builtin_cexpi (exp, target, subtarget);
6424 gcc_assert (target);
6425 return target;
6426
4f35b1fc 6427 CASE_FLT_FN (BUILT_IN_SIN):
6428 CASE_FLT_FN (BUILT_IN_COS):
6b43bae4 6429 if (! flag_unsafe_math_optimizations)
6430 break;
6431 target = expand_builtin_mathfn_3 (exp, target, subtarget);
6432 if (target)
6433 return target;
6434 break;
6435
c3147c1a 6436 CASE_FLT_FN (BUILT_IN_SINCOS):
6437 if (! flag_unsafe_math_optimizations)
6438 break;
6439 target = expand_builtin_sincos (exp);
6440 if (target)
6441 return target;
6442 break;
6443
53800dbe 6444 case BUILT_IN_APPLY_ARGS:
6445 return expand_builtin_apply_args ();
6446
6447 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
6448 FUNCTION with a copy of the parameters described by
6449 ARGUMENTS, and ARGSIZE. It returns a block of memory
6450 allocated on the stack into which is stored all the registers
6451 that might possibly be used for returning the result of a
6452 function. ARGUMENTS is the value returned by
6453 __builtin_apply_args. ARGSIZE is the number of bytes of
6454 arguments that must be copied. ??? How should this value be
6455 computed? We'll also need a safe worst case value for varargs
6456 functions. */
6457 case BUILT_IN_APPLY:
c2f47e15 6458 if (!validate_arglist (exp, POINTER_TYPE,
0eb671f7 6459 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
c2f47e15 6460 && !validate_arglist (exp, REFERENCE_TYPE,
0eb671f7 6461 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
53800dbe 6462 return const0_rtx;
6463 else
6464 {
53800dbe 6465 rtx ops[3];
6466
c2f47e15 6467 ops[0] = expand_normal (CALL_EXPR_ARG (exp, 0));
6468 ops[1] = expand_normal (CALL_EXPR_ARG (exp, 1));
6469 ops[2] = expand_normal (CALL_EXPR_ARG (exp, 2));
53800dbe 6470
6471 return expand_builtin_apply (ops[0], ops[1], ops[2]);
6472 }
6473
6474 /* __builtin_return (RESULT) causes the function to return the
6475 value described by RESULT. RESULT is address of the block of
6476 memory returned by __builtin_apply. */
6477 case BUILT_IN_RETURN:
c2f47e15 6478 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6479 expand_builtin_return (expand_normal (CALL_EXPR_ARG (exp, 0)));
53800dbe 6480 return const0_rtx;
6481
6482 case BUILT_IN_SAVEREGS:
a66c9326 6483 return expand_builtin_saveregs ();
53800dbe 6484
6485 case BUILT_IN_ARGS_INFO:
c2f47e15 6486 return expand_builtin_args_info (exp);
53800dbe 6487
48dc2227 6488 case BUILT_IN_VA_ARG_PACK:
6489 /* All valid uses of __builtin_va_arg_pack () are removed during
6490 inlining. */
b8c23db3 6491 error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp);
48dc2227 6492 return const0_rtx;
6493
4e1d7ea4 6494 case BUILT_IN_VA_ARG_PACK_LEN:
6495 /* All valid uses of __builtin_va_arg_pack_len () are removed during
6496 inlining. */
b8c23db3 6497 error ("%Kinvalid use of %<__builtin_va_arg_pack_len ()%>", exp);
4e1d7ea4 6498 return const0_rtx;
6499
53800dbe 6500 /* Return the address of the first anonymous stack arg. */
6501 case BUILT_IN_NEXT_ARG:
c2f47e15 6502 if (fold_builtin_next_arg (exp, false))
a0c938f0 6503 return const0_rtx;
79012a9d 6504 return expand_builtin_next_arg ();
53800dbe 6505
ac8fb6db 6506 case BUILT_IN_CLEAR_CACHE:
6507 target = expand_builtin___clear_cache (exp);
6508 if (target)
6509 return target;
6510 break;
6511
53800dbe 6512 case BUILT_IN_CLASSIFY_TYPE:
c2f47e15 6513 return expand_builtin_classify_type (exp);
53800dbe 6514
6515 case BUILT_IN_CONSTANT_P:
4ee9c684 6516 return const0_rtx;
53800dbe 6517
6518 case BUILT_IN_FRAME_ADDRESS:
6519 case BUILT_IN_RETURN_ADDRESS:
c2f47e15 6520 return expand_builtin_frame_address (fndecl, exp);
53800dbe 6521
6522 /* Returns the address of the area where the structure is returned.
6523 0 otherwise. */
6524 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
c2f47e15 6525 if (call_expr_nargs (exp) != 0
9342ee68 6526 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
e16ceb8e 6527 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
9342ee68 6528 return const0_rtx;
53800dbe 6529 else
9342ee68 6530 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
53800dbe 6531
6532 case BUILT_IN_ALLOCA:
c2f47e15 6533 target = expand_builtin_alloca (exp, target);
53800dbe 6534 if (target)
6535 return target;
6536 break;
6537
4ee9c684 6538 case BUILT_IN_STACK_SAVE:
6539 return expand_stack_save ();
6540
6541 case BUILT_IN_STACK_RESTORE:
c2f47e15 6542 expand_stack_restore (CALL_EXPR_ARG (exp, 0));
4ee9c684 6543 return const0_rtx;
6544
42791117 6545 case BUILT_IN_BSWAP32:
6546 case BUILT_IN_BSWAP64:
c2f47e15 6547 target = expand_builtin_bswap (exp, target, subtarget);
42791117 6548
6549 if (target)
6550 return target;
6551 break;
6552
4f35b1fc 6553 CASE_INT_FN (BUILT_IN_FFS):
5053259b 6554 case BUILT_IN_FFSIMAX:
c2f47e15 6555 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6556 subtarget, ffs_optab);
6a08d0ab 6557 if (target)
6558 return target;
6559 break;
6560
4f35b1fc 6561 CASE_INT_FN (BUILT_IN_CLZ):
5053259b 6562 case BUILT_IN_CLZIMAX:
c2f47e15 6563 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6564 subtarget, clz_optab);
6a08d0ab 6565 if (target)
6566 return target;
6567 break;
6568
4f35b1fc 6569 CASE_INT_FN (BUILT_IN_CTZ):
5053259b 6570 case BUILT_IN_CTZIMAX:
c2f47e15 6571 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6572 subtarget, ctz_optab);
6a08d0ab 6573 if (target)
6574 return target;
6575 break;
6576
4f35b1fc 6577 CASE_INT_FN (BUILT_IN_POPCOUNT):
5053259b 6578 case BUILT_IN_POPCOUNTIMAX:
c2f47e15 6579 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6580 subtarget, popcount_optab);
6a08d0ab 6581 if (target)
6582 return target;
6583 break;
6584
4f35b1fc 6585 CASE_INT_FN (BUILT_IN_PARITY):
5053259b 6586 case BUILT_IN_PARITYIMAX:
c2f47e15 6587 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6588 subtarget, parity_optab);
53800dbe 6589 if (target)
6590 return target;
6591 break;
6592
6593 case BUILT_IN_STRLEN:
c2f47e15 6594 target = expand_builtin_strlen (exp, target, target_mode);
53800dbe 6595 if (target)
6596 return target;
6597 break;
6598
6599 case BUILT_IN_STRCPY:
c2f47e15 6600 target = expand_builtin_strcpy (fndecl, exp, target, mode);
53800dbe 6601 if (target)
6602 return target;
6603 break;
bf8e3599 6604
ed09096d 6605 case BUILT_IN_STRNCPY:
8ff6a5cd 6606 target = expand_builtin_strncpy (exp, target, mode);
ed09096d 6607 if (target)
6608 return target;
6609 break;
bf8e3599 6610
3b824fa6 6611 case BUILT_IN_STPCPY:
dc369150 6612 target = expand_builtin_stpcpy (exp, target, mode);
3b824fa6 6613 if (target)
6614 return target;
6615 break;
6616
49f0327b 6617 case BUILT_IN_STRCAT:
c2f47e15 6618 target = expand_builtin_strcat (fndecl, exp, target, mode);
49f0327b 6619 if (target)
6620 return target;
6621 break;
bf8e3599 6622
49f0327b 6623 case BUILT_IN_STRNCAT:
c2f47e15 6624 target = expand_builtin_strncat (exp, target, mode);
49f0327b 6625 if (target)
6626 return target;
6627 break;
bf8e3599 6628
49f0327b 6629 case BUILT_IN_STRSPN:
c2f47e15 6630 target = expand_builtin_strspn (exp, target, mode);
49f0327b 6631 if (target)
6632 return target;
6633 break;
bf8e3599 6634
49f0327b 6635 case BUILT_IN_STRCSPN:
c2f47e15 6636 target = expand_builtin_strcspn (exp, target, mode);
49f0327b 6637 if (target)
6638 return target;
6639 break;
bf8e3599 6640
17f5ea87 6641 case BUILT_IN_STRSTR:
c2f47e15 6642 target = expand_builtin_strstr (exp, target, mode);
17f5ea87 6643 if (target)
6644 return target;
6645 break;
bf8e3599 6646
46f3a74a 6647 case BUILT_IN_STRPBRK:
c2f47e15 6648 target = expand_builtin_strpbrk (exp, target, mode);
46f3a74a 6649 if (target)
6650 return target;
6651 break;
bf8e3599 6652
398aae36 6653 case BUILT_IN_INDEX:
83d79705 6654 case BUILT_IN_STRCHR:
c2f47e15 6655 target = expand_builtin_strchr (exp, target, mode);
83d79705 6656 if (target)
6657 return target;
6658 break;
6659
398aae36 6660 case BUILT_IN_RINDEX:
83d79705 6661 case BUILT_IN_STRRCHR:
c2f47e15 6662 target = expand_builtin_strrchr (exp, target, mode);
83d79705 6663 if (target)
6664 return target;
6665 break;
6666
53800dbe 6667 case BUILT_IN_MEMCPY:
5a0de151 6668 target = expand_builtin_memcpy (exp, target, mode);
3b824fa6 6669 if (target)
6670 return target;
6671 break;
6672
6673 case BUILT_IN_MEMPCPY:
c2f47e15 6674 target = expand_builtin_mempcpy (exp, target, mode);
53800dbe 6675 if (target)
6676 return target;
6677 break;
6678
c4950093 6679 case BUILT_IN_MEMMOVE:
c2f47e15 6680 target = expand_builtin_memmove (exp, target, mode, ignore);
c4950093 6681 if (target)
6682 return target;
6683 break;
6684
6685 case BUILT_IN_BCOPY:
c2f47e15 6686 target = expand_builtin_bcopy (exp, ignore);
c4950093 6687 if (target)
6688 return target;
6689 break;
6690
53800dbe 6691 case BUILT_IN_MEMSET:
c2f47e15 6692 target = expand_builtin_memset (exp, target, mode);
53800dbe 6693 if (target)
6694 return target;
6695 break;
6696
ffc83088 6697 case BUILT_IN_BZERO:
0b25db21 6698 target = expand_builtin_bzero (exp);
ffc83088 6699 if (target)
6700 return target;
6701 break;
6702
53800dbe 6703 case BUILT_IN_STRCMP:
83d79705 6704 target = expand_builtin_strcmp (exp, target, mode);
53800dbe 6705 if (target)
6706 return target;
6707 break;
6708
ed09096d 6709 case BUILT_IN_STRNCMP:
6710 target = expand_builtin_strncmp (exp, target, mode);
6711 if (target)
6712 return target;
6713 break;
6714
7959b13b 6715 case BUILT_IN_MEMCHR:
6716 target = expand_builtin_memchr (exp, target, mode);
6717 if (target)
6718 return target;
6719 break;
6720
071f1696 6721 case BUILT_IN_BCMP:
53800dbe 6722 case BUILT_IN_MEMCMP:
c2f47e15 6723 target = expand_builtin_memcmp (exp, target, mode);
53800dbe 6724 if (target)
6725 return target;
6726 break;
53800dbe 6727
6728 case BUILT_IN_SETJMP:
2c8a1497 6729 /* This should have been lowered to the builtins below. */
6730 gcc_unreachable ();
6731
6732 case BUILT_IN_SETJMP_SETUP:
6733 /* __builtin_setjmp_setup is passed a pointer to an array of five words
6734 and the receiver label. */
c2f47e15 6735 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2c8a1497 6736 {
c2f47e15 6737 rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
2c8a1497 6738 VOIDmode, EXPAND_NORMAL);
c2f47e15 6739 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 1), 0);
2c8a1497 6740 rtx label_r = label_rtx (label);
6741
6742 /* This is copied from the handling of non-local gotos. */
6743 expand_builtin_setjmp_setup (buf_addr, label_r);
6744 nonlocal_goto_handler_labels
6745 = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6746 nonlocal_goto_handler_labels);
6747 /* ??? Do not let expand_label treat us as such since we would
6748 not want to be both on the list of non-local labels and on
6749 the list of forced labels. */
6750 FORCED_LABEL (label) = 0;
6751 return const0_rtx;
6752 }
6753 break;
6754
6755 case BUILT_IN_SETJMP_DISPATCHER:
6756 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */
c2f47e15 6757 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
2c8a1497 6758 {
c2f47e15 6759 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
2c8a1497 6760 rtx label_r = label_rtx (label);
6761
6762 /* Remove the dispatcher label from the list of non-local labels
6763 since the receiver labels have been added to it above. */
6764 remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6765 return const0_rtx;
6766 }
6767 break;
6768
6769 case BUILT_IN_SETJMP_RECEIVER:
6770 /* __builtin_setjmp_receiver is passed the receiver label. */
c2f47e15 6771 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
2c8a1497 6772 {
c2f47e15 6773 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
2c8a1497 6774 rtx label_r = label_rtx (label);
6775
6776 expand_builtin_setjmp_receiver (label_r);
6777 return const0_rtx;
6778 }
6b7f6858 6779 break;
53800dbe 6780
6781 /* __builtin_longjmp is passed a pointer to an array of five words.
6782 It's similar to the C library longjmp function but works with
6783 __builtin_setjmp above. */
6784 case BUILT_IN_LONGJMP:
c2f47e15 6785 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
53800dbe 6786 {
c2f47e15 6787 rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
8ec3c5c2 6788 VOIDmode, EXPAND_NORMAL);
c2f47e15 6789 rtx value = expand_normal (CALL_EXPR_ARG (exp, 1));
53800dbe 6790
6791 if (value != const1_rtx)
6792 {
1e5fcbe2 6793 error ("%<__builtin_longjmp%> second argument must be 1");
53800dbe 6794 return const0_rtx;
6795 }
6796
6797 expand_builtin_longjmp (buf_addr, value);
6798 return const0_rtx;
6799 }
2c8a1497 6800 break;
53800dbe 6801
4ee9c684 6802 case BUILT_IN_NONLOCAL_GOTO:
c2f47e15 6803 target = expand_builtin_nonlocal_goto (exp);
4ee9c684 6804 if (target)
6805 return target;
6806 break;
6807
843d08a9 6808 /* This updates the setjmp buffer that is its argument with the value
6809 of the current stack pointer. */
6810 case BUILT_IN_UPDATE_SETJMP_BUF:
c2f47e15 6811 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
843d08a9 6812 {
6813 rtx buf_addr
c2f47e15 6814 = expand_normal (CALL_EXPR_ARG (exp, 0));
843d08a9 6815
6816 expand_builtin_update_setjmp_buf (buf_addr);
6817 return const0_rtx;
6818 }
6819 break;
6820
53800dbe 6821 case BUILT_IN_TRAP:
a0ef1725 6822 expand_builtin_trap ();
53800dbe 6823 return const0_rtx;
6824
d2b48f0c 6825 case BUILT_IN_UNREACHABLE:
6826 expand_builtin_unreachable ();
6827 return const0_rtx;
6828
19bf118a 6829 case BUILT_IN_PRINTF:
0b25db21 6830 target = expand_builtin_printf (exp, target, mode, false);
19bf118a 6831 if (target)
6832 return target;
6833 break;
6834
6835 case BUILT_IN_PRINTF_UNLOCKED:
0b25db21 6836 target = expand_builtin_printf (exp, target, mode, true);
19bf118a 6837 if (target)
6838 return target;
6839 break;
6840
df94cd3b 6841 case BUILT_IN_FPUTS:
c2f47e15 6842 target = expand_builtin_fputs (exp, target, false);
c013a46e 6843 if (target)
6844 return target;
6845 break;
6846 case BUILT_IN_FPUTS_UNLOCKED:
c2f47e15 6847 target = expand_builtin_fputs (exp, target, true);
19bf118a 6848 if (target)
6849 return target;
6850 break;
6851
6852 case BUILT_IN_FPRINTF:
0b25db21 6853 target = expand_builtin_fprintf (exp, target, mode, false);
19bf118a 6854 if (target)
6855 return target;
6856 break;
6857
6858 case BUILT_IN_FPRINTF_UNLOCKED:
0b25db21 6859 target = expand_builtin_fprintf (exp, target, mode, true);
df94cd3b 6860 if (target)
6861 return target;
6862 break;
bf8e3599 6863
6411575e 6864 case BUILT_IN_SPRINTF:
c2f47e15 6865 target = expand_builtin_sprintf (exp, target, mode);
6411575e 6866 if (target)
6867 return target;
6868 break;
6869
4f35b1fc 6870 CASE_FLT_FN (BUILT_IN_SIGNBIT):
004e23c4 6871 case BUILT_IN_SIGNBITD32:
6872 case BUILT_IN_SIGNBITD64:
6873 case BUILT_IN_SIGNBITD128:
27f261ef 6874 target = expand_builtin_signbit (exp, target);
6875 if (target)
6876 return target;
6877 break;
6878
53800dbe 6879 /* Various hooks for the DWARF 2 __throw routine. */
6880 case BUILT_IN_UNWIND_INIT:
6881 expand_builtin_unwind_init ();
6882 return const0_rtx;
6883 case BUILT_IN_DWARF_CFA:
6884 return virtual_cfa_rtx;
6885#ifdef DWARF2_UNWIND_INFO
f8f023a5 6886 case BUILT_IN_DWARF_SP_COLUMN:
6887 return expand_builtin_dwarf_sp_column ();
695e919b 6888 case BUILT_IN_INIT_DWARF_REG_SIZES:
c2f47e15 6889 expand_builtin_init_dwarf_reg_sizes (CALL_EXPR_ARG (exp, 0));
695e919b 6890 return const0_rtx;
53800dbe 6891#endif
6892 case BUILT_IN_FROB_RETURN_ADDR:
c2f47e15 6893 return expand_builtin_frob_return_addr (CALL_EXPR_ARG (exp, 0));
53800dbe 6894 case BUILT_IN_EXTRACT_RETURN_ADDR:
c2f47e15 6895 return expand_builtin_extract_return_addr (CALL_EXPR_ARG (exp, 0));
53800dbe 6896 case BUILT_IN_EH_RETURN:
c2f47e15 6897 expand_builtin_eh_return (CALL_EXPR_ARG (exp, 0),
6898 CALL_EXPR_ARG (exp, 1));
53800dbe 6899 return const0_rtx;
df4b504c 6900#ifdef EH_RETURN_DATA_REGNO
6901 case BUILT_IN_EH_RETURN_DATA_REGNO:
c2f47e15 6902 return expand_builtin_eh_return_data_regno (exp);
df4b504c 6903#endif
26093bf4 6904 case BUILT_IN_EXTEND_POINTER:
c2f47e15 6905 return expand_builtin_extend_pointer (CALL_EXPR_ARG (exp, 0));
26093bf4 6906
7ccc713a 6907 case BUILT_IN_VA_START:
c2f47e15 6908 return expand_builtin_va_start (exp);
a66c9326 6909 case BUILT_IN_VA_END:
c2f47e15 6910 return expand_builtin_va_end (exp);
a66c9326 6911 case BUILT_IN_VA_COPY:
c2f47e15 6912 return expand_builtin_va_copy (exp);
89cfe6e5 6913 case BUILT_IN_EXPECT:
c2f47e15 6914 return expand_builtin_expect (exp, target);
5e3608d8 6915 case BUILT_IN_PREFETCH:
c2f47e15 6916 expand_builtin_prefetch (exp);
5e3608d8 6917 return const0_rtx;
6918
4ee9c684 6919 case BUILT_IN_PROFILE_FUNC_ENTER:
6920 return expand_builtin_profile_func (false);
6921 case BUILT_IN_PROFILE_FUNC_EXIT:
6922 return expand_builtin_profile_func (true);
6923
6924 case BUILT_IN_INIT_TRAMPOLINE:
c2f47e15 6925 return expand_builtin_init_trampoline (exp);
4ee9c684 6926 case BUILT_IN_ADJUST_TRAMPOLINE:
c2f47e15 6927 return expand_builtin_adjust_trampoline (exp);
4ee9c684 6928
73673831 6929 case BUILT_IN_FORK:
6930 case BUILT_IN_EXECL:
6931 case BUILT_IN_EXECV:
6932 case BUILT_IN_EXECLP:
6933 case BUILT_IN_EXECLE:
6934 case BUILT_IN_EXECVP:
6935 case BUILT_IN_EXECVE:
c2f47e15 6936 target = expand_builtin_fork_or_exec (fndecl, exp, target, ignore);
73673831 6937 if (target)
6938 return target;
6939 break;
53800dbe 6940
b6a5fc45 6941 case BUILT_IN_FETCH_AND_ADD_1:
6942 case BUILT_IN_FETCH_AND_ADD_2:
6943 case BUILT_IN_FETCH_AND_ADD_4:
6944 case BUILT_IN_FETCH_AND_ADD_8:
27213ba3 6945 case BUILT_IN_FETCH_AND_ADD_16:
3e272de8 6946 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
c2f47e15 6947 target = expand_builtin_sync_operation (mode, exp, PLUS,
b6a5fc45 6948 false, target, ignore);
6949 if (target)
6950 return target;
6951 break;
6952
6953 case BUILT_IN_FETCH_AND_SUB_1:
6954 case BUILT_IN_FETCH_AND_SUB_2:
6955 case BUILT_IN_FETCH_AND_SUB_4:
6956 case BUILT_IN_FETCH_AND_SUB_8:
27213ba3 6957 case BUILT_IN_FETCH_AND_SUB_16:
3e272de8 6958 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
c2f47e15 6959 target = expand_builtin_sync_operation (mode, exp, MINUS,
b6a5fc45 6960 false, target, ignore);
6961 if (target)
6962 return target;
6963 break;
6964
6965 case BUILT_IN_FETCH_AND_OR_1:
6966 case BUILT_IN_FETCH_AND_OR_2:
6967 case BUILT_IN_FETCH_AND_OR_4:
6968 case BUILT_IN_FETCH_AND_OR_8:
27213ba3 6969 case BUILT_IN_FETCH_AND_OR_16:
3e272de8 6970 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
c2f47e15 6971 target = expand_builtin_sync_operation (mode, exp, IOR,
b6a5fc45 6972 false, target, ignore);
6973 if (target)
6974 return target;
6975 break;
6976
6977 case BUILT_IN_FETCH_AND_AND_1:
6978 case BUILT_IN_FETCH_AND_AND_2:
6979 case BUILT_IN_FETCH_AND_AND_4:
6980 case BUILT_IN_FETCH_AND_AND_8:
27213ba3 6981 case BUILT_IN_FETCH_AND_AND_16:
3e272de8 6982 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
c2f47e15 6983 target = expand_builtin_sync_operation (mode, exp, AND,
b6a5fc45 6984 false, target, ignore);
6985 if (target)
6986 return target;
6987 break;
6988
6989 case BUILT_IN_FETCH_AND_XOR_1:
6990 case BUILT_IN_FETCH_AND_XOR_2:
6991 case BUILT_IN_FETCH_AND_XOR_4:
6992 case BUILT_IN_FETCH_AND_XOR_8:
27213ba3 6993 case BUILT_IN_FETCH_AND_XOR_16:
3e272de8 6994 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
c2f47e15 6995 target = expand_builtin_sync_operation (mode, exp, XOR,
b6a5fc45 6996 false, target, ignore);
6997 if (target)
6998 return target;
6999 break;
7000
7001 case BUILT_IN_FETCH_AND_NAND_1:
7002 case BUILT_IN_FETCH_AND_NAND_2:
7003 case BUILT_IN_FETCH_AND_NAND_4:
7004 case BUILT_IN_FETCH_AND_NAND_8:
27213ba3 7005 case BUILT_IN_FETCH_AND_NAND_16:
3e272de8 7006 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
c2f47e15 7007 target = expand_builtin_sync_operation (mode, exp, NOT,
b6a5fc45 7008 false, target, ignore);
7009 if (target)
7010 return target;
7011 break;
7012
7013 case BUILT_IN_ADD_AND_FETCH_1:
7014 case BUILT_IN_ADD_AND_FETCH_2:
7015 case BUILT_IN_ADD_AND_FETCH_4:
7016 case BUILT_IN_ADD_AND_FETCH_8:
27213ba3 7017 case BUILT_IN_ADD_AND_FETCH_16:
3e272de8 7018 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
c2f47e15 7019 target = expand_builtin_sync_operation (mode, exp, PLUS,
b6a5fc45 7020 true, target, ignore);
7021 if (target)
7022 return target;
7023 break;
7024
7025 case BUILT_IN_SUB_AND_FETCH_1:
7026 case BUILT_IN_SUB_AND_FETCH_2:
7027 case BUILT_IN_SUB_AND_FETCH_4:
7028 case BUILT_IN_SUB_AND_FETCH_8:
27213ba3 7029 case BUILT_IN_SUB_AND_FETCH_16:
3e272de8 7030 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
c2f47e15 7031 target = expand_builtin_sync_operation (mode, exp, MINUS,
b6a5fc45 7032 true, target, ignore);
7033 if (target)
7034 return target;
7035 break;
7036
7037 case BUILT_IN_OR_AND_FETCH_1:
7038 case BUILT_IN_OR_AND_FETCH_2:
7039 case BUILT_IN_OR_AND_FETCH_4:
7040 case BUILT_IN_OR_AND_FETCH_8:
27213ba3 7041 case BUILT_IN_OR_AND_FETCH_16:
3e272de8 7042 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
c2f47e15 7043 target = expand_builtin_sync_operation (mode, exp, IOR,
b6a5fc45 7044 true, target, ignore);
7045 if (target)
7046 return target;
7047 break;
7048
7049 case BUILT_IN_AND_AND_FETCH_1:
7050 case BUILT_IN_AND_AND_FETCH_2:
7051 case BUILT_IN_AND_AND_FETCH_4:
7052 case BUILT_IN_AND_AND_FETCH_8:
27213ba3 7053 case BUILT_IN_AND_AND_FETCH_16:
3e272de8 7054 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
c2f47e15 7055 target = expand_builtin_sync_operation (mode, exp, AND,
b6a5fc45 7056 true, target, ignore);
7057 if (target)
7058 return target;
7059 break;
7060
7061 case BUILT_IN_XOR_AND_FETCH_1:
7062 case BUILT_IN_XOR_AND_FETCH_2:
7063 case BUILT_IN_XOR_AND_FETCH_4:
7064 case BUILT_IN_XOR_AND_FETCH_8:
27213ba3 7065 case BUILT_IN_XOR_AND_FETCH_16:
3e272de8 7066 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
c2f47e15 7067 target = expand_builtin_sync_operation (mode, exp, XOR,
b6a5fc45 7068 true, target, ignore);
7069 if (target)
7070 return target;
7071 break;
7072
7073 case BUILT_IN_NAND_AND_FETCH_1:
7074 case BUILT_IN_NAND_AND_FETCH_2:
7075 case BUILT_IN_NAND_AND_FETCH_4:
7076 case BUILT_IN_NAND_AND_FETCH_8:
27213ba3 7077 case BUILT_IN_NAND_AND_FETCH_16:
3e272de8 7078 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
c2f47e15 7079 target = expand_builtin_sync_operation (mode, exp, NOT,
b6a5fc45 7080 true, target, ignore);
7081 if (target)
7082 return target;
7083 break;
7084
7085 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
7086 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
7087 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
7088 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
27213ba3 7089 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
a601d32a 7090 if (mode == VOIDmode)
7091 mode = TYPE_MODE (boolean_type_node);
b6a5fc45 7092 if (!target || !register_operand (target, mode))
7093 target = gen_reg_rtx (mode);
3e272de8 7094
7095 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
c2f47e15 7096 target = expand_builtin_compare_and_swap (mode, exp, true, target);
b6a5fc45 7097 if (target)
7098 return target;
7099 break;
7100
7101 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
7102 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
7103 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
7104 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
27213ba3 7105 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
3e272de8 7106 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
c2f47e15 7107 target = expand_builtin_compare_and_swap (mode, exp, false, target);
b6a5fc45 7108 if (target)
7109 return target;
7110 break;
7111
7112 case BUILT_IN_LOCK_TEST_AND_SET_1:
7113 case BUILT_IN_LOCK_TEST_AND_SET_2:
7114 case BUILT_IN_LOCK_TEST_AND_SET_4:
7115 case BUILT_IN_LOCK_TEST_AND_SET_8:
27213ba3 7116 case BUILT_IN_LOCK_TEST_AND_SET_16:
3e272de8 7117 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
c2f47e15 7118 target = expand_builtin_lock_test_and_set (mode, exp, target);
b6a5fc45 7119 if (target)
7120 return target;
7121 break;
7122
7123 case BUILT_IN_LOCK_RELEASE_1:
7124 case BUILT_IN_LOCK_RELEASE_2:
7125 case BUILT_IN_LOCK_RELEASE_4:
7126 case BUILT_IN_LOCK_RELEASE_8:
27213ba3 7127 case BUILT_IN_LOCK_RELEASE_16:
3e272de8 7128 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
c2f47e15 7129 expand_builtin_lock_release (mode, exp);
b6a5fc45 7130 return const0_rtx;
7131
7132 case BUILT_IN_SYNCHRONIZE:
7133 expand_builtin_synchronize ();
7134 return const0_rtx;
7135
0a39fd54 7136 case BUILT_IN_OBJECT_SIZE:
7137 return expand_builtin_object_size (exp);
7138
7139 case BUILT_IN_MEMCPY_CHK:
7140 case BUILT_IN_MEMPCPY_CHK:
7141 case BUILT_IN_MEMMOVE_CHK:
7142 case BUILT_IN_MEMSET_CHK:
7143 target = expand_builtin_memory_chk (exp, target, mode, fcode);
7144 if (target)
7145 return target;
7146 break;
7147
7148 case BUILT_IN_STRCPY_CHK:
7149 case BUILT_IN_STPCPY_CHK:
7150 case BUILT_IN_STRNCPY_CHK:
7151 case BUILT_IN_STRCAT_CHK:
b356dfef 7152 case BUILT_IN_STRNCAT_CHK:
0a39fd54 7153 case BUILT_IN_SNPRINTF_CHK:
7154 case BUILT_IN_VSNPRINTF_CHK:
7155 maybe_emit_chk_warning (exp, fcode);
7156 break;
7157
7158 case BUILT_IN_SPRINTF_CHK:
7159 case BUILT_IN_VSPRINTF_CHK:
7160 maybe_emit_sprintf_chk_warning (exp, fcode);
7161 break;
7162
2c281b15 7163 case BUILT_IN_FREE:
7164 maybe_emit_free_warning (exp);
7165 break;
7166
92482ee0 7167 default: /* just do library call, if unknown builtin */
146c1b4f 7168 break;
53800dbe 7169 }
7170
7171 /* The switch statement above can drop through to cause the function
7172 to be called normally. */
7173 return expand_call (exp, target, ignore);
7174}
650e4c94 7175
805e22b2 7176/* Determine whether a tree node represents a call to a built-in
52203a9d 7177 function. If the tree T is a call to a built-in function with
7178 the right number of arguments of the appropriate types, return
7179 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
7180 Otherwise the return value is END_BUILTINS. */
aecda0d6 7181
805e22b2 7182enum built_in_function
b7bf20db 7183builtin_mathfn_code (const_tree t)
805e22b2 7184{
b7bf20db 7185 const_tree fndecl, arg, parmlist;
7186 const_tree argtype, parmtype;
7187 const_call_expr_arg_iterator iter;
805e22b2 7188
7189 if (TREE_CODE (t) != CALL_EXPR
c2f47e15 7190 || TREE_CODE (CALL_EXPR_FN (t)) != ADDR_EXPR)
805e22b2 7191 return END_BUILTINS;
7192
c6e6ecb1 7193 fndecl = get_callee_fndecl (t);
7194 if (fndecl == NULL_TREE
52203a9d 7195 || TREE_CODE (fndecl) != FUNCTION_DECL
805e22b2 7196 || ! DECL_BUILT_IN (fndecl)
7197 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7198 return END_BUILTINS;
7199
52203a9d 7200 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
b7bf20db 7201 init_const_call_expr_arg_iterator (t, &iter);
52203a9d 7202 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
e9f80ff5 7203 {
52203a9d 7204 /* If a function doesn't take a variable number of arguments,
7205 the last element in the list will have type `void'. */
7206 parmtype = TREE_VALUE (parmlist);
7207 if (VOID_TYPE_P (parmtype))
7208 {
b7bf20db 7209 if (more_const_call_expr_args_p (&iter))
52203a9d 7210 return END_BUILTINS;
7211 return DECL_FUNCTION_CODE (fndecl);
7212 }
7213
b7bf20db 7214 if (! more_const_call_expr_args_p (&iter))
e9f80ff5 7215 return END_BUILTINS;
c2f47e15 7216
b7bf20db 7217 arg = next_const_call_expr_arg (&iter);
c2f47e15 7218 argtype = TREE_TYPE (arg);
52203a9d 7219
7220 if (SCALAR_FLOAT_TYPE_P (parmtype))
7221 {
7222 if (! SCALAR_FLOAT_TYPE_P (argtype))
7223 return END_BUILTINS;
7224 }
7225 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
7226 {
7227 if (! COMPLEX_FLOAT_TYPE_P (argtype))
7228 return END_BUILTINS;
7229 }
7230 else if (POINTER_TYPE_P (parmtype))
7231 {
7232 if (! POINTER_TYPE_P (argtype))
7233 return END_BUILTINS;
7234 }
7235 else if (INTEGRAL_TYPE_P (parmtype))
7236 {
7237 if (! INTEGRAL_TYPE_P (argtype))
7238 return END_BUILTINS;
7239 }
7240 else
e9f80ff5 7241 return END_BUILTINS;
e9f80ff5 7242 }
7243
52203a9d 7244 /* Variable-length argument list. */
805e22b2 7245 return DECL_FUNCTION_CODE (fndecl);
7246}
7247
c2f47e15 7248/* Fold a call to __builtin_constant_p, if we know its argument ARG will
7249 evaluate to a constant. */
650e4c94 7250
7251static tree
c2f47e15 7252fold_builtin_constant_p (tree arg)
650e4c94 7253{
650e4c94 7254 /* We return 1 for a numeric type that's known to be a constant
7255 value at compile-time or for an aggregate type that's a
7256 literal constant. */
c2f47e15 7257 STRIP_NOPS (arg);
650e4c94 7258
7259 /* If we know this is a constant, emit the constant of one. */
c2f47e15 7260 if (CONSTANT_CLASS_P (arg)
7261 || (TREE_CODE (arg) == CONSTRUCTOR
7262 && TREE_CONSTANT (arg)))
650e4c94 7263 return integer_one_node;
c2f47e15 7264 if (TREE_CODE (arg) == ADDR_EXPR)
adcfa3a3 7265 {
c2f47e15 7266 tree op = TREE_OPERAND (arg, 0);
adcfa3a3 7267 if (TREE_CODE (op) == STRING_CST
7268 || (TREE_CODE (op) == ARRAY_REF
7269 && integer_zerop (TREE_OPERAND (op, 1))
7270 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
7271 return integer_one_node;
7272 }
650e4c94 7273
1fb4300c 7274 /* If this expression has side effects, show we don't know it to be a
7275 constant. Likewise if it's a pointer or aggregate type since in
7276 those case we only want literals, since those are only optimized
f97c71a1 7277 when generating RTL, not later.
7278 And finally, if we are compiling an initializer, not code, we
7279 need to return a definite result now; there's not going to be any
7280 more optimization done. */
c2f47e15 7281 if (TREE_SIDE_EFFECTS (arg)
7282 || AGGREGATE_TYPE_P (TREE_TYPE (arg))
7283 || POINTER_TYPE_P (TREE_TYPE (arg))
47be647d 7284 || cfun == 0
7285 || folding_initializer)
650e4c94 7286 return integer_zero_node;
7287
c2f47e15 7288 return NULL_TREE;
650e4c94 7289}
7290
76f5a783 7291/* Create builtin_expect with PRED and EXPECTED as its arguments and
7292 return it as a truthvalue. */
4ee9c684 7293
7294static tree
76f5a783 7295build_builtin_expect_predicate (tree pred, tree expected)
4ee9c684 7296{
76f5a783 7297 tree fn, arg_types, pred_type, expected_type, call_expr, ret_type;
4ee9c684 7298
76f5a783 7299 fn = built_in_decls[BUILT_IN_EXPECT];
7300 arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
7301 ret_type = TREE_TYPE (TREE_TYPE (fn));
7302 pred_type = TREE_VALUE (arg_types);
7303 expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
7304
7305 pred = fold_convert (pred_type, pred);
7306 expected = fold_convert (expected_type, expected);
7307 call_expr = build_call_expr (fn, 2, pred, expected);
7308
7309 return build2 (NE_EXPR, TREE_TYPE (pred), call_expr,
7310 build_int_cst (ret_type, 0));
7311}
7312
7313/* Fold a call to builtin_expect with arguments ARG0 and ARG1. Return
7314 NULL_TREE if no simplification is possible. */
7315
7316static tree
7317fold_builtin_expect (tree arg0, tree arg1)
7318{
7319 tree inner, fndecl;
7320 enum tree_code code;
7321
7322 /* If this is a builtin_expect within a builtin_expect keep the
7323 inner one. See through a comparison against a constant. It
7324 might have been added to create a thruthvalue. */
7325 inner = arg0;
7326 if (COMPARISON_CLASS_P (inner)
7327 && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST)
7328 inner = TREE_OPERAND (inner, 0);
7329
7330 if (TREE_CODE (inner) == CALL_EXPR
7331 && (fndecl = get_callee_fndecl (inner))
7332 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
7333 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT)
7334 return arg0;
7335
7336 /* Distribute the expected value over short-circuiting operators.
7337 See through the cast from truthvalue_type_node to long. */
7338 inner = arg0;
7339 while (TREE_CODE (inner) == NOP_EXPR
7340 && INTEGRAL_TYPE_P (TREE_TYPE (inner))
7341 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (inner, 0))))
7342 inner = TREE_OPERAND (inner, 0);
7343
7344 code = TREE_CODE (inner);
7345 if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
7346 {
7347 tree op0 = TREE_OPERAND (inner, 0);
7348 tree op1 = TREE_OPERAND (inner, 1);
7349
7350 op0 = build_builtin_expect_predicate (op0, arg1);
7351 op1 = build_builtin_expect_predicate (op1, arg1);
7352 inner = build2 (code, TREE_TYPE (inner), op0, op1);
7353
7354 return fold_convert (TREE_TYPE (arg0), inner);
7355 }
7356
7357 /* If the argument isn't invariant then there's nothing else we can do. */
c7d4e749 7358 if (!TREE_CONSTANT (arg0))
c2f47e15 7359 return NULL_TREE;
4ee9c684 7360
76f5a783 7361 /* If we expect that a comparison against the argument will fold to
7362 a constant return the constant. In practice, this means a true
7363 constant or the address of a non-weak symbol. */
7364 inner = arg0;
4ee9c684 7365 STRIP_NOPS (inner);
7366 if (TREE_CODE (inner) == ADDR_EXPR)
7367 {
7368 do
7369 {
7370 inner = TREE_OPERAND (inner, 0);
7371 }
7372 while (TREE_CODE (inner) == COMPONENT_REF
7373 || TREE_CODE (inner) == ARRAY_REF);
062b4460 7374 if ((TREE_CODE (inner) == VAR_DECL
7375 || TREE_CODE (inner) == FUNCTION_DECL)
7376 && DECL_WEAK (inner))
c2f47e15 7377 return NULL_TREE;
4ee9c684 7378 }
7379
76f5a783 7380 /* Otherwise, ARG0 already has the proper type for the return value. */
7381 return arg0;
4ee9c684 7382}
7383
c2f47e15 7384/* Fold a call to __builtin_classify_type with argument ARG. */
27d0c333 7385
539a3a92 7386static tree
c2f47e15 7387fold_builtin_classify_type (tree arg)
539a3a92 7388{
c2f47e15 7389 if (arg == 0)
7016c612 7390 return build_int_cst (NULL_TREE, no_type_class);
539a3a92 7391
c2f47e15 7392 return build_int_cst (NULL_TREE, type_to_class (TREE_TYPE (arg)));
539a3a92 7393}
7394
c2f47e15 7395/* Fold a call to __builtin_strlen with argument ARG. */
e6e27594 7396
7397static tree
c2f47e15 7398fold_builtin_strlen (tree arg)
e6e27594 7399{
c2f47e15 7400 if (!validate_arg (arg, POINTER_TYPE))
e6e27594 7401 return NULL_TREE;
7402 else
7403 {
c2f47e15 7404 tree len = c_strlen (arg, 0);
e6e27594 7405
7406 if (len)
7407 {
7408 /* Convert from the internal "sizetype" type to "size_t". */
7409 if (size_type_node)
7410 len = fold_convert (size_type_node, len);
7411 return len;
7412 }
7413
7414 return NULL_TREE;
7415 }
7416}
7417
92c43e3c 7418/* Fold a call to __builtin_inf or __builtin_huge_val. */
7419
7420static tree
aecda0d6 7421fold_builtin_inf (tree type, int warn)
92c43e3c 7422{
aa870c1b 7423 REAL_VALUE_TYPE real;
7424
40f4dbd5 7425 /* __builtin_inff is intended to be usable to define INFINITY on all
7426 targets. If an infinity is not available, INFINITY expands "to a
7427 positive constant of type float that overflows at translation
7428 time", footnote "In this case, using INFINITY will violate the
7429 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
7430 Thus we pedwarn to ensure this constraint violation is
7431 diagnosed. */
92c43e3c 7432 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
21ca8540 7433 pedwarn (input_location, 0, "target format does not support infinity");
92c43e3c 7434
aa870c1b 7435 real_inf (&real);
7436 return build_real (type, real);
92c43e3c 7437}
7438
c2f47e15 7439/* Fold a call to __builtin_nan or __builtin_nans with argument ARG. */
b0db7939 7440
7441static tree
c2f47e15 7442fold_builtin_nan (tree arg, tree type, int quiet)
b0db7939 7443{
7444 REAL_VALUE_TYPE real;
7445 const char *str;
7446
c2f47e15 7447 if (!validate_arg (arg, POINTER_TYPE))
7448 return NULL_TREE;
7449 str = c_getstr (arg);
b0db7939 7450 if (!str)
c2f47e15 7451 return NULL_TREE;
b0db7939 7452
7453 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
c2f47e15 7454 return NULL_TREE;
b0db7939 7455
7456 return build_real (type, real);
7457}
7458
277f8dd2 7459/* Return true if the floating point expression T has an integer value.
7460 We also allow +Inf, -Inf and NaN to be considered integer values. */
7461
7462static bool
7463integer_valued_real_p (tree t)
7464{
7465 switch (TREE_CODE (t))
7466 {
7467 case FLOAT_EXPR:
7468 return true;
7469
7470 case ABS_EXPR:
7471 case SAVE_EXPR:
277f8dd2 7472 return integer_valued_real_p (TREE_OPERAND (t, 0));
7473
7474 case COMPOUND_EXPR:
41076ef6 7475 case MODIFY_EXPR:
277f8dd2 7476 case BIND_EXPR:
75a70cf9 7477 return integer_valued_real_p (TREE_OPERAND (t, 1));
277f8dd2 7478
7479 case PLUS_EXPR:
7480 case MINUS_EXPR:
7481 case MULT_EXPR:
7482 case MIN_EXPR:
7483 case MAX_EXPR:
7484 return integer_valued_real_p (TREE_OPERAND (t, 0))
7485 && integer_valued_real_p (TREE_OPERAND (t, 1));
7486
7487 case COND_EXPR:
7488 return integer_valued_real_p (TREE_OPERAND (t, 1))
7489 && integer_valued_real_p (TREE_OPERAND (t, 2));
7490
7491 case REAL_CST:
0570334c 7492 return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t)));
277f8dd2 7493
7494 case NOP_EXPR:
7495 {
7496 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
7497 if (TREE_CODE (type) == INTEGER_TYPE)
7498 return true;
7499 if (TREE_CODE (type) == REAL_TYPE)
7500 return integer_valued_real_p (TREE_OPERAND (t, 0));
7501 break;
7502 }
7503
7504 case CALL_EXPR:
7505 switch (builtin_mathfn_code (t))
7506 {
4f35b1fc 7507 CASE_FLT_FN (BUILT_IN_CEIL):
7508 CASE_FLT_FN (BUILT_IN_FLOOR):
7509 CASE_FLT_FN (BUILT_IN_NEARBYINT):
7510 CASE_FLT_FN (BUILT_IN_RINT):
7511 CASE_FLT_FN (BUILT_IN_ROUND):
7512 CASE_FLT_FN (BUILT_IN_TRUNC):
277f8dd2 7513 return true;
7514
d4a43a03 7515 CASE_FLT_FN (BUILT_IN_FMIN):
7516 CASE_FLT_FN (BUILT_IN_FMAX):
c2f47e15 7517 return integer_valued_real_p (CALL_EXPR_ARG (t, 0))
7518 && integer_valued_real_p (CALL_EXPR_ARG (t, 1));
d4a43a03 7519
277f8dd2 7520 default:
7521 break;
7522 }
7523 break;
7524
7525 default:
7526 break;
7527 }
7528 return false;
7529}
7530
c2f47e15 7531/* FNDECL is assumed to be a builtin where truncation can be propagated
6528f4f4 7532 across (for instance floor((double)f) == (double)floorf (f).
c2f47e15 7533 Do the transformation for a call with argument ARG. */
277f8dd2 7534
6528f4f4 7535static tree
c2f47e15 7536fold_trunc_transparent_mathfn (tree fndecl, tree arg)
6528f4f4 7537{
6528f4f4 7538 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
277f8dd2 7539
c2f47e15 7540 if (!validate_arg (arg, REAL_TYPE))
7541 return NULL_TREE;
6528f4f4 7542
277f8dd2 7543 /* Integer rounding functions are idempotent. */
7544 if (fcode == builtin_mathfn_code (arg))
7545 return arg;
7546
7547 /* If argument is already integer valued, and we don't need to worry
7548 about setting errno, there's no need to perform rounding. */
7549 if (! flag_errno_math && integer_valued_real_p (arg))
7550 return arg;
7551
7552 if (optimize)
6528f4f4 7553 {
277f8dd2 7554 tree arg0 = strip_float_extensions (arg);
2426241c 7555 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6528f4f4 7556 tree newtype = TREE_TYPE (arg0);
7557 tree decl;
7558
7559 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7560 && (decl = mathfn_built_in (newtype, fcode)))
c2f47e15 7561 return fold_convert (ftype,
7562 build_call_expr (decl, 1,
7563 fold_convert (newtype, arg0)));
6528f4f4 7564 }
c2f47e15 7565 return NULL_TREE;
6528f4f4 7566}
7567
c2f47e15 7568/* FNDECL is assumed to be builtin which can narrow the FP type of
7569 the argument, for instance lround((double)f) -> lroundf (f).
7570 Do the transformation for a call with argument ARG. */
9ed65c7f 7571
7572static tree
c2f47e15 7573fold_fixed_mathfn (tree fndecl, tree arg)
9ed65c7f 7574{
9ed65c7f 7575 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
9ed65c7f 7576
c2f47e15 7577 if (!validate_arg (arg, REAL_TYPE))
7578 return NULL_TREE;
9ed65c7f 7579
7580 /* If argument is already integer valued, and we don't need to worry
7581 about setting errno, there's no need to perform rounding. */
7582 if (! flag_errno_math && integer_valued_real_p (arg))
49d00087 7583 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
9ed65c7f 7584
7585 if (optimize)
7586 {
7587 tree ftype = TREE_TYPE (arg);
7588 tree arg0 = strip_float_extensions (arg);
7589 tree newtype = TREE_TYPE (arg0);
7590 tree decl;
7591
7592 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7593 && (decl = mathfn_built_in (newtype, fcode)))
c2f47e15 7594 return build_call_expr (decl, 1, fold_convert (newtype, arg0));
9ed65c7f 7595 }
73a0da56 7596
7597 /* Canonicalize llround (x) to lround (x) on LP64 targets where
7598 sizeof (long long) == sizeof (long). */
7599 if (TYPE_PRECISION (long_long_integer_type_node)
7600 == TYPE_PRECISION (long_integer_type_node))
7601 {
7602 tree newfn = NULL_TREE;
7603 switch (fcode)
7604 {
7605 CASE_FLT_FN (BUILT_IN_LLCEIL):
7606 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7607 break;
7608
7609 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7610 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7611 break;
7612
7613 CASE_FLT_FN (BUILT_IN_LLROUND):
7614 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7615 break;
7616
7617 CASE_FLT_FN (BUILT_IN_LLRINT):
7618 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7619 break;
7620
7621 default:
7622 break;
7623 }
7624
7625 if (newfn)
7626 {
c2f47e15 7627 tree newcall = build_call_expr(newfn, 1, arg);
73a0da56 7628 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
7629 }
7630 }
7631
c2f47e15 7632 return NULL_TREE;
9ed65c7f 7633}
7634
c2f47e15 7635/* Fold call to builtin cabs, cabsf or cabsl with argument ARG. TYPE is the
7636 return type. Return NULL_TREE if no simplification can be made. */
c63f4ad3 7637
7638static tree
c2f47e15 7639fold_builtin_cabs (tree arg, tree type, tree fndecl)
c63f4ad3 7640{
c2f47e15 7641 tree res;
c63f4ad3 7642
c63f4ad3 7643 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
7644 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7645 return NULL_TREE;
7646
b4725390 7647 /* Calculate the result when the argument is a constant. */
7648 if (TREE_CODE (arg) == COMPLEX_CST
7649 && (res = do_mpfr_arg2 (TREE_REALPART (arg), TREE_IMAGPART (arg),
7650 type, mpfr_hypot)))
7651 return res;
7652
1af0d139 7653 if (TREE_CODE (arg) == COMPLEX_EXPR)
7654 {
7655 tree real = TREE_OPERAND (arg, 0);
7656 tree imag = TREE_OPERAND (arg, 1);
7657
7658 /* If either part is zero, cabs is fabs of the other. */
7659 if (real_zerop (real))
7660 return fold_build1 (ABS_EXPR, type, imag);
7661 if (real_zerop (imag))
7662 return fold_build1 (ABS_EXPR, type, real);
7663
7664 /* cabs(x+xi) -> fabs(x)*sqrt(2). */
7665 if (flag_unsafe_math_optimizations
7666 && operand_equal_p (real, imag, OEP_PURE_SAME))
7667 {
2e7ca27b 7668 const REAL_VALUE_TYPE sqrt2_trunc
7910b2fb 7669 = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
1af0d139 7670 STRIP_NOPS (real);
7671 return fold_build2 (MULT_EXPR, type,
7672 fold_build1 (ABS_EXPR, type, real),
2e7ca27b 7673 build_real (type, sqrt2_trunc));
1af0d139 7674 }
7675 }
c63f4ad3 7676
749891b2 7677 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
7678 if (TREE_CODE (arg) == NEGATE_EXPR
7679 || TREE_CODE (arg) == CONJ_EXPR)
c2f47e15 7680 return build_call_expr (fndecl, 1, TREE_OPERAND (arg, 0));
749891b2 7681
7d3f6cc7 7682 /* Don't do this when optimizing for size. */
7683 if (flag_unsafe_math_optimizations
0bfd8d5c 7684 && optimize && optimize_function_for_speed_p (cfun))
c63f4ad3 7685 {
0da0dbfa 7686 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
c63f4ad3 7687
7688 if (sqrtfn != NULL_TREE)
7689 {
c2f47e15 7690 tree rpart, ipart, result;
c63f4ad3 7691
4ee9c684 7692 arg = builtin_save_expr (arg);
29a6518e 7693
49d00087 7694 rpart = fold_build1 (REALPART_EXPR, type, arg);
7695 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
c63f4ad3 7696
4ee9c684 7697 rpart = builtin_save_expr (rpart);
7698 ipart = builtin_save_expr (ipart);
c63f4ad3 7699
49d00087 7700 result = fold_build2 (PLUS_EXPR, type,
7701 fold_build2 (MULT_EXPR, type,
7702 rpart, rpart),
7703 fold_build2 (MULT_EXPR, type,
7704 ipart, ipart));
c63f4ad3 7705
c2f47e15 7706 return build_call_expr (sqrtfn, 1, result);
c63f4ad3 7707 }
7708 }
7709
7710 return NULL_TREE;
7711}
7712
c2f47e15 7713/* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG.
7714 Return NULL_TREE if no simplification can be made. */
e6e27594 7715
7716static tree
c2f47e15 7717fold_builtin_sqrt (tree arg, tree type)
e6e27594 7718{
7719
7720 enum built_in_function fcode;
b4e8ab0c 7721 tree res;
c2f47e15 7722
7723 if (!validate_arg (arg, REAL_TYPE))
e6e27594 7724 return NULL_TREE;
7725
b4e8ab0c 7726 /* Calculate the result when the argument is a constant. */
7727 if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst0, NULL, true)))
7728 return res;
7729
e6e27594 7730 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7731 fcode = builtin_mathfn_code (arg);
7732 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7733 {
c2f47e15 7734 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
49d00087 7735 arg = fold_build2 (MULT_EXPR, type,
c2f47e15 7736 CALL_EXPR_ARG (arg, 0),
49d00087 7737 build_real (type, dconsthalf));
c2f47e15 7738 return build_call_expr (expfn, 1, arg);
e6e27594 7739 }
7740
7741 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7742 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7743 {
7744 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7745
7746 if (powfn)
7747 {
c2f47e15 7748 tree arg0 = CALL_EXPR_ARG (arg, 0);
e6e27594 7749 tree tree_root;
7750 /* The inner root was either sqrt or cbrt. */
57510da6 7751 /* This was a conditional expression but it triggered a bug
18381619 7752 in Sun C 5.5. */
ce6cd837 7753 REAL_VALUE_TYPE dconstroot;
7754 if (BUILTIN_SQRT_P (fcode))
7755 dconstroot = dconsthalf;
7756 else
7757 dconstroot = dconst_third ();
e6e27594 7758
7759 /* Adjust for the outer root. */
7760 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7761 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7762 tree_root = build_real (type, dconstroot);
c2f47e15 7763 return build_call_expr (powfn, 2, arg0, tree_root);
e6e27594 7764 }
7765 }
7766
bc33117f 7767 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
e6e27594 7768 if (flag_unsafe_math_optimizations
7769 && (fcode == BUILT_IN_POW
7770 || fcode == BUILT_IN_POWF
7771 || fcode == BUILT_IN_POWL))
7772 {
c2f47e15 7773 tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7774 tree arg0 = CALL_EXPR_ARG (arg, 0);
7775 tree arg1 = CALL_EXPR_ARG (arg, 1);
bc33117f 7776 tree narg1;
7777 if (!tree_expr_nonnegative_p (arg0))
7778 arg0 = build1 (ABS_EXPR, type, arg0);
49d00087 7779 narg1 = fold_build2 (MULT_EXPR, type, arg1,
7780 build_real (type, dconsthalf));
c2f47e15 7781 return build_call_expr (powfn, 2, arg0, narg1);
e6e27594 7782 }
7783
7784 return NULL_TREE;
7785}
7786
c2f47e15 7787/* Fold a builtin function call to cbrt, cbrtf, or cbrtl with argument ARG.
7788 Return NULL_TREE if no simplification can be made. */
7789
e6e27594 7790static tree
c2f47e15 7791fold_builtin_cbrt (tree arg, tree type)
e6e27594 7792{
e6e27594 7793 const enum built_in_function fcode = builtin_mathfn_code (arg);
29f4cd78 7794 tree res;
e6e27594 7795
c2f47e15 7796 if (!validate_arg (arg, REAL_TYPE))
e6e27594 7797 return NULL_TREE;
7798
29f4cd78 7799 /* Calculate the result when the argument is a constant. */
7800 if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7801 return res;
e6e27594 7802
cdfeb715 7803 if (flag_unsafe_math_optimizations)
e6e27594 7804 {
cdfeb715 7805 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7806 if (BUILTIN_EXPONENT_P (fcode))
a0c938f0 7807 {
c2f47e15 7808 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
cdfeb715 7809 const REAL_VALUE_TYPE third_trunc =
7910b2fb 7810 real_value_truncate (TYPE_MODE (type), dconst_third ());
49d00087 7811 arg = fold_build2 (MULT_EXPR, type,
c2f47e15 7812 CALL_EXPR_ARG (arg, 0),
49d00087 7813 build_real (type, third_trunc));
c2f47e15 7814 return build_call_expr (expfn, 1, arg);
cdfeb715 7815 }
e6e27594 7816
cdfeb715 7817 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7818 if (BUILTIN_SQRT_P (fcode))
a0c938f0 7819 {
cdfeb715 7820 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
e6e27594 7821
cdfeb715 7822 if (powfn)
7823 {
c2f47e15 7824 tree arg0 = CALL_EXPR_ARG (arg, 0);
cdfeb715 7825 tree tree_root;
7910b2fb 7826 REAL_VALUE_TYPE dconstroot = dconst_third ();
cdfeb715 7827
7828 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7829 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7830 tree_root = build_real (type, dconstroot);
c2f47e15 7831 return build_call_expr (powfn, 2, arg0, tree_root);
cdfeb715 7832 }
e6e27594 7833 }
7834
cdfeb715 7835 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7836 if (BUILTIN_CBRT_P (fcode))
a0c938f0 7837 {
c2f47e15 7838 tree arg0 = CALL_EXPR_ARG (arg, 0);
cdfeb715 7839 if (tree_expr_nonnegative_p (arg0))
7840 {
7841 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7842
7843 if (powfn)
a0c938f0 7844 {
cdfeb715 7845 tree tree_root;
7846 REAL_VALUE_TYPE dconstroot;
a0c938f0 7847
3fa759a9 7848 real_arithmetic (&dconstroot, MULT_EXPR,
7910b2fb 7849 dconst_third_ptr (), dconst_third_ptr ());
cdfeb715 7850 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7851 tree_root = build_real (type, dconstroot);
c2f47e15 7852 return build_call_expr (powfn, 2, arg0, tree_root);
cdfeb715 7853 }
7854 }
7855 }
a0c938f0 7856
cdfeb715 7857 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
c2f47e15 7858 if (fcode == BUILT_IN_POW
7859 || fcode == BUILT_IN_POWF
cdfeb715 7860 || fcode == BUILT_IN_POWL)
a0c938f0 7861 {
c2f47e15 7862 tree arg00 = CALL_EXPR_ARG (arg, 0);
7863 tree arg01 = CALL_EXPR_ARG (arg, 1);
cdfeb715 7864 if (tree_expr_nonnegative_p (arg00))
7865 {
c2f47e15 7866 tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
cdfeb715 7867 const REAL_VALUE_TYPE dconstroot
7910b2fb 7868 = real_value_truncate (TYPE_MODE (type), dconst_third ());
49d00087 7869 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7870 build_real (type, dconstroot));
c2f47e15 7871 return build_call_expr (powfn, 2, arg00, narg01);
cdfeb715 7872 }
7873 }
e6e27594 7874 }
7875 return NULL_TREE;
7876}
7877
c2f47e15 7878/* Fold function call to builtin cos, cosf, or cosl with argument ARG.
7879 TYPE is the type of the return value. Return NULL_TREE if no
7880 simplification can be made. */
7881
e6e27594 7882static tree
c2f47e15 7883fold_builtin_cos (tree arg, tree type, tree fndecl)
e6e27594 7884{
e6ab33d8 7885 tree res, narg;
e6e27594 7886
c2f47e15 7887 if (!validate_arg (arg, REAL_TYPE))
e6e27594 7888 return NULL_TREE;
7889
bffb7645 7890 /* Calculate the result when the argument is a constant. */
728bac60 7891 if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
bffb7645 7892 return res;
7893
e6e27594 7894 /* Optimize cos(-x) into cos (x). */
e6ab33d8 7895 if ((narg = fold_strip_sign_ops (arg)))
c2f47e15 7896 return build_call_expr (fndecl, 1, narg);
e6e27594 7897
7898 return NULL_TREE;
7899}
7900
c2f47e15 7901/* Fold function call to builtin cosh, coshf, or coshl with argument ARG.
7902 Return NULL_TREE if no simplification can be made. */
7903
cacdc1af 7904static tree
c2f47e15 7905fold_builtin_cosh (tree arg, tree type, tree fndecl)
cacdc1af 7906{
c2f47e15 7907 if (validate_arg (arg, REAL_TYPE))
cacdc1af 7908 {
cacdc1af 7909 tree res, narg;
7910
7911 /* Calculate the result when the argument is a constant. */
7912 if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0)))
7913 return res;
7914
7915 /* Optimize cosh(-x) into cosh (x). */
7916 if ((narg = fold_strip_sign_ops (arg)))
c2f47e15 7917 return build_call_expr (fndecl, 1, narg);
cacdc1af 7918 }
7919
7920 return NULL_TREE;
7921}
7922
239d491a 7923/* Fold function call to builtin ccos (or ccosh if HYPER is TRUE) with
7924 argument ARG. TYPE is the type of the return value. Return
7925 NULL_TREE if no simplification can be made. */
7926
7927static tree
7928fold_builtin_ccos (tree arg, tree type ATTRIBUTE_UNUSED, tree fndecl,
7929 bool hyper ATTRIBUTE_UNUSED)
7930{
7931 if (validate_arg (arg, COMPLEX_TYPE)
7932 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
7933 {
7934 tree tmp;
7935
7936#ifdef HAVE_mpc
7937 /* Calculate the result when the argument is a constant. */
7938 if ((tmp = do_mpc_arg1 (arg, type, (hyper ? mpc_cosh : mpc_cos))))
7939 return tmp;
7940#endif
7941
7942 /* Optimize fn(-x) into fn(x). */
7943 if ((tmp = fold_strip_sign_ops (arg)))
7944 return build_call_expr (fndecl, 1, tmp);
7945 }
7946
7947 return NULL_TREE;
7948}
7949
c2f47e15 7950/* Fold function call to builtin tan, tanf, or tanl with argument ARG.
7951 Return NULL_TREE if no simplification can be made. */
7952
e6e27594 7953static tree
c2f47e15 7954fold_builtin_tan (tree arg, tree type)
e6e27594 7955{
7956 enum built_in_function fcode;
29f4cd78 7957 tree res;
e6e27594 7958
c2f47e15 7959 if (!validate_arg (arg, REAL_TYPE))
e6e27594 7960 return NULL_TREE;
7961
bffb7645 7962 /* Calculate the result when the argument is a constant. */
728bac60 7963 if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0)))
bffb7645 7964 return res;
7965
e6e27594 7966 /* Optimize tan(atan(x)) = x. */
7967 fcode = builtin_mathfn_code (arg);
7968 if (flag_unsafe_math_optimizations
7969 && (fcode == BUILT_IN_ATAN
7970 || fcode == BUILT_IN_ATANF
7971 || fcode == BUILT_IN_ATANL))
c2f47e15 7972 return CALL_EXPR_ARG (arg, 0);
e6e27594 7973
7974 return NULL_TREE;
7975}
7976
d735c391 7977/* Fold function call to builtin sincos, sincosf, or sincosl. Return
7978 NULL_TREE if no simplification can be made. */
7979
7980static tree
c2f47e15 7981fold_builtin_sincos (tree arg0, tree arg1, tree arg2)
d735c391 7982{
c2f47e15 7983 tree type;
d735c391 7984 tree res, fn, call;
7985
c2f47e15 7986 if (!validate_arg (arg0, REAL_TYPE)
7987 || !validate_arg (arg1, POINTER_TYPE)
7988 || !validate_arg (arg2, POINTER_TYPE))
d735c391 7989 return NULL_TREE;
7990
d735c391 7991 type = TREE_TYPE (arg0);
d735c391 7992
7993 /* Calculate the result when the argument is a constant. */
7994 if ((res = do_mpfr_sincos (arg0, arg1, arg2)))
7995 return res;
7996
7997 /* Canonicalize sincos to cexpi. */
2a6b4c77 7998 if (!TARGET_C99_FUNCTIONS)
7999 return NULL_TREE;
d735c391 8000 fn = mathfn_built_in (type, BUILT_IN_CEXPI);
8001 if (!fn)
8002 return NULL_TREE;
8003
c2f47e15 8004 call = build_call_expr (fn, 1, arg0);
d735c391 8005 call = builtin_save_expr (call);
8006
a75b1c71 8007 return build2 (COMPOUND_EXPR, void_type_node,
d735c391 8008 build2 (MODIFY_EXPR, void_type_node,
8009 build_fold_indirect_ref (arg1),
8010 build1 (IMAGPART_EXPR, type, call)),
8011 build2 (MODIFY_EXPR, void_type_node,
8012 build_fold_indirect_ref (arg2),
8013 build1 (REALPART_EXPR, type, call)));
8014}
8015
c5bb2c4b 8016/* Fold function call to builtin cexp, cexpf, or cexpl. Return
8017 NULL_TREE if no simplification can be made. */
8018
8019static tree
c2f47e15 8020fold_builtin_cexp (tree arg0, tree type)
c5bb2c4b 8021{
c2f47e15 8022 tree rtype;
c5bb2c4b 8023 tree realp, imagp, ifn;
239d491a 8024#ifdef HAVE_mpc
8025 tree res;
8026#endif
c5bb2c4b 8027
239d491a 8028 if (!validate_arg (arg0, COMPLEX_TYPE)
8029 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
c5bb2c4b 8030 return NULL_TREE;
8031
239d491a 8032#ifdef HAVE_mpc
8033 /* Calculate the result when the argument is a constant. */
8034 if ((res = do_mpc_arg1 (arg0, type, mpc_exp)))
8035 return res;
8036#endif
8037
c5bb2c4b 8038 rtype = TREE_TYPE (TREE_TYPE (arg0));
8039
8040 /* In case we can figure out the real part of arg0 and it is constant zero
8041 fold to cexpi. */
2a6b4c77 8042 if (!TARGET_C99_FUNCTIONS)
8043 return NULL_TREE;
c5bb2c4b 8044 ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
8045 if (!ifn)
8046 return NULL_TREE;
8047
8048 if ((realp = fold_unary (REALPART_EXPR, rtype, arg0))
8049 && real_zerop (realp))
8050 {
8051 tree narg = fold_build1 (IMAGPART_EXPR, rtype, arg0);
c2f47e15 8052 return build_call_expr (ifn, 1, narg);
c5bb2c4b 8053 }
8054
8055 /* In case we can easily decompose real and imaginary parts split cexp
8056 to exp (r) * cexpi (i). */
8057 if (flag_unsafe_math_optimizations
8058 && realp)
8059 {
8060 tree rfn, rcall, icall;
8061
8062 rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
8063 if (!rfn)
8064 return NULL_TREE;
8065
8066 imagp = fold_unary (IMAGPART_EXPR, rtype, arg0);
8067 if (!imagp)
8068 return NULL_TREE;
8069
c2f47e15 8070 icall = build_call_expr (ifn, 1, imagp);
c5bb2c4b 8071 icall = builtin_save_expr (icall);
c2f47e15 8072 rcall = build_call_expr (rfn, 1, realp);
c5bb2c4b 8073 rcall = builtin_save_expr (rcall);
71bf42bb 8074 return fold_build2 (COMPLEX_EXPR, type,
8075 fold_build2 (MULT_EXPR, rtype,
8076 rcall,
8077 fold_build1 (REALPART_EXPR, rtype, icall)),
8078 fold_build2 (MULT_EXPR, rtype,
8079 rcall,
8080 fold_build1 (IMAGPART_EXPR, rtype, icall)));
c5bb2c4b 8081 }
8082
8083 return NULL_TREE;
8084}
8085
c2f47e15 8086/* Fold function call to builtin trunc, truncf or truncl with argument ARG.
8087 Return NULL_TREE if no simplification can be made. */
277f8dd2 8088
8089static tree
c2f47e15 8090fold_builtin_trunc (tree fndecl, tree arg)
277f8dd2 8091{
c2f47e15 8092 if (!validate_arg (arg, REAL_TYPE))
8093 return NULL_TREE;
277f8dd2 8094
8095 /* Optimize trunc of constant value. */
f96bd2bf 8096 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
277f8dd2 8097 {
8098 REAL_VALUE_TYPE r, x;
2426241c 8099 tree type = TREE_TYPE (TREE_TYPE (fndecl));
277f8dd2 8100
8101 x = TREE_REAL_CST (arg);
8102 real_trunc (&r, TYPE_MODE (type), &x);
8103 return build_real (type, r);
8104 }
8105
c2f47e15 8106 return fold_trunc_transparent_mathfn (fndecl, arg);
277f8dd2 8107}
8108
c2f47e15 8109/* Fold function call to builtin floor, floorf or floorl with argument ARG.
8110 Return NULL_TREE if no simplification can be made. */
277f8dd2 8111
8112static tree
c2f47e15 8113fold_builtin_floor (tree fndecl, tree arg)
277f8dd2 8114{
c2f47e15 8115 if (!validate_arg (arg, REAL_TYPE))
8116 return NULL_TREE;
277f8dd2 8117
8118 /* Optimize floor of constant value. */
f96bd2bf 8119 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
277f8dd2 8120 {
8121 REAL_VALUE_TYPE x;
8122
8123 x = TREE_REAL_CST (arg);
8124 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
8125 {
2426241c 8126 tree type = TREE_TYPE (TREE_TYPE (fndecl));
277f8dd2 8127 REAL_VALUE_TYPE r;
8128
8129 real_floor (&r, TYPE_MODE (type), &x);
8130 return build_real (type, r);
8131 }
8132 }
8133
acc2b92e 8134 /* Fold floor (x) where x is nonnegative to trunc (x). */
8135 if (tree_expr_nonnegative_p (arg))
30fe8286 8136 {
8137 tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
8138 if (truncfn)
c2f47e15 8139 return build_call_expr (truncfn, 1, arg);
30fe8286 8140 }
acc2b92e 8141
c2f47e15 8142 return fold_trunc_transparent_mathfn (fndecl, arg);
277f8dd2 8143}
8144
c2f47e15 8145/* Fold function call to builtin ceil, ceilf or ceill with argument ARG.
8146 Return NULL_TREE if no simplification can be made. */
277f8dd2 8147
8148static tree
c2f47e15 8149fold_builtin_ceil (tree fndecl, tree arg)
277f8dd2 8150{
c2f47e15 8151 if (!validate_arg (arg, REAL_TYPE))
8152 return NULL_TREE;
277f8dd2 8153
8154 /* Optimize ceil of constant value. */
f96bd2bf 8155 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
277f8dd2 8156 {
8157 REAL_VALUE_TYPE x;
8158
8159 x = TREE_REAL_CST (arg);
8160 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
8161 {
2426241c 8162 tree type = TREE_TYPE (TREE_TYPE (fndecl));
277f8dd2 8163 REAL_VALUE_TYPE r;
8164
8165 real_ceil (&r, TYPE_MODE (type), &x);
8166 return build_real (type, r);
8167 }
8168 }
8169
c2f47e15 8170 return fold_trunc_transparent_mathfn (fndecl, arg);
277f8dd2 8171}
8172
c2f47e15 8173/* Fold function call to builtin round, roundf or roundl with argument ARG.
8174 Return NULL_TREE if no simplification can be made. */
89ab3887 8175
8176static tree
c2f47e15 8177fold_builtin_round (tree fndecl, tree arg)
89ab3887 8178{
c2f47e15 8179 if (!validate_arg (arg, REAL_TYPE))
8180 return NULL_TREE;
89ab3887 8181
34f17811 8182 /* Optimize round of constant value. */
f96bd2bf 8183 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
89ab3887 8184 {
8185 REAL_VALUE_TYPE x;
8186
8187 x = TREE_REAL_CST (arg);
8188 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
8189 {
2426241c 8190 tree type = TREE_TYPE (TREE_TYPE (fndecl));
89ab3887 8191 REAL_VALUE_TYPE r;
8192
8193 real_round (&r, TYPE_MODE (type), &x);
8194 return build_real (type, r);
8195 }
8196 }
8197
c2f47e15 8198 return fold_trunc_transparent_mathfn (fndecl, arg);
89ab3887 8199}
8200
34f17811 8201/* Fold function call to builtin lround, lroundf or lroundl (or the
c2f47e15 8202 corresponding long long versions) and other rounding functions. ARG
8203 is the argument to the call. Return NULL_TREE if no simplification
8204 can be made. */
34f17811 8205
8206static tree
c2f47e15 8207fold_builtin_int_roundingfn (tree fndecl, tree arg)
34f17811 8208{
c2f47e15 8209 if (!validate_arg (arg, REAL_TYPE))
8210 return NULL_TREE;
34f17811 8211
8212 /* Optimize lround of constant value. */
f96bd2bf 8213 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
34f17811 8214 {
8215 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
8216
776a7bab 8217 if (real_isfinite (&x))
34f17811 8218 {
2426241c 8219 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
ca9b061d 8220 tree ftype = TREE_TYPE (arg);
8221 unsigned HOST_WIDE_INT lo2;
34f17811 8222 HOST_WIDE_INT hi, lo;
8223 REAL_VALUE_TYPE r;
8224
ad52b9b7 8225 switch (DECL_FUNCTION_CODE (fndecl))
8226 {
4f35b1fc 8227 CASE_FLT_FN (BUILT_IN_LFLOOR):
8228 CASE_FLT_FN (BUILT_IN_LLFLOOR):
ad52b9b7 8229 real_floor (&r, TYPE_MODE (ftype), &x);
8230 break;
8231
4f35b1fc 8232 CASE_FLT_FN (BUILT_IN_LCEIL):
8233 CASE_FLT_FN (BUILT_IN_LLCEIL):
ac148751 8234 real_ceil (&r, TYPE_MODE (ftype), &x);
8235 break;
8236
4f35b1fc 8237 CASE_FLT_FN (BUILT_IN_LROUND):
8238 CASE_FLT_FN (BUILT_IN_LLROUND):
ad52b9b7 8239 real_round (&r, TYPE_MODE (ftype), &x);
8240 break;
8241
8242 default:
8243 gcc_unreachable ();
8244 }
8245
34f17811 8246 REAL_VALUE_TO_INT (&lo, &hi, r);
ca9b061d 8247 if (!fit_double_type (lo, hi, &lo2, &hi, itype))
8248 return build_int_cst_wide (itype, lo2, hi);
34f17811 8249 }
8250 }
8251
acc2b92e 8252 switch (DECL_FUNCTION_CODE (fndecl))
8253 {
8254 CASE_FLT_FN (BUILT_IN_LFLOOR):
8255 CASE_FLT_FN (BUILT_IN_LLFLOOR):
8256 /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x). */
8257 if (tree_expr_nonnegative_p (arg))
8258 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)),
8259 arg);
8260 break;
8261 default:;
8262 }
8263
c2f47e15 8264 return fold_fixed_mathfn (fndecl, arg);
34f17811 8265}
8266
70fb4c07 8267/* Fold function call to builtin ffs, clz, ctz, popcount and parity
c2f47e15 8268 and their long and long long variants (i.e. ffsl and ffsll). ARG is
8269 the argument to the call. Return NULL_TREE if no simplification can
8270 be made. */
70fb4c07 8271
8272static tree
c2f47e15 8273fold_builtin_bitop (tree fndecl, tree arg)
70fb4c07 8274{
c2f47e15 8275 if (!validate_arg (arg, INTEGER_TYPE))
70fb4c07 8276 return NULL_TREE;
8277
8278 /* Optimize for constant argument. */
f96bd2bf 8279 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
70fb4c07 8280 {
8281 HOST_WIDE_INT hi, width, result;
8282 unsigned HOST_WIDE_INT lo;
7c446c95 8283 tree type;
70fb4c07 8284
8285 type = TREE_TYPE (arg);
8286 width = TYPE_PRECISION (type);
8287 lo = TREE_INT_CST_LOW (arg);
8288
8289 /* Clear all the bits that are beyond the type's precision. */
8290 if (width > HOST_BITS_PER_WIDE_INT)
8291 {
8292 hi = TREE_INT_CST_HIGH (arg);
8293 if (width < 2 * HOST_BITS_PER_WIDE_INT)
8294 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
8295 }
8296 else
8297 {
8298 hi = 0;
8299 if (width < HOST_BITS_PER_WIDE_INT)
8300 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
8301 }
8302
8303 switch (DECL_FUNCTION_CODE (fndecl))
8304 {
4f35b1fc 8305 CASE_INT_FN (BUILT_IN_FFS):
70fb4c07 8306 if (lo != 0)
8307 result = exact_log2 (lo & -lo) + 1;
8308 else if (hi != 0)
8309 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
8310 else
8311 result = 0;
8312 break;
8313
4f35b1fc 8314 CASE_INT_FN (BUILT_IN_CLZ):
70fb4c07 8315 if (hi != 0)
8316 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
8317 else if (lo != 0)
8318 result = width - floor_log2 (lo) - 1;
8319 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8320 result = width;
8321 break;
8322
4f35b1fc 8323 CASE_INT_FN (BUILT_IN_CTZ):
70fb4c07 8324 if (lo != 0)
8325 result = exact_log2 (lo & -lo);
8326 else if (hi != 0)
8327 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
8328 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8329 result = width;
8330 break;
8331
4f35b1fc 8332 CASE_INT_FN (BUILT_IN_POPCOUNT):
70fb4c07 8333 result = 0;
8334 while (lo)
8335 result++, lo &= lo - 1;
8336 while (hi)
8337 result++, hi &= hi - 1;
8338 break;
8339
4f35b1fc 8340 CASE_INT_FN (BUILT_IN_PARITY):
70fb4c07 8341 result = 0;
8342 while (lo)
8343 result++, lo &= lo - 1;
8344 while (hi)
8345 result++, hi &= hi - 1;
8346 result &= 1;
8347 break;
8348
8349 default:
64db345d 8350 gcc_unreachable ();
70fb4c07 8351 }
8352
2426241c 8353 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
70fb4c07 8354 }
8355
8356 return NULL_TREE;
8357}
8358
42791117 8359/* Fold function call to builtin_bswap and the long and long long
8360 variants. Return NULL_TREE if no simplification can be made. */
8361static tree
c2f47e15 8362fold_builtin_bswap (tree fndecl, tree arg)
42791117 8363{
c2f47e15 8364 if (! validate_arg (arg, INTEGER_TYPE))
8365 return NULL_TREE;
42791117 8366
8367 /* Optimize constant value. */
f96bd2bf 8368 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
42791117 8369 {
8370 HOST_WIDE_INT hi, width, r_hi = 0;
8371 unsigned HOST_WIDE_INT lo, r_lo = 0;
8372 tree type;
8373
8374 type = TREE_TYPE (arg);
8375 width = TYPE_PRECISION (type);
8376 lo = TREE_INT_CST_LOW (arg);
8377 hi = TREE_INT_CST_HIGH (arg);
8378
8379 switch (DECL_FUNCTION_CODE (fndecl))
8380 {
8381 case BUILT_IN_BSWAP32:
8382 case BUILT_IN_BSWAP64:
8383 {
8384 int s;
8385
8386 for (s = 0; s < width; s += 8)
8387 {
8388 int d = width - s - 8;
8389 unsigned HOST_WIDE_INT byte;
8390
8391 if (s < HOST_BITS_PER_WIDE_INT)
8392 byte = (lo >> s) & 0xff;
8393 else
8394 byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
8395
8396 if (d < HOST_BITS_PER_WIDE_INT)
8397 r_lo |= byte << d;
8398 else
8399 r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
8400 }
8401 }
8402
8403 break;
8404
8405 default:
8406 gcc_unreachable ();
8407 }
8408
8409 if (width < HOST_BITS_PER_WIDE_INT)
8410 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo);
8411 else
8412 return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi);
8413 }
8414
8415 return NULL_TREE;
8416}
c2f47e15 8417
8918c507 8418/* A subroutine of fold_builtin to fold the various logarithmic
29f4cd78 8419 functions. Return NULL_TREE if no simplification can me made.
8420 FUNC is the corresponding MPFR logarithm function. */
8918c507 8421
8422static tree
c2f47e15 8423fold_builtin_logarithm (tree fndecl, tree arg,
29f4cd78 8424 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8918c507 8425{
c2f47e15 8426 if (validate_arg (arg, REAL_TYPE))
8918c507 8427 {
8918c507 8428 tree type = TREE_TYPE (TREE_TYPE (fndecl));
29f4cd78 8429 tree res;
8918c507 8430 const enum built_in_function fcode = builtin_mathfn_code (arg);
0862b7e9 8431
29f4cd78 8432 /* Calculate the result when the argument is a constant. */
8433 if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
8434 return res;
8435
8918c507 8436 /* Special case, optimize logN(expN(x)) = x. */
8437 if (flag_unsafe_math_optimizations
29f4cd78 8438 && ((func == mpfr_log
8918c507 8439 && (fcode == BUILT_IN_EXP
8440 || fcode == BUILT_IN_EXPF
8441 || fcode == BUILT_IN_EXPL))
29f4cd78 8442 || (func == mpfr_log2
8918c507 8443 && (fcode == BUILT_IN_EXP2
8444 || fcode == BUILT_IN_EXP2F
8445 || fcode == BUILT_IN_EXP2L))
29f4cd78 8446 || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
c2f47e15 8447 return fold_convert (type, CALL_EXPR_ARG (arg, 0));
8918c507 8448
ca273d4a 8449 /* Optimize logN(func()) for various exponential functions. We
a0c938f0 8450 want to determine the value "x" and the power "exponent" in
8451 order to transform logN(x**exponent) into exponent*logN(x). */
8918c507 8452 if (flag_unsafe_math_optimizations)
a0c938f0 8453 {
8918c507 8454 tree exponent = 0, x = 0;
0862b7e9 8455
8918c507 8456 switch (fcode)
8457 {
4f35b1fc 8458 CASE_FLT_FN (BUILT_IN_EXP):
8918c507 8459 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7910b2fb 8460 x = build_real (type, real_value_truncate (TYPE_MODE (type),
8461 dconst_e ()));
c2f47e15 8462 exponent = CALL_EXPR_ARG (arg, 0);
8918c507 8463 break;
4f35b1fc 8464 CASE_FLT_FN (BUILT_IN_EXP2):
8918c507 8465 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
8466 x = build_real (type, dconst2);
c2f47e15 8467 exponent = CALL_EXPR_ARG (arg, 0);
8918c507 8468 break;
4f35b1fc 8469 CASE_FLT_FN (BUILT_IN_EXP10):
8470 CASE_FLT_FN (BUILT_IN_POW10):
8918c507 8471 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
3fa759a9 8472 {
8473 REAL_VALUE_TYPE dconst10;
8474 real_from_integer (&dconst10, VOIDmode, 10, 0, 0);
8475 x = build_real (type, dconst10);
8476 }
c2f47e15 8477 exponent = CALL_EXPR_ARG (arg, 0);
8918c507 8478 break;
4f35b1fc 8479 CASE_FLT_FN (BUILT_IN_SQRT):
8918c507 8480 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
c2f47e15 8481 x = CALL_EXPR_ARG (arg, 0);
8918c507 8482 exponent = build_real (type, dconsthalf);
8483 break;
4f35b1fc 8484 CASE_FLT_FN (BUILT_IN_CBRT):
8918c507 8485 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
c2f47e15 8486 x = CALL_EXPR_ARG (arg, 0);
8918c507 8487 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7910b2fb 8488 dconst_third ()));
8918c507 8489 break;
4f35b1fc 8490 CASE_FLT_FN (BUILT_IN_POW):
8918c507 8491 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
c2f47e15 8492 x = CALL_EXPR_ARG (arg, 0);
8493 exponent = CALL_EXPR_ARG (arg, 1);
8918c507 8494 break;
8495 default:
8496 break;
8497 }
8498
8499 /* Now perform the optimization. */
8500 if (x && exponent)
8501 {
c2f47e15 8502 tree logfn = build_call_expr (fndecl, 1, x);
49d00087 8503 return fold_build2 (MULT_EXPR, type, exponent, logfn);
8918c507 8504 }
8505 }
8506 }
8507
c2f47e15 8508 return NULL_TREE;
8918c507 8509}
0862b7e9 8510
f0c477f2 8511/* Fold a builtin function call to hypot, hypotf, or hypotl. Return
8512 NULL_TREE if no simplification can be made. */
8513
8514static tree
c2f47e15 8515fold_builtin_hypot (tree fndecl, tree arg0, tree arg1, tree type)
f0c477f2 8516{
e6ab33d8 8517 tree res, narg0, narg1;
f0c477f2 8518
c2f47e15 8519 if (!validate_arg (arg0, REAL_TYPE)
8520 || !validate_arg (arg1, REAL_TYPE))
f0c477f2 8521 return NULL_TREE;
8522
8523 /* Calculate the result when the argument is a constant. */
8524 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
8525 return res;
8526
6c95f21c 8527 /* If either argument to hypot has a negate or abs, strip that off.
8528 E.g. hypot(-x,fabs(y)) -> hypot(x,y). */
e6ab33d8 8529 narg0 = fold_strip_sign_ops (arg0);
8530 narg1 = fold_strip_sign_ops (arg1);
8531 if (narg0 || narg1)
8532 {
c2f47e15 8533 return build_call_expr (fndecl, 2, narg0 ? narg0 : arg0,
8534 narg1 ? narg1 : arg1);
6c95f21c 8535 }
8536
f0c477f2 8537 /* If either argument is zero, hypot is fabs of the other. */
8538 if (real_zerop (arg0))
8539 return fold_build1 (ABS_EXPR, type, arg1);
8540 else if (real_zerop (arg1))
8541 return fold_build1 (ABS_EXPR, type, arg0);
8542
6c95f21c 8543 /* hypot(x,x) -> fabs(x)*sqrt(2). */
8544 if (flag_unsafe_math_optimizations
8545 && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
f0c477f2 8546 {
2e7ca27b 8547 const REAL_VALUE_TYPE sqrt2_trunc
7910b2fb 8548 = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
6c95f21c 8549 return fold_build2 (MULT_EXPR, type,
8550 fold_build1 (ABS_EXPR, type, arg0),
2e7ca27b 8551 build_real (type, sqrt2_trunc));
f0c477f2 8552 }
8553
f0c477f2 8554 return NULL_TREE;
8555}
8556
8557
e6e27594 8558/* Fold a builtin function call to pow, powf, or powl. Return
8559 NULL_TREE if no simplification can be made. */
8560static tree
c2f47e15 8561fold_builtin_pow (tree fndecl, tree arg0, tree arg1, tree type)
e6e27594 8562{
f0c477f2 8563 tree res;
e6e27594 8564
c2f47e15 8565 if (!validate_arg (arg0, REAL_TYPE)
8566 || !validate_arg (arg1, REAL_TYPE))
e6e27594 8567 return NULL_TREE;
8568
f0c477f2 8569 /* Calculate the result when the argument is a constant. */
8570 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
8571 return res;
8572
e6e27594 8573 /* Optimize pow(1.0,y) = 1.0. */
8574 if (real_onep (arg0))
8575 return omit_one_operand (type, build_real (type, dconst1), arg1);
8576
8577 if (TREE_CODE (arg1) == REAL_CST
f96bd2bf 8578 && !TREE_OVERFLOW (arg1))
e6e27594 8579 {
198d9bbe 8580 REAL_VALUE_TYPE cint;
e6e27594 8581 REAL_VALUE_TYPE c;
198d9bbe 8582 HOST_WIDE_INT n;
8583
e6e27594 8584 c = TREE_REAL_CST (arg1);
8585
8586 /* Optimize pow(x,0.0) = 1.0. */
8587 if (REAL_VALUES_EQUAL (c, dconst0))
8588 return omit_one_operand (type, build_real (type, dconst1),
8589 arg0);
8590
8591 /* Optimize pow(x,1.0) = x. */
8592 if (REAL_VALUES_EQUAL (c, dconst1))
8593 return arg0;
8594
8595 /* Optimize pow(x,-1.0) = 1.0/x. */
8596 if (REAL_VALUES_EQUAL (c, dconstm1))
49d00087 8597 return fold_build2 (RDIV_EXPR, type,
8598 build_real (type, dconst1), arg0);
e6e27594 8599
8600 /* Optimize pow(x,0.5) = sqrt(x). */
8601 if (flag_unsafe_math_optimizations
8602 && REAL_VALUES_EQUAL (c, dconsthalf))
8603 {
8604 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8605
8606 if (sqrtfn != NULL_TREE)
c2f47e15 8607 return build_call_expr (sqrtfn, 1, arg0);
e6e27594 8608 }
8609
feb5b3eb 8610 /* Optimize pow(x,1.0/3.0) = cbrt(x). */
8611 if (flag_unsafe_math_optimizations)
8612 {
8613 const REAL_VALUE_TYPE dconstroot
7910b2fb 8614 = real_value_truncate (TYPE_MODE (type), dconst_third ());
feb5b3eb 8615
8616 if (REAL_VALUES_EQUAL (c, dconstroot))
8617 {
8618 tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
8619 if (cbrtfn != NULL_TREE)
c2f47e15 8620 return build_call_expr (cbrtfn, 1, arg0);
feb5b3eb 8621 }
8622 }
8623
198d9bbe 8624 /* Check for an integer exponent. */
8625 n = real_to_integer (&c);
8626 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
8627 if (real_identical (&c, &cint))
e6e27594 8628 {
a2b30b48 8629 /* Attempt to evaluate pow at compile-time, unless this should
8630 raise an exception. */
198d9bbe 8631 if (TREE_CODE (arg0) == REAL_CST
a2b30b48 8632 && !TREE_OVERFLOW (arg0)
8633 && (n > 0
8634 || (!flag_trapping_math && !flag_errno_math)
8635 || !REAL_VALUES_EQUAL (TREE_REAL_CST (arg0), dconst0)))
e6e27594 8636 {
8637 REAL_VALUE_TYPE x;
8638 bool inexact;
8639
8640 x = TREE_REAL_CST (arg0);
8641 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8642 if (flag_unsafe_math_optimizations || !inexact)
8643 return build_real (type, x);
8644 }
198d9bbe 8645
8646 /* Strip sign ops from even integer powers. */
8647 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
8648 {
8649 tree narg0 = fold_strip_sign_ops (arg0);
8650 if (narg0)
c2f47e15 8651 return build_call_expr (fndecl, 2, narg0, arg1);
198d9bbe 8652 }
e6e27594 8653 }
8654 }
8655
cdfeb715 8656 if (flag_unsafe_math_optimizations)
e6e27594 8657 {
cdfeb715 8658 const enum built_in_function fcode = builtin_mathfn_code (arg0);
e6e27594 8659
cdfeb715 8660 /* Optimize pow(expN(x),y) = expN(x*y). */
8661 if (BUILTIN_EXPONENT_P (fcode))
a0c938f0 8662 {
c2f47e15 8663 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0);
8664 tree arg = CALL_EXPR_ARG (arg0, 0);
49d00087 8665 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
c2f47e15 8666 return build_call_expr (expfn, 1, arg);
cdfeb715 8667 }
e6e27594 8668
cdfeb715 8669 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
8670 if (BUILTIN_SQRT_P (fcode))
a0c938f0 8671 {
c2f47e15 8672 tree narg0 = CALL_EXPR_ARG (arg0, 0);
49d00087 8673 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
8674 build_real (type, dconsthalf));
c2f47e15 8675 return build_call_expr (fndecl, 2, narg0, narg1);
cdfeb715 8676 }
8677
8678 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
8679 if (BUILTIN_CBRT_P (fcode))
a0c938f0 8680 {
c2f47e15 8681 tree arg = CALL_EXPR_ARG (arg0, 0);
cdfeb715 8682 if (tree_expr_nonnegative_p (arg))
8683 {
8684 const REAL_VALUE_TYPE dconstroot
7910b2fb 8685 = real_value_truncate (TYPE_MODE (type), dconst_third ());
49d00087 8686 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
8687 build_real (type, dconstroot));
c2f47e15 8688 return build_call_expr (fndecl, 2, arg, narg1);
cdfeb715 8689 }
8690 }
a0c938f0 8691
cdfeb715 8692 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
c2f47e15 8693 if (fcode == BUILT_IN_POW
8694 || fcode == BUILT_IN_POWF
8695 || fcode == BUILT_IN_POWL)
a0c938f0 8696 {
c2f47e15 8697 tree arg00 = CALL_EXPR_ARG (arg0, 0);
8698 tree arg01 = CALL_EXPR_ARG (arg0, 1);
49d00087 8699 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
c2f47e15 8700 return build_call_expr (fndecl, 2, arg00, narg1);
cdfeb715 8701 }
e6e27594 8702 }
cdfeb715 8703
e6e27594 8704 return NULL_TREE;
8705}
8706
c2f47e15 8707/* Fold a builtin function call to powi, powif, or powil with argument ARG.
8708 Return NULL_TREE if no simplification can be made. */
b4d0c20c 8709static tree
c2f47e15 8710fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED,
8711 tree arg0, tree arg1, tree type)
b4d0c20c 8712{
c2f47e15 8713 if (!validate_arg (arg0, REAL_TYPE)
8714 || !validate_arg (arg1, INTEGER_TYPE))
b4d0c20c 8715 return NULL_TREE;
8716
8717 /* Optimize pow(1.0,y) = 1.0. */
8718 if (real_onep (arg0))
8719 return omit_one_operand (type, build_real (type, dconst1), arg1);
8720
8721 if (host_integerp (arg1, 0))
8722 {
8723 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
8724
8725 /* Evaluate powi at compile-time. */
8726 if (TREE_CODE (arg0) == REAL_CST
f96bd2bf 8727 && !TREE_OVERFLOW (arg0))
b4d0c20c 8728 {
8729 REAL_VALUE_TYPE x;
8730 x = TREE_REAL_CST (arg0);
8731 real_powi (&x, TYPE_MODE (type), &x, c);
8732 return build_real (type, x);
8733 }
8734
8735 /* Optimize pow(x,0) = 1.0. */
8736 if (c == 0)
8737 return omit_one_operand (type, build_real (type, dconst1),
8738 arg0);
8739
8740 /* Optimize pow(x,1) = x. */
8741 if (c == 1)
8742 return arg0;
8743
8744 /* Optimize pow(x,-1) = 1.0/x. */
8745 if (c == -1)
49d00087 8746 return fold_build2 (RDIV_EXPR, type,
8747 build_real (type, dconst1), arg0);
b4d0c20c 8748 }
8749
8750 return NULL_TREE;
8751}
8752
8918c507 8753/* A subroutine of fold_builtin to fold the various exponent
c2f47e15 8754 functions. Return NULL_TREE if no simplification can be made.
debf9994 8755 FUNC is the corresponding MPFR exponent function. */
8918c507 8756
8757static tree
c2f47e15 8758fold_builtin_exponent (tree fndecl, tree arg,
debf9994 8759 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8918c507 8760{
c2f47e15 8761 if (validate_arg (arg, REAL_TYPE))
8918c507 8762 {
8918c507 8763 tree type = TREE_TYPE (TREE_TYPE (fndecl));
29f4cd78 8764 tree res;
debf9994 8765
8766 /* Calculate the result when the argument is a constant. */
728bac60 8767 if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
debf9994 8768 return res;
8918c507 8769
8770 /* Optimize expN(logN(x)) = x. */
8771 if (flag_unsafe_math_optimizations)
a0c938f0 8772 {
8918c507 8773 const enum built_in_function fcode = builtin_mathfn_code (arg);
8774
debf9994 8775 if ((func == mpfr_exp
8918c507 8776 && (fcode == BUILT_IN_LOG
8777 || fcode == BUILT_IN_LOGF
8778 || fcode == BUILT_IN_LOGL))
debf9994 8779 || (func == mpfr_exp2
8918c507 8780 && (fcode == BUILT_IN_LOG2
8781 || fcode == BUILT_IN_LOG2F
8782 || fcode == BUILT_IN_LOG2L))
debf9994 8783 || (func == mpfr_exp10
8918c507 8784 && (fcode == BUILT_IN_LOG10
8785 || fcode == BUILT_IN_LOG10F
8786 || fcode == BUILT_IN_LOG10L)))
c2f47e15 8787 return fold_convert (type, CALL_EXPR_ARG (arg, 0));
8918c507 8788 }
8789 }
8790
c2f47e15 8791 return NULL_TREE;
8918c507 8792}
8793
e973ffcc 8794/* Return true if VAR is a VAR_DECL or a component thereof. */
8795
8796static bool
8797var_decl_component_p (tree var)
8798{
8799 tree inner = var;
8800 while (handled_component_p (inner))
8801 inner = TREE_OPERAND (inner, 0);
8802 return SSA_VAR_P (inner);
8803}
8804
4f46f2b9 8805/* Fold function call to builtin memset. Return
9c8a1629 8806 NULL_TREE if no simplification can be made. */
8807
8808static tree
c2f47e15 8809fold_builtin_memset (tree dest, tree c, tree len, tree type, bool ignore)
9c8a1629 8810{
45bb3afb 8811 tree var, ret, etype;
4f46f2b9 8812 unsigned HOST_WIDE_INT length, cval;
9c8a1629 8813
c2f47e15 8814 if (! validate_arg (dest, POINTER_TYPE)
8815 || ! validate_arg (c, INTEGER_TYPE)
8816 || ! validate_arg (len, INTEGER_TYPE))
8817 return NULL_TREE;
9c8a1629 8818
4f46f2b9 8819 if (! host_integerp (len, 1))
c2f47e15 8820 return NULL_TREE;
4f46f2b9 8821
9c8a1629 8822 /* If the LEN parameter is zero, return DEST. */
8823 if (integer_zerop (len))
4f46f2b9 8824 return omit_one_operand (type, dest, c);
9c8a1629 8825
4f46f2b9 8826 if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
c2f47e15 8827 return NULL_TREE;
9c8a1629 8828
4f46f2b9 8829 var = dest;
8830 STRIP_NOPS (var);
8831 if (TREE_CODE (var) != ADDR_EXPR)
c2f47e15 8832 return NULL_TREE;
4f46f2b9 8833
8834 var = TREE_OPERAND (var, 0);
8835 if (TREE_THIS_VOLATILE (var))
c2f47e15 8836 return NULL_TREE;
4f46f2b9 8837
45bb3afb 8838 etype = TREE_TYPE (var);
8839 if (TREE_CODE (etype) == ARRAY_TYPE)
8840 etype = TREE_TYPE (etype);
8841
8842 if (!INTEGRAL_TYPE_P (etype)
8843 && !POINTER_TYPE_P (etype))
c2f47e15 8844 return NULL_TREE;
4f46f2b9 8845
e973ffcc 8846 if (! var_decl_component_p (var))
c2f47e15 8847 return NULL_TREE;
e973ffcc 8848
4f46f2b9 8849 length = tree_low_cst (len, 1);
45bb3afb 8850 if (GET_MODE_SIZE (TYPE_MODE (etype)) != length
4f46f2b9 8851 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8852 < (int) length)
c2f47e15 8853 return NULL_TREE;
4f46f2b9 8854
8855 if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
c2f47e15 8856 return NULL_TREE;
4f46f2b9 8857
8858 if (integer_zerop (c))
8859 cval = 0;
8860 else
8861 {
8862 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
c2f47e15 8863 return NULL_TREE;
4f46f2b9 8864
8865 cval = tree_low_cst (c, 1);
8866 cval &= 0xff;
8867 cval |= cval << 8;
8868 cval |= cval << 16;
8869 cval |= (cval << 31) << 1;
8870 }
8871
45bb3afb 8872 ret = build_int_cst_type (etype, cval);
8873 var = build_fold_indirect_ref (fold_convert (build_pointer_type (etype),
8874 dest));
8875 ret = build2 (MODIFY_EXPR, etype, var, ret);
4f46f2b9 8876 if (ignore)
8877 return ret;
8878
8879 return omit_one_operand (type, dest, ret);
9c8a1629 8880}
8881
4f46f2b9 8882/* Fold function call to builtin memset. Return
9c8a1629 8883 NULL_TREE if no simplification can be made. */
8884
8885static tree
c2f47e15 8886fold_builtin_bzero (tree dest, tree size, bool ignore)
9c8a1629 8887{
c2f47e15 8888 if (! validate_arg (dest, POINTER_TYPE)
8889 || ! validate_arg (size, INTEGER_TYPE))
8890 return NULL_TREE;
9c8a1629 8891
4f46f2b9 8892 if (!ignore)
c2f47e15 8893 return NULL_TREE;
a0c938f0 8894
4f46f2b9 8895 /* New argument list transforming bzero(ptr x, int y) to
8896 memset(ptr x, int 0, size_t y). This is done this way
8897 so that if it isn't expanded inline, we fallback to
8898 calling bzero instead of memset. */
8899
c2f47e15 8900 return fold_builtin_memset (dest, integer_zero_node,
8901 fold_convert (sizetype, size),
8902 void_type_node, ignore);
9c8a1629 8903}
8904
4f46f2b9 8905/* Fold function call to builtin mem{{,p}cpy,move}. Return
8906 NULL_TREE if no simplification can be made.
8907 If ENDP is 0, return DEST (like memcpy).
8908 If ENDP is 1, return DEST+LEN (like mempcpy).
8909 If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8910 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8911 (memmove). */
9c8a1629 8912
8913static tree
c2f47e15 8914fold_builtin_memory_op (tree dest, tree src, tree len, tree type, bool ignore, int endp)
9c8a1629 8915{
c2f47e15 8916 tree destvar, srcvar, expr;
9c8a1629 8917
c2f47e15 8918 if (! validate_arg (dest, POINTER_TYPE)
8919 || ! validate_arg (src, POINTER_TYPE)
8920 || ! validate_arg (len, INTEGER_TYPE))
8921 return NULL_TREE;
9c8a1629 8922
8923 /* If the LEN parameter is zero, return DEST. */
8924 if (integer_zerop (len))
7e72af53 8925 return omit_one_operand (type, dest, src);
9c8a1629 8926
4f46f2b9 8927 /* If SRC and DEST are the same (and not volatile), return
8928 DEST{,+LEN,+LEN-1}. */
9c8a1629 8929 if (operand_equal_p (src, dest, 0))
4f46f2b9 8930 expr = len;
8931 else
8932 {
5a84fdd6 8933 tree srctype, desttype;
5383fb56 8934 int src_align, dest_align;
8935
3b1757a2 8936 if (endp == 3)
8937 {
5383fb56 8938 src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
8939 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
5a84fdd6 8940
3b1757a2 8941 /* Both DEST and SRC must be pointer types.
8942 ??? This is what old code did. Is the testing for pointer types
8943 really mandatory?
8944
8945 If either SRC is readonly or length is 1, we can use memcpy. */
3f95c690 8946 if (!dest_align || !src_align)
8947 return NULL_TREE;
8948 if (readonly_data_expr (src)
8949 || (host_integerp (len, 1)
8950 && (MIN (src_align, dest_align) / BITS_PER_UNIT
8951 >= tree_low_cst (len, 1))))
3b1757a2 8952 {
8953 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8954 if (!fn)
c2f47e15 8955 return NULL_TREE;
8956 return build_call_expr (fn, 3, dest, src, len);
3b1757a2 8957 }
3f95c690 8958
8959 /* If *src and *dest can't overlap, optimize into memcpy as well. */
8960 srcvar = build_fold_indirect_ref (src);
8961 destvar = build_fold_indirect_ref (dest);
8962 if (srcvar
8963 && !TREE_THIS_VOLATILE (srcvar)
8964 && destvar
8965 && !TREE_THIS_VOLATILE (destvar))
8966 {
8967 tree src_base, dest_base, fn;
8968 HOST_WIDE_INT src_offset = 0, dest_offset = 0;
8969 HOST_WIDE_INT size = -1;
8970 HOST_WIDE_INT maxsize = -1;
8971
8972 src_base = srcvar;
8973 if (handled_component_p (src_base))
8974 src_base = get_ref_base_and_extent (src_base, &src_offset,
8975 &size, &maxsize);
8976 dest_base = destvar;
8977 if (handled_component_p (dest_base))
8978 dest_base = get_ref_base_and_extent (dest_base, &dest_offset,
8979 &size, &maxsize);
8980 if (host_integerp (len, 1))
8981 {
8982 maxsize = tree_low_cst (len, 1);
8983 if (maxsize
8984 > INTTYPE_MAXIMUM (HOST_WIDE_INT) / BITS_PER_UNIT)
8985 maxsize = -1;
8986 else
8987 maxsize *= BITS_PER_UNIT;
8988 }
8989 else
8990 maxsize = -1;
8991 if (SSA_VAR_P (src_base)
8992 && SSA_VAR_P (dest_base))
8993 {
8994 if (operand_equal_p (src_base, dest_base, 0)
8995 && ranges_overlap_p (src_offset, maxsize,
8996 dest_offset, maxsize))
8997 return NULL_TREE;
8998 }
8999 else if (TREE_CODE (src_base) == INDIRECT_REF
9000 && TREE_CODE (dest_base) == INDIRECT_REF)
9001 {
9002 if (! operand_equal_p (TREE_OPERAND (src_base, 0),
9003 TREE_OPERAND (dest_base, 0), 0)
9004 || ranges_overlap_p (src_offset, maxsize,
9005 dest_offset, maxsize))
9006 return NULL_TREE;
9007 }
9008 else
9009 return NULL_TREE;
9010
9011 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
9012 if (!fn)
9013 return NULL_TREE;
9014 return build_call_expr (fn, 3, dest, src, len);
9015 }
c2f47e15 9016 return NULL_TREE;
3b1757a2 9017 }
4f46f2b9 9018
5a84fdd6 9019 if (!host_integerp (len, 0))
c2f47e15 9020 return NULL_TREE;
5a84fdd6 9021 /* FIXME:
9022 This logic lose for arguments like (type *)malloc (sizeof (type)),
9023 since we strip the casts of up to VOID return value from malloc.
9024 Perhaps we ought to inherit type from non-VOID argument here? */
9025 STRIP_NOPS (src);
9026 STRIP_NOPS (dest);
45bb3afb 9027 /* As we fold (void *)(p + CST) to (void *)p + CST undo this here. */
9028 if (TREE_CODE (src) == POINTER_PLUS_EXPR)
9029 {
9030 tree tem = TREE_OPERAND (src, 0);
9031 STRIP_NOPS (tem);
9032 if (tem != TREE_OPERAND (src, 0))
9033 src = build1 (NOP_EXPR, TREE_TYPE (tem), src);
9034 }
9035 if (TREE_CODE (dest) == POINTER_PLUS_EXPR)
9036 {
9037 tree tem = TREE_OPERAND (dest, 0);
9038 STRIP_NOPS (tem);
9039 if (tem != TREE_OPERAND (dest, 0))
9040 dest = build1 (NOP_EXPR, TREE_TYPE (tem), dest);
9041 }
5a84fdd6 9042 srctype = TREE_TYPE (TREE_TYPE (src));
45bb3afb 9043 if (srctype
97d4c6a6 9044 && TREE_CODE (srctype) == ARRAY_TYPE
9045 && !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
45bb3afb 9046 {
9047 srctype = TREE_TYPE (srctype);
9048 STRIP_NOPS (src);
9049 src = build1 (NOP_EXPR, build_pointer_type (srctype), src);
9050 }
5a84fdd6 9051 desttype = TREE_TYPE (TREE_TYPE (dest));
45bb3afb 9052 if (desttype
97d4c6a6 9053 && TREE_CODE (desttype) == ARRAY_TYPE
9054 && !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
45bb3afb 9055 {
9056 desttype = TREE_TYPE (desttype);
9057 STRIP_NOPS (dest);
9058 dest = build1 (NOP_EXPR, build_pointer_type (desttype), dest);
9059 }
5a84fdd6 9060 if (!srctype || !desttype
9061 || !TYPE_SIZE_UNIT (srctype)
9062 || !TYPE_SIZE_UNIT (desttype)
9063 || TREE_CODE (TYPE_SIZE_UNIT (srctype)) != INTEGER_CST
6f52ebeb 9064 || TREE_CODE (TYPE_SIZE_UNIT (desttype)) != INTEGER_CST
9065 || TYPE_VOLATILE (srctype)
9066 || TYPE_VOLATILE (desttype))
c2f47e15 9067 return NULL_TREE;
4f46f2b9 9068
5383fb56 9069 src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
9070 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
9071 if (dest_align < (int) TYPE_ALIGN (desttype)
9072 || src_align < (int) TYPE_ALIGN (srctype))
c2f47e15 9073 return NULL_TREE;
e973ffcc 9074
5a84fdd6 9075 if (!ignore)
9076 dest = builtin_save_expr (dest);
4f46f2b9 9077
5383fb56 9078 srcvar = NULL_TREE;
9079 if (tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
9080 {
9081 srcvar = build_fold_indirect_ref (src);
9082 if (TREE_THIS_VOLATILE (srcvar))
6f52ebeb 9083 return NULL_TREE;
5383fb56 9084 else if (!tree_int_cst_equal (lang_hooks.expr_size (srcvar), len))
9085 srcvar = NULL_TREE;
9086 /* With memcpy, it is possible to bypass aliasing rules, so without
9087 this check i.e. execute/20060930-2.c would be misoptimized,
9088 because it use conflicting alias set to hold argument for the
9089 memcpy call. This check is probably unnecessary with
9090 -fno-strict-aliasing. Similarly for destvar. See also
9091 PR29286. */
9092 else if (!var_decl_component_p (srcvar))
9093 srcvar = NULL_TREE;
9094 }
4f46f2b9 9095
5383fb56 9096 destvar = NULL_TREE;
9097 if (tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
9098 {
9099 destvar = build_fold_indirect_ref (dest);
9100 if (TREE_THIS_VOLATILE (destvar))
6f52ebeb 9101 return NULL_TREE;
5383fb56 9102 else if (!tree_int_cst_equal (lang_hooks.expr_size (destvar), len))
9103 destvar = NULL_TREE;
9104 else if (!var_decl_component_p (destvar))
9105 destvar = NULL_TREE;
9106 }
9107
9108 if (srcvar == NULL_TREE && destvar == NULL_TREE)
c2f47e15 9109 return NULL_TREE;
4f46f2b9 9110
5383fb56 9111 if (srcvar == NULL_TREE)
9112 {
9113 tree srcptype;
9114 if (TREE_ADDRESSABLE (TREE_TYPE (destvar)))
9115 return NULL_TREE;
9116
6f52ebeb 9117 srctype = build_qualified_type (desttype, 0);
5383fb56 9118 if (src_align < (int) TYPE_ALIGN (srctype))
9119 {
9120 if (AGGREGATE_TYPE_P (srctype)
9121 || SLOW_UNALIGNED_ACCESS (TYPE_MODE (srctype), src_align))
9122 return NULL_TREE;
9123
9124 srctype = build_variant_type_copy (srctype);
9125 TYPE_ALIGN (srctype) = src_align;
9126 TYPE_USER_ALIGN (srctype) = 1;
9127 TYPE_PACKED (srctype) = 1;
9128 }
9129 srcptype = build_pointer_type_for_mode (srctype, ptr_mode, true);
9130 src = fold_convert (srcptype, src);
9131 srcvar = build_fold_indirect_ref (src);
9132 }
9133 else if (destvar == NULL_TREE)
9134 {
9135 tree destptype;
9136 if (TREE_ADDRESSABLE (TREE_TYPE (srcvar)))
9137 return NULL_TREE;
9138
6f52ebeb 9139 desttype = build_qualified_type (srctype, 0);
5383fb56 9140 if (dest_align < (int) TYPE_ALIGN (desttype))
9141 {
9142 if (AGGREGATE_TYPE_P (desttype)
9143 || SLOW_UNALIGNED_ACCESS (TYPE_MODE (desttype), dest_align))
9144 return NULL_TREE;
9145
9146 desttype = build_variant_type_copy (desttype);
9147 TYPE_ALIGN (desttype) = dest_align;
9148 TYPE_USER_ALIGN (desttype) = 1;
9149 TYPE_PACKED (desttype) = 1;
9150 }
9151 destptype = build_pointer_type_for_mode (desttype, ptr_mode, true);
9152 dest = fold_convert (destptype, dest);
9153 destvar = build_fold_indirect_ref (dest);
9154 }
9155
5a84fdd6 9156 if (srctype == desttype
2d04fd8d 9157 || (gimple_in_ssa_p (cfun)
548044d8 9158 && useless_type_conversion_p (desttype, srctype)))
5a84fdd6 9159 expr = srcvar;
9160 else if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
4f46f2b9 9161 || POINTER_TYPE_P (TREE_TYPE (srcvar)))
9162 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
9163 || POINTER_TYPE_P (TREE_TYPE (destvar))))
9164 expr = fold_convert (TREE_TYPE (destvar), srcvar);
9165 else
9166 expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar);
41076ef6 9167 expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, expr);
4f46f2b9 9168 }
9169
9170 if (ignore)
9171 return expr;
9172
9173 if (endp == 0 || endp == 3)
9174 return omit_one_operand (type, dest, expr);
9175
9176 if (expr == len)
c2f47e15 9177 expr = NULL_TREE;
4f46f2b9 9178
9179 if (endp == 2)
9180 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
9181 ssize_int (1));
9182
f5fec377 9183 len = fold_convert (sizetype, len);
0de36bdb 9184 dest = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
4f46f2b9 9185 dest = fold_convert (type, dest);
9186 if (expr)
9187 dest = omit_one_operand (type, dest, expr);
9188 return dest;
9189}
9190
c2f47e15 9191/* Fold function call to builtin strcpy with arguments DEST and SRC.
9192 If LEN is not NULL, it represents the length of the string to be
9193 copied. Return NULL_TREE if no simplification can be made. */
9c8a1629 9194
f0613857 9195tree
c2f47e15 9196fold_builtin_strcpy (tree fndecl, tree dest, tree src, tree len)
9c8a1629 9197{
c2f47e15 9198 tree fn;
9c8a1629 9199
c2f47e15 9200 if (!validate_arg (dest, POINTER_TYPE)
9201 || !validate_arg (src, POINTER_TYPE))
9202 return NULL_TREE;
9c8a1629 9203
9204 /* If SRC and DEST are the same (and not volatile), return DEST. */
9205 if (operand_equal_p (src, dest, 0))
2426241c 9206 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
9c8a1629 9207
0bfd8d5c 9208 if (optimize_function_for_size_p (cfun))
c2f47e15 9209 return NULL_TREE;
f0613857 9210
9211 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
9212 if (!fn)
c2f47e15 9213 return NULL_TREE;
f0613857 9214
9215 if (!len)
9216 {
9217 len = c_strlen (src, 1);
9218 if (! len || TREE_SIDE_EFFECTS (len))
c2f47e15 9219 return NULL_TREE;
f0613857 9220 }
9221
9222 len = size_binop (PLUS_EXPR, len, ssize_int (1));
2426241c 9223 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
c2f47e15 9224 build_call_expr (fn, 3, dest, src, len));
9c8a1629 9225}
9226
c2f47e15 9227/* Fold function call to builtin strncpy with arguments DEST, SRC, and LEN.
9228 If SLEN is not NULL, it represents the length of the source string.
9229 Return NULL_TREE if no simplification can be made. */
9c8a1629 9230
f0613857 9231tree
c2f47e15 9232fold_builtin_strncpy (tree fndecl, tree dest, tree src, tree len, tree slen)
9c8a1629 9233{
c2f47e15 9234 tree fn;
9c8a1629 9235
c2f47e15 9236 if (!validate_arg (dest, POINTER_TYPE)
9237 || !validate_arg (src, POINTER_TYPE)
9238 || !validate_arg (len, INTEGER_TYPE))
9239 return NULL_TREE;
9c8a1629 9240
9241 /* If the LEN parameter is zero, return DEST. */
9242 if (integer_zerop (len))
2426241c 9243 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
9c8a1629 9244
19226313 9245 /* We can't compare slen with len as constants below if len is not a
9246 constant. */
9247 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
c2f47e15 9248 return NULL_TREE;
19226313 9249
f0613857 9250 if (!slen)
9251 slen = c_strlen (src, 1);
9252
9253 /* Now, we must be passed a constant src ptr parameter. */
9254 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
c2f47e15 9255 return NULL_TREE;
f0613857 9256
9257 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
9258
9259 /* We do not support simplification of this case, though we do
9260 support it when expanding trees into RTL. */
9261 /* FIXME: generate a call to __builtin_memset. */
9262 if (tree_int_cst_lt (slen, len))
c2f47e15 9263 return NULL_TREE;
f0613857 9264
9265 /* OK transform into builtin memcpy. */
9266 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
9267 if (!fn)
c2f47e15 9268 return NULL_TREE;
2426241c 9269 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
c2f47e15 9270 build_call_expr (fn, 3, dest, src, len));
9c8a1629 9271}
9272
7959b13b 9273/* Fold function call to builtin memchr. ARG1, ARG2 and LEN are the
9274 arguments to the call, and TYPE is its return type.
9275 Return NULL_TREE if no simplification can be made. */
9276
9277static tree
9278fold_builtin_memchr (tree arg1, tree arg2, tree len, tree type)
9279{
9280 if (!validate_arg (arg1, POINTER_TYPE)
9281 || !validate_arg (arg2, INTEGER_TYPE)
9282 || !validate_arg (len, INTEGER_TYPE))
9283 return NULL_TREE;
9284 else
9285 {
9286 const char *p1;
9287
9288 if (TREE_CODE (arg2) != INTEGER_CST
9289 || !host_integerp (len, 1))
9290 return NULL_TREE;
9291
9292 p1 = c_getstr (arg1);
9293 if (p1 && compare_tree_int (len, strlen (p1) + 1) <= 0)
9294 {
9295 char c;
9296 const char *r;
9297 tree tem;
9298
9299 if (target_char_cast (arg2, &c))
9300 return NULL_TREE;
9301
364c0c59 9302 r = (char *) memchr (p1, c, tree_low_cst (len, 1));
7959b13b 9303
9304 if (r == NULL)
9305 return build_int_cst (TREE_TYPE (arg1), 0);
9306
0de36bdb 9307 tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (arg1), arg1,
9308 size_int (r - p1));
7959b13b 9309 return fold_convert (type, tem);
9310 }
9311 return NULL_TREE;
9312 }
9313}
9314
c2f47e15 9315/* Fold function call to builtin memcmp with arguments ARG1 and ARG2.
9316 Return NULL_TREE if no simplification can be made. */
9c8a1629 9317
9318static tree
c2f47e15 9319fold_builtin_memcmp (tree arg1, tree arg2, tree len)
9c8a1629 9320{
c4fef134 9321 const char *p1, *p2;
9c8a1629 9322
c2f47e15 9323 if (!validate_arg (arg1, POINTER_TYPE)
9324 || !validate_arg (arg2, POINTER_TYPE)
9325 || !validate_arg (len, INTEGER_TYPE))
9326 return NULL_TREE;
9c8a1629 9327
9328 /* If the LEN parameter is zero, return zero. */
9329 if (integer_zerop (len))
c4fef134 9330 return omit_two_operands (integer_type_node, integer_zero_node,
9331 arg1, arg2);
9c8a1629 9332
9333 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
9334 if (operand_equal_p (arg1, arg2, 0))
c4fef134 9335 return omit_one_operand (integer_type_node, integer_zero_node, len);
9336
9337 p1 = c_getstr (arg1);
9338 p2 = c_getstr (arg2);
9339
9340 /* If all arguments are constant, and the value of len is not greater
9341 than the lengths of arg1 and arg2, evaluate at compile-time. */
9342 if (host_integerp (len, 1) && p1 && p2
9343 && compare_tree_int (len, strlen (p1) + 1) <= 0
9344 && compare_tree_int (len, strlen (p2) + 1) <= 0)
9345 {
9346 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
9347
9348 if (r > 0)
9349 return integer_one_node;
9350 else if (r < 0)
9351 return integer_minus_one_node;
9352 else
9353 return integer_zero_node;
9354 }
9355
9356 /* If len parameter is one, return an expression corresponding to
9357 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
9358 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9359 {
9360 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9361 tree cst_uchar_ptr_node
9362 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9363
c4fef134 9364 tree ind1 = fold_convert (integer_type_node,
9365 build1 (INDIRECT_REF, cst_uchar_node,
9366 fold_convert (cst_uchar_ptr_node,
9367 arg1)));
9368 tree ind2 = fold_convert (integer_type_node,
9369 build1 (INDIRECT_REF, cst_uchar_node,
9370 fold_convert (cst_uchar_ptr_node,
9371 arg2)));
49d00087 9372 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
c4fef134 9373 }
9c8a1629 9374
c2f47e15 9375 return NULL_TREE;
9c8a1629 9376}
9377
c2f47e15 9378/* Fold function call to builtin strcmp with arguments ARG1 and ARG2.
9379 Return NULL_TREE if no simplification can be made. */
9c8a1629 9380
9381static tree
c2f47e15 9382fold_builtin_strcmp (tree arg1, tree arg2)
9c8a1629 9383{
9c8a1629 9384 const char *p1, *p2;
9385
c2f47e15 9386 if (!validate_arg (arg1, POINTER_TYPE)
9387 || !validate_arg (arg2, POINTER_TYPE))
9388 return NULL_TREE;
9c8a1629 9389
9390 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
9391 if (operand_equal_p (arg1, arg2, 0))
c4fef134 9392 return integer_zero_node;
9c8a1629 9393
9394 p1 = c_getstr (arg1);
9395 p2 = c_getstr (arg2);
9396
9397 if (p1 && p2)
9398 {
9c8a1629 9399 const int i = strcmp (p1, p2);
9400 if (i < 0)
c4fef134 9401 return integer_minus_one_node;
9c8a1629 9402 else if (i > 0)
c4fef134 9403 return integer_one_node;
9c8a1629 9404 else
c4fef134 9405 return integer_zero_node;
9406 }
9407
9408 /* If the second arg is "", return *(const unsigned char*)arg1. */
9409 if (p2 && *p2 == '\0')
9410 {
9411 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9412 tree cst_uchar_ptr_node
9413 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9414
c4fef134 9415 return fold_convert (integer_type_node,
9416 build1 (INDIRECT_REF, cst_uchar_node,
9417 fold_convert (cst_uchar_ptr_node,
9418 arg1)));
9419 }
9420
9421 /* If the first arg is "", return -*(const unsigned char*)arg2. */
9422 if (p1 && *p1 == '\0')
9423 {
9424 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9425 tree cst_uchar_ptr_node
9426 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9427
c4fef134 9428 tree temp = fold_convert (integer_type_node,
9429 build1 (INDIRECT_REF, cst_uchar_node,
9430 fold_convert (cst_uchar_ptr_node,
9431 arg2)));
49d00087 9432 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
9c8a1629 9433 }
9434
c2f47e15 9435 return NULL_TREE;
9c8a1629 9436}
9437
c2f47e15 9438/* Fold function call to builtin strncmp with arguments ARG1, ARG2, and LEN.
9439 Return NULL_TREE if no simplification can be made. */
9c8a1629 9440
9441static tree
c2f47e15 9442fold_builtin_strncmp (tree arg1, tree arg2, tree len)
9c8a1629 9443{
9c8a1629 9444 const char *p1, *p2;
9445
c2f47e15 9446 if (!validate_arg (arg1, POINTER_TYPE)
9447 || !validate_arg (arg2, POINTER_TYPE)
9448 || !validate_arg (len, INTEGER_TYPE))
9449 return NULL_TREE;
9c8a1629 9450
9451 /* If the LEN parameter is zero, return zero. */
9452 if (integer_zerop (len))
c4fef134 9453 return omit_two_operands (integer_type_node, integer_zero_node,
9454 arg1, arg2);
9c8a1629 9455
9456 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
9457 if (operand_equal_p (arg1, arg2, 0))
c4fef134 9458 return omit_one_operand (integer_type_node, integer_zero_node, len);
9c8a1629 9459
9460 p1 = c_getstr (arg1);
9461 p2 = c_getstr (arg2);
9462
9463 if (host_integerp (len, 1) && p1 && p2)
9464 {
9c8a1629 9465 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
c4fef134 9466 if (i > 0)
9467 return integer_one_node;
9468 else if (i < 0)
9469 return integer_minus_one_node;
9c8a1629 9470 else
c4fef134 9471 return integer_zero_node;
9472 }
9473
9474 /* If the second arg is "", and the length is greater than zero,
9475 return *(const unsigned char*)arg1. */
9476 if (p2 && *p2 == '\0'
9477 && TREE_CODE (len) == INTEGER_CST
9478 && tree_int_cst_sgn (len) == 1)
9479 {
9480 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9481 tree cst_uchar_ptr_node
9482 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9483
c4fef134 9484 return fold_convert (integer_type_node,
9485 build1 (INDIRECT_REF, cst_uchar_node,
9486 fold_convert (cst_uchar_ptr_node,
9487 arg1)));
9488 }
9489
9490 /* If the first arg is "", and the length is greater than zero,
9491 return -*(const unsigned char*)arg2. */
9492 if (p1 && *p1 == '\0'
9493 && TREE_CODE (len) == INTEGER_CST
9494 && tree_int_cst_sgn (len) == 1)
9495 {
9496 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9497 tree cst_uchar_ptr_node
9498 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9499
c4fef134 9500 tree temp = fold_convert (integer_type_node,
9501 build1 (INDIRECT_REF, cst_uchar_node,
9502 fold_convert (cst_uchar_ptr_node,
9503 arg2)));
49d00087 9504 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
c4fef134 9505 }
9506
9507 /* If len parameter is one, return an expression corresponding to
9508 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
9509 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9510 {
9511 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9512 tree cst_uchar_ptr_node
9513 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9514
c4fef134 9515 tree ind1 = fold_convert (integer_type_node,
9516 build1 (INDIRECT_REF, cst_uchar_node,
9517 fold_convert (cst_uchar_ptr_node,
9518 arg1)));
9519 tree ind2 = fold_convert (integer_type_node,
9520 build1 (INDIRECT_REF, cst_uchar_node,
9521 fold_convert (cst_uchar_ptr_node,
9522 arg2)));
49d00087 9523 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
9c8a1629 9524 }
9525
c2f47e15 9526 return NULL_TREE;
9c8a1629 9527}
9528
c2f47e15 9529/* Fold function call to builtin signbit, signbitf or signbitl with argument
9530 ARG. Return NULL_TREE if no simplification can be made. */
27f261ef 9531
9532static tree
c2f47e15 9533fold_builtin_signbit (tree arg, tree type)
27f261ef 9534{
c2f47e15 9535 tree temp;
27f261ef 9536
c2f47e15 9537 if (!validate_arg (arg, REAL_TYPE))
27f261ef 9538 return NULL_TREE;
9539
27f261ef 9540 /* If ARG is a compile-time constant, determine the result. */
9541 if (TREE_CODE (arg) == REAL_CST
f96bd2bf 9542 && !TREE_OVERFLOW (arg))
27f261ef 9543 {
9544 REAL_VALUE_TYPE c;
9545
9546 c = TREE_REAL_CST (arg);
9547 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
2426241c 9548 return fold_convert (type, temp);
27f261ef 9549 }
9550
9551 /* If ARG is non-negative, the result is always zero. */
9552 if (tree_expr_nonnegative_p (arg))
2426241c 9553 return omit_one_operand (type, integer_zero_node, arg);
27f261ef 9554
9555 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
9556 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
49d00087 9557 return fold_build2 (LT_EXPR, type, arg,
9558 build_real (TREE_TYPE (arg), dconst0));
27f261ef 9559
9560 return NULL_TREE;
9561}
9562
c2f47e15 9563/* Fold function call to builtin copysign, copysignf or copysignl with
9564 arguments ARG1 and ARG2. Return NULL_TREE if no simplification can
9565 be made. */
467214fd 9566
9567static tree
c2f47e15 9568fold_builtin_copysign (tree fndecl, tree arg1, tree arg2, tree type)
467214fd 9569{
c2f47e15 9570 tree tem;
467214fd 9571
c2f47e15 9572 if (!validate_arg (arg1, REAL_TYPE)
9573 || !validate_arg (arg2, REAL_TYPE))
467214fd 9574 return NULL_TREE;
9575
467214fd 9576 /* copysign(X,X) is X. */
9577 if (operand_equal_p (arg1, arg2, 0))
9578 return fold_convert (type, arg1);
9579
9580 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
9581 if (TREE_CODE (arg1) == REAL_CST
9582 && TREE_CODE (arg2) == REAL_CST
f96bd2bf 9583 && !TREE_OVERFLOW (arg1)
9584 && !TREE_OVERFLOW (arg2))
467214fd 9585 {
9586 REAL_VALUE_TYPE c1, c2;
9587
9588 c1 = TREE_REAL_CST (arg1);
9589 c2 = TREE_REAL_CST (arg2);
749680e2 9590 /* c1.sign := c2.sign. */
467214fd 9591 real_copysign (&c1, &c2);
9592 return build_real (type, c1);
467214fd 9593 }
9594
9595 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
9596 Remember to evaluate Y for side-effects. */
9597 if (tree_expr_nonnegative_p (arg2))
9598 return omit_one_operand (type,
49d00087 9599 fold_build1 (ABS_EXPR, type, arg1),
467214fd 9600 arg2);
9601
198d9bbe 9602 /* Strip sign changing operations for the first argument. */
9603 tem = fold_strip_sign_ops (arg1);
9604 if (tem)
c2f47e15 9605 return build_call_expr (fndecl, 2, tem, arg2);
198d9bbe 9606
467214fd 9607 return NULL_TREE;
9608}
9609
c2f47e15 9610/* Fold a call to builtin isascii with argument ARG. */
d49367d4 9611
9612static tree
c2f47e15 9613fold_builtin_isascii (tree arg)
d49367d4 9614{
c2f47e15 9615 if (!validate_arg (arg, INTEGER_TYPE))
9616 return NULL_TREE;
d49367d4 9617 else
9618 {
9619 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
7c446c95 9620 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
9621 build_int_cst (NULL_TREE,
7016c612 9622 ~ (unsigned HOST_WIDE_INT) 0x7f));
f2532264 9623 return fold_build2 (EQ_EXPR, integer_type_node,
9624 arg, integer_zero_node);
d49367d4 9625 }
9626}
9627
c2f47e15 9628/* Fold a call to builtin toascii with argument ARG. */
d49367d4 9629
9630static tree
c2f47e15 9631fold_builtin_toascii (tree arg)
d49367d4 9632{
c2f47e15 9633 if (!validate_arg (arg, INTEGER_TYPE))
9634 return NULL_TREE;
9635
9636 /* Transform toascii(c) -> (c & 0x7f). */
9637 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
9638 build_int_cst (NULL_TREE, 0x7f));
d49367d4 9639}
9640
c2f47e15 9641/* Fold a call to builtin isdigit with argument ARG. */
df1cf42e 9642
9643static tree
c2f47e15 9644fold_builtin_isdigit (tree arg)
df1cf42e 9645{
c2f47e15 9646 if (!validate_arg (arg, INTEGER_TYPE))
9647 return NULL_TREE;
df1cf42e 9648 else
9649 {
9650 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
624d37a6 9651 /* According to the C standard, isdigit is unaffected by locale.
9652 However, it definitely is affected by the target character set. */
624d37a6 9653 unsigned HOST_WIDE_INT target_digit0
9654 = lang_hooks.to_target_charset ('0');
9655
9656 if (target_digit0 == 0)
9657 return NULL_TREE;
9658
c2f47e15 9659 arg = fold_convert (unsigned_type_node, arg);
05abc81b 9660 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
624d37a6 9661 build_int_cst (unsigned_type_node, target_digit0));
f2532264 9662 return fold_build2 (LE_EXPR, integer_type_node, arg,
9663 build_int_cst (unsigned_type_node, 9));
df1cf42e 9664 }
9665}
27f261ef 9666
c2f47e15 9667/* Fold a call to fabs, fabsf or fabsl with argument ARG. */
d1aade50 9668
9669static tree
c2f47e15 9670fold_builtin_fabs (tree arg, tree type)
d1aade50 9671{
c2f47e15 9672 if (!validate_arg (arg, REAL_TYPE))
9673 return NULL_TREE;
d1aade50 9674
9829e110 9675 arg = fold_convert (type, arg);
d1aade50 9676 if (TREE_CODE (arg) == REAL_CST)
9677 return fold_abs_const (arg, type);
49d00087 9678 return fold_build1 (ABS_EXPR, type, arg);
d1aade50 9679}
9680
c2f47e15 9681/* Fold a call to abs, labs, llabs or imaxabs with argument ARG. */
d1aade50 9682
9683static tree
c2f47e15 9684fold_builtin_abs (tree arg, tree type)
d1aade50 9685{
c2f47e15 9686 if (!validate_arg (arg, INTEGER_TYPE))
9687 return NULL_TREE;
d1aade50 9688
9829e110 9689 arg = fold_convert (type, arg);
d1aade50 9690 if (TREE_CODE (arg) == INTEGER_CST)
9691 return fold_abs_const (arg, type);
49d00087 9692 return fold_build1 (ABS_EXPR, type, arg);
d1aade50 9693}
9694
d4a43a03 9695/* Fold a call to builtin fmin or fmax. */
9696
9697static tree
c2f47e15 9698fold_builtin_fmin_fmax (tree arg0, tree arg1, tree type, bool max)
d4a43a03 9699{
c2f47e15 9700 if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, REAL_TYPE))
d4a43a03 9701 {
d4a43a03 9702 /* Calculate the result when the argument is a constant. */
9703 tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
9704
9705 if (res)
9706 return res;
9707
61fe3555 9708 /* If either argument is NaN, return the other one. Avoid the
9709 transformation if we get (and honor) a signalling NaN. Using
9710 omit_one_operand() ensures we create a non-lvalue. */
9711 if (TREE_CODE (arg0) == REAL_CST
9712 && real_isnan (&TREE_REAL_CST (arg0))
9713 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
9714 || ! TREE_REAL_CST (arg0).signalling))
9715 return omit_one_operand (type, arg1, arg0);
9716 if (TREE_CODE (arg1) == REAL_CST
9717 && real_isnan (&TREE_REAL_CST (arg1))
9718 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
9719 || ! TREE_REAL_CST (arg1).signalling))
9720 return omit_one_operand (type, arg0, arg1);
9721
d4a43a03 9722 /* Transform fmin/fmax(x,x) -> x. */
9723 if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
9724 return omit_one_operand (type, arg0, arg1);
9725
9726 /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR. C99 requires these
9727 functions to return the numeric arg if the other one is NaN.
9728 These tree codes don't honor that, so only transform if
9729 -ffinite-math-only is set. C99 doesn't require -0.0 to be
9730 handled, so we don't have to worry about it either. */
9731 if (flag_finite_math_only)
9732 return fold_build2 ((max ? MAX_EXPR : MIN_EXPR), type,
9733 fold_convert (type, arg0),
9734 fold_convert (type, arg1));
9735 }
9736 return NULL_TREE;
9737}
9738
abe4dcf6 9739/* Fold a call to builtin carg(a+bi) -> atan2(b,a). */
9740
9741static tree
c2f47e15 9742fold_builtin_carg (tree arg, tree type)
abe4dcf6 9743{
239d491a 9744 if (validate_arg (arg, COMPLEX_TYPE)
9745 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
abe4dcf6 9746 {
9747 tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2);
9748
9749 if (atan2_fn)
9750 {
c2f47e15 9751 tree new_arg = builtin_save_expr (arg);
9752 tree r_arg = fold_build1 (REALPART_EXPR, type, new_arg);
9753 tree i_arg = fold_build1 (IMAGPART_EXPR, type, new_arg);
9754 return build_call_expr (atan2_fn, 2, i_arg, r_arg);
abe4dcf6 9755 }
9756 }
9757
9758 return NULL_TREE;
9759}
9760
cb2b9385 9761/* Fold a call to builtin logb/ilogb. */
9762
9763static tree
9764fold_builtin_logb (tree arg, tree rettype)
9765{
9766 if (! validate_arg (arg, REAL_TYPE))
9767 return NULL_TREE;
9768
9769 STRIP_NOPS (arg);
9770
9771 if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9772 {
9773 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9774
9775 switch (value->cl)
9776 {
9777 case rvc_nan:
9778 case rvc_inf:
9779 /* If arg is Inf or NaN and we're logb, return it. */
9780 if (TREE_CODE (rettype) == REAL_TYPE)
9781 return fold_convert (rettype, arg);
9782 /* Fall through... */
9783 case rvc_zero:
9784 /* Zero may set errno and/or raise an exception for logb, also
9785 for ilogb we don't know FP_ILOGB0. */
9786 return NULL_TREE;
9787 case rvc_normal:
9788 /* For normal numbers, proceed iff radix == 2. In GCC,
9789 normalized significands are in the range [0.5, 1.0). We
9790 want the exponent as if they were [1.0, 2.0) so get the
9791 exponent and subtract 1. */
9792 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9793 return fold_convert (rettype, build_int_cst (NULL_TREE,
9794 REAL_EXP (value)-1));
9795 break;
9796 }
9797 }
9798
9799 return NULL_TREE;
9800}
9801
9802/* Fold a call to builtin significand, if radix == 2. */
9803
9804static tree
9805fold_builtin_significand (tree arg, tree rettype)
9806{
9807 if (! validate_arg (arg, REAL_TYPE))
9808 return NULL_TREE;
9809
9810 STRIP_NOPS (arg);
9811
9812 if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9813 {
9814 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9815
9816 switch (value->cl)
9817 {
9818 case rvc_zero:
9819 case rvc_nan:
9820 case rvc_inf:
9821 /* If arg is +-0, +-Inf or +-NaN, then return it. */
9822 return fold_convert (rettype, arg);
9823 case rvc_normal:
9824 /* For normal numbers, proceed iff radix == 2. */
9825 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9826 {
9827 REAL_VALUE_TYPE result = *value;
9828 /* In GCC, normalized significands are in the range [0.5,
9829 1.0). We want them to be [1.0, 2.0) so set the
9830 exponent to 1. */
9831 SET_REAL_EXP (&result, 1);
9832 return build_real (rettype, result);
9833 }
9834 break;
9835 }
9836 }
9837
9838 return NULL_TREE;
9839}
9840
3838b9ae 9841/* Fold a call to builtin frexp, we can assume the base is 2. */
9842
9843static tree
9844fold_builtin_frexp (tree arg0, tree arg1, tree rettype)
9845{
9846 if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9847 return NULL_TREE;
9848
9849 STRIP_NOPS (arg0);
9850
9851 if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9852 return NULL_TREE;
9853
9854 arg1 = build_fold_indirect_ref (arg1);
9855
9856 /* Proceed if a valid pointer type was passed in. */
9857 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == integer_type_node)
9858 {
9859 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9860 tree frac, exp;
9861
9862 switch (value->cl)
9863 {
9864 case rvc_zero:
9865 /* For +-0, return (*exp = 0, +-0). */
9866 exp = integer_zero_node;
9867 frac = arg0;
9868 break;
9869 case rvc_nan:
9870 case rvc_inf:
9871 /* For +-NaN or +-Inf, *exp is unspecified, return arg0. */
9872 return omit_one_operand (rettype, arg0, arg1);
9873 case rvc_normal:
9874 {
9875 /* Since the frexp function always expects base 2, and in
9876 GCC normalized significands are already in the range
9877 [0.5, 1.0), we have exactly what frexp wants. */
9878 REAL_VALUE_TYPE frac_rvt = *value;
9879 SET_REAL_EXP (&frac_rvt, 0);
9880 frac = build_real (rettype, frac_rvt);
9881 exp = build_int_cst (NULL_TREE, REAL_EXP (value));
9882 }
9883 break;
9884 default:
9885 gcc_unreachable ();
9886 }
9887
9888 /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9889 arg1 = fold_build2 (MODIFY_EXPR, rettype, arg1, exp);
9890 TREE_SIDE_EFFECTS (arg1) = 1;
9891 return fold_build2 (COMPOUND_EXPR, rettype, arg1, frac);
9892 }
9893
9894 return NULL_TREE;
9895}
9896
7587301b 9897/* Fold a call to builtin ldexp or scalbn/scalbln. If LDEXP is true
9898 then we can assume the base is two. If it's false, then we have to
9899 check the mode of the TYPE parameter in certain cases. */
9900
9901static tree
9902fold_builtin_load_exponent (tree arg0, tree arg1, tree type, bool ldexp)
9903{
9904 if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, INTEGER_TYPE))
9905 {
9906 STRIP_NOPS (arg0);
9907 STRIP_NOPS (arg1);
9908
9909 /* If arg0 is 0, Inf or NaN, or if arg1 is 0, then return arg0. */
9910 if (real_zerop (arg0) || integer_zerop (arg1)
9911 || (TREE_CODE (arg0) == REAL_CST
776a7bab 9912 && !real_isfinite (&TREE_REAL_CST (arg0))))
7587301b 9913 return omit_one_operand (type, arg0, arg1);
9914
9915 /* If both arguments are constant, then try to evaluate it. */
9916 if ((ldexp || REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2)
9917 && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
9918 && host_integerp (arg1, 0))
9919 {
9920 /* Bound the maximum adjustment to twice the range of the
9921 mode's valid exponents. Use abs to ensure the range is
9922 positive as a sanity check. */
9923 const long max_exp_adj = 2 *
9924 labs (REAL_MODE_FORMAT (TYPE_MODE (type))->emax
9925 - REAL_MODE_FORMAT (TYPE_MODE (type))->emin);
9926
9927 /* Get the user-requested adjustment. */
9928 const HOST_WIDE_INT req_exp_adj = tree_low_cst (arg1, 0);
9929
9930 /* The requested adjustment must be inside this range. This
9931 is a preliminary cap to avoid things like overflow, we
9932 may still fail to compute the result for other reasons. */
9933 if (-max_exp_adj < req_exp_adj && req_exp_adj < max_exp_adj)
9934 {
9935 REAL_VALUE_TYPE initial_result;
9936
9937 real_ldexp (&initial_result, &TREE_REAL_CST (arg0), req_exp_adj);
9938
9939 /* Ensure we didn't overflow. */
9940 if (! real_isinf (&initial_result))
9941 {
9942 const REAL_VALUE_TYPE trunc_result
9943 = real_value_truncate (TYPE_MODE (type), initial_result);
9944
9945 /* Only proceed if the target mode can hold the
9946 resulting value. */
9947 if (REAL_VALUES_EQUAL (initial_result, trunc_result))
9948 return build_real (type, trunc_result);
9949 }
9950 }
9951 }
9952 }
9953
9954 return NULL_TREE;
9955}
9956
ebf8b4f5 9957/* Fold a call to builtin modf. */
9958
9959static tree
9960fold_builtin_modf (tree arg0, tree arg1, tree rettype)
9961{
9962 if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9963 return NULL_TREE;
9964
9965 STRIP_NOPS (arg0);
9966
9967 if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9968 return NULL_TREE;
9969
9970 arg1 = build_fold_indirect_ref (arg1);
9971
9972 /* Proceed if a valid pointer type was passed in. */
9973 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == TYPE_MAIN_VARIANT (rettype))
9974 {
9975 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9976 REAL_VALUE_TYPE trunc, frac;
9977
9978 switch (value->cl)
9979 {
9980 case rvc_nan:
9981 case rvc_zero:
9982 /* For +-NaN or +-0, return (*arg1 = arg0, arg0). */
9983 trunc = frac = *value;
9984 break;
9985 case rvc_inf:
9986 /* For +-Inf, return (*arg1 = arg0, +-0). */
9987 frac = dconst0;
9988 frac.sign = value->sign;
9989 trunc = *value;
9990 break;
9991 case rvc_normal:
9992 /* Return (*arg1 = trunc(arg0), arg0-trunc(arg0)). */
9993 real_trunc (&trunc, VOIDmode, value);
9994 real_arithmetic (&frac, MINUS_EXPR, value, &trunc);
9995 /* If the original number was negative and already
9996 integral, then the fractional part is -0.0. */
9997 if (value->sign && frac.cl == rvc_zero)
9998 frac.sign = value->sign;
9999 break;
10000 }
10001
10002 /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
10003 arg1 = fold_build2 (MODIFY_EXPR, rettype, arg1,
10004 build_real (rettype, trunc));
10005 TREE_SIDE_EFFECTS (arg1) = 1;
10006 return fold_build2 (COMPOUND_EXPR, rettype, arg1,
10007 build_real (rettype, frac));
10008 }
10009
10010 return NULL_TREE;
10011}
10012
726069ba 10013/* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
c2f47e15 10014 ARG is the argument for the call. */
726069ba 10015
10016static tree
c2f47e15 10017fold_builtin_classify (tree fndecl, tree arg, int builtin_index)
726069ba 10018{
726069ba 10019 tree type = TREE_TYPE (TREE_TYPE (fndecl));
726069ba 10020 REAL_VALUE_TYPE r;
10021
c2f47e15 10022 if (!validate_arg (arg, REAL_TYPE))
d43cee80 10023 return NULL_TREE;
726069ba 10024
726069ba 10025 switch (builtin_index)
10026 {
10027 case BUILT_IN_ISINF:
b70bfd00 10028 if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
a0c938f0 10029 return omit_one_operand (type, integer_zero_node, arg);
726069ba 10030
10031 if (TREE_CODE (arg) == REAL_CST)
10032 {
10033 r = TREE_REAL_CST (arg);
10034 if (real_isinf (&r))
10035 return real_compare (GT_EXPR, &r, &dconst0)
10036 ? integer_one_node : integer_minus_one_node;
10037 else
10038 return integer_zero_node;
10039 }
10040
10041 return NULL_TREE;
10042
c319d56a 10043 case BUILT_IN_ISINF_SIGN:
10044 {
10045 /* isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 */
10046 /* In a boolean context, GCC will fold the inner COND_EXPR to
10047 1. So e.g. "if (isinf_sign(x))" would be folded to just
10048 "if (isinf(x) ? 1 : 0)" which becomes "if (isinf(x))". */
10049 tree signbit_fn = mathfn_built_in_1 (TREE_TYPE (arg), BUILT_IN_SIGNBIT, 0);
10050 tree isinf_fn = built_in_decls[BUILT_IN_ISINF];
10051 tree tmp = NULL_TREE;
10052
10053 arg = builtin_save_expr (arg);
10054
10055 if (signbit_fn && isinf_fn)
10056 {
10057 tree signbit_call = build_call_expr (signbit_fn, 1, arg);
10058 tree isinf_call = build_call_expr (isinf_fn, 1, arg);
10059
10060 signbit_call = fold_build2 (NE_EXPR, integer_type_node,
10061 signbit_call, integer_zero_node);
10062 isinf_call = fold_build2 (NE_EXPR, integer_type_node,
10063 isinf_call, integer_zero_node);
10064
10065 tmp = fold_build3 (COND_EXPR, integer_type_node, signbit_call,
10066 integer_minus_one_node, integer_one_node);
10067 tmp = fold_build3 (COND_EXPR, integer_type_node, isinf_call, tmp,
10068 integer_zero_node);
10069 }
10070
10071 return tmp;
10072 }
10073
cde061c1 10074 case BUILT_IN_ISFINITE:
b70bfd00 10075 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
10076 && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
34709e02 10077 return omit_one_operand (type, integer_one_node, arg);
726069ba 10078
10079 if (TREE_CODE (arg) == REAL_CST)
10080 {
10081 r = TREE_REAL_CST (arg);
776a7bab 10082 return real_isfinite (&r) ? integer_one_node : integer_zero_node;
726069ba 10083 }
10084
10085 return NULL_TREE;
10086
10087 case BUILT_IN_ISNAN:
b70bfd00 10088 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
a0c938f0 10089 return omit_one_operand (type, integer_zero_node, arg);
726069ba 10090
10091 if (TREE_CODE (arg) == REAL_CST)
10092 {
10093 r = TREE_REAL_CST (arg);
10094 return real_isnan (&r) ? integer_one_node : integer_zero_node;
10095 }
10096
10097 arg = builtin_save_expr (arg);
49d00087 10098 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
726069ba 10099
10100 default:
64db345d 10101 gcc_unreachable ();
726069ba 10102 }
10103}
10104
19fbe3a4 10105/* Fold a call to __builtin_fpclassify(int, int, int, int, int, ...).
10106 This builtin will generate code to return the appropriate floating
10107 point classification depending on the value of the floating point
10108 number passed in. The possible return values must be supplied as
921b27c0 10109 int arguments to the call in the following order: FP_NAN, FP_INFINITE,
19fbe3a4 10110 FP_NORMAL, FP_SUBNORMAL and FP_ZERO. The ellipses is for exactly
10111 one floating point argument which is "type generic". */
10112
10113static tree
10114fold_builtin_fpclassify (tree exp)
10115{
921b27c0 10116 tree fp_nan, fp_infinite, fp_normal, fp_subnormal, fp_zero,
10117 arg, type, res, tmp;
19fbe3a4 10118 enum machine_mode mode;
10119 REAL_VALUE_TYPE r;
10120 char buf[128];
10121
10122 /* Verify the required arguments in the original call. */
10123 if (!validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE,
10124 INTEGER_TYPE, INTEGER_TYPE,
10125 INTEGER_TYPE, REAL_TYPE, VOID_TYPE))
10126 return NULL_TREE;
10127
10128 fp_nan = CALL_EXPR_ARG (exp, 0);
921b27c0 10129 fp_infinite = CALL_EXPR_ARG (exp, 1);
19fbe3a4 10130 fp_normal = CALL_EXPR_ARG (exp, 2);
10131 fp_subnormal = CALL_EXPR_ARG (exp, 3);
10132 fp_zero = CALL_EXPR_ARG (exp, 4);
10133 arg = CALL_EXPR_ARG (exp, 5);
10134 type = TREE_TYPE (arg);
10135 mode = TYPE_MODE (type);
10136 arg = builtin_save_expr (fold_build1 (ABS_EXPR, type, arg));
10137
10138 /* fpclassify(x) ->
10139 isnan(x) ? FP_NAN :
921b27c0 10140 (fabs(x) == Inf ? FP_INFINITE :
19fbe3a4 10141 (fabs(x) >= DBL_MIN ? FP_NORMAL :
10142 (x == 0 ? FP_ZERO : FP_SUBNORMAL))). */
10143
10144 tmp = fold_build2 (EQ_EXPR, integer_type_node, arg,
10145 build_real (type, dconst0));
10146 res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_zero, fp_subnormal);
10147
10148 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
10149 real_from_string (&r, buf);
10150 tmp = fold_build2 (GE_EXPR, integer_type_node, arg, build_real (type, r));
10151 res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_normal, res);
10152
10153 if (HONOR_INFINITIES (mode))
10154 {
10155 real_inf (&r);
10156 tmp = fold_build2 (EQ_EXPR, integer_type_node, arg,
10157 build_real (type, r));
921b27c0 10158 res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_infinite, res);
19fbe3a4 10159 }
10160
10161 if (HONOR_NANS (mode))
10162 {
10163 tmp = fold_build2 (ORDERED_EXPR, integer_type_node, arg, arg);
10164 res = fold_build3 (COND_EXPR, integer_type_node, tmp, res, fp_nan);
10165 }
10166
10167 return res;
10168}
10169
9bc9f15f 10170/* Fold a call to an unordered comparison function such as
d5019fe8 10171 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
c2f47e15 10172 being called and ARG0 and ARG1 are the arguments for the call.
726069ba 10173 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
10174 the opposite of the desired result. UNORDERED_CODE is used
10175 for modes that can hold NaNs and ORDERED_CODE is used for
10176 the rest. */
9bc9f15f 10177
10178static tree
c2f47e15 10179fold_builtin_unordered_cmp (tree fndecl, tree arg0, tree arg1,
9bc9f15f 10180 enum tree_code unordered_code,
10181 enum tree_code ordered_code)
10182{
859f903a 10183 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9bc9f15f 10184 enum tree_code code;
6978db0d 10185 tree type0, type1;
10186 enum tree_code code0, code1;
10187 tree cmp_type = NULL_TREE;
9bc9f15f 10188
6978db0d 10189 type0 = TREE_TYPE (arg0);
10190 type1 = TREE_TYPE (arg1);
a0c938f0 10191
6978db0d 10192 code0 = TREE_CODE (type0);
10193 code1 = TREE_CODE (type1);
a0c938f0 10194
6978db0d 10195 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
10196 /* Choose the wider of two real types. */
10197 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
10198 ? type0 : type1;
10199 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
10200 cmp_type = type0;
10201 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
10202 cmp_type = type1;
a0c938f0 10203
6978db0d 10204 arg0 = fold_convert (cmp_type, arg0);
10205 arg1 = fold_convert (cmp_type, arg1);
859f903a 10206
10207 if (unordered_code == UNORDERED_EXPR)
10208 {
b70bfd00 10209 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
859f903a 10210 return omit_two_operands (type, integer_zero_node, arg0, arg1);
49d00087 10211 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
859f903a 10212 }
9bc9f15f 10213
b70bfd00 10214 code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
10215 : ordered_code;
49d00087 10216 return fold_build1 (TRUTH_NOT_EXPR, type,
10217 fold_build2 (code, type, arg0, arg1));
9bc9f15f 10218}
10219
c2f47e15 10220/* Fold a call to built-in function FNDECL with 0 arguments.
10221 IGNORE is true if the result of the function call is ignored. This
10222 function returns NULL_TREE if no simplification was possible. */
650e4c94 10223
4ee9c684 10224static tree
c2f47e15 10225fold_builtin_0 (tree fndecl, bool ignore ATTRIBUTE_UNUSED)
650e4c94 10226{
e9f80ff5 10227 tree type = TREE_TYPE (TREE_TYPE (fndecl));
c2f47e15 10228 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
189b3398 10229 switch (fcode)
650e4c94 10230 {
c2f47e15 10231 CASE_FLT_FN (BUILT_IN_INF):
10232 case BUILT_IN_INFD32:
10233 case BUILT_IN_INFD64:
10234 case BUILT_IN_INFD128:
10235 return fold_builtin_inf (type, true);
7c2f0500 10236
c2f47e15 10237 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
10238 return fold_builtin_inf (type, false);
7c2f0500 10239
c2f47e15 10240 case BUILT_IN_CLASSIFY_TYPE:
10241 return fold_builtin_classify_type (NULL_TREE);
7c2f0500 10242
c2f47e15 10243 default:
10244 break;
10245 }
10246 return NULL_TREE;
10247}
7c2f0500 10248
c2f47e15 10249/* Fold a call to built-in function FNDECL with 1 argument, ARG0.
10250 IGNORE is true if the result of the function call is ignored. This
10251 function returns NULL_TREE if no simplification was possible. */
7c2f0500 10252
c2f47e15 10253static tree
10254fold_builtin_1 (tree fndecl, tree arg0, bool ignore)
10255{
10256 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10257 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10258 switch (fcode)
10259 {
7c2f0500 10260
650e4c94 10261 case BUILT_IN_CONSTANT_P:
7c2f0500 10262 {
c2f47e15 10263 tree val = fold_builtin_constant_p (arg0);
7c2f0500 10264
7c2f0500 10265 /* Gimplification will pull the CALL_EXPR for the builtin out of
10266 an if condition. When not optimizing, we'll not CSE it back.
10267 To avoid link error types of regressions, return false now. */
10268 if (!val && !optimize)
10269 val = integer_zero_node;
10270
10271 return val;
10272 }
650e4c94 10273
539a3a92 10274 case BUILT_IN_CLASSIFY_TYPE:
c2f47e15 10275 return fold_builtin_classify_type (arg0);
539a3a92 10276
650e4c94 10277 case BUILT_IN_STRLEN:
c2f47e15 10278 return fold_builtin_strlen (arg0);
650e4c94 10279
4f35b1fc 10280 CASE_FLT_FN (BUILT_IN_FABS):
c2f47e15 10281 return fold_builtin_fabs (arg0, type);
d1aade50 10282
10283 case BUILT_IN_ABS:
10284 case BUILT_IN_LABS:
10285 case BUILT_IN_LLABS:
10286 case BUILT_IN_IMAXABS:
c2f47e15 10287 return fold_builtin_abs (arg0, type);
c63f4ad3 10288
4f35b1fc 10289 CASE_FLT_FN (BUILT_IN_CONJ):
239d491a 10290 if (validate_arg (arg0, COMPLEX_TYPE)
10291 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
c2f47e15 10292 return fold_build1 (CONJ_EXPR, type, arg0);
10293 break;
36d3581d 10294
4f35b1fc 10295 CASE_FLT_FN (BUILT_IN_CREAL):
239d491a 10296 if (validate_arg (arg0, COMPLEX_TYPE)
10297 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
c2f47e15 10298 return non_lvalue (fold_build1 (REALPART_EXPR, type, arg0));;
10299 break;
36d3581d 10300
4f35b1fc 10301 CASE_FLT_FN (BUILT_IN_CIMAG):
c2f47e15 10302 if (validate_arg (arg0, COMPLEX_TYPE))
10303 return non_lvalue (fold_build1 (IMAGPART_EXPR, type, arg0));
10304 break;
36d3581d 10305
503733d5 10306 CASE_FLT_FN (BUILT_IN_CCOS):
239d491a 10307 return fold_builtin_ccos(arg0, type, fndecl, /*hyper=*/ false);
10308
503733d5 10309 CASE_FLT_FN (BUILT_IN_CCOSH):
239d491a 10310 return fold_builtin_ccos(arg0, type, fndecl, /*hyper=*/ true);
10311
10312#ifdef HAVE_mpc
10313 CASE_FLT_FN (BUILT_IN_CSIN):
10314 if (validate_arg (arg0, COMPLEX_TYPE)
10315 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10316 return do_mpc_arg1 (arg0, type, mpc_sin);
c2f47e15 10317 break;
239d491a 10318
10319 CASE_FLT_FN (BUILT_IN_CSINH):
10320 if (validate_arg (arg0, COMPLEX_TYPE)
10321 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10322 return do_mpc_arg1 (arg0, type, mpc_sinh);
10323 break;
10324
10325 CASE_FLT_FN (BUILT_IN_CTAN):
10326 if (validate_arg (arg0, COMPLEX_TYPE)
10327 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10328 return do_mpc_arg1 (arg0, type, mpc_tan);
10329 break;
10330
10331 CASE_FLT_FN (BUILT_IN_CTANH):
10332 if (validate_arg (arg0, COMPLEX_TYPE)
10333 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10334 return do_mpc_arg1 (arg0, type, mpc_tanh);
10335 break;
10336
10337 CASE_FLT_FN (BUILT_IN_CLOG):
10338 if (validate_arg (arg0, COMPLEX_TYPE)
10339 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10340 return do_mpc_arg1 (arg0, type, mpc_log);
10341 break;
10342
10343 CASE_FLT_FN (BUILT_IN_CSQRT):
10344 if (validate_arg (arg0, COMPLEX_TYPE)
10345 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10346 return do_mpc_arg1 (arg0, type, mpc_sqrt);
10347 break;
10348#endif
10349
4f35b1fc 10350 CASE_FLT_FN (BUILT_IN_CABS):
c2f47e15 10351 return fold_builtin_cabs (arg0, type, fndecl);
c63f4ad3 10352
abe4dcf6 10353 CASE_FLT_FN (BUILT_IN_CARG):
c2f47e15 10354 return fold_builtin_carg (arg0, type);
abe4dcf6 10355
4f35b1fc 10356 CASE_FLT_FN (BUILT_IN_SQRT):
c2f47e15 10357 return fold_builtin_sqrt (arg0, type);
805e22b2 10358
4f35b1fc 10359 CASE_FLT_FN (BUILT_IN_CBRT):
c2f47e15 10360 return fold_builtin_cbrt (arg0, type);
3bc5c41b 10361
728bac60 10362 CASE_FLT_FN (BUILT_IN_ASIN):
c2f47e15 10363 if (validate_arg (arg0, REAL_TYPE))
10364 return do_mpfr_arg1 (arg0, type, mpfr_asin,
728bac60 10365 &dconstm1, &dconst1, true);
10366 break;
10367
10368 CASE_FLT_FN (BUILT_IN_ACOS):
c2f47e15 10369 if (validate_arg (arg0, REAL_TYPE))
10370 return do_mpfr_arg1 (arg0, type, mpfr_acos,
728bac60 10371 &dconstm1, &dconst1, true);
10372 break;
10373
10374 CASE_FLT_FN (BUILT_IN_ATAN):
c2f47e15 10375 if (validate_arg (arg0, REAL_TYPE))
10376 return do_mpfr_arg1 (arg0, type, mpfr_atan, NULL, NULL, 0);
728bac60 10377 break;
10378
10379 CASE_FLT_FN (BUILT_IN_ASINH):
c2f47e15 10380 if (validate_arg (arg0, REAL_TYPE))
10381 return do_mpfr_arg1 (arg0, type, mpfr_asinh, NULL, NULL, 0);
728bac60 10382 break;
10383
10384 CASE_FLT_FN (BUILT_IN_ACOSH):
c2f47e15 10385 if (validate_arg (arg0, REAL_TYPE))
10386 return do_mpfr_arg1 (arg0, type, mpfr_acosh,
728bac60 10387 &dconst1, NULL, true);
10388 break;
10389
10390 CASE_FLT_FN (BUILT_IN_ATANH):
c2f47e15 10391 if (validate_arg (arg0, REAL_TYPE))
10392 return do_mpfr_arg1 (arg0, type, mpfr_atanh,
728bac60 10393 &dconstm1, &dconst1, false);
10394 break;
10395
4f35b1fc 10396 CASE_FLT_FN (BUILT_IN_SIN):
c2f47e15 10397 if (validate_arg (arg0, REAL_TYPE))
10398 return do_mpfr_arg1 (arg0, type, mpfr_sin, NULL, NULL, 0);
728bac60 10399 break;
77e89269 10400
4f35b1fc 10401 CASE_FLT_FN (BUILT_IN_COS):
c2f47e15 10402 return fold_builtin_cos (arg0, type, fndecl);
77e89269 10403
728bac60 10404 CASE_FLT_FN (BUILT_IN_TAN):
c2f47e15 10405 return fold_builtin_tan (arg0, type);
d735c391 10406
c5bb2c4b 10407 CASE_FLT_FN (BUILT_IN_CEXP):
c2f47e15 10408 return fold_builtin_cexp (arg0, type);
c5bb2c4b 10409
d735c391 10410 CASE_FLT_FN (BUILT_IN_CEXPI):
c2f47e15 10411 if (validate_arg (arg0, REAL_TYPE))
10412 return do_mpfr_sincos (arg0, NULL_TREE, NULL_TREE);
10413 break;
d92f994c 10414
728bac60 10415 CASE_FLT_FN (BUILT_IN_SINH):
c2f47e15 10416 if (validate_arg (arg0, REAL_TYPE))
10417 return do_mpfr_arg1 (arg0, type, mpfr_sinh, NULL, NULL, 0);
728bac60 10418 break;
10419
10420 CASE_FLT_FN (BUILT_IN_COSH):
c2f47e15 10421 return fold_builtin_cosh (arg0, type, fndecl);
728bac60 10422
10423 CASE_FLT_FN (BUILT_IN_TANH):
c2f47e15 10424 if (validate_arg (arg0, REAL_TYPE))
10425 return do_mpfr_arg1 (arg0, type, mpfr_tanh, NULL, NULL, 0);
728bac60 10426 break;
10427
29f4cd78 10428 CASE_FLT_FN (BUILT_IN_ERF):
c2f47e15 10429 if (validate_arg (arg0, REAL_TYPE))
10430 return do_mpfr_arg1 (arg0, type, mpfr_erf, NULL, NULL, 0);
29f4cd78 10431 break;
10432
10433 CASE_FLT_FN (BUILT_IN_ERFC):
c2f47e15 10434 if (validate_arg (arg0, REAL_TYPE))
10435 return do_mpfr_arg1 (arg0, type, mpfr_erfc, NULL, NULL, 0);
29f4cd78 10436 break;
10437
32dba52b 10438 CASE_FLT_FN (BUILT_IN_TGAMMA):
c2f47e15 10439 if (validate_arg (arg0, REAL_TYPE))
10440 return do_mpfr_arg1 (arg0, type, mpfr_gamma, NULL, NULL, 0);
32dba52b 10441 break;
10442
4f35b1fc 10443 CASE_FLT_FN (BUILT_IN_EXP):
c2f47e15 10444 return fold_builtin_exponent (fndecl, arg0, mpfr_exp);
467214fd 10445
4f35b1fc 10446 CASE_FLT_FN (BUILT_IN_EXP2):
c2f47e15 10447 return fold_builtin_exponent (fndecl, arg0, mpfr_exp2);
467214fd 10448
4f35b1fc 10449 CASE_FLT_FN (BUILT_IN_EXP10):
10450 CASE_FLT_FN (BUILT_IN_POW10):
c2f47e15 10451 return fold_builtin_exponent (fndecl, arg0, mpfr_exp10);
467214fd 10452
29f4cd78 10453 CASE_FLT_FN (BUILT_IN_EXPM1):
c2f47e15 10454 if (validate_arg (arg0, REAL_TYPE))
10455 return do_mpfr_arg1 (arg0, type, mpfr_expm1, NULL, NULL, 0);
29f4cd78 10456 break;
10457
4f35b1fc 10458 CASE_FLT_FN (BUILT_IN_LOG):
c2f47e15 10459 return fold_builtin_logarithm (fndecl, arg0, mpfr_log);
467214fd 10460
4f35b1fc 10461 CASE_FLT_FN (BUILT_IN_LOG2):
c2f47e15 10462 return fold_builtin_logarithm (fndecl, arg0, mpfr_log2);
467214fd 10463
4f35b1fc 10464 CASE_FLT_FN (BUILT_IN_LOG10):
c2f47e15 10465 return fold_builtin_logarithm (fndecl, arg0, mpfr_log10);
29f4cd78 10466
10467 CASE_FLT_FN (BUILT_IN_LOG1P):
c2f47e15 10468 if (validate_arg (arg0, REAL_TYPE))
10469 return do_mpfr_arg1 (arg0, type, mpfr_log1p,
29f4cd78 10470 &dconstm1, NULL, false);
10471 break;
805e22b2 10472
65dd1378 10473 CASE_FLT_FN (BUILT_IN_J0):
10474 if (validate_arg (arg0, REAL_TYPE))
10475 return do_mpfr_arg1 (arg0, type, mpfr_j0,
10476 NULL, NULL, 0);
10477 break;
10478
10479 CASE_FLT_FN (BUILT_IN_J1):
10480 if (validate_arg (arg0, REAL_TYPE))
10481 return do_mpfr_arg1 (arg0, type, mpfr_j1,
10482 NULL, NULL, 0);
10483 break;
6ff9eeff 10484
10485 CASE_FLT_FN (BUILT_IN_Y0):
10486 if (validate_arg (arg0, REAL_TYPE))
10487 return do_mpfr_arg1 (arg0, type, mpfr_y0,
10488 &dconst0, NULL, false);
10489 break;
10490
10491 CASE_FLT_FN (BUILT_IN_Y1):
10492 if (validate_arg (arg0, REAL_TYPE))
10493 return do_mpfr_arg1 (arg0, type, mpfr_y1,
10494 &dconst0, NULL, false);
10495 break;
65dd1378 10496
4f35b1fc 10497 CASE_FLT_FN (BUILT_IN_NAN):
c4503c0a 10498 case BUILT_IN_NAND32:
10499 case BUILT_IN_NAND64:
10500 case BUILT_IN_NAND128:
c2f47e15 10501 return fold_builtin_nan (arg0, type, true);
b0db7939 10502
4f35b1fc 10503 CASE_FLT_FN (BUILT_IN_NANS):
c2f47e15 10504 return fold_builtin_nan (arg0, type, false);
b0db7939 10505
4f35b1fc 10506 CASE_FLT_FN (BUILT_IN_FLOOR):
c2f47e15 10507 return fold_builtin_floor (fndecl, arg0);
277f8dd2 10508
4f35b1fc 10509 CASE_FLT_FN (BUILT_IN_CEIL):
c2f47e15 10510 return fold_builtin_ceil (fndecl, arg0);
277f8dd2 10511
4f35b1fc 10512 CASE_FLT_FN (BUILT_IN_TRUNC):
c2f47e15 10513 return fold_builtin_trunc (fndecl, arg0);
277f8dd2 10514
4f35b1fc 10515 CASE_FLT_FN (BUILT_IN_ROUND):
c2f47e15 10516 return fold_builtin_round (fndecl, arg0);
89ab3887 10517
4f35b1fc 10518 CASE_FLT_FN (BUILT_IN_NEARBYINT):
10519 CASE_FLT_FN (BUILT_IN_RINT):
c2f47e15 10520 return fold_trunc_transparent_mathfn (fndecl, arg0);
6528f4f4 10521
4f35b1fc 10522 CASE_FLT_FN (BUILT_IN_LCEIL):
10523 CASE_FLT_FN (BUILT_IN_LLCEIL):
10524 CASE_FLT_FN (BUILT_IN_LFLOOR):
10525 CASE_FLT_FN (BUILT_IN_LLFLOOR):
a0c938f0 10526 CASE_FLT_FN (BUILT_IN_LROUND):
4f35b1fc 10527 CASE_FLT_FN (BUILT_IN_LLROUND):
c2f47e15 10528 return fold_builtin_int_roundingfn (fndecl, arg0);
34f17811 10529
4f35b1fc 10530 CASE_FLT_FN (BUILT_IN_LRINT):
10531 CASE_FLT_FN (BUILT_IN_LLRINT):
c2f47e15 10532 return fold_fixed_mathfn (fndecl, arg0);
9ed65c7f 10533
42791117 10534 case BUILT_IN_BSWAP32:
10535 case BUILT_IN_BSWAP64:
c2f47e15 10536 return fold_builtin_bswap (fndecl, arg0);
42791117 10537
4f35b1fc 10538 CASE_INT_FN (BUILT_IN_FFS):
10539 CASE_INT_FN (BUILT_IN_CLZ):
10540 CASE_INT_FN (BUILT_IN_CTZ):
10541 CASE_INT_FN (BUILT_IN_POPCOUNT):
10542 CASE_INT_FN (BUILT_IN_PARITY):
c2f47e15 10543 return fold_builtin_bitop (fndecl, arg0);
9c8a1629 10544
4f35b1fc 10545 CASE_FLT_FN (BUILT_IN_SIGNBIT):
c2f47e15 10546 return fold_builtin_signbit (arg0, type);
27f261ef 10547
cb2b9385 10548 CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
10549 return fold_builtin_significand (arg0, type);
10550
10551 CASE_FLT_FN (BUILT_IN_ILOGB):
10552 CASE_FLT_FN (BUILT_IN_LOGB):
10553 return fold_builtin_logb (arg0, type);
10554
d49367d4 10555 case BUILT_IN_ISASCII:
c2f47e15 10556 return fold_builtin_isascii (arg0);
d49367d4 10557
10558 case BUILT_IN_TOASCII:
c2f47e15 10559 return fold_builtin_toascii (arg0);
d49367d4 10560
df1cf42e 10561 case BUILT_IN_ISDIGIT:
c2f47e15 10562 return fold_builtin_isdigit (arg0);
467214fd 10563
4f35b1fc 10564 CASE_FLT_FN (BUILT_IN_FINITE):
c4503c0a 10565 case BUILT_IN_FINITED32:
10566 case BUILT_IN_FINITED64:
10567 case BUILT_IN_FINITED128:
cde061c1 10568 case BUILT_IN_ISFINITE:
10569 return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISFINITE);
726069ba 10570
4f35b1fc 10571 CASE_FLT_FN (BUILT_IN_ISINF):
c4503c0a 10572 case BUILT_IN_ISINFD32:
10573 case BUILT_IN_ISINFD64:
10574 case BUILT_IN_ISINFD128:
c2f47e15 10575 return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISINF);
726069ba 10576
c319d56a 10577 case BUILT_IN_ISINF_SIGN:
10578 return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISINF_SIGN);
10579
4f35b1fc 10580 CASE_FLT_FN (BUILT_IN_ISNAN):
c4503c0a 10581 case BUILT_IN_ISNAND32:
10582 case BUILT_IN_ISNAND64:
10583 case BUILT_IN_ISNAND128:
c2f47e15 10584 return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISNAN);
10585
10586 case BUILT_IN_PRINTF:
10587 case BUILT_IN_PRINTF_UNLOCKED:
10588 case BUILT_IN_VPRINTF:
10589 return fold_builtin_printf (fndecl, arg0, NULL_TREE, ignore, fcode);
10590
10591 default:
10592 break;
10593 }
10594
10595 return NULL_TREE;
10596
10597}
10598
10599/* Fold a call to built-in function FNDECL with 2 arguments, ARG0 and ARG1.
10600 IGNORE is true if the result of the function call is ignored. This
10601 function returns NULL_TREE if no simplification was possible. */
10602
10603static tree
10604fold_builtin_2 (tree fndecl, tree arg0, tree arg1, bool ignore)
10605{
10606 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10607 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10608
10609 switch (fcode)
10610 {
65dd1378 10611 CASE_FLT_FN (BUILT_IN_JN):
10612 if (validate_arg (arg0, INTEGER_TYPE)
10613 && validate_arg (arg1, REAL_TYPE))
10614 return do_mpfr_bessel_n (arg0, arg1, type, mpfr_jn, NULL, 0);
10615 break;
6ff9eeff 10616
10617 CASE_FLT_FN (BUILT_IN_YN):
10618 if (validate_arg (arg0, INTEGER_TYPE)
10619 && validate_arg (arg1, REAL_TYPE))
10620 return do_mpfr_bessel_n (arg0, arg1, type, mpfr_yn,
10621 &dconst0, false);
10622 break;
e5407ca6 10623
10624 CASE_FLT_FN (BUILT_IN_DREM):
10625 CASE_FLT_FN (BUILT_IN_REMAINDER):
10626 if (validate_arg (arg0, REAL_TYPE)
10627 && validate_arg(arg1, REAL_TYPE))
10628 return do_mpfr_arg2 (arg0, arg1, type, mpfr_remainder);
10629 break;
e84da7c1 10630
10631 CASE_FLT_FN_REENT (BUILT_IN_GAMMA): /* GAMMA_R */
10632 CASE_FLT_FN_REENT (BUILT_IN_LGAMMA): /* LGAMMA_R */
10633 if (validate_arg (arg0, REAL_TYPE)
10634 && validate_arg(arg1, POINTER_TYPE))
10635 return do_mpfr_lgamma_r (arg0, arg1, type);
10636 break;
c2f47e15 10637
10638 CASE_FLT_FN (BUILT_IN_ATAN2):
10639 if (validate_arg (arg0, REAL_TYPE)
10640 && validate_arg(arg1, REAL_TYPE))
10641 return do_mpfr_arg2 (arg0, arg1, type, mpfr_atan2);
10642 break;
10643
10644 CASE_FLT_FN (BUILT_IN_FDIM):
10645 if (validate_arg (arg0, REAL_TYPE)
10646 && validate_arg(arg1, REAL_TYPE))
10647 return do_mpfr_arg2 (arg0, arg1, type, mpfr_dim);
10648 break;
10649
10650 CASE_FLT_FN (BUILT_IN_HYPOT):
10651 return fold_builtin_hypot (fndecl, arg0, arg1, type);
10652
c699fab8 10653#ifdef HAVE_mpc_pow
10654 CASE_FLT_FN (BUILT_IN_CPOW):
10655 if (validate_arg (arg0, COMPLEX_TYPE)
10656 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
10657 && validate_arg (arg1, COMPLEX_TYPE)
10658 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE)
10659 return do_mpc_arg2 (arg0, arg1, type, mpc_pow);
10660 break;
10661#endif
10662
7587301b 10663 CASE_FLT_FN (BUILT_IN_LDEXP):
10664 return fold_builtin_load_exponent (arg0, arg1, type, /*ldexp=*/true);
10665 CASE_FLT_FN (BUILT_IN_SCALBN):
10666 CASE_FLT_FN (BUILT_IN_SCALBLN):
10667 return fold_builtin_load_exponent (arg0, arg1, type, /*ldexp=*/false);
10668
3838b9ae 10669 CASE_FLT_FN (BUILT_IN_FREXP):
10670 return fold_builtin_frexp (arg0, arg1, type);
10671
ebf8b4f5 10672 CASE_FLT_FN (BUILT_IN_MODF):
10673 return fold_builtin_modf (arg0, arg1, type);
10674
c2f47e15 10675 case BUILT_IN_BZERO:
10676 return fold_builtin_bzero (arg0, arg1, ignore);
10677
10678 case BUILT_IN_FPUTS:
10679 return fold_builtin_fputs (arg0, arg1, ignore, false, NULL_TREE);
10680
10681 case BUILT_IN_FPUTS_UNLOCKED:
10682 return fold_builtin_fputs (arg0, arg1, ignore, true, NULL_TREE);
10683
10684 case BUILT_IN_STRSTR:
10685 return fold_builtin_strstr (arg0, arg1, type);
10686
10687 case BUILT_IN_STRCAT:
10688 return fold_builtin_strcat (arg0, arg1);
10689
10690 case BUILT_IN_STRSPN:
10691 return fold_builtin_strspn (arg0, arg1);
10692
10693 case BUILT_IN_STRCSPN:
10694 return fold_builtin_strcspn (arg0, arg1);
10695
10696 case BUILT_IN_STRCHR:
10697 case BUILT_IN_INDEX:
10698 return fold_builtin_strchr (arg0, arg1, type);
10699
10700 case BUILT_IN_STRRCHR:
10701 case BUILT_IN_RINDEX:
10702 return fold_builtin_strrchr (arg0, arg1, type);
10703
10704 case BUILT_IN_STRCPY:
10705 return fold_builtin_strcpy (fndecl, arg0, arg1, NULL_TREE);
10706
c8b17b2e 10707 case BUILT_IN_STPCPY:
10708 if (ignore)
10709 {
10710 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10711 if (!fn)
10712 break;
10713
10714 return build_call_expr (fn, 2, arg0, arg1);
10715 }
10716 break;
10717
c2f47e15 10718 case BUILT_IN_STRCMP:
10719 return fold_builtin_strcmp (arg0, arg1);
10720
10721 case BUILT_IN_STRPBRK:
10722 return fold_builtin_strpbrk (arg0, arg1, type);
10723
10724 case BUILT_IN_EXPECT:
76f5a783 10725 return fold_builtin_expect (arg0, arg1);
c2f47e15 10726
10727 CASE_FLT_FN (BUILT_IN_POW):
10728 return fold_builtin_pow (fndecl, arg0, arg1, type);
10729
10730 CASE_FLT_FN (BUILT_IN_POWI):
10731 return fold_builtin_powi (fndecl, arg0, arg1, type);
10732
10733 CASE_FLT_FN (BUILT_IN_COPYSIGN):
10734 return fold_builtin_copysign (fndecl, arg0, arg1, type);
10735
10736 CASE_FLT_FN (BUILT_IN_FMIN):
10737 return fold_builtin_fmin_fmax (arg0, arg1, type, /*max=*/false);
10738
10739 CASE_FLT_FN (BUILT_IN_FMAX):
10740 return fold_builtin_fmin_fmax (arg0, arg1, type, /*max=*/true);
726069ba 10741
9bc9f15f 10742 case BUILT_IN_ISGREATER:
c2f47e15 10743 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNLE_EXPR, LE_EXPR);
9bc9f15f 10744 case BUILT_IN_ISGREATEREQUAL:
c2f47e15 10745 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNLT_EXPR, LT_EXPR);
9bc9f15f 10746 case BUILT_IN_ISLESS:
c2f47e15 10747 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNGE_EXPR, GE_EXPR);
9bc9f15f 10748 case BUILT_IN_ISLESSEQUAL:
c2f47e15 10749 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNGT_EXPR, GT_EXPR);
9bc9f15f 10750 case BUILT_IN_ISLESSGREATER:
c2f47e15 10751 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNEQ_EXPR, EQ_EXPR);
9bc9f15f 10752 case BUILT_IN_ISUNORDERED:
c2f47e15 10753 return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNORDERED_EXPR,
d5019fe8 10754 NOP_EXPR);
9bc9f15f 10755
7c2f0500 10756 /* We do the folding for va_start in the expander. */
10757 case BUILT_IN_VA_START:
10758 break;
f0613857 10759
c2f47e15 10760 case BUILT_IN_SPRINTF:
10761 return fold_builtin_sprintf (arg0, arg1, NULL_TREE, ignore);
10762
0a39fd54 10763 case BUILT_IN_OBJECT_SIZE:
c2f47e15 10764 return fold_builtin_object_size (arg0, arg1);
0a39fd54 10765
10766 case BUILT_IN_PRINTF:
10767 case BUILT_IN_PRINTF_UNLOCKED:
10768 case BUILT_IN_VPRINTF:
c2f47e15 10769 return fold_builtin_printf (fndecl, arg0, arg1, ignore, fcode);
10770
0a39fd54 10771 case BUILT_IN_PRINTF_CHK:
10772 case BUILT_IN_VPRINTF_CHK:
c2f47e15 10773 if (!validate_arg (arg0, INTEGER_TYPE)
10774 || TREE_SIDE_EFFECTS (arg0))
10775 return NULL_TREE;
10776 else
10777 return fold_builtin_printf (fndecl, arg1, NULL_TREE, ignore, fcode);
10778 break;
0a39fd54 10779
10780 case BUILT_IN_FPRINTF:
10781 case BUILT_IN_FPRINTF_UNLOCKED:
10782 case BUILT_IN_VFPRINTF:
c2f47e15 10783 return fold_builtin_fprintf (fndecl, arg0, arg1, NULL_TREE,
10784 ignore, fcode);
10785
10786 default:
10787 break;
10788 }
10789 return NULL_TREE;
10790}
10791
10792/* Fold a call to built-in function FNDECL with 3 arguments, ARG0, ARG1,
10793 and ARG2. IGNORE is true if the result of the function call is ignored.
10794 This function returns NULL_TREE if no simplification was possible. */
10795
10796static tree
10797fold_builtin_3 (tree fndecl, tree arg0, tree arg1, tree arg2, bool ignore)
10798{
10799 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10800 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10801 switch (fcode)
10802 {
10803
10804 CASE_FLT_FN (BUILT_IN_SINCOS):
10805 return fold_builtin_sincos (arg0, arg1, arg2);
10806
10807 CASE_FLT_FN (BUILT_IN_FMA):
10808 if (validate_arg (arg0, REAL_TYPE)
10809 && validate_arg(arg1, REAL_TYPE)
10810 && validate_arg(arg2, REAL_TYPE))
10811 return do_mpfr_arg3 (arg0, arg1, arg2, type, mpfr_fma);
10812 break;
10813
e5407ca6 10814 CASE_FLT_FN (BUILT_IN_REMQUO):
10815 if (validate_arg (arg0, REAL_TYPE)
10816 && validate_arg(arg1, REAL_TYPE)
10817 && validate_arg(arg2, POINTER_TYPE))
10818 return do_mpfr_remquo (arg0, arg1, arg2);
10819 break;
e5407ca6 10820
c2f47e15 10821 case BUILT_IN_MEMSET:
10822 return fold_builtin_memset (arg0, arg1, arg2, type, ignore);
10823
10824 case BUILT_IN_BCOPY:
10825 return fold_builtin_memory_op (arg1, arg0, arg2, void_type_node, true, /*endp=*/3);
10826
10827 case BUILT_IN_MEMCPY:
10828 return fold_builtin_memory_op (arg0, arg1, arg2, type, ignore, /*endp=*/0);
10829
10830 case BUILT_IN_MEMPCPY:
10831 return fold_builtin_memory_op (arg0, arg1, arg2, type, ignore, /*endp=*/1);
10832
10833 case BUILT_IN_MEMMOVE:
10834 return fold_builtin_memory_op (arg0, arg1, arg2, type, ignore, /*endp=*/3);
10835
10836 case BUILT_IN_STRNCAT:
10837 return fold_builtin_strncat (arg0, arg1, arg2);
10838
10839 case BUILT_IN_STRNCPY:
10840 return fold_builtin_strncpy (fndecl, arg0, arg1, arg2, NULL_TREE);
10841
10842 case BUILT_IN_STRNCMP:
10843 return fold_builtin_strncmp (arg0, arg1, arg2);
10844
7959b13b 10845 case BUILT_IN_MEMCHR:
10846 return fold_builtin_memchr (arg0, arg1, arg2, type);
10847
c2f47e15 10848 case BUILT_IN_BCMP:
10849 case BUILT_IN_MEMCMP:
10850 return fold_builtin_memcmp (arg0, arg1, arg2);;
10851
10852 case BUILT_IN_SPRINTF:
10853 return fold_builtin_sprintf (arg0, arg1, arg2, ignore);
10854
10855 case BUILT_IN_STRCPY_CHK:
10856 case BUILT_IN_STPCPY_CHK:
10857 return fold_builtin_stxcpy_chk (fndecl, arg0, arg1, arg2, NULL_TREE,
10858 ignore, fcode);
10859
10860 case BUILT_IN_STRCAT_CHK:
10861 return fold_builtin_strcat_chk (fndecl, arg0, arg1, arg2);
10862
10863 case BUILT_IN_PRINTF_CHK:
10864 case BUILT_IN_VPRINTF_CHK:
10865 if (!validate_arg (arg0, INTEGER_TYPE)
10866 || TREE_SIDE_EFFECTS (arg0))
10867 return NULL_TREE;
10868 else
10869 return fold_builtin_printf (fndecl, arg1, arg2, ignore, fcode);
10870 break;
10871
10872 case BUILT_IN_FPRINTF:
10873 case BUILT_IN_FPRINTF_UNLOCKED:
10874 case BUILT_IN_VFPRINTF:
10875 return fold_builtin_fprintf (fndecl, arg0, arg1, arg2, ignore, fcode);
10876
0a39fd54 10877 case BUILT_IN_FPRINTF_CHK:
10878 case BUILT_IN_VFPRINTF_CHK:
c2f47e15 10879 if (!validate_arg (arg1, INTEGER_TYPE)
10880 || TREE_SIDE_EFFECTS (arg1))
10881 return NULL_TREE;
10882 else
10883 return fold_builtin_fprintf (fndecl, arg0, arg2, NULL_TREE,
10884 ignore, fcode);
0a39fd54 10885
650e4c94 10886 default:
10887 break;
10888 }
c2f47e15 10889 return NULL_TREE;
10890}
650e4c94 10891
c2f47e15 10892/* Fold a call to built-in function FNDECL with 4 arguments, ARG0, ARG1,
10893 ARG2, and ARG3. IGNORE is true if the result of the function call is
10894 ignored. This function returns NULL_TREE if no simplification was
10895 possible. */
10896
10897static tree
10898fold_builtin_4 (tree fndecl, tree arg0, tree arg1, tree arg2, tree arg3,
10899 bool ignore)
10900{
10901 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10902
10903 switch (fcode)
10904 {
10905 case BUILT_IN_MEMCPY_CHK:
10906 case BUILT_IN_MEMPCPY_CHK:
10907 case BUILT_IN_MEMMOVE_CHK:
10908 case BUILT_IN_MEMSET_CHK:
10909 return fold_builtin_memory_chk (fndecl, arg0, arg1, arg2, arg3,
10910 NULL_TREE, ignore,
10911 DECL_FUNCTION_CODE (fndecl));
10912
10913 case BUILT_IN_STRNCPY_CHK:
10914 return fold_builtin_strncpy_chk (arg0, arg1, arg2, arg3, NULL_TREE);
10915
10916 case BUILT_IN_STRNCAT_CHK:
10917 return fold_builtin_strncat_chk (fndecl, arg0, arg1, arg2, arg3);
10918
10919 case BUILT_IN_FPRINTF_CHK:
10920 case BUILT_IN_VFPRINTF_CHK:
10921 if (!validate_arg (arg1, INTEGER_TYPE)
10922 || TREE_SIDE_EFFECTS (arg1))
10923 return NULL_TREE;
10924 else
10925 return fold_builtin_fprintf (fndecl, arg0, arg2, arg3,
10926 ignore, fcode);
10927 break;
10928
10929 default:
10930 break;
10931 }
10932 return NULL_TREE;
10933}
10934
10935/* Fold a call to built-in function FNDECL. ARGS is an array of NARGS
10936 arguments, where NARGS <= 4. IGNORE is true if the result of the
10937 function call is ignored. This function returns NULL_TREE if no
10938 simplification was possible. Note that this only folds builtins with
10939 fixed argument patterns. Foldings that do varargs-to-varargs
10940 transformations, or that match calls with more than 4 arguments,
10941 need to be handled with fold_builtin_varargs instead. */
10942
10943#define MAX_ARGS_TO_FOLD_BUILTIN 4
10944
10945static tree
10946fold_builtin_n (tree fndecl, tree *args, int nargs, bool ignore)
10947{
10948 tree ret = NULL_TREE;
a7f5bb2d 10949
c2f47e15 10950 switch (nargs)
10951 {
10952 case 0:
10953 ret = fold_builtin_0 (fndecl, ignore);
10954 break;
10955 case 1:
10956 ret = fold_builtin_1 (fndecl, args[0], ignore);
10957 break;
10958 case 2:
10959 ret = fold_builtin_2 (fndecl, args[0], args[1], ignore);
10960 break;
10961 case 3:
10962 ret = fold_builtin_3 (fndecl, args[0], args[1], args[2], ignore);
10963 break;
10964 case 4:
10965 ret = fold_builtin_4 (fndecl, args[0], args[1], args[2], args[3],
10966 ignore);
10967 break;
10968 default:
10969 break;
10970 }
10971 if (ret)
10972 {
75a70cf9 10973 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
c2f47e15 10974 TREE_NO_WARNING (ret) = 1;
10975 return ret;
10976 }
10977 return NULL_TREE;
10978}
10979
10980/* Builtins with folding operations that operate on "..." arguments
10981 need special handling; we need to store the arguments in a convenient
10982 data structure before attempting any folding. Fortunately there are
10983 only a few builtins that fall into this category. FNDECL is the
10984 function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
10985 result of the function call is ignored. */
10986
10987static tree
10988fold_builtin_varargs (tree fndecl, tree exp, bool ignore ATTRIBUTE_UNUSED)
10989{
10990 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10991 tree ret = NULL_TREE;
10992
10993 switch (fcode)
10994 {
10995 case BUILT_IN_SPRINTF_CHK:
10996 case BUILT_IN_VSPRINTF_CHK:
10997 ret = fold_builtin_sprintf_chk (exp, fcode);
10998 break;
10999
11000 case BUILT_IN_SNPRINTF_CHK:
11001 case BUILT_IN_VSNPRINTF_CHK:
11002 ret = fold_builtin_snprintf_chk (exp, NULL_TREE, fcode);
19fbe3a4 11003 break;
11004
11005 case BUILT_IN_FPCLASSIFY:
11006 ret = fold_builtin_fpclassify (exp);
11007 break;
c2f47e15 11008
11009 default:
11010 break;
11011 }
11012 if (ret)
11013 {
11014 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
11015 TREE_NO_WARNING (ret) = 1;
11016 return ret;
11017 }
11018 return NULL_TREE;
650e4c94 11019}
7e15618b 11020
198622c0 11021/* Return true if FNDECL shouldn't be folded right now.
11022 If a built-in function has an inline attribute always_inline
11023 wrapper, defer folding it after always_inline functions have
11024 been inlined, otherwise e.g. -D_FORTIFY_SOURCE checking
11025 might not be performed. */
11026
11027static bool
11028avoid_folding_inline_builtin (tree fndecl)
11029{
11030 return (DECL_DECLARED_INLINE_P (fndecl)
11031 && DECL_DISREGARD_INLINE_LIMITS (fndecl)
11032 && cfun
11033 && !cfun->always_inline_functions_inlined
11034 && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fndecl)));
11035}
11036
4ee9c684 11037/* A wrapper function for builtin folding that prevents warnings for
491e04ef 11038 "statement without effect" and the like, caused by removing the
4ee9c684 11039 call node earlier than the warning is generated. */
11040
11041tree
c2f47e15 11042fold_call_expr (tree exp, bool ignore)
4ee9c684 11043{
c2f47e15 11044 tree ret = NULL_TREE;
11045 tree fndecl = get_callee_fndecl (exp);
11046 if (fndecl
11047 && TREE_CODE (fndecl) == FUNCTION_DECL
48dc2227 11048 && DECL_BUILT_IN (fndecl)
11049 /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized
11050 yet. Defer folding until we see all the arguments
11051 (after inlining). */
11052 && !CALL_EXPR_VA_ARG_PACK (exp))
11053 {
11054 int nargs = call_expr_nargs (exp);
11055
11056 /* Before gimplification CALL_EXPR_VA_ARG_PACK is not set, but
11057 instead last argument is __builtin_va_arg_pack (). Defer folding
11058 even in that case, until arguments are finalized. */
11059 if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR)
11060 {
11061 tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1));
11062 if (fndecl2
11063 && TREE_CODE (fndecl2) == FUNCTION_DECL
11064 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
11065 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
11066 return NULL_TREE;
11067 }
11068
198622c0 11069 if (avoid_folding_inline_builtin (fndecl))
11070 return NULL_TREE;
11071
c2f47e15 11072 /* FIXME: Don't use a list in this interface. */
11073 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
11074 return targetm.fold_builtin (fndecl, CALL_EXPR_ARGS (exp), ignore);
11075 else
11076 {
c2f47e15 11077 if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
11078 {
11079 tree *args = CALL_EXPR_ARGP (exp);
11080 ret = fold_builtin_n (fndecl, args, nargs, ignore);
11081 }
11082 if (!ret)
11083 ret = fold_builtin_varargs (fndecl, exp, ignore);
11084 if (ret)
11085 {
11086 /* Propagate location information from original call to
11087 expansion of builtin. Otherwise things like
11088 maybe_emit_chk_warning, that operate on the expansion
11089 of a builtin, will use the wrong location information. */
11090 if (CAN_HAVE_LOCATION_P (exp) && EXPR_HAS_LOCATION (exp))
11091 {
11092 tree realret = ret;
11093 if (TREE_CODE (ret) == NOP_EXPR)
11094 realret = TREE_OPERAND (ret, 0);
11095 if (CAN_HAVE_LOCATION_P (realret)
11096 && !EXPR_HAS_LOCATION (realret))
11097 SET_EXPR_LOCATION (realret, EXPR_LOCATION (exp));
11098 }
11099 return ret;
11100 }
11101 }
4ee9c684 11102 }
c2f47e15 11103 return NULL_TREE;
11104}
11105
11106/* Conveniently construct a function call expression. FNDECL names the
11107 function to be called and ARGLIST is a TREE_LIST of arguments. */
11108
11109tree
11110build_function_call_expr (tree fndecl, tree arglist)
11111{
11112 tree fntype = TREE_TYPE (fndecl);
11113 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
d01f58f9 11114 int n = list_length (arglist);
11115 tree *argarray = (tree *) alloca (n * sizeof (tree));
11116 int i;
11117
11118 for (i = 0; i < n; i++, arglist = TREE_CHAIN (arglist))
11119 argarray[i] = TREE_VALUE (arglist);
11120 return fold_builtin_call_array (TREE_TYPE (fntype), fn, n, argarray);
c2f47e15 11121}
11122
11123/* Conveniently construct a function call expression. FNDECL names the
11124 function to be called, N is the number of arguments, and the "..."
11125 parameters are the argument expressions. */
11126
11127tree
11128build_call_expr (tree fndecl, int n, ...)
11129{
11130 va_list ap;
c2f47e15 11131 tree fntype = TREE_TYPE (fndecl);
11132 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
d01f58f9 11133 tree *argarray = (tree *) alloca (n * sizeof (tree));
11134 int i;
c2f47e15 11135
11136 va_start (ap, n);
d01f58f9 11137 for (i = 0; i < n; i++)
11138 argarray[i] = va_arg (ap, tree);
c2f47e15 11139 va_end (ap);
d01f58f9 11140 return fold_builtin_call_array (TREE_TYPE (fntype), fn, n, argarray);
4ee9c684 11141}
11142
c2f47e15 11143/* Construct a CALL_EXPR with type TYPE with FN as the function expression.
d01f58f9 11144 N arguments are passed in the array ARGARRAY. */
805e22b2 11145
11146tree
d01f58f9 11147fold_builtin_call_array (tree type,
11148 tree fn,
11149 int n,
11150 tree *argarray)
7e15618b 11151{
c2f47e15 11152 tree ret = NULL_TREE;
11153 int i;
11154 tree exp;
11155
11156 if (TREE_CODE (fn) == ADDR_EXPR)
11157 {
11158 tree fndecl = TREE_OPERAND (fn, 0);
11159 if (TREE_CODE (fndecl) == FUNCTION_DECL
11160 && DECL_BUILT_IN (fndecl))
11161 {
48dc2227 11162 /* If last argument is __builtin_va_arg_pack (), arguments to this
11163 function are not finalized yet. Defer folding until they are. */
11164 if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
11165 {
11166 tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
11167 if (fndecl2
11168 && TREE_CODE (fndecl2) == FUNCTION_DECL
11169 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
11170 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
11171 return build_call_array (type, fn, n, argarray);
11172 }
198622c0 11173 if (avoid_folding_inline_builtin (fndecl))
11174 return build_call_array (type, fn, n, argarray);
c2f47e15 11175 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
11176 {
11177 tree arglist = NULL_TREE;
d01f58f9 11178 for (i = n - 1; i >= 0; i--)
11179 arglist = tree_cons (NULL_TREE, argarray[i], arglist);
c2f47e15 11180 ret = targetm.fold_builtin (fndecl, arglist, false);
11181 if (ret)
11182 return ret;
198622c0 11183 return build_call_array (type, fn, n, argarray);
c2f47e15 11184 }
11185 else if (n <= MAX_ARGS_TO_FOLD_BUILTIN)
11186 {
11187 /* First try the transformations that don't require consing up
11188 an exp. */
d01f58f9 11189 ret = fold_builtin_n (fndecl, argarray, n, false);
c2f47e15 11190 if (ret)
11191 return ret;
11192 }
11193
11194 /* If we got this far, we need to build an exp. */
d01f58f9 11195 exp = build_call_array (type, fn, n, argarray);
c2f47e15 11196 ret = fold_builtin_varargs (fndecl, exp, false);
11197 return ret ? ret : exp;
11198 }
11199 }
11200
d01f58f9 11201 return build_call_array (type, fn, n, argarray);
c2f47e15 11202}
11203
11204/* Construct a new CALL_EXPR using the tail of the argument list of EXP
11205 along with N new arguments specified as the "..." parameters. SKIP
11206 is the number of arguments in EXP to be omitted. This function is used
11207 to do varargs-to-varargs transformations. */
11208
11209static tree
11210rewrite_call_expr (tree exp, int skip, tree fndecl, int n, ...)
11211{
11212 int oldnargs = call_expr_nargs (exp);
11213 int nargs = oldnargs - skip + n;
11214 tree fntype = TREE_TYPE (fndecl);
11215 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
11216 tree *buffer;
11217
11218 if (n > 0)
11219 {
11220 int i, j;
11221 va_list ap;
7e15618b 11222
364c0c59 11223 buffer = XALLOCAVEC (tree, nargs);
c2f47e15 11224 va_start (ap, n);
11225 for (i = 0; i < n; i++)
11226 buffer[i] = va_arg (ap, tree);
11227 va_end (ap);
11228 for (j = skip; j < oldnargs; j++, i++)
11229 buffer[i] = CALL_EXPR_ARG (exp, j);
11230 }
11231 else
11232 buffer = CALL_EXPR_ARGP (exp) + skip;
11233
11234 return fold (build_call_array (TREE_TYPE (exp), fn, nargs, buffer));
11235}
11236
11237/* Validate a single argument ARG against a tree code CODE representing
11238 a type. */
11239
11240static bool
b7bf20db 11241validate_arg (const_tree arg, enum tree_code code)
c2f47e15 11242{
11243 if (!arg)
11244 return false;
11245 else if (code == POINTER_TYPE)
11246 return POINTER_TYPE_P (TREE_TYPE (arg));
c7f617c2 11247 else if (code == INTEGER_TYPE)
11248 return INTEGRAL_TYPE_P (TREE_TYPE (arg));
c2f47e15 11249 return code == TREE_CODE (TREE_TYPE (arg));
7e15618b 11250}
0eb671f7 11251
75a70cf9 11252/* This function validates the types of a function call argument list
11253 against a specified list of tree_codes. If the last specifier is a 0,
11254 that represents an ellipses, otherwise the last specifier must be a
11255 VOID_TYPE.
11256
11257 This is the GIMPLE version of validate_arglist. Eventually we want to
11258 completely convert builtins.c to work from GIMPLEs and the tree based
11259 validate_arglist will then be removed. */
11260
11261bool
11262validate_gimple_arglist (const_gimple call, ...)
11263{
11264 enum tree_code code;
11265 bool res = 0;
11266 va_list ap;
11267 const_tree arg;
11268 size_t i;
11269
11270 va_start (ap, call);
11271 i = 0;
11272
11273 do
11274 {
d62e827b 11275 code = (enum tree_code) va_arg (ap, int);
75a70cf9 11276 switch (code)
11277 {
11278 case 0:
11279 /* This signifies an ellipses, any further arguments are all ok. */
11280 res = true;
11281 goto end;
11282 case VOID_TYPE:
11283 /* This signifies an endlink, if no arguments remain, return
11284 true, otherwise return false. */
11285 res = (i == gimple_call_num_args (call));
11286 goto end;
11287 default:
11288 /* If no parameters remain or the parameter's code does not
11289 match the specified code, return false. Otherwise continue
11290 checking any remaining arguments. */
11291 arg = gimple_call_arg (call, i++);
11292 if (!validate_arg (arg, code))
11293 goto end;
11294 break;
11295 }
11296 }
11297 while (1);
11298
11299 /* We need gotos here since we can only have one VA_CLOSE in a
11300 function. */
11301 end: ;
11302 va_end (ap);
11303
11304 return res;
11305}
11306
0eb671f7 11307/* This function validates the types of a function call argument list
c2f47e15 11308 against a specified list of tree_codes. If the last specifier is a 0,
11309 that represents an ellipses, otherwise the last specifier must be a
11310 VOID_TYPE. */
27d0c333 11311
c2f47e15 11312bool
b7bf20db 11313validate_arglist (const_tree callexpr, ...)
0eb671f7 11314{
0eb671f7 11315 enum tree_code code;
c2f47e15 11316 bool res = 0;
ee582a61 11317 va_list ap;
b7bf20db 11318 const_call_expr_arg_iterator iter;
11319 const_tree arg;
aecda0d6 11320
c2f47e15 11321 va_start (ap, callexpr);
b7bf20db 11322 init_const_call_expr_arg_iterator (callexpr, &iter);
0eb671f7 11323
f0ce3b1f 11324 do
0eb671f7 11325 {
d62e827b 11326 code = (enum tree_code) va_arg (ap, int);
f0ce3b1f 11327 switch (code)
11328 {
11329 case 0:
11330 /* This signifies an ellipses, any further arguments are all ok. */
c2f47e15 11331 res = true;
f0ce3b1f 11332 goto end;
11333 case VOID_TYPE:
11334 /* This signifies an endlink, if no arguments remain, return
11335 true, otherwise return false. */
b7bf20db 11336 res = !more_const_call_expr_args_p (&iter);
f0ce3b1f 11337 goto end;
11338 default:
11339 /* If no parameters remain or the parameter's code does not
11340 match the specified code, return false. Otherwise continue
11341 checking any remaining arguments. */
b7bf20db 11342 arg = next_const_call_expr_arg (&iter);
c2f47e15 11343 if (!validate_arg (arg, code))
f0ce3b1f 11344 goto end;
11345 break;
11346 }
0eb671f7 11347 }
f0ce3b1f 11348 while (1);
0903457a 11349
11350 /* We need gotos here since we can only have one VA_CLOSE in a
11351 function. */
11352 end: ;
ee582a61 11353 va_end (ap);
0903457a 11354
11355 return res;
0eb671f7 11356}
fc2a2dcb 11357
fc2a2dcb 11358/* Default target-specific builtin expander that does nothing. */
11359
11360rtx
aecda0d6 11361default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
11362 rtx target ATTRIBUTE_UNUSED,
11363 rtx subtarget ATTRIBUTE_UNUSED,
11364 enum machine_mode mode ATTRIBUTE_UNUSED,
11365 int ignore ATTRIBUTE_UNUSED)
fc2a2dcb 11366{
11367 return NULL_RTX;
11368}
c7926a82 11369
01537105 11370/* Returns true is EXP represents data that would potentially reside
11371 in a readonly section. */
11372
11373static bool
11374readonly_data_expr (tree exp)
11375{
11376 STRIP_NOPS (exp);
11377
9ff0637e 11378 if (TREE_CODE (exp) != ADDR_EXPR)
11379 return false;
11380
11381 exp = get_base_address (TREE_OPERAND (exp, 0));
11382 if (!exp)
11383 return false;
11384
11385 /* Make sure we call decl_readonly_section only for trees it
11386 can handle (since it returns true for everything it doesn't
11387 understand). */
491e04ef 11388 if (TREE_CODE (exp) == STRING_CST
9ff0637e 11389 || TREE_CODE (exp) == CONSTRUCTOR
11390 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
11391 return decl_readonly_section (exp, 0);
01537105 11392 else
11393 return false;
11394}
4ee9c684 11395
c2f47e15 11396/* Simplify a call to the strstr builtin. S1 and S2 are the arguments
11397 to the call, and TYPE is its return type.
4ee9c684 11398
c2f47e15 11399 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11400 simplified form of the call as a tree.
11401
11402 The simplified form may be a constant or other expression which
11403 computes the same value, but in a more efficient manner (including
11404 calls to other builtin functions).
11405
11406 The call may contain arguments which need to be evaluated, but
11407 which are not useful to determine the result of the call. In
11408 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11409 COMPOUND_EXPR will be an argument which must be evaluated.
11410 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11411 COMPOUND_EXPR in the chain will contain the tree for the simplified
11412 form of the builtin function call. */
11413
11414static tree
c2f47e15 11415fold_builtin_strstr (tree s1, tree s2, tree type)
4ee9c684 11416{
c2f47e15 11417 if (!validate_arg (s1, POINTER_TYPE)
11418 || !validate_arg (s2, POINTER_TYPE))
11419 return NULL_TREE;
4ee9c684 11420 else
11421 {
4ee9c684 11422 tree fn;
11423 const char *p1, *p2;
11424
11425 p2 = c_getstr (s2);
11426 if (p2 == NULL)
c2f47e15 11427 return NULL_TREE;
4ee9c684 11428
11429 p1 = c_getstr (s1);
11430 if (p1 != NULL)
11431 {
11432 const char *r = strstr (p1, p2);
daa1d5f5 11433 tree tem;
4ee9c684 11434
4ee9c684 11435 if (r == NULL)
779b4c41 11436 return build_int_cst (TREE_TYPE (s1), 0);
c0c67e38 11437
11438 /* Return an offset into the constant string argument. */
0de36bdb 11439 tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
11440 s1, size_int (r - p1));
daa1d5f5 11441 return fold_convert (type, tem);
4ee9c684 11442 }
11443
7efa231c 11444 /* The argument is const char *, and the result is char *, so we need
11445 a type conversion here to avoid a warning. */
4ee9c684 11446 if (p2[0] == '\0')
7efa231c 11447 return fold_convert (type, s1);
4ee9c684 11448
11449 if (p2[1] != '\0')
c2f47e15 11450 return NULL_TREE;
4ee9c684 11451
11452 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11453 if (!fn)
c2f47e15 11454 return NULL_TREE;
4ee9c684 11455
11456 /* New argument list transforming strstr(s1, s2) to
11457 strchr(s1, s2[0]). */
c2f47e15 11458 return build_call_expr (fn, 2, s1, build_int_cst (NULL_TREE, p2[0]));
4ee9c684 11459 }
11460}
11461
c2f47e15 11462/* Simplify a call to the strchr builtin. S1 and S2 are the arguments to
11463 the call, and TYPE is its return type.
4ee9c684 11464
c2f47e15 11465 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11466 simplified form of the call as a tree.
11467
11468 The simplified form may be a constant or other expression which
11469 computes the same value, but in a more efficient manner (including
11470 calls to other builtin functions).
11471
11472 The call may contain arguments which need to be evaluated, but
11473 which are not useful to determine the result of the call. In
11474 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11475 COMPOUND_EXPR will be an argument which must be evaluated.
11476 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11477 COMPOUND_EXPR in the chain will contain the tree for the simplified
11478 form of the builtin function call. */
11479
11480static tree
c2f47e15 11481fold_builtin_strchr (tree s1, tree s2, tree type)
4ee9c684 11482{
c2f47e15 11483 if (!validate_arg (s1, POINTER_TYPE)
11484 || !validate_arg (s2, INTEGER_TYPE))
11485 return NULL_TREE;
4ee9c684 11486 else
11487 {
4ee9c684 11488 const char *p1;
11489
11490 if (TREE_CODE (s2) != INTEGER_CST)
c2f47e15 11491 return NULL_TREE;
4ee9c684 11492
11493 p1 = c_getstr (s1);
11494 if (p1 != NULL)
11495 {
11496 char c;
11497 const char *r;
daa1d5f5 11498 tree tem;
4ee9c684 11499
11500 if (target_char_cast (s2, &c))
c2f47e15 11501 return NULL_TREE;
4ee9c684 11502
11503 r = strchr (p1, c);
11504
11505 if (r == NULL)
779b4c41 11506 return build_int_cst (TREE_TYPE (s1), 0);
4ee9c684 11507
11508 /* Return an offset into the constant string argument. */
0de36bdb 11509 tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
11510 s1, size_int (r - p1));
daa1d5f5 11511 return fold_convert (type, tem);
4ee9c684 11512 }
c2f47e15 11513 return NULL_TREE;
4ee9c684 11514 }
11515}
11516
c2f47e15 11517/* Simplify a call to the strrchr builtin. S1 and S2 are the arguments to
11518 the call, and TYPE is its return type.
4ee9c684 11519
c2f47e15 11520 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11521 simplified form of the call as a tree.
11522
11523 The simplified form may be a constant or other expression which
11524 computes the same value, but in a more efficient manner (including
11525 calls to other builtin functions).
11526
11527 The call may contain arguments which need to be evaluated, but
11528 which are not useful to determine the result of the call. In
11529 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11530 COMPOUND_EXPR will be an argument which must be evaluated.
11531 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11532 COMPOUND_EXPR in the chain will contain the tree for the simplified
11533 form of the builtin function call. */
11534
11535static tree
c2f47e15 11536fold_builtin_strrchr (tree s1, tree s2, tree type)
4ee9c684 11537{
c2f47e15 11538 if (!validate_arg (s1, POINTER_TYPE)
11539 || !validate_arg (s2, INTEGER_TYPE))
11540 return NULL_TREE;
4ee9c684 11541 else
11542 {
4ee9c684 11543 tree fn;
11544 const char *p1;
11545
11546 if (TREE_CODE (s2) != INTEGER_CST)
c2f47e15 11547 return NULL_TREE;
4ee9c684 11548
11549 p1 = c_getstr (s1);
11550 if (p1 != NULL)
11551 {
11552 char c;
11553 const char *r;
daa1d5f5 11554 tree tem;
4ee9c684 11555
11556 if (target_char_cast (s2, &c))
c2f47e15 11557 return NULL_TREE;
4ee9c684 11558
11559 r = strrchr (p1, c);
11560
11561 if (r == NULL)
779b4c41 11562 return build_int_cst (TREE_TYPE (s1), 0);
4ee9c684 11563
11564 /* Return an offset into the constant string argument. */
0de36bdb 11565 tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
11566 s1, size_int (r - p1));
daa1d5f5 11567 return fold_convert (type, tem);
4ee9c684 11568 }
11569
11570 if (! integer_zerop (s2))
c2f47e15 11571 return NULL_TREE;
4ee9c684 11572
11573 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11574 if (!fn)
c2f47e15 11575 return NULL_TREE;
4ee9c684 11576
11577 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
c2f47e15 11578 return build_call_expr (fn, 2, s1, s2);
4ee9c684 11579 }
11580}
11581
c2f47e15 11582/* Simplify a call to the strpbrk builtin. S1 and S2 are the arguments
11583 to the call, and TYPE is its return type.
4ee9c684 11584
c2f47e15 11585 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11586 simplified form of the call as a tree.
11587
11588 The simplified form may be a constant or other expression which
11589 computes the same value, but in a more efficient manner (including
11590 calls to other builtin functions).
11591
11592 The call may contain arguments which need to be evaluated, but
11593 which are not useful to determine the result of the call. In
11594 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11595 COMPOUND_EXPR will be an argument which must be evaluated.
11596 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11597 COMPOUND_EXPR in the chain will contain the tree for the simplified
11598 form of the builtin function call. */
11599
11600static tree
c2f47e15 11601fold_builtin_strpbrk (tree s1, tree s2, tree type)
4ee9c684 11602{
c2f47e15 11603 if (!validate_arg (s1, POINTER_TYPE)
11604 || !validate_arg (s2, POINTER_TYPE))
11605 return NULL_TREE;
4ee9c684 11606 else
11607 {
4ee9c684 11608 tree fn;
11609 const char *p1, *p2;
11610
11611 p2 = c_getstr (s2);
11612 if (p2 == NULL)
c2f47e15 11613 return NULL_TREE;
4ee9c684 11614
11615 p1 = c_getstr (s1);
11616 if (p1 != NULL)
11617 {
11618 const char *r = strpbrk (p1, p2);
daa1d5f5 11619 tree tem;
4ee9c684 11620
11621 if (r == NULL)
779b4c41 11622 return build_int_cst (TREE_TYPE (s1), 0);
4ee9c684 11623
11624 /* Return an offset into the constant string argument. */
0de36bdb 11625 tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
11626 s1, size_int (r - p1));
daa1d5f5 11627 return fold_convert (type, tem);
4ee9c684 11628 }
11629
11630 if (p2[0] == '\0')
05abc81b 11631 /* strpbrk(x, "") == NULL.
11632 Evaluate and ignore s1 in case it had side-effects. */
11633 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
4ee9c684 11634
11635 if (p2[1] != '\0')
c2f47e15 11636 return NULL_TREE; /* Really call strpbrk. */
4ee9c684 11637
11638 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11639 if (!fn)
c2f47e15 11640 return NULL_TREE;
4ee9c684 11641
11642 /* New argument list transforming strpbrk(s1, s2) to
11643 strchr(s1, s2[0]). */
c2f47e15 11644 return build_call_expr (fn, 2, s1, build_int_cst (NULL_TREE, p2[0]));
4ee9c684 11645 }
11646}
11647
c2f47e15 11648/* Simplify a call to the strcat builtin. DST and SRC are the arguments
11649 to the call.
4ee9c684 11650
c2f47e15 11651 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11652 simplified form of the call as a tree.
11653
11654 The simplified form may be a constant or other expression which
11655 computes the same value, but in a more efficient manner (including
11656 calls to other builtin functions).
11657
11658 The call may contain arguments which need to be evaluated, but
11659 which are not useful to determine the result of the call. In
11660 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11661 COMPOUND_EXPR will be an argument which must be evaluated.
11662 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11663 COMPOUND_EXPR in the chain will contain the tree for the simplified
11664 form of the builtin function call. */
11665
11666static tree
c2f47e15 11667fold_builtin_strcat (tree dst, tree src)
4ee9c684 11668{
c2f47e15 11669 if (!validate_arg (dst, POINTER_TYPE)
11670 || !validate_arg (src, POINTER_TYPE))
11671 return NULL_TREE;
4ee9c684 11672 else
11673 {
4ee9c684 11674 const char *p = c_getstr (src);
11675
11676 /* If the string length is zero, return the dst parameter. */
11677 if (p && *p == '\0')
11678 return dst;
11679
c2f47e15 11680 return NULL_TREE;
4ee9c684 11681 }
11682}
11683
c2f47e15 11684/* Simplify a call to the strncat builtin. DST, SRC, and LEN are the
11685 arguments to the call.
4ee9c684 11686
c2f47e15 11687 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11688 simplified form of the call as a tree.
11689
11690 The simplified form may be a constant or other expression which
11691 computes the same value, but in a more efficient manner (including
11692 calls to other builtin functions).
11693
11694 The call may contain arguments which need to be evaluated, but
11695 which are not useful to determine the result of the call. In
11696 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11697 COMPOUND_EXPR will be an argument which must be evaluated.
11698 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11699 COMPOUND_EXPR in the chain will contain the tree for the simplified
11700 form of the builtin function call. */
11701
11702static tree
c2f47e15 11703fold_builtin_strncat (tree dst, tree src, tree len)
4ee9c684 11704{
c2f47e15 11705 if (!validate_arg (dst, POINTER_TYPE)
11706 || !validate_arg (src, POINTER_TYPE)
11707 || !validate_arg (len, INTEGER_TYPE))
11708 return NULL_TREE;
4ee9c684 11709 else
11710 {
4ee9c684 11711 const char *p = c_getstr (src);
11712
11713 /* If the requested length is zero, or the src parameter string
0a39fd54 11714 length is zero, return the dst parameter. */
4ee9c684 11715 if (integer_zerop (len) || (p && *p == '\0'))
a0c938f0 11716 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
4ee9c684 11717
11718 /* If the requested len is greater than or equal to the string
a0c938f0 11719 length, call strcat. */
4ee9c684 11720 if (TREE_CODE (len) == INTEGER_CST && p
11721 && compare_tree_int (len, strlen (p)) >= 0)
11722 {
4ee9c684 11723 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
11724
11725 /* If the replacement _DECL isn't initialized, don't do the
11726 transformation. */
11727 if (!fn)
c2f47e15 11728 return NULL_TREE;
4ee9c684 11729
c2f47e15 11730 return build_call_expr (fn, 2, dst, src);
4ee9c684 11731 }
c2f47e15 11732 return NULL_TREE;
4ee9c684 11733 }
11734}
11735
c2f47e15 11736/* Simplify a call to the strspn builtin. S1 and S2 are the arguments
11737 to the call.
4ee9c684 11738
c2f47e15 11739 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11740 simplified form of the call as a tree.
11741
11742 The simplified form may be a constant or other expression which
11743 computes the same value, but in a more efficient manner (including
11744 calls to other builtin functions).
11745
11746 The call may contain arguments which need to be evaluated, but
11747 which are not useful to determine the result of the call. In
11748 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11749 COMPOUND_EXPR will be an argument which must be evaluated.
11750 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11751 COMPOUND_EXPR in the chain will contain the tree for the simplified
11752 form of the builtin function call. */
11753
11754static tree
c2f47e15 11755fold_builtin_strspn (tree s1, tree s2)
4ee9c684 11756{
c2f47e15 11757 if (!validate_arg (s1, POINTER_TYPE)
11758 || !validate_arg (s2, POINTER_TYPE))
11759 return NULL_TREE;
4ee9c684 11760 else
11761 {
4ee9c684 11762 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11763
11764 /* If both arguments are constants, evaluate at compile-time. */
11765 if (p1 && p2)
11766 {
11767 const size_t r = strspn (p1, p2);
11768 return size_int (r);
11769 }
11770
c2f47e15 11771 /* If either argument is "", return NULL_TREE. */
4ee9c684 11772 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9bc9f15f 11773 /* Evaluate and ignore both arguments in case either one has
11774 side-effects. */
39761420 11775 return omit_two_operands (size_type_node, size_zero_node,
9bc9f15f 11776 s1, s2);
c2f47e15 11777 return NULL_TREE;
4ee9c684 11778 }
11779}
11780
c2f47e15 11781/* Simplify a call to the strcspn builtin. S1 and S2 are the arguments
11782 to the call.
4ee9c684 11783
c2f47e15 11784 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11785 simplified form of the call as a tree.
11786
11787 The simplified form may be a constant or other expression which
11788 computes the same value, but in a more efficient manner (including
11789 calls to other builtin functions).
11790
11791 The call may contain arguments which need to be evaluated, but
11792 which are not useful to determine the result of the call. In
11793 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11794 COMPOUND_EXPR will be an argument which must be evaluated.
11795 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11796 COMPOUND_EXPR in the chain will contain the tree for the simplified
11797 form of the builtin function call. */
11798
11799static tree
c2f47e15 11800fold_builtin_strcspn (tree s1, tree s2)
4ee9c684 11801{
c2f47e15 11802 if (!validate_arg (s1, POINTER_TYPE)
11803 || !validate_arg (s2, POINTER_TYPE))
11804 return NULL_TREE;
4ee9c684 11805 else
11806 {
4ee9c684 11807 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11808
11809 /* If both arguments are constants, evaluate at compile-time. */
11810 if (p1 && p2)
11811 {
11812 const size_t r = strcspn (p1, p2);
11813 return size_int (r);
11814 }
11815
c2f47e15 11816 /* If the first argument is "", return NULL_TREE. */
4ee9c684 11817 if (p1 && *p1 == '\0')
11818 {
11819 /* Evaluate and ignore argument s2 in case it has
11820 side-effects. */
39761420 11821 return omit_one_operand (size_type_node,
11822 size_zero_node, s2);
4ee9c684 11823 }
11824
11825 /* If the second argument is "", return __builtin_strlen(s1). */
11826 if (p2 && *p2 == '\0')
11827 {
c2f47e15 11828 tree fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4ee9c684 11829
11830 /* If the replacement _DECL isn't initialized, don't do the
11831 transformation. */
11832 if (!fn)
c2f47e15 11833 return NULL_TREE;
4ee9c684 11834
c2f47e15 11835 return build_call_expr (fn, 1, s1);
4ee9c684 11836 }
c2f47e15 11837 return NULL_TREE;
4ee9c684 11838 }
11839}
11840
c2f47e15 11841/* Fold a call to the fputs builtin. ARG0 and ARG1 are the arguments
11842 to the call. IGNORE is true if the value returned
f0613857 11843 by the builtin will be ignored. UNLOCKED is true is true if this
11844 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
11845 the known length of the string. Return NULL_TREE if no simplification
11846 was possible. */
4ee9c684 11847
11848tree
c2f47e15 11849fold_builtin_fputs (tree arg0, tree arg1, bool ignore, bool unlocked, tree len)
4ee9c684 11850{
6d77ed92 11851 /* If we're using an unlocked function, assume the other unlocked
11852 functions exist explicitly. */
11853 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4ee9c684 11854 : implicit_built_in_decls[BUILT_IN_FPUTC];
6d77ed92 11855 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4ee9c684 11856 : implicit_built_in_decls[BUILT_IN_FWRITE];
11857
c403edd4 11858 /* If the return value is used, don't do the transformation. */
11859 if (!ignore)
c2f47e15 11860 return NULL_TREE;
4ee9c684 11861
11862 /* Verify the arguments in the original call. */
c2f47e15 11863 if (!validate_arg (arg0, POINTER_TYPE)
11864 || !validate_arg (arg1, POINTER_TYPE))
11865 return NULL_TREE;
4ee9c684 11866
f0613857 11867 if (! len)
c2f47e15 11868 len = c_strlen (arg0, 0);
4ee9c684 11869
11870 /* Get the length of the string passed to fputs. If the length
11871 can't be determined, punt. */
11872 if (!len
11873 || TREE_CODE (len) != INTEGER_CST)
c2f47e15 11874 return NULL_TREE;
4ee9c684 11875
11876 switch (compare_tree_int (len, 1))
11877 {
11878 case -1: /* length is 0, delete the call entirely . */
c2f47e15 11879 return omit_one_operand (integer_type_node, integer_zero_node, arg1);;
05abc81b 11880
4ee9c684 11881 case 0: /* length is 1, call fputc. */
11882 {
c2f47e15 11883 const char *p = c_getstr (arg0);
4ee9c684 11884
11885 if (p != NULL)
11886 {
c2f47e15 11887 if (fn_fputc)
11888 return build_call_expr (fn_fputc, 2,
11889 build_int_cst (NULL_TREE, p[0]), arg1);
11890 else
11891 return NULL_TREE;
4ee9c684 11892 }
11893 }
11894 /* FALLTHROUGH */
11895 case 1: /* length is greater than 1, call fwrite. */
11896 {
0bed3869 11897 /* If optimizing for size keep fputs. */
0bfd8d5c 11898 if (optimize_function_for_size_p (cfun))
c2f47e15 11899 return NULL_TREE;
4ee9c684 11900 /* New argument list transforming fputs(string, stream) to
11901 fwrite(string, 1, len, stream). */
c2f47e15 11902 if (fn_fwrite)
11903 return build_call_expr (fn_fwrite, 4, arg0, size_one_node, len, arg1);
11904 else
11905 return NULL_TREE;
4ee9c684 11906 }
11907 default:
64db345d 11908 gcc_unreachable ();
4ee9c684 11909 }
c2f47e15 11910 return NULL_TREE;
4ee9c684 11911}
11912
c2f47e15 11913/* Fold the next_arg or va_start call EXP. Returns true if there was an error
743b0c6a 11914 produced. False otherwise. This is done so that we don't output the error
11915 or warning twice or three times. */
75a70cf9 11916
743b0c6a 11917bool
c2f47e15 11918fold_builtin_next_arg (tree exp, bool va_start_p)
4ee9c684 11919{
11920 tree fntype = TREE_TYPE (current_function_decl);
c2f47e15 11921 int nargs = call_expr_nargs (exp);
11922 tree arg;
4ee9c684 11923
11924 if (TYPE_ARG_TYPES (fntype) == 0
11925 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
11926 == void_type_node))
743b0c6a 11927 {
11928 error ("%<va_start%> used in function with fixed args");
11929 return true;
11930 }
c2f47e15 11931
11932 if (va_start_p)
79012a9d 11933 {
c2f47e15 11934 if (va_start_p && (nargs != 2))
11935 {
11936 error ("wrong number of arguments to function %<va_start%>");
11937 return true;
11938 }
11939 arg = CALL_EXPR_ARG (exp, 1);
79012a9d 11940 }
11941 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
11942 when we checked the arguments and if needed issued a warning. */
c2f47e15 11943 else
4ee9c684 11944 {
c2f47e15 11945 if (nargs == 0)
11946 {
11947 /* Evidently an out of date version of <stdarg.h>; can't validate
11948 va_start's second argument, but can still work as intended. */
11949 warning (0, "%<__builtin_next_arg%> called without an argument");
11950 return true;
11951 }
11952 else if (nargs > 1)
a0c938f0 11953 {
c2f47e15 11954 error ("wrong number of arguments to function %<__builtin_next_arg%>");
a0c938f0 11955 return true;
11956 }
c2f47e15 11957 arg = CALL_EXPR_ARG (exp, 0);
11958 }
11959
a8dd994c 11960 if (TREE_CODE (arg) == SSA_NAME)
11961 arg = SSA_NAME_VAR (arg);
11962
c2f47e15 11963 /* We destructively modify the call to be __builtin_va_start (ap, 0)
11964 or __builtin_next_arg (0) the first time we see it, after checking
11965 the arguments and if needed issuing a warning. */
11966 if (!integer_zerop (arg))
11967 {
11968 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
79012a9d 11969
4ee9c684 11970 /* Strip off all nops for the sake of the comparison. This
11971 is not quite the same as STRIP_NOPS. It does more.
11972 We must also strip off INDIRECT_EXPR for C++ reference
11973 parameters. */
72dd6141 11974 while (CONVERT_EXPR_P (arg)
4ee9c684 11975 || TREE_CODE (arg) == INDIRECT_REF)
11976 arg = TREE_OPERAND (arg, 0);
11977 if (arg != last_parm)
a0c938f0 11978 {
b08cf617 11979 /* FIXME: Sometimes with the tree optimizers we can get the
11980 not the last argument even though the user used the last
11981 argument. We just warn and set the arg to be the last
11982 argument so that we will get wrong-code because of
11983 it. */
c3ceba8e 11984 warning (0, "second parameter of %<va_start%> not last named argument");
743b0c6a 11985 }
24158ad7 11986
11987 /* Undefined by C99 7.15.1.4p4 (va_start):
11988 "If the parameter parmN is declared with the register storage
11989 class, with a function or array type, or with a type that is
11990 not compatible with the type that results after application of
11991 the default argument promotions, the behavior is undefined."
11992 */
11993 else if (DECL_REGISTER (arg))
11994 warning (0, "undefined behaviour when second parameter of "
11995 "%<va_start%> is declared with %<register%> storage");
11996
79012a9d 11997 /* We want to verify the second parameter just once before the tree
a0c938f0 11998 optimizers are run and then avoid keeping it in the tree,
11999 as otherwise we could warn even for correct code like:
12000 void foo (int i, ...)
12001 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
c2f47e15 12002 if (va_start_p)
12003 CALL_EXPR_ARG (exp, 1) = integer_zero_node;
12004 else
12005 CALL_EXPR_ARG (exp, 0) = integer_zero_node;
743b0c6a 12006 }
12007 return false;
4ee9c684 12008}
12009
12010
c2f47e15 12011/* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG.
12012 ORIG may be null if this is a 2-argument call. We don't attempt to
12013 simplify calls with more than 3 arguments.
4ee9c684 12014
c2f47e15 12015 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 12016 simplified form of the call as a tree. If IGNORED is true, it means that
12017 the caller does not use the returned value of the function. */
12018
12019static tree
c2f47e15 12020fold_builtin_sprintf (tree dest, tree fmt, tree orig, int ignored)
4ee9c684 12021{
c2f47e15 12022 tree call, retval;
4ee9c684 12023 const char *fmt_str = NULL;
12024
12025 /* Verify the required arguments in the original call. We deal with two
12026 types of sprintf() calls: 'sprintf (str, fmt)' and
12027 'sprintf (dest, "%s", orig)'. */
c2f47e15 12028 if (!validate_arg (dest, POINTER_TYPE)
12029 || !validate_arg (fmt, POINTER_TYPE))
12030 return NULL_TREE;
12031 if (orig && !validate_arg (orig, POINTER_TYPE))
4ee9c684 12032 return NULL_TREE;
4ee9c684 12033
12034 /* Check whether the format is a literal string constant. */
12035 fmt_str = c_getstr (fmt);
12036 if (fmt_str == NULL)
12037 return NULL_TREE;
12038
12039 call = NULL_TREE;
12040 retval = NULL_TREE;
12041
d4473c84 12042 if (!init_target_chars ())
c2f47e15 12043 return NULL_TREE;
99eabcc1 12044
4ee9c684 12045 /* If the format doesn't contain % args or %%, use strcpy. */
99eabcc1 12046 if (strchr (fmt_str, target_percent) == NULL)
4ee9c684 12047 {
12048 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
12049
12050 if (!fn)
12051 return NULL_TREE;
12052
72dfb3f2 12053 /* Don't optimize sprintf (buf, "abc", ptr++). */
c2f47e15 12054 if (orig)
72dfb3f2 12055 return NULL_TREE;
12056
4ee9c684 12057 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
12058 'format' is known to contain no % formats. */
c2f47e15 12059 call = build_call_expr (fn, 2, dest, fmt);
4ee9c684 12060 if (!ignored)
7016c612 12061 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
4ee9c684 12062 }
12063
12064 /* If the format is "%s", use strcpy if the result isn't used. */
99eabcc1 12065 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
4ee9c684 12066 {
c2f47e15 12067 tree fn;
4ee9c684 12068 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
12069
12070 if (!fn)
12071 return NULL_TREE;
12072
72dfb3f2 12073 /* Don't crash on sprintf (str1, "%s"). */
c2f47e15 12074 if (!orig)
72dfb3f2 12075 return NULL_TREE;
12076
4ee9c684 12077 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
4ee9c684 12078 if (!ignored)
12079 {
12080 retval = c_strlen (orig, 1);
12081 if (!retval || TREE_CODE (retval) != INTEGER_CST)
12082 return NULL_TREE;
12083 }
c2f47e15 12084 call = build_call_expr (fn, 2, dest, orig);
4ee9c684 12085 }
12086
12087 if (call && retval)
12088 {
e3b560a6 12089 retval = fold_convert
4ee9c684 12090 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
12091 retval);
05abc81b 12092 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
4ee9c684 12093 }
12094 else
12095 return call;
12096}
0a39fd54 12097
c2f47e15 12098/* Expand a call EXP to __builtin_object_size. */
0a39fd54 12099
12100rtx
12101expand_builtin_object_size (tree exp)
12102{
12103 tree ost;
12104 int object_size_type;
12105 tree fndecl = get_callee_fndecl (exp);
0a39fd54 12106
c2f47e15 12107 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
0a39fd54 12108 {
b8c23db3 12109 error ("%Kfirst argument of %D must be a pointer, second integer constant",
12110 exp, fndecl);
0a39fd54 12111 expand_builtin_trap ();
12112 return const0_rtx;
12113 }
12114
c2f47e15 12115 ost = CALL_EXPR_ARG (exp, 1);
0a39fd54 12116 STRIP_NOPS (ost);
12117
12118 if (TREE_CODE (ost) != INTEGER_CST
12119 || tree_int_cst_sgn (ost) < 0
12120 || compare_tree_int (ost, 3) > 0)
12121 {
b8c23db3 12122 error ("%Klast argument of %D is not integer constant between 0 and 3",
12123 exp, fndecl);
0a39fd54 12124 expand_builtin_trap ();
12125 return const0_rtx;
12126 }
12127
12128 object_size_type = tree_low_cst (ost, 0);
12129
12130 return object_size_type < 2 ? constm1_rtx : const0_rtx;
12131}
12132
12133/* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
12134 FCODE is the BUILT_IN_* to use.
c2f47e15 12135 Return NULL_RTX if we failed; the caller should emit a normal call,
0a39fd54 12136 otherwise try to get the result in TARGET, if convenient (and in
12137 mode MODE if that's convenient). */
12138
12139static rtx
12140expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
12141 enum built_in_function fcode)
12142{
0a39fd54 12143 tree dest, src, len, size;
12144
c2f47e15 12145 if (!validate_arglist (exp,
0a39fd54 12146 POINTER_TYPE,
12147 fcode == BUILT_IN_MEMSET_CHK
12148 ? INTEGER_TYPE : POINTER_TYPE,
12149 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
c2f47e15 12150 return NULL_RTX;
0a39fd54 12151
c2f47e15 12152 dest = CALL_EXPR_ARG (exp, 0);
12153 src = CALL_EXPR_ARG (exp, 1);
12154 len = CALL_EXPR_ARG (exp, 2);
12155 size = CALL_EXPR_ARG (exp, 3);
0a39fd54 12156
12157 if (! host_integerp (size, 1))
c2f47e15 12158 return NULL_RTX;
0a39fd54 12159
12160 if (host_integerp (len, 1) || integer_all_onesp (size))
12161 {
12162 tree fn;
12163
12164 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
12165 {
b430e8d9 12166 warning_at (tree_nonartificial_location (exp),
12167 0, "%Kcall to %D will always overflow destination buffer",
12168 exp, get_callee_fndecl (exp));
c2f47e15 12169 return NULL_RTX;
0a39fd54 12170 }
12171
0a39fd54 12172 fn = NULL_TREE;
12173 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12174 mem{cpy,pcpy,move,set} is available. */
12175 switch (fcode)
12176 {
12177 case BUILT_IN_MEMCPY_CHK:
12178 fn = built_in_decls[BUILT_IN_MEMCPY];
12179 break;
12180 case BUILT_IN_MEMPCPY_CHK:
12181 fn = built_in_decls[BUILT_IN_MEMPCPY];
12182 break;
12183 case BUILT_IN_MEMMOVE_CHK:
12184 fn = built_in_decls[BUILT_IN_MEMMOVE];
12185 break;
12186 case BUILT_IN_MEMSET_CHK:
12187 fn = built_in_decls[BUILT_IN_MEMSET];
12188 break;
12189 default:
12190 break;
12191 }
12192
12193 if (! fn)
c2f47e15 12194 return NULL_RTX;
0a39fd54 12195
c2f47e15 12196 fn = build_call_expr (fn, 3, dest, src, len);
6d54e886 12197 STRIP_TYPE_NOPS (fn);
12198 while (TREE_CODE (fn) == COMPOUND_EXPR)
12199 {
12200 expand_expr (TREE_OPERAND (fn, 0), const0_rtx, VOIDmode,
12201 EXPAND_NORMAL);
12202 fn = TREE_OPERAND (fn, 1);
12203 }
0a39fd54 12204 if (TREE_CODE (fn) == CALL_EXPR)
12205 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
12206 return expand_expr (fn, target, mode, EXPAND_NORMAL);
12207 }
12208 else if (fcode == BUILT_IN_MEMSET_CHK)
c2f47e15 12209 return NULL_RTX;
0a39fd54 12210 else
12211 {
12212 unsigned int dest_align
12213 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
12214
12215 /* If DEST is not a pointer type, call the normal function. */
12216 if (dest_align == 0)
c2f47e15 12217 return NULL_RTX;
0a39fd54 12218
12219 /* If SRC and DEST are the same (and not volatile), do nothing. */
12220 if (operand_equal_p (src, dest, 0))
12221 {
12222 tree expr;
12223
12224 if (fcode != BUILT_IN_MEMPCPY_CHK)
12225 {
12226 /* Evaluate and ignore LEN in case it has side-effects. */
12227 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
12228 return expand_expr (dest, target, mode, EXPAND_NORMAL);
12229 }
12230
0de36bdb 12231 expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
0a39fd54 12232 return expand_expr (expr, target, mode, EXPAND_NORMAL);
12233 }
12234
12235 /* __memmove_chk special case. */
12236 if (fcode == BUILT_IN_MEMMOVE_CHK)
12237 {
12238 unsigned int src_align
12239 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
12240
12241 if (src_align == 0)
c2f47e15 12242 return NULL_RTX;
0a39fd54 12243
12244 /* If src is categorized for a readonly section we can use
12245 normal __memcpy_chk. */
12246 if (readonly_data_expr (src))
12247 {
12248 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12249 if (!fn)
c2f47e15 12250 return NULL_RTX;
12251 fn = build_call_expr (fn, 4, dest, src, len, size);
6d54e886 12252 STRIP_TYPE_NOPS (fn);
12253 while (TREE_CODE (fn) == COMPOUND_EXPR)
12254 {
12255 expand_expr (TREE_OPERAND (fn, 0), const0_rtx, VOIDmode,
12256 EXPAND_NORMAL);
12257 fn = TREE_OPERAND (fn, 1);
12258 }
0a39fd54 12259 if (TREE_CODE (fn) == CALL_EXPR)
12260 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
12261 return expand_expr (fn, target, mode, EXPAND_NORMAL);
12262 }
12263 }
c2f47e15 12264 return NULL_RTX;
0a39fd54 12265 }
12266}
12267
12268/* Emit warning if a buffer overflow is detected at compile time. */
12269
12270static void
12271maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
12272{
c2f47e15 12273 int is_strlen = 0;
0a39fd54 12274 tree len, size;
b430e8d9 12275 location_t loc = tree_nonartificial_location (exp);
0a39fd54 12276
12277 switch (fcode)
12278 {
12279 case BUILT_IN_STRCPY_CHK:
12280 case BUILT_IN_STPCPY_CHK:
12281 /* For __strcat_chk the warning will be emitted only if overflowing
12282 by at least strlen (dest) + 1 bytes. */
12283 case BUILT_IN_STRCAT_CHK:
c2f47e15 12284 len = CALL_EXPR_ARG (exp, 1);
12285 size = CALL_EXPR_ARG (exp, 2);
0a39fd54 12286 is_strlen = 1;
12287 break;
b356dfef 12288 case BUILT_IN_STRNCAT_CHK:
0a39fd54 12289 case BUILT_IN_STRNCPY_CHK:
c2f47e15 12290 len = CALL_EXPR_ARG (exp, 2);
12291 size = CALL_EXPR_ARG (exp, 3);
0a39fd54 12292 break;
12293 case BUILT_IN_SNPRINTF_CHK:
12294 case BUILT_IN_VSNPRINTF_CHK:
c2f47e15 12295 len = CALL_EXPR_ARG (exp, 1);
12296 size = CALL_EXPR_ARG (exp, 3);
0a39fd54 12297 break;
12298 default:
12299 gcc_unreachable ();
12300 }
12301
0a39fd54 12302 if (!len || !size)
12303 return;
12304
0a39fd54 12305 if (! host_integerp (size, 1) || integer_all_onesp (size))
12306 return;
12307
12308 if (is_strlen)
12309 {
12310 len = c_strlen (len, 1);
12311 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12312 return;
12313 }
b356dfef 12314 else if (fcode == BUILT_IN_STRNCAT_CHK)
12315 {
c2f47e15 12316 tree src = CALL_EXPR_ARG (exp, 1);
b356dfef 12317 if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12318 return;
12319 src = c_strlen (src, 1);
12320 if (! src || ! host_integerp (src, 1))
12321 {
b430e8d9 12322 warning_at (loc, 0, "%Kcall to %D might overflow destination buffer",
12323 exp, get_callee_fndecl (exp));
b356dfef 12324 return;
12325 }
12326 else if (tree_int_cst_lt (src, size))
12327 return;
12328 }
0a39fd54 12329 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
12330 return;
12331
b430e8d9 12332 warning_at (loc, 0, "%Kcall to %D will always overflow destination buffer",
12333 exp, get_callee_fndecl (exp));
0a39fd54 12334}
12335
12336/* Emit warning if a buffer overflow is detected at compile time
12337 in __sprintf_chk/__vsprintf_chk calls. */
12338
12339static void
12340maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
12341{
0a39fd54 12342 tree dest, size, len, fmt, flag;
12343 const char *fmt_str;
c2f47e15 12344 int nargs = call_expr_nargs (exp);
0a39fd54 12345
12346 /* Verify the required arguments in the original call. */
c2f47e15 12347
12348 if (nargs < 4)
0a39fd54 12349 return;
c2f47e15 12350 dest = CALL_EXPR_ARG (exp, 0);
12351 flag = CALL_EXPR_ARG (exp, 1);
12352 size = CALL_EXPR_ARG (exp, 2);
12353 fmt = CALL_EXPR_ARG (exp, 3);
0a39fd54 12354
12355 if (! host_integerp (size, 1) || integer_all_onesp (size))
12356 return;
12357
12358 /* Check whether the format is a literal string constant. */
12359 fmt_str = c_getstr (fmt);
12360 if (fmt_str == NULL)
12361 return;
12362
d4473c84 12363 if (!init_target_chars ())
99eabcc1 12364 return;
12365
0a39fd54 12366 /* If the format doesn't contain % args or %%, we know its size. */
99eabcc1 12367 if (strchr (fmt_str, target_percent) == 0)
0a39fd54 12368 len = build_int_cstu (size_type_node, strlen (fmt_str));
12369 /* If the format is "%s" and first ... argument is a string literal,
12370 we know it too. */
c2f47e15 12371 else if (fcode == BUILT_IN_SPRINTF_CHK
12372 && strcmp (fmt_str, target_percent_s) == 0)
0a39fd54 12373 {
12374 tree arg;
12375
c2f47e15 12376 if (nargs < 5)
0a39fd54 12377 return;
c2f47e15 12378 arg = CALL_EXPR_ARG (exp, 4);
0a39fd54 12379 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
12380 return;
12381
12382 len = c_strlen (arg, 1);
12383 if (!len || ! host_integerp (len, 1))
12384 return;
12385 }
12386 else
12387 return;
12388
12389 if (! tree_int_cst_lt (len, size))
b430e8d9 12390 warning_at (tree_nonartificial_location (exp),
12391 0, "%Kcall to %D will always overflow destination buffer",
12392 exp, get_callee_fndecl (exp));
0a39fd54 12393}
12394
2c281b15 12395/* Emit warning if a free is called with address of a variable. */
12396
12397static void
12398maybe_emit_free_warning (tree exp)
12399{
12400 tree arg = CALL_EXPR_ARG (exp, 0);
12401
12402 STRIP_NOPS (arg);
12403 if (TREE_CODE (arg) != ADDR_EXPR)
12404 return;
12405
12406 arg = get_base_address (TREE_OPERAND (arg, 0));
12407 if (arg == NULL || INDIRECT_REF_P (arg))
12408 return;
12409
12410 if (SSA_VAR_P (arg))
b430e8d9 12411 warning_at (tree_nonartificial_location (exp),
12412 0, "%Kattempt to free a non-heap object %qD", exp, arg);
2c281b15 12413 else
b430e8d9 12414 warning_at (tree_nonartificial_location (exp),
12415 0, "%Kattempt to free a non-heap object", exp);
2c281b15 12416}
12417
c2f47e15 12418/* Fold a call to __builtin_object_size with arguments PTR and OST,
12419 if possible. */
0a39fd54 12420
12421tree
c2f47e15 12422fold_builtin_object_size (tree ptr, tree ost)
0a39fd54 12423{
c2f47e15 12424 tree ret = NULL_TREE;
0a39fd54 12425 int object_size_type;
12426
c2f47e15 12427 if (!validate_arg (ptr, POINTER_TYPE)
12428 || !validate_arg (ost, INTEGER_TYPE))
12429 return NULL_TREE;
0a39fd54 12430
0a39fd54 12431 STRIP_NOPS (ost);
12432
12433 if (TREE_CODE (ost) != INTEGER_CST
12434 || tree_int_cst_sgn (ost) < 0
12435 || compare_tree_int (ost, 3) > 0)
c2f47e15 12436 return NULL_TREE;
0a39fd54 12437
12438 object_size_type = tree_low_cst (ost, 0);
12439
12440 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
12441 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
12442 and (size_t) 0 for types 2 and 3. */
12443 if (TREE_SIDE_EFFECTS (ptr))
697bbc3f 12444 return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0);
0a39fd54 12445
12446 if (TREE_CODE (ptr) == ADDR_EXPR)
12447 ret = build_int_cstu (size_type_node,
697bbc3f 12448 compute_builtin_object_size (ptr, object_size_type));
0a39fd54 12449
12450 else if (TREE_CODE (ptr) == SSA_NAME)
12451 {
12452 unsigned HOST_WIDE_INT bytes;
12453
12454 /* If object size is not known yet, delay folding until
12455 later. Maybe subsequent passes will help determining
12456 it. */
12457 bytes = compute_builtin_object_size (ptr, object_size_type);
12458 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
12459 ? -1 : 0))
12460 ret = build_int_cstu (size_type_node, bytes);
12461 }
12462
12463 if (ret)
12464 {
697bbc3f 12465 unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (ret);
12466 HOST_WIDE_INT high = TREE_INT_CST_HIGH (ret);
12467 if (fit_double_type (low, high, &low, &high, TREE_TYPE (ret)))
12468 ret = NULL_TREE;
0a39fd54 12469 }
12470
12471 return ret;
12472}
12473
12474/* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
c2f47e15 12475 DEST, SRC, LEN, and SIZE are the arguments to the call.
0a39fd54 12476 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
12477 code of the builtin. If MAXLEN is not NULL, it is maximum length
12478 passed as third argument. */
12479
12480tree
c2f47e15 12481fold_builtin_memory_chk (tree fndecl,
12482 tree dest, tree src, tree len, tree size,
12483 tree maxlen, bool ignore,
0a39fd54 12484 enum built_in_function fcode)
12485{
c2f47e15 12486 tree fn;
0a39fd54 12487
c2f47e15 12488 if (!validate_arg (dest, POINTER_TYPE)
12489 || !validate_arg (src,
12490 (fcode == BUILT_IN_MEMSET_CHK
12491 ? INTEGER_TYPE : POINTER_TYPE))
12492 || !validate_arg (len, INTEGER_TYPE)
12493 || !validate_arg (size, INTEGER_TYPE))
12494 return NULL_TREE;
0a39fd54 12495
12496 /* If SRC and DEST are the same (and not volatile), return DEST
12497 (resp. DEST+LEN for __mempcpy_chk). */
12498 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
12499 {
12500 if (fcode != BUILT_IN_MEMPCPY_CHK)
12501 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
12502 else
12503 {
0de36bdb 12504 tree temp = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
0a39fd54 12505 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
12506 }
12507 }
12508
12509 if (! host_integerp (size, 1))
c2f47e15 12510 return NULL_TREE;
0a39fd54 12511
12512 if (! integer_all_onesp (size))
12513 {
12514 if (! host_integerp (len, 1))
12515 {
12516 /* If LEN is not constant, try MAXLEN too.
12517 For MAXLEN only allow optimizing into non-_ocs function
12518 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12519 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12520 {
12521 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
12522 {
12523 /* (void) __mempcpy_chk () can be optimized into
12524 (void) __memcpy_chk (). */
12525 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12526 if (!fn)
c2f47e15 12527 return NULL_TREE;
0a39fd54 12528
c2f47e15 12529 return build_call_expr (fn, 4, dest, src, len, size);
0a39fd54 12530 }
c2f47e15 12531 return NULL_TREE;
0a39fd54 12532 }
0a39fd54 12533 }
ad89623c 12534 else
12535 maxlen = len;
0a39fd54 12536
ad89623c 12537 if (tree_int_cst_lt (size, maxlen))
c2f47e15 12538 return NULL_TREE;
0a39fd54 12539 }
12540
0a39fd54 12541 fn = NULL_TREE;
12542 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12543 mem{cpy,pcpy,move,set} is available. */
12544 switch (fcode)
12545 {
12546 case BUILT_IN_MEMCPY_CHK:
12547 fn = built_in_decls[BUILT_IN_MEMCPY];
12548 break;
12549 case BUILT_IN_MEMPCPY_CHK:
12550 fn = built_in_decls[BUILT_IN_MEMPCPY];
12551 break;
12552 case BUILT_IN_MEMMOVE_CHK:
12553 fn = built_in_decls[BUILT_IN_MEMMOVE];
12554 break;
12555 case BUILT_IN_MEMSET_CHK:
12556 fn = built_in_decls[BUILT_IN_MEMSET];
12557 break;
12558 default:
12559 break;
12560 }
12561
12562 if (!fn)
c2f47e15 12563 return NULL_TREE;
0a39fd54 12564
c2f47e15 12565 return build_call_expr (fn, 3, dest, src, len);
0a39fd54 12566}
12567
12568/* Fold a call to the __st[rp]cpy_chk builtin.
c2f47e15 12569 DEST, SRC, and SIZE are the arguments to the call.
12570 IGNORE is true if return value can be ignored. FCODE is the BUILT_IN_*
0a39fd54 12571 code of the builtin. If MAXLEN is not NULL, it is maximum length of
12572 strings passed as second argument. */
12573
12574tree
c2f47e15 12575fold_builtin_stxcpy_chk (tree fndecl, tree dest, tree src, tree size,
12576 tree maxlen, bool ignore,
0a39fd54 12577 enum built_in_function fcode)
12578{
c2f47e15 12579 tree len, fn;
0a39fd54 12580
c2f47e15 12581 if (!validate_arg (dest, POINTER_TYPE)
12582 || !validate_arg (src, POINTER_TYPE)
12583 || !validate_arg (size, INTEGER_TYPE))
12584 return NULL_TREE;
0a39fd54 12585
12586 /* If SRC and DEST are the same (and not volatile), return DEST. */
12587 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
12588 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
a0c938f0 12589
0a39fd54 12590 if (! host_integerp (size, 1))
c2f47e15 12591 return NULL_TREE;
0a39fd54 12592
12593 if (! integer_all_onesp (size))
12594 {
12595 len = c_strlen (src, 1);
12596 if (! len || ! host_integerp (len, 1))
12597 {
12598 /* If LEN is not constant, try MAXLEN too.
12599 For MAXLEN only allow optimizing into non-_ocs function
12600 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12601 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12602 {
12603 if (fcode == BUILT_IN_STPCPY_CHK)
12604 {
12605 if (! ignore)
c2f47e15 12606 return NULL_TREE;
0a39fd54 12607
12608 /* If return value of __stpcpy_chk is ignored,
12609 optimize into __strcpy_chk. */
12610 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
12611 if (!fn)
c2f47e15 12612 return NULL_TREE;
0a39fd54 12613
c2f47e15 12614 return build_call_expr (fn, 3, dest, src, size);
0a39fd54 12615 }
12616
12617 if (! len || TREE_SIDE_EFFECTS (len))
c2f47e15 12618 return NULL_TREE;
0a39fd54 12619
12620 /* If c_strlen returned something, but not a constant,
12621 transform __strcpy_chk into __memcpy_chk. */
12622 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12623 if (!fn)
c2f47e15 12624 return NULL_TREE;
0a39fd54 12625
12626 len = size_binop (PLUS_EXPR, len, ssize_int (1));
0a39fd54 12627 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
c2f47e15 12628 build_call_expr (fn, 4,
12629 dest, src, len, size));
0a39fd54 12630 }
0a39fd54 12631 }
ad89623c 12632 else
12633 maxlen = len;
12634
12635 if (! tree_int_cst_lt (maxlen, size))
c2f47e15 12636 return NULL_TREE;
0a39fd54 12637 }
12638
0a39fd54 12639 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
12640 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
12641 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
12642 if (!fn)
c2f47e15 12643 return NULL_TREE;
0a39fd54 12644
c2f47e15 12645 return build_call_expr (fn, 2, dest, src);
0a39fd54 12646}
12647
c2f47e15 12648/* Fold a call to the __strncpy_chk builtin. DEST, SRC, LEN, and SIZE
12649 are the arguments to the call. If MAXLEN is not NULL, it is maximum
12650 length passed as third argument. */
0a39fd54 12651
12652tree
c2f47e15 12653fold_builtin_strncpy_chk (tree dest, tree src, tree len, tree size,
12654 tree maxlen)
0a39fd54 12655{
c2f47e15 12656 tree fn;
0a39fd54 12657
c2f47e15 12658 if (!validate_arg (dest, POINTER_TYPE)
12659 || !validate_arg (src, POINTER_TYPE)
12660 || !validate_arg (len, INTEGER_TYPE)
12661 || !validate_arg (size, INTEGER_TYPE))
12662 return NULL_TREE;
0a39fd54 12663
12664 if (! host_integerp (size, 1))
c2f47e15 12665 return NULL_TREE;
0a39fd54 12666
12667 if (! integer_all_onesp (size))
12668 {
12669 if (! host_integerp (len, 1))
12670 {
12671 /* If LEN is not constant, try MAXLEN too.
12672 For MAXLEN only allow optimizing into non-_ocs function
12673 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12674 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
c2f47e15 12675 return NULL_TREE;
0a39fd54 12676 }
ad89623c 12677 else
12678 maxlen = len;
0a39fd54 12679
ad89623c 12680 if (tree_int_cst_lt (size, maxlen))
c2f47e15 12681 return NULL_TREE;
0a39fd54 12682 }
12683
0a39fd54 12684 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
12685 fn = built_in_decls[BUILT_IN_STRNCPY];
12686 if (!fn)
c2f47e15 12687 return NULL_TREE;
0a39fd54 12688
c2f47e15 12689 return build_call_expr (fn, 3, dest, src, len);
0a39fd54 12690}
12691
c2f47e15 12692/* Fold a call to the __strcat_chk builtin FNDECL. DEST, SRC, and SIZE
12693 are the arguments to the call. */
0a39fd54 12694
12695static tree
c2f47e15 12696fold_builtin_strcat_chk (tree fndecl, tree dest, tree src, tree size)
0a39fd54 12697{
c2f47e15 12698 tree fn;
0a39fd54 12699 const char *p;
12700
c2f47e15 12701 if (!validate_arg (dest, POINTER_TYPE)
12702 || !validate_arg (src, POINTER_TYPE)
12703 || !validate_arg (size, INTEGER_TYPE))
12704 return NULL_TREE;
0a39fd54 12705
12706 p = c_getstr (src);
12707 /* If the SRC parameter is "", return DEST. */
12708 if (p && *p == '\0')
12709 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
12710
12711 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
c2f47e15 12712 return NULL_TREE;
0a39fd54 12713
12714 /* If __builtin_strcat_chk is used, assume strcat is available. */
12715 fn = built_in_decls[BUILT_IN_STRCAT];
12716 if (!fn)
c2f47e15 12717 return NULL_TREE;
0a39fd54 12718
c2f47e15 12719 return build_call_expr (fn, 2, dest, src);
0a39fd54 12720}
12721
c2f47e15 12722/* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
12723 LEN, and SIZE. */
0a39fd54 12724
12725static tree
c2f47e15 12726fold_builtin_strncat_chk (tree fndecl,
12727 tree dest, tree src, tree len, tree size)
0a39fd54 12728{
c2f47e15 12729 tree fn;
0a39fd54 12730 const char *p;
12731
c2f47e15 12732 if (!validate_arg (dest, POINTER_TYPE)
12733 || !validate_arg (src, POINTER_TYPE)
12734 || !validate_arg (size, INTEGER_TYPE)
12735 || !validate_arg (size, INTEGER_TYPE))
12736 return NULL_TREE;
0a39fd54 12737
12738 p = c_getstr (src);
12739 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
12740 if (p && *p == '\0')
12741 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
12742 else if (integer_zerop (len))
12743 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
12744
12745 if (! host_integerp (size, 1))
c2f47e15 12746 return NULL_TREE;
0a39fd54 12747
12748 if (! integer_all_onesp (size))
12749 {
12750 tree src_len = c_strlen (src, 1);
12751 if (src_len
12752 && host_integerp (src_len, 1)
12753 && host_integerp (len, 1)
12754 && ! tree_int_cst_lt (len, src_len))
12755 {
12756 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
12757 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
12758 if (!fn)
c2f47e15 12759 return NULL_TREE;
0a39fd54 12760
c2f47e15 12761 return build_call_expr (fn, 3, dest, src, size);
0a39fd54 12762 }
c2f47e15 12763 return NULL_TREE;
0a39fd54 12764 }
12765
0a39fd54 12766 /* If __builtin_strncat_chk is used, assume strncat is available. */
12767 fn = built_in_decls[BUILT_IN_STRNCAT];
12768 if (!fn)
c2f47e15 12769 return NULL_TREE;
0a39fd54 12770
c2f47e15 12771 return build_call_expr (fn, 3, dest, src, len);
0a39fd54 12772}
12773
c2f47e15 12774/* Fold a call EXP to __{,v}sprintf_chk. Return NULL_TREE if
0a39fd54 12775 a normal call should be emitted rather than expanding the function
12776 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
12777
12778static tree
c2f47e15 12779fold_builtin_sprintf_chk (tree exp, enum built_in_function fcode)
0a39fd54 12780{
12781 tree dest, size, len, fn, fmt, flag;
12782 const char *fmt_str;
c2f47e15 12783 int nargs = call_expr_nargs (exp);
0a39fd54 12784
12785 /* Verify the required arguments in the original call. */
c2f47e15 12786 if (nargs < 4)
12787 return NULL_TREE;
12788 dest = CALL_EXPR_ARG (exp, 0);
12789 if (!validate_arg (dest, POINTER_TYPE))
12790 return NULL_TREE;
12791 flag = CALL_EXPR_ARG (exp, 1);
12792 if (!validate_arg (flag, INTEGER_TYPE))
12793 return NULL_TREE;
12794 size = CALL_EXPR_ARG (exp, 2);
12795 if (!validate_arg (size, INTEGER_TYPE))
12796 return NULL_TREE;
12797 fmt = CALL_EXPR_ARG (exp, 3);
12798 if (!validate_arg (fmt, POINTER_TYPE))
12799 return NULL_TREE;
0a39fd54 12800
12801 if (! host_integerp (size, 1))
c2f47e15 12802 return NULL_TREE;
0a39fd54 12803
12804 len = NULL_TREE;
12805
d4473c84 12806 if (!init_target_chars ())
c2f47e15 12807 return NULL_TREE;
99eabcc1 12808
0a39fd54 12809 /* Check whether the format is a literal string constant. */
12810 fmt_str = c_getstr (fmt);
12811 if (fmt_str != NULL)
12812 {
12813 /* If the format doesn't contain % args or %%, we know the size. */
99eabcc1 12814 if (strchr (fmt_str, target_percent) == 0)
0a39fd54 12815 {
c2f47e15 12816 if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
0a39fd54 12817 len = build_int_cstu (size_type_node, strlen (fmt_str));
12818 }
12819 /* If the format is "%s" and first ... argument is a string literal,
12820 we know the size too. */
c2f47e15 12821 else if (fcode == BUILT_IN_SPRINTF_CHK
12822 && strcmp (fmt_str, target_percent_s) == 0)
0a39fd54 12823 {
12824 tree arg;
12825
c2f47e15 12826 if (nargs == 5)
0a39fd54 12827 {
c2f47e15 12828 arg = CALL_EXPR_ARG (exp, 4);
12829 if (validate_arg (arg, POINTER_TYPE))
0a39fd54 12830 {
12831 len = c_strlen (arg, 1);
12832 if (! len || ! host_integerp (len, 1))
12833 len = NULL_TREE;
12834 }
12835 }
12836 }
12837 }
12838
12839 if (! integer_all_onesp (size))
12840 {
12841 if (! len || ! tree_int_cst_lt (len, size))
c2f47e15 12842 return NULL_TREE;
0a39fd54 12843 }
12844
12845 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
12846 or if format doesn't contain % chars or is "%s". */
12847 if (! integer_zerop (flag))
12848 {
12849 if (fmt_str == NULL)
c2f47e15 12850 return NULL_TREE;
12851 if (strchr (fmt_str, target_percent) != NULL
12852 && strcmp (fmt_str, target_percent_s))
12853 return NULL_TREE;
0a39fd54 12854 }
12855
0a39fd54 12856 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
12857 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
12858 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
12859 if (!fn)
c2f47e15 12860 return NULL_TREE;
0a39fd54 12861
c2f47e15 12862 return rewrite_call_expr (exp, 4, fn, 2, dest, fmt);
0a39fd54 12863}
12864
c2f47e15 12865/* Fold a call EXP to {,v}snprintf. Return NULL_TREE if
0a39fd54 12866 a normal call should be emitted rather than expanding the function
12867 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
12868 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
12869 passed as second argument. */
12870
12871tree
c2f47e15 12872fold_builtin_snprintf_chk (tree exp, tree maxlen,
0a39fd54 12873 enum built_in_function fcode)
12874{
12875 tree dest, size, len, fn, fmt, flag;
12876 const char *fmt_str;
12877
12878 /* Verify the required arguments in the original call. */
c2f47e15 12879 if (call_expr_nargs (exp) < 5)
12880 return NULL_TREE;
12881 dest = CALL_EXPR_ARG (exp, 0);
12882 if (!validate_arg (dest, POINTER_TYPE))
12883 return NULL_TREE;
12884 len = CALL_EXPR_ARG (exp, 1);
12885 if (!validate_arg (len, INTEGER_TYPE))
12886 return NULL_TREE;
12887 flag = CALL_EXPR_ARG (exp, 2);
12888 if (!validate_arg (flag, INTEGER_TYPE))
12889 return NULL_TREE;
12890 size = CALL_EXPR_ARG (exp, 3);
12891 if (!validate_arg (size, INTEGER_TYPE))
12892 return NULL_TREE;
12893 fmt = CALL_EXPR_ARG (exp, 4);
12894 if (!validate_arg (fmt, POINTER_TYPE))
12895 return NULL_TREE;
0a39fd54 12896
12897 if (! host_integerp (size, 1))
c2f47e15 12898 return NULL_TREE;
0a39fd54 12899
12900 if (! integer_all_onesp (size))
12901 {
12902 if (! host_integerp (len, 1))
12903 {
12904 /* If LEN is not constant, try MAXLEN too.
12905 For MAXLEN only allow optimizing into non-_ocs function
12906 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12907 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
c2f47e15 12908 return NULL_TREE;
0a39fd54 12909 }
ad89623c 12910 else
12911 maxlen = len;
0a39fd54 12912
ad89623c 12913 if (tree_int_cst_lt (size, maxlen))
c2f47e15 12914 return NULL_TREE;
0a39fd54 12915 }
12916
d4473c84 12917 if (!init_target_chars ())
c2f47e15 12918 return NULL_TREE;
99eabcc1 12919
0a39fd54 12920 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
12921 or if format doesn't contain % chars or is "%s". */
12922 if (! integer_zerop (flag))
12923 {
12924 fmt_str = c_getstr (fmt);
12925 if (fmt_str == NULL)
c2f47e15 12926 return NULL_TREE;
12927 if (strchr (fmt_str, target_percent) != NULL
12928 && strcmp (fmt_str, target_percent_s))
12929 return NULL_TREE;
0a39fd54 12930 }
12931
0a39fd54 12932 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
12933 available. */
12934 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
12935 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
12936 if (!fn)
c2f47e15 12937 return NULL_TREE;
0a39fd54 12938
c2f47e15 12939 return rewrite_call_expr (exp, 5, fn, 3, dest, len, fmt);
0a39fd54 12940}
12941
12942/* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
c2f47e15 12943 FMT and ARG are the arguments to the call; we don't fold cases with
12944 more than 2 arguments, and ARG may be null if this is a 1-argument case.
0a39fd54 12945
c2f47e15 12946 Return NULL_TREE if no simplification was possible, otherwise return the
0a39fd54 12947 simplified form of the call as a tree. FCODE is the BUILT_IN_*
12948 code of the function to be simplified. */
12949
12950static tree
c2f47e15 12951fold_builtin_printf (tree fndecl, tree fmt, tree arg, bool ignore,
0a39fd54 12952 enum built_in_function fcode)
12953{
c2f47e15 12954 tree fn_putchar, fn_puts, newarg, call = NULL_TREE;
0a39fd54 12955 const char *fmt_str = NULL;
12956
12957 /* If the return value is used, don't do the transformation. */
12958 if (! ignore)
c2f47e15 12959 return NULL_TREE;
0a39fd54 12960
12961 /* Verify the required arguments in the original call. */
c2f47e15 12962 if (!validate_arg (fmt, POINTER_TYPE))
12963 return NULL_TREE;
0a39fd54 12964
12965 /* Check whether the format is a literal string constant. */
12966 fmt_str = c_getstr (fmt);
12967 if (fmt_str == NULL)
12968 return NULL_TREE;
12969
12970 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
12971 {
6d77ed92 12972 /* If we're using an unlocked function, assume the other
12973 unlocked functions exist explicitly. */
12974 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
12975 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
0a39fd54 12976 }
12977 else
12978 {
12979 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
12980 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
12981 }
12982
d4473c84 12983 if (!init_target_chars ())
c2f47e15 12984 return NULL_TREE;
a0c938f0 12985
c2f47e15 12986 if (strcmp (fmt_str, target_percent_s) == 0
12987 || strchr (fmt_str, target_percent) == NULL)
0a39fd54 12988 {
12989 const char *str;
12990
99eabcc1 12991 if (strcmp (fmt_str, target_percent_s) == 0)
0a39fd54 12992 {
12993 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
c2f47e15 12994 return NULL_TREE;
0a39fd54 12995
c2f47e15 12996 if (!arg || !validate_arg (arg, POINTER_TYPE))
12997 return NULL_TREE;
0a39fd54 12998
c2f47e15 12999 str = c_getstr (arg);
0a39fd54 13000 if (str == NULL)
c2f47e15 13001 return NULL_TREE;
0a39fd54 13002 }
13003 else
13004 {
13005 /* The format specifier doesn't contain any '%' characters. */
13006 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
c2f47e15 13007 && arg)
13008 return NULL_TREE;
0a39fd54 13009 str = fmt_str;
13010 }
13011
13012 /* If the string was "", printf does nothing. */
13013 if (str[0] == '\0')
13014 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
13015
13016 /* If the string has length of 1, call putchar. */
13017 if (str[1] == '\0')
13018 {
13019 /* Given printf("c"), (where c is any one character,)
13020 convert "c"[0] to an int and pass that to the replacement
13021 function. */
c2f47e15 13022 newarg = build_int_cst (NULL_TREE, str[0]);
13023 if (fn_putchar)
13024 call = build_call_expr (fn_putchar, 1, newarg);
0a39fd54 13025 }
13026 else
13027 {
13028 /* If the string was "string\n", call puts("string"). */
13029 size_t len = strlen (str);
99eabcc1 13030 if ((unsigned char)str[len - 1] == target_newline)
0a39fd54 13031 {
13032 /* Create a NUL-terminated string that's one char shorter
13033 than the original, stripping off the trailing '\n'. */
364c0c59 13034 char *newstr = XALLOCAVEC (char, len);
0a39fd54 13035 memcpy (newstr, str, len - 1);
13036 newstr[len - 1] = 0;
13037
c2f47e15 13038 newarg = build_string_literal (len, newstr);
13039 if (fn_puts)
13040 call = build_call_expr (fn_puts, 1, newarg);
0a39fd54 13041 }
13042 else
13043 /* We'd like to arrange to call fputs(string,stdout) here,
13044 but we need stdout and don't have a way to get it yet. */
c2f47e15 13045 return NULL_TREE;
0a39fd54 13046 }
13047 }
13048
13049 /* The other optimizations can be done only on the non-va_list variants. */
13050 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
c2f47e15 13051 return NULL_TREE;
0a39fd54 13052
13053 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
99eabcc1 13054 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
0a39fd54 13055 {
c2f47e15 13056 if (!arg || !validate_arg (arg, POINTER_TYPE))
13057 return NULL_TREE;
13058 if (fn_puts)
13059 call = build_call_expr (fn_puts, 1, arg);
0a39fd54 13060 }
13061
13062 /* If the format specifier was "%c", call __builtin_putchar(arg). */
99eabcc1 13063 else if (strcmp (fmt_str, target_percent_c) == 0)
0a39fd54 13064 {
c2f47e15 13065 if (!arg || !validate_arg (arg, INTEGER_TYPE))
13066 return NULL_TREE;
13067 if (fn_putchar)
13068 call = build_call_expr (fn_putchar, 1, arg);
0a39fd54 13069 }
13070
c2f47e15 13071 if (!call)
13072 return NULL_TREE;
0a39fd54 13073
0a39fd54 13074 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
13075}
13076
13077/* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
c2f47e15 13078 FP, FMT, and ARG are the arguments to the call. We don't fold calls with
13079 more than 3 arguments, and ARG may be null in the 2-argument case.
0a39fd54 13080
c2f47e15 13081 Return NULL_TREE if no simplification was possible, otherwise return the
0a39fd54 13082 simplified form of the call as a tree. FCODE is the BUILT_IN_*
13083 code of the function to be simplified. */
13084
13085static tree
c2f47e15 13086fold_builtin_fprintf (tree fndecl, tree fp, tree fmt, tree arg, bool ignore,
0a39fd54 13087 enum built_in_function fcode)
13088{
c2f47e15 13089 tree fn_fputc, fn_fputs, call = NULL_TREE;
0a39fd54 13090 const char *fmt_str = NULL;
13091
13092 /* If the return value is used, don't do the transformation. */
13093 if (! ignore)
c2f47e15 13094 return NULL_TREE;
0a39fd54 13095
13096 /* Verify the required arguments in the original call. */
c2f47e15 13097 if (!validate_arg (fp, POINTER_TYPE))
13098 return NULL_TREE;
13099 if (!validate_arg (fmt, POINTER_TYPE))
13100 return NULL_TREE;
0a39fd54 13101
13102 /* Check whether the format is a literal string constant. */
13103 fmt_str = c_getstr (fmt);
13104 if (fmt_str == NULL)
13105 return NULL_TREE;
13106
13107 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
13108 {
6d77ed92 13109 /* If we're using an unlocked function, assume the other
13110 unlocked functions exist explicitly. */
13111 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
13112 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
0a39fd54 13113 }
13114 else
13115 {
13116 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
13117 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
13118 }
13119
d4473c84 13120 if (!init_target_chars ())
c2f47e15 13121 return NULL_TREE;
a0c938f0 13122
0a39fd54 13123 /* If the format doesn't contain % args or %%, use strcpy. */
99eabcc1 13124 if (strchr (fmt_str, target_percent) == NULL)
0a39fd54 13125 {
13126 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
c2f47e15 13127 && arg)
13128 return NULL_TREE;
0a39fd54 13129
13130 /* If the format specifier was "", fprintf does nothing. */
13131 if (fmt_str[0] == '\0')
13132 {
13133 /* If FP has side-effects, just wait until gimplification is
13134 done. */
13135 if (TREE_SIDE_EFFECTS (fp))
c2f47e15 13136 return NULL_TREE;
0a39fd54 13137
13138 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
13139 }
13140
13141 /* When "string" doesn't contain %, replace all cases of
13142 fprintf (fp, string) with fputs (string, fp). The fputs
13143 builtin will take care of special cases like length == 1. */
c2f47e15 13144 if (fn_fputs)
13145 call = build_call_expr (fn_fputs, 2, fmt, fp);
0a39fd54 13146 }
13147
13148 /* The other optimizations can be done only on the non-va_list variants. */
13149 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
c2f47e15 13150 return NULL_TREE;
0a39fd54 13151
13152 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
99eabcc1 13153 else if (strcmp (fmt_str, target_percent_s) == 0)
0a39fd54 13154 {
c2f47e15 13155 if (!arg || !validate_arg (arg, POINTER_TYPE))
13156 return NULL_TREE;
13157 if (fn_fputs)
13158 call = build_call_expr (fn_fputs, 2, arg, fp);
0a39fd54 13159 }
13160
13161 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
99eabcc1 13162 else if (strcmp (fmt_str, target_percent_c) == 0)
0a39fd54 13163 {
c2f47e15 13164 if (!arg || !validate_arg (arg, INTEGER_TYPE))
13165 return NULL_TREE;
13166 if (fn_fputc)
13167 call = build_call_expr (fn_fputc, 2, arg, fp);
0a39fd54 13168 }
13169
c2f47e15 13170 if (!call)
13171 return NULL_TREE;
0a39fd54 13172 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
13173}
99eabcc1 13174
13175/* Initialize format string characters in the target charset. */
13176
13177static bool
13178init_target_chars (void)
13179{
13180 static bool init;
13181 if (!init)
13182 {
13183 target_newline = lang_hooks.to_target_charset ('\n');
13184 target_percent = lang_hooks.to_target_charset ('%');
13185 target_c = lang_hooks.to_target_charset ('c');
13186 target_s = lang_hooks.to_target_charset ('s');
13187 if (target_newline == 0 || target_percent == 0 || target_c == 0
13188 || target_s == 0)
13189 return false;
13190
13191 target_percent_c[0] = target_percent;
13192 target_percent_c[1] = target_c;
13193 target_percent_c[2] = '\0';
13194
13195 target_percent_s[0] = target_percent;
13196 target_percent_s[1] = target_s;
13197 target_percent_s[2] = '\0';
13198
13199 target_percent_s_newline[0] = target_percent;
13200 target_percent_s_newline[1] = target_s;
13201 target_percent_s_newline[2] = target_newline;
13202 target_percent_s_newline[3] = '\0';
a0c938f0 13203
99eabcc1 13204 init = true;
13205 }
13206 return true;
13207}
bffb7645 13208
f0c477f2 13209/* Helper function for do_mpfr_arg*(). Ensure M is a normal number
13210 and no overflow/underflow occurred. INEXACT is true if M was not
fa7637bd 13211 exactly calculated. TYPE is the tree type for the result. This
f0c477f2 13212 function assumes that you cleared the MPFR flags and then
13213 calculated M to see if anything subsequently set a flag prior to
13214 entering this function. Return NULL_TREE if any checks fail. */
13215
13216static tree
d4473c84 13217do_mpfr_ckconv (mpfr_srcptr m, tree type, int inexact)
f0c477f2 13218{
13219 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13220 overflow/underflow occurred. If -frounding-math, proceed iff the
13221 result of calling FUNC was exact. */
d4473c84 13222 if (mpfr_number_p (m) && !mpfr_overflow_p () && !mpfr_underflow_p ()
f0c477f2 13223 && (!flag_rounding_math || !inexact))
13224 {
13225 REAL_VALUE_TYPE rr;
13226
66fa16e6 13227 real_from_mpfr (&rr, m, type, GMP_RNDN);
f0c477f2 13228 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
13229 check for overflow/underflow. If the REAL_VALUE_TYPE is zero
13230 but the mpft_t is not, then we underflowed in the
13231 conversion. */
776a7bab 13232 if (real_isfinite (&rr)
f0c477f2 13233 && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
13234 {
13235 REAL_VALUE_TYPE rmode;
13236
13237 real_convert (&rmode, TYPE_MODE (type), &rr);
13238 /* Proceed iff the specified mode can hold the value. */
13239 if (real_identical (&rmode, &rr))
13240 return build_real (type, rmode);
13241 }
13242 }
13243 return NULL_TREE;
13244}
13245
239d491a 13246#ifdef HAVE_mpc
13247/* Helper function for do_mpc_arg*(). Ensure M is a normal complex
13248 number and no overflow/underflow occurred. INEXACT is true if M
13249 was not exactly calculated. TYPE is the tree type for the result.
13250 This function assumes that you cleared the MPFR flags and then
13251 calculated M to see if anything subsequently set a flag prior to
13252 entering this function. Return NULL_TREE if any checks fail. */
13253
13254static tree
13255do_mpc_ckconv (mpc_srcptr m, tree type, int inexact)
13256{
13257 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13258 overflow/underflow occurred. If -frounding-math, proceed iff the
13259 result of calling FUNC was exact. */
c3cfad90 13260 if (mpfr_number_p (mpc_realref (m)) && mpfr_number_p (mpc_imagref (m))
239d491a 13261 && !mpfr_overflow_p () && !mpfr_underflow_p ()
13262 && (!flag_rounding_math || !inexact))
13263 {
13264 REAL_VALUE_TYPE re, im;
13265
c3cfad90 13266 real_from_mpfr (&re, mpc_realref (m), type, GMP_RNDN);
13267 real_from_mpfr (&im, mpc_imagref (m), type, GMP_RNDN);
239d491a 13268 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR values,
13269 check for overflow/underflow. If the REAL_VALUE_TYPE is zero
13270 but the mpft_t is not, then we underflowed in the
13271 conversion. */
13272 if (real_isfinite (&re) && real_isfinite (&im)
c3cfad90 13273 && (re.cl == rvc_zero) == (mpfr_zero_p (mpc_realref (m)) != 0)
13274 && (im.cl == rvc_zero) == (mpfr_zero_p (mpc_imagref (m)) != 0))
239d491a 13275 {
13276 REAL_VALUE_TYPE re_mode, im_mode;
13277
13278 real_convert (&re_mode, TYPE_MODE (TREE_TYPE (type)), &re);
13279 real_convert (&im_mode, TYPE_MODE (TREE_TYPE (type)), &im);
13280 /* Proceed iff the specified mode can hold the value. */
13281 if (real_identical (&re_mode, &re) && real_identical (&im_mode, &im))
13282 return build_complex (type, build_real (TREE_TYPE (type), re_mode),
13283 build_real (TREE_TYPE (type), im_mode));
13284 }
13285 }
13286 return NULL_TREE;
13287}
13288#endif /* HAVE_mpc */
13289
bffb7645 13290/* If argument ARG is a REAL_CST, call the one-argument mpfr function
13291 FUNC on it and return the resulting value as a tree with type TYPE.
728bac60 13292 If MIN and/or MAX are not NULL, then the supplied ARG must be
13293 within those bounds. If INCLUSIVE is true, then MIN/MAX are
13294 acceptable values, otherwise they are not. The mpfr precision is
13295 set to the precision of TYPE. We assume that function FUNC returns
13296 zero if the result could be calculated exactly within the requested
13297 precision. */
bffb7645 13298
13299static tree
728bac60 13300do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
13301 const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
13302 bool inclusive)
bffb7645 13303{
13304 tree result = NULL_TREE;
13305
13306 STRIP_NOPS (arg);
13307
bd7d6fa4 13308 /* To proceed, MPFR must exactly represent the target floating point
13309 format, which only happens when the target base equals two. */
13310 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
f96bd2bf 13311 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
bffb7645 13312 {
f0c477f2 13313 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
bffb7645 13314
776a7bab 13315 if (real_isfinite (ra)
f0c477f2 13316 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
13317 && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
bffb7645 13318 {
e2eb2b7f 13319 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13320 const int prec = fmt->p;
13321 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
debf9994 13322 int inexact;
bffb7645 13323 mpfr_t m;
13324
13325 mpfr_init2 (m, prec);
66fa16e6 13326 mpfr_from_real (m, ra, GMP_RNDN);
d4473c84 13327 mpfr_clear_flags ();
e2eb2b7f 13328 inexact = func (m, m, rnd);
f0c477f2 13329 result = do_mpfr_ckconv (m, type, inexact);
bffb7645 13330 mpfr_clear (m);
13331 }
13332 }
13333
13334 return result;
13335}
f0c477f2 13336
13337/* If argument ARG is a REAL_CST, call the two-argument mpfr function
13338 FUNC on it and return the resulting value as a tree with type TYPE.
13339 The mpfr precision is set to the precision of TYPE. We assume that
13340 function FUNC returns zero if the result could be calculated
13341 exactly within the requested precision. */
13342
13343static tree
13344do_mpfr_arg2 (tree arg1, tree arg2, tree type,
13345 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13346{
13347 tree result = NULL_TREE;
13348
13349 STRIP_NOPS (arg1);
13350 STRIP_NOPS (arg2);
13351
bd7d6fa4 13352 /* To proceed, MPFR must exactly represent the target floating point
13353 format, which only happens when the target base equals two. */
13354 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
f96bd2bf 13355 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13356 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
f0c477f2 13357 {
13358 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13359 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13360
776a7bab 13361 if (real_isfinite (ra1) && real_isfinite (ra2))
f0c477f2 13362 {
e2eb2b7f 13363 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13364 const int prec = fmt->p;
13365 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
f0c477f2 13366 int inexact;
13367 mpfr_t m1, m2;
13368
13369 mpfr_inits2 (prec, m1, m2, NULL);
66fa16e6 13370 mpfr_from_real (m1, ra1, GMP_RNDN);
13371 mpfr_from_real (m2, ra2, GMP_RNDN);
d4473c84 13372 mpfr_clear_flags ();
e2eb2b7f 13373 inexact = func (m1, m1, m2, rnd);
f0c477f2 13374 result = do_mpfr_ckconv (m1, type, inexact);
13375 mpfr_clears (m1, m2, NULL);
13376 }
13377 }
13378
13379 return result;
13380}
d92f994c 13381
9917422b 13382/* If argument ARG is a REAL_CST, call the three-argument mpfr function
13383 FUNC on it and return the resulting value as a tree with type TYPE.
13384 The mpfr precision is set to the precision of TYPE. We assume that
13385 function FUNC returns zero if the result could be calculated
13386 exactly within the requested precision. */
13387
13388static tree
13389do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
13390 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13391{
13392 tree result = NULL_TREE;
13393
13394 STRIP_NOPS (arg1);
13395 STRIP_NOPS (arg2);
13396 STRIP_NOPS (arg3);
13397
bd7d6fa4 13398 /* To proceed, MPFR must exactly represent the target floating point
13399 format, which only happens when the target base equals two. */
13400 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
f96bd2bf 13401 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13402 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)
13403 && TREE_CODE (arg3) == REAL_CST && !TREE_OVERFLOW (arg3))
9917422b 13404 {
13405 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13406 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13407 const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
13408
776a7bab 13409 if (real_isfinite (ra1) && real_isfinite (ra2) && real_isfinite (ra3))
9917422b 13410 {
e2eb2b7f 13411 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13412 const int prec = fmt->p;
13413 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
9917422b 13414 int inexact;
13415 mpfr_t m1, m2, m3;
13416
13417 mpfr_inits2 (prec, m1, m2, m3, NULL);
66fa16e6 13418 mpfr_from_real (m1, ra1, GMP_RNDN);
13419 mpfr_from_real (m2, ra2, GMP_RNDN);
13420 mpfr_from_real (m3, ra3, GMP_RNDN);
d4473c84 13421 mpfr_clear_flags ();
e2eb2b7f 13422 inexact = func (m1, m1, m2, m3, rnd);
9917422b 13423 result = do_mpfr_ckconv (m1, type, inexact);
13424 mpfr_clears (m1, m2, m3, NULL);
13425 }
13426 }
13427
13428 return result;
13429}
13430
d92f994c 13431/* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
13432 the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
d735c391 13433 If ARG_SINP and ARG_COSP are NULL then the result is returned
13434 as a complex value.
d92f994c 13435 The type is taken from the type of ARG and is used for setting the
13436 precision of the calculation and results. */
13437
13438static tree
13439do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
13440{
bd7d6fa4 13441 tree const type = TREE_TYPE (arg);
d92f994c 13442 tree result = NULL_TREE;
13443
13444 STRIP_NOPS (arg);
13445
bd7d6fa4 13446 /* To proceed, MPFR must exactly represent the target floating point
13447 format, which only happens when the target base equals two. */
13448 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
f96bd2bf 13449 && TREE_CODE (arg) == REAL_CST
13450 && !TREE_OVERFLOW (arg))
d92f994c 13451 {
13452 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
13453
776a7bab 13454 if (real_isfinite (ra))
d92f994c 13455 {
e2eb2b7f 13456 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13457 const int prec = fmt->p;
13458 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
d92f994c 13459 tree result_s, result_c;
13460 int inexact;
13461 mpfr_t m, ms, mc;
13462
13463 mpfr_inits2 (prec, m, ms, mc, NULL);
66fa16e6 13464 mpfr_from_real (m, ra, GMP_RNDN);
d4473c84 13465 mpfr_clear_flags ();
e2eb2b7f 13466 inexact = mpfr_sin_cos (ms, mc, m, rnd);
d92f994c 13467 result_s = do_mpfr_ckconv (ms, type, inexact);
13468 result_c = do_mpfr_ckconv (mc, type, inexact);
13469 mpfr_clears (m, ms, mc, NULL);
13470 if (result_s && result_c)
13471 {
d735c391 13472 /* If we are to return in a complex value do so. */
13473 if (!arg_sinp && !arg_cosp)
13474 return build_complex (build_complex_type (type),
13475 result_c, result_s);
13476
d92f994c 13477 /* Dereference the sin/cos pointer arguments. */
13478 arg_sinp = build_fold_indirect_ref (arg_sinp);
13479 arg_cosp = build_fold_indirect_ref (arg_cosp);
13480 /* Proceed if valid pointer type were passed in. */
13481 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
13482 && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
13483 {
13484 /* Set the values. */
41076ef6 13485 result_s = fold_build2 (MODIFY_EXPR, type, arg_sinp,
35cc02b5 13486 result_s);
d92f994c 13487 TREE_SIDE_EFFECTS (result_s) = 1;
41076ef6 13488 result_c = fold_build2 (MODIFY_EXPR, type, arg_cosp,
35cc02b5 13489 result_c);
d92f994c 13490 TREE_SIDE_EFFECTS (result_c) = 1;
13491 /* Combine the assignments into a compound expr. */
13492 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13493 result_s, result_c));
13494 }
13495 }
13496 }
13497 }
13498 return result;
13499}
65dd1378 13500
65dd1378 13501/* If argument ARG1 is an INTEGER_CST and ARG2 is a REAL_CST, call the
13502 two-argument mpfr order N Bessel function FUNC on them and return
13503 the resulting value as a tree with type TYPE. The mpfr precision
13504 is set to the precision of TYPE. We assume that function FUNC
13505 returns zero if the result could be calculated exactly within the
13506 requested precision. */
13507static tree
13508do_mpfr_bessel_n (tree arg1, tree arg2, tree type,
13509 int (*func)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
13510 const REAL_VALUE_TYPE *min, bool inclusive)
13511{
13512 tree result = NULL_TREE;
13513
13514 STRIP_NOPS (arg1);
13515 STRIP_NOPS (arg2);
13516
13517 /* To proceed, MPFR must exactly represent the target floating point
13518 format, which only happens when the target base equals two. */
13519 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13520 && host_integerp (arg1, 0)
13521 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
13522 {
13523 const HOST_WIDE_INT n = tree_low_cst(arg1, 0);
13524 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg2);
13525
13526 if (n == (long)n
776a7bab 13527 && real_isfinite (ra)
65dd1378 13528 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min)))
13529 {
e2eb2b7f 13530 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13531 const int prec = fmt->p;
13532 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
65dd1378 13533 int inexact;
13534 mpfr_t m;
13535
13536 mpfr_init2 (m, prec);
13537 mpfr_from_real (m, ra, GMP_RNDN);
13538 mpfr_clear_flags ();
e2eb2b7f 13539 inexact = func (m, n, m, rnd);
65dd1378 13540 result = do_mpfr_ckconv (m, type, inexact);
13541 mpfr_clear (m);
13542 }
13543 }
13544
13545 return result;
13546}
e5407ca6 13547
13548/* If arguments ARG0 and ARG1 are REAL_CSTs, call mpfr_remquo() to set
13549 the pointer *(ARG_QUO) and return the result. The type is taken
13550 from the type of ARG0 and is used for setting the precision of the
13551 calculation and results. */
13552
13553static tree
13554do_mpfr_remquo (tree arg0, tree arg1, tree arg_quo)
13555{
13556 tree const type = TREE_TYPE (arg0);
13557 tree result = NULL_TREE;
13558
13559 STRIP_NOPS (arg0);
13560 STRIP_NOPS (arg1);
13561
13562 /* To proceed, MPFR must exactly represent the target floating point
13563 format, which only happens when the target base equals two. */
13564 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13565 && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
13566 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1))
13567 {
13568 const REAL_VALUE_TYPE *const ra0 = TREE_REAL_CST_PTR (arg0);
13569 const REAL_VALUE_TYPE *const ra1 = TREE_REAL_CST_PTR (arg1);
13570
776a7bab 13571 if (real_isfinite (ra0) && real_isfinite (ra1))
e5407ca6 13572 {
e2eb2b7f 13573 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13574 const int prec = fmt->p;
13575 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
e5407ca6 13576 tree result_rem;
13577 long integer_quo;
13578 mpfr_t m0, m1;
13579
13580 mpfr_inits2 (prec, m0, m1, NULL);
13581 mpfr_from_real (m0, ra0, GMP_RNDN);
13582 mpfr_from_real (m1, ra1, GMP_RNDN);
13583 mpfr_clear_flags ();
e2eb2b7f 13584 mpfr_remquo (m0, &integer_quo, m0, m1, rnd);
e5407ca6 13585 /* Remquo is independent of the rounding mode, so pass
13586 inexact=0 to do_mpfr_ckconv(). */
13587 result_rem = do_mpfr_ckconv (m0, type, /*inexact=*/ 0);
13588 mpfr_clears (m0, m1, NULL);
13589 if (result_rem)
13590 {
13591 /* MPFR calculates quo in the host's long so it may
13592 return more bits in quo than the target int can hold
13593 if sizeof(host long) > sizeof(target int). This can
13594 happen even for native compilers in LP64 mode. In
13595 these cases, modulo the quo value with the largest
13596 number that the target int can hold while leaving one
13597 bit for the sign. */
13598 if (sizeof (integer_quo) * CHAR_BIT > INT_TYPE_SIZE)
13599 integer_quo %= (long)(1UL << (INT_TYPE_SIZE - 1));
13600
13601 /* Dereference the quo pointer argument. */
13602 arg_quo = build_fold_indirect_ref (arg_quo);
13603 /* Proceed iff a valid pointer type was passed in. */
13604 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_quo)) == integer_type_node)
13605 {
13606 /* Set the value. */
13607 tree result_quo = fold_build2 (MODIFY_EXPR,
13608 TREE_TYPE (arg_quo), arg_quo,
13609 build_int_cst (NULL, integer_quo));
13610 TREE_SIDE_EFFECTS (result_quo) = 1;
13611 /* Combine the quo assignment with the rem. */
13612 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13613 result_quo, result_rem));
13614 }
13615 }
13616 }
13617 }
13618 return result;
13619}
e84da7c1 13620
13621/* If ARG is a REAL_CST, call mpfr_lgamma() on it and return the
13622 resulting value as a tree with type TYPE. The mpfr precision is
13623 set to the precision of TYPE. We assume that this mpfr function
13624 returns zero if the result could be calculated exactly within the
13625 requested precision. In addition, the integer pointer represented
13626 by ARG_SG will be dereferenced and set to the appropriate signgam
13627 (-1,1) value. */
13628
13629static tree
13630do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type)
13631{
13632 tree result = NULL_TREE;
13633
13634 STRIP_NOPS (arg);
13635
13636 /* To proceed, MPFR must exactly represent the target floating point
13637 format, which only happens when the target base equals two. Also
13638 verify ARG is a constant and that ARG_SG is an int pointer. */
13639 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13640 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)
13641 && TREE_CODE (TREE_TYPE (arg_sg)) == POINTER_TYPE
13642 && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg_sg))) == integer_type_node)
13643 {
13644 const REAL_VALUE_TYPE *const ra = TREE_REAL_CST_PTR (arg);
13645
13646 /* In addition to NaN and Inf, the argument cannot be zero or a
13647 negative integer. */
776a7bab 13648 if (real_isfinite (ra)
e84da7c1 13649 && ra->cl != rvc_zero
13650 && !(real_isneg(ra) && real_isinteger(ra, TYPE_MODE (type))))
13651 {
e2eb2b7f 13652 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13653 const int prec = fmt->p;
13654 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
e84da7c1 13655 int inexact, sg;
13656 mpfr_t m;
13657 tree result_lg;
13658
13659 mpfr_init2 (m, prec);
13660 mpfr_from_real (m, ra, GMP_RNDN);
13661 mpfr_clear_flags ();
e2eb2b7f 13662 inexact = mpfr_lgamma (m, &sg, m, rnd);
e84da7c1 13663 result_lg = do_mpfr_ckconv (m, type, inexact);
13664 mpfr_clear (m);
13665 if (result_lg)
13666 {
13667 tree result_sg;
13668
13669 /* Dereference the arg_sg pointer argument. */
13670 arg_sg = build_fold_indirect_ref (arg_sg);
13671 /* Assign the signgam value into *arg_sg. */
13672 result_sg = fold_build2 (MODIFY_EXPR,
13673 TREE_TYPE (arg_sg), arg_sg,
13674 build_int_cst (NULL, sg));
13675 TREE_SIDE_EFFECTS (result_sg) = 1;
13676 /* Combine the signgam assignment with the lgamma result. */
13677 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13678 result_sg, result_lg));
13679 }
13680 }
13681 }
13682
13683 return result;
13684}
75a70cf9 13685
239d491a 13686#ifdef HAVE_mpc
13687/* If argument ARG is a COMPLEX_CST, call the one-argument mpc
13688 function FUNC on it and return the resulting value as a tree with
13689 type TYPE. The mpfr precision is set to the precision of TYPE. We
13690 assume that function FUNC returns zero if the result could be
13691 calculated exactly within the requested precision. */
13692
13693static tree
13694do_mpc_arg1 (tree arg, tree type, int (*func)(mpc_ptr, mpc_srcptr, mpc_rnd_t))
13695{
13696 tree result = NULL_TREE;
13697
13698 STRIP_NOPS (arg);
13699
13700 /* To proceed, MPFR must exactly represent the target floating point
13701 format, which only happens when the target base equals two. */
13702 if (TREE_CODE (arg) == COMPLEX_CST && !TREE_OVERFLOW (arg)
13703 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE
13704 && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg))))->b == 2)
13705 {
13706 const REAL_VALUE_TYPE *const re = TREE_REAL_CST_PTR (TREE_REALPART (arg));
13707 const REAL_VALUE_TYPE *const im = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
13708
13709 if (real_isfinite (re) && real_isfinite (im))
13710 {
13711 const struct real_format *const fmt =
13712 REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
13713 const int prec = fmt->p;
13714 const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
44d89feb 13715 const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
239d491a 13716 int inexact;
13717 mpc_t m;
13718
13719 mpc_init2 (m, prec);
c3cfad90 13720 mpfr_from_real (mpc_realref(m), re, rnd);
13721 mpfr_from_real (mpc_imagref(m), im, rnd);
239d491a 13722 mpfr_clear_flags ();
44d89feb 13723 inexact = func (m, m, crnd);
239d491a 13724 result = do_mpc_ckconv (m, type, inexact);
13725 mpc_clear (m);
13726 }
13727 }
13728
13729 return result;
13730}
c699fab8 13731
13732/* If arguments ARG0 and ARG1 are a COMPLEX_CST, call the two-argument
13733 mpc function FUNC on it and return the resulting value as a tree
13734 with type TYPE. The mpfr precision is set to the precision of
13735 TYPE. We assume that function FUNC returns zero if the result
13736 could be calculated exactly within the requested precision. */
13737
13738#ifdef HAVE_mpc_pow
13739static tree
13740do_mpc_arg2 (tree arg0, tree arg1, tree type,
13741 int (*func)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t))
13742{
13743 tree result = NULL_TREE;
13744
13745 STRIP_NOPS (arg0);
13746 STRIP_NOPS (arg1);
13747
13748 /* To proceed, MPFR must exactly represent the target floating point
13749 format, which only happens when the target base equals two. */
13750 if (TREE_CODE (arg0) == COMPLEX_CST && !TREE_OVERFLOW (arg0)
13751 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
13752 && TREE_CODE (arg1) == COMPLEX_CST && !TREE_OVERFLOW (arg1)
13753 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE
13754 && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))))->b == 2)
13755 {
13756 const REAL_VALUE_TYPE *const re0 = TREE_REAL_CST_PTR (TREE_REALPART (arg0));
13757 const REAL_VALUE_TYPE *const im0 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg0));
13758 const REAL_VALUE_TYPE *const re1 = TREE_REAL_CST_PTR (TREE_REALPART (arg1));
13759 const REAL_VALUE_TYPE *const im1 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg1));
13760
13761 if (real_isfinite (re0) && real_isfinite (im0)
13762 && real_isfinite (re1) && real_isfinite (im1))
13763 {
13764 const struct real_format *const fmt =
13765 REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
13766 const int prec = fmt->p;
13767 const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
13768 const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
13769 int inexact;
13770 mpc_t m0, m1;
13771
13772 mpc_init2 (m0, prec);
13773 mpc_init2 (m1, prec);
13774 mpfr_from_real (mpc_realref(m0), re0, rnd);
13775 mpfr_from_real (mpc_imagref(m0), im0, rnd);
13776 mpfr_from_real (mpc_realref(m1), re1, rnd);
13777 mpfr_from_real (mpc_imagref(m1), im1, rnd);
13778 mpfr_clear_flags ();
13779 inexact = func (m0, m0, m1, crnd);
13780 result = do_mpc_ckconv (m0, type, inexact);
13781 mpc_clear (m0);
13782 mpc_clear (m1);
13783 }
13784 }
13785
13786 return result;
13787}
13788# endif
239d491a 13789#endif /* HAVE_mpc */
13790
75a70cf9 13791/* FIXME tuples.
13792 The functions below provide an alternate interface for folding
13793 builtin function calls presented as GIMPLE_CALL statements rather
13794 than as CALL_EXPRs. The folded result is still expressed as a
13795 tree. There is too much code duplication in the handling of
13796 varargs functions, and a more intrusive re-factoring would permit
13797 better sharing of code between the tree and statement-based
13798 versions of these functions. */
13799
13800/* Construct a new CALL_EXPR using the tail of the argument list of STMT
13801 along with N new arguments specified as the "..." parameters. SKIP
13802 is the number of arguments in STMT to be omitted. This function is used
13803 to do varargs-to-varargs transformations. */
13804
13805static tree
13806gimple_rewrite_call_expr (gimple stmt, int skip, tree fndecl, int n, ...)
13807{
13808 int oldnargs = gimple_call_num_args (stmt);
13809 int nargs = oldnargs - skip + n;
13810 tree fntype = TREE_TYPE (fndecl);
13811 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
13812 tree *buffer;
13813 int i, j;
13814 va_list ap;
13815
13816 buffer = XALLOCAVEC (tree, nargs);
13817 va_start (ap, n);
13818 for (i = 0; i < n; i++)
13819 buffer[i] = va_arg (ap, tree);
13820 va_end (ap);
13821 for (j = skip; j < oldnargs; j++, i++)
13822 buffer[i] = gimple_call_arg (stmt, j);
13823
13824 return fold (build_call_array (TREE_TYPE (fntype), fn, nargs, buffer));
13825}
13826
13827/* Fold a call STMT to __{,v}sprintf_chk. Return NULL_TREE if
13828 a normal call should be emitted rather than expanding the function
13829 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
13830
13831static tree
13832gimple_fold_builtin_sprintf_chk (gimple stmt, enum built_in_function fcode)
13833{
13834 tree dest, size, len, fn, fmt, flag;
13835 const char *fmt_str;
13836 int nargs = gimple_call_num_args (stmt);
13837
13838 /* Verify the required arguments in the original call. */
13839 if (nargs < 4)
13840 return NULL_TREE;
13841 dest = gimple_call_arg (stmt, 0);
13842 if (!validate_arg (dest, POINTER_TYPE))
13843 return NULL_TREE;
13844 flag = gimple_call_arg (stmt, 1);
13845 if (!validate_arg (flag, INTEGER_TYPE))
13846 return NULL_TREE;
13847 size = gimple_call_arg (stmt, 2);
13848 if (!validate_arg (size, INTEGER_TYPE))
13849 return NULL_TREE;
13850 fmt = gimple_call_arg (stmt, 3);
13851 if (!validate_arg (fmt, POINTER_TYPE))
13852 return NULL_TREE;
13853
13854 if (! host_integerp (size, 1))
13855 return NULL_TREE;
13856
13857 len = NULL_TREE;
13858
13859 if (!init_target_chars ())
13860 return NULL_TREE;
13861
13862 /* Check whether the format is a literal string constant. */
13863 fmt_str = c_getstr (fmt);
13864 if (fmt_str != NULL)
13865 {
13866 /* If the format doesn't contain % args or %%, we know the size. */
13867 if (strchr (fmt_str, target_percent) == 0)
13868 {
13869 if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
13870 len = build_int_cstu (size_type_node, strlen (fmt_str));
13871 }
13872 /* If the format is "%s" and first ... argument is a string literal,
13873 we know the size too. */
13874 else if (fcode == BUILT_IN_SPRINTF_CHK
13875 && strcmp (fmt_str, target_percent_s) == 0)
13876 {
13877 tree arg;
13878
13879 if (nargs == 5)
13880 {
13881 arg = gimple_call_arg (stmt, 4);
13882 if (validate_arg (arg, POINTER_TYPE))
13883 {
13884 len = c_strlen (arg, 1);
13885 if (! len || ! host_integerp (len, 1))
13886 len = NULL_TREE;
13887 }
13888 }
13889 }
13890 }
13891
13892 if (! integer_all_onesp (size))
13893 {
13894 if (! len || ! tree_int_cst_lt (len, size))
13895 return NULL_TREE;
13896 }
13897
13898 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
13899 or if format doesn't contain % chars or is "%s". */
13900 if (! integer_zerop (flag))
13901 {
13902 if (fmt_str == NULL)
13903 return NULL_TREE;
13904 if (strchr (fmt_str, target_percent) != NULL
13905 && strcmp (fmt_str, target_percent_s))
13906 return NULL_TREE;
13907 }
13908
13909 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
13910 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
13911 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
13912 if (!fn)
13913 return NULL_TREE;
13914
13915 return gimple_rewrite_call_expr (stmt, 4, fn, 2, dest, fmt);
13916}
13917
13918/* Fold a call STMT to {,v}snprintf. Return NULL_TREE if
13919 a normal call should be emitted rather than expanding the function
13920 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
13921 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
13922 passed as second argument. */
13923
13924tree
13925gimple_fold_builtin_snprintf_chk (gimple stmt, tree maxlen,
13926 enum built_in_function fcode)
13927{
13928 tree dest, size, len, fn, fmt, flag;
13929 const char *fmt_str;
13930
13931 /* Verify the required arguments in the original call. */
13932 if (gimple_call_num_args (stmt) < 5)
13933 return NULL_TREE;
13934 dest = gimple_call_arg (stmt, 0);
13935 if (!validate_arg (dest, POINTER_TYPE))
13936 return NULL_TREE;
13937 len = gimple_call_arg (stmt, 1);
13938 if (!validate_arg (len, INTEGER_TYPE))
13939 return NULL_TREE;
13940 flag = gimple_call_arg (stmt, 2);
13941 if (!validate_arg (flag, INTEGER_TYPE))
13942 return NULL_TREE;
13943 size = gimple_call_arg (stmt, 3);
13944 if (!validate_arg (size, INTEGER_TYPE))
13945 return NULL_TREE;
13946 fmt = gimple_call_arg (stmt, 4);
13947 if (!validate_arg (fmt, POINTER_TYPE))
13948 return NULL_TREE;
13949
13950 if (! host_integerp (size, 1))
13951 return NULL_TREE;
13952
13953 if (! integer_all_onesp (size))
13954 {
13955 if (! host_integerp (len, 1))
13956 {
13957 /* If LEN is not constant, try MAXLEN too.
13958 For MAXLEN only allow optimizing into non-_ocs function
13959 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
13960 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
13961 return NULL_TREE;
13962 }
13963 else
13964 maxlen = len;
13965
13966 if (tree_int_cst_lt (size, maxlen))
13967 return NULL_TREE;
13968 }
13969
13970 if (!init_target_chars ())
13971 return NULL_TREE;
13972
13973 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
13974 or if format doesn't contain % chars or is "%s". */
13975 if (! integer_zerop (flag))
13976 {
13977 fmt_str = c_getstr (fmt);
13978 if (fmt_str == NULL)
13979 return NULL_TREE;
13980 if (strchr (fmt_str, target_percent) != NULL
13981 && strcmp (fmt_str, target_percent_s))
13982 return NULL_TREE;
13983 }
13984
13985 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
13986 available. */
13987 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
13988 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
13989 if (!fn)
13990 return NULL_TREE;
13991
13992 return gimple_rewrite_call_expr (stmt, 5, fn, 3, dest, len, fmt);
13993}
13994
13995/* Builtins with folding operations that operate on "..." arguments
13996 need special handling; we need to store the arguments in a convenient
13997 data structure before attempting any folding. Fortunately there are
13998 only a few builtins that fall into this category. FNDECL is the
13999 function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
14000 result of the function call is ignored. */
14001
14002static tree
14003gimple_fold_builtin_varargs (tree fndecl, gimple stmt, bool ignore ATTRIBUTE_UNUSED)
14004{
14005 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
14006 tree ret = NULL_TREE;
14007
14008 switch (fcode)
14009 {
14010 case BUILT_IN_SPRINTF_CHK:
14011 case BUILT_IN_VSPRINTF_CHK:
14012 ret = gimple_fold_builtin_sprintf_chk (stmt, fcode);
14013 break;
14014
14015 case BUILT_IN_SNPRINTF_CHK:
14016 case BUILT_IN_VSNPRINTF_CHK:
14017 ret = gimple_fold_builtin_snprintf_chk (stmt, NULL_TREE, fcode);
14018
14019 default:
14020 break;
14021 }
14022 if (ret)
14023 {
14024 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
14025 TREE_NO_WARNING (ret) = 1;
14026 return ret;
14027 }
14028 return NULL_TREE;
14029}
14030
14031/* A wrapper function for builtin folding that prevents warnings for
14032 "statement without effect" and the like, caused by removing the
14033 call node earlier than the warning is generated. */
14034
14035tree
14036fold_call_stmt (gimple stmt, bool ignore)
14037{
14038 tree ret = NULL_TREE;
14039 tree fndecl = gimple_call_fndecl (stmt);
14040 if (fndecl
14041 && TREE_CODE (fndecl) == FUNCTION_DECL
14042 && DECL_BUILT_IN (fndecl)
14043 && !gimple_call_va_arg_pack_p (stmt))
14044 {
14045 int nargs = gimple_call_num_args (stmt);
14046
198622c0 14047 if (avoid_folding_inline_builtin (fndecl))
14048 return NULL_TREE;
75a70cf9 14049 /* FIXME: Don't use a list in this interface. */
14050 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
14051 {
14052 tree arglist = NULL_TREE;
14053 int i;
14054 for (i = nargs - 1; i >= 0; i--)
14055 arglist = tree_cons (NULL_TREE, gimple_call_arg (stmt, i), arglist);
14056 return targetm.fold_builtin (fndecl, arglist, ignore);
14057 }
14058 else
14059 {
14060 if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
14061 {
14062 tree args[MAX_ARGS_TO_FOLD_BUILTIN];
14063 int i;
14064 for (i = 0; i < nargs; i++)
14065 args[i] = gimple_call_arg (stmt, i);
14066 ret = fold_builtin_n (fndecl, args, nargs, ignore);
14067 }
14068 if (!ret)
14069 ret = gimple_fold_builtin_varargs (fndecl, stmt, ignore);
14070 if (ret)
14071 {
14072 /* Propagate location information from original call to
14073 expansion of builtin. Otherwise things like
14074 maybe_emit_chk_warning, that operate on the expansion
14075 of a builtin, will use the wrong location information. */
14076 if (gimple_has_location (stmt))
14077 {
14078 tree realret = ret;
14079 if (TREE_CODE (ret) == NOP_EXPR)
14080 realret = TREE_OPERAND (ret, 0);
14081 if (CAN_HAVE_LOCATION_P (realret)
14082 && !EXPR_HAS_LOCATION (realret))
14083 SET_EXPR_LOCATION (realret, gimple_location (stmt));
14084 return realret;
14085 }
14086 return ret;
14087 }
14088 }
14089 }
14090 return NULL_TREE;
14091}