]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/builtins.c
PR c++/41553
[thirdparty/gcc.git] / gcc / builtins.c
CommitLineData
53800dbe 1/* Expand builtin functions.
61f1dccc 2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
062b4460 3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
f96bd2bf 4 Free Software Foundation, Inc.
53800dbe 5
f12b58b3 6This file is part of GCC.
53800dbe 7
f12b58b3 8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
8c4c00c1 10Software Foundation; either version 3, or (at your option) any later
f12b58b3 11version.
53800dbe 12
f12b58b3 13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
53800dbe 17
18You should have received a copy of the GNU General Public License
8c4c00c1 19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
53800dbe 21
22#include "config.h"
23#include "system.h"
805e22b2 24#include "coretypes.h"
25#include "tm.h"
53800dbe 26#include "machmode.h"
ef258422 27#include "real.h"
53800dbe 28#include "rtl.h"
29#include "tree.h"
75a70cf9 30#include "gimple.h"
53800dbe 31#include "flags.h"
32#include "regs.h"
33#include "hard-reg-set.h"
34#include "except.h"
35#include "function.h"
53800dbe 36#include "insn-config.h"
37#include "expr.h"
d8fc4d0b 38#include "optabs.h"
39#include "libfuncs.h"
53800dbe 40#include "recog.h"
41#include "output.h"
42#include "typeclass.h"
53800dbe 43#include "toplev.h"
689df48e 44#include "predict.h"
1dd6c958 45#include "tm_p.h"
fc2a2dcb 46#include "target.h"
63c62881 47#include "langhooks.h"
0ec80471 48#include "basic-block.h"
fd62c19a 49#include "tree-mudflap.h"
5a84fdd6 50#include "tree-flow.h"
162719b3 51#include "value-prof.h"
07311427 52#include "diagnostic.h"
53800dbe 53
5383fb56 54#ifndef SLOW_UNALIGNED_ACCESS
55#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) STRICT_ALIGNMENT
56#endif
57
726e2588 58#ifndef PAD_VARARGS_DOWN
59#define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
60#endif
239d491a 61#ifdef HAVE_mpc
62static tree do_mpc_arg1 (tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_rnd_t));
63#endif
726e2588 64
ab7943b9 65/* Define the names of the builtin function types and codes. */
8934cb0c 66const char *const built_in_class_names[4]
ab7943b9 67 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
68
9cfddb70 69#define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
0dfc45b5 70const char * built_in_names[(int) END_BUILTINS] =
4e9d90c7 71{
72#include "builtins.def"
73};
74#undef DEF_BUILTIN
ab7943b9 75
df94cd3b 76/* Setup an array of _DECL trees, make sure each element is
77 initialized to NULL_TREE. */
d2d4bdde 78tree built_in_decls[(int) END_BUILTINS];
0a68165a 79/* Declarations used when constructing the builtin implicitly in the compiler.
80 It may be NULL_TREE when this is invalid (for instance runtime is not
4ee9c684 81 required to implement the function call in all cases). */
0a68165a 82tree implicit_built_in_decls[(int) END_BUILTINS];
df94cd3b 83
aecda0d6 84static const char *c_getstr (tree);
85static rtx c_readstr (const char *, enum machine_mode);
86static int target_char_cast (tree, char *);
d8ae1baa 87static rtx get_memory_rtx (tree, tree);
aecda0d6 88static int apply_args_size (void);
89static int apply_result_size (void);
d8c9779c 90#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
aecda0d6 91static rtx result_vector (int, rtx);
d8c9779c 92#endif
843d08a9 93static void expand_builtin_update_setjmp_buf (rtx);
aecda0d6 94static void expand_builtin_prefetch (tree);
95static rtx expand_builtin_apply_args (void);
96static rtx expand_builtin_apply_args_1 (void);
97static rtx expand_builtin_apply (rtx, rtx, rtx);
98static void expand_builtin_return (rtx);
99static enum type_class type_to_class (tree);
100static rtx expand_builtin_classify_type (tree);
101static void expand_errno_check (tree, rtx);
102static rtx expand_builtin_mathfn (tree, rtx, rtx);
103static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
6b43bae4 104static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
a67a90e5 105static rtx expand_builtin_interclass_mathfn (tree, rtx, rtx);
c3147c1a 106static rtx expand_builtin_sincos (tree);
d735c391 107static rtx expand_builtin_cexpi (tree, rtx, rtx);
ff1b14e4 108static rtx expand_builtin_int_roundingfn (tree, rtx);
109static rtx expand_builtin_int_roundingfn_2 (tree, rtx);
aecda0d6 110static rtx expand_builtin_args_info (tree);
79012a9d 111static rtx expand_builtin_next_arg (void);
aecda0d6 112static rtx expand_builtin_va_start (tree);
113static rtx expand_builtin_va_end (tree);
114static rtx expand_builtin_va_copy (tree);
c2f47e15 115static rtx expand_builtin_memcmp (tree, rtx, enum machine_mode);
a65c4d64 116static rtx expand_builtin_strcmp (tree, rtx);
aecda0d6 117static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
118static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
a65c4d64 119static rtx expand_builtin_memcpy (tree, rtx);
c2f47e15 120static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode);
a65c4d64 121static rtx expand_builtin_mempcpy_args (tree, tree, tree, rtx,
c2f47e15 122 enum machine_mode, int);
a65c4d64 123static rtx expand_builtin_strcpy (tree, rtx);
124static rtx expand_builtin_strcpy_args (tree, tree, rtx);
aecda0d6 125static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
a65c4d64 126static rtx expand_builtin_strncpy (tree, rtx);
aecda0d6 127static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
c2f47e15 128static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
129static rtx expand_builtin_memset_args (tree, tree, tree, rtx, enum machine_mode, tree);
aecda0d6 130static rtx expand_builtin_bzero (tree);
131static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
aecda0d6 132static rtx expand_builtin_alloca (tree, rtx);
133static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
134static rtx expand_builtin_frame_address (tree, tree);
19bf118a 135static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
136static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
6411575e 137static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
389dd41b 138static tree stabilize_va_list_loc (location_t, tree, int);
aecda0d6 139static rtx expand_builtin_expect (tree, rtx);
140static tree fold_builtin_constant_p (tree);
389dd41b 141static tree fold_builtin_expect (location_t, tree, tree);
aecda0d6 142static tree fold_builtin_classify_type (tree);
389dd41b 143static tree fold_builtin_strlen (location_t, tree);
144static tree fold_builtin_inf (location_t, tree, int);
aecda0d6 145static tree fold_builtin_nan (tree, tree, int);
389dd41b 146static tree rewrite_call_expr (location_t, tree, int, tree, int, ...);
b7bf20db 147static bool validate_arg (const_tree, enum tree_code code);
277f8dd2 148static bool integer_valued_real_p (tree);
389dd41b 149static tree fold_trunc_transparent_mathfn (location_t, tree, tree);
aecda0d6 150static bool readonly_data_expr (tree);
151static rtx expand_builtin_fabs (tree, rtx, rtx);
27f261ef 152static rtx expand_builtin_signbit (tree, rtx);
389dd41b 153static tree fold_builtin_sqrt (location_t, tree, tree);
154static tree fold_builtin_cbrt (location_t, tree, tree);
155static tree fold_builtin_pow (location_t, tree, tree, tree, tree);
156static tree fold_builtin_powi (location_t, tree, tree, tree, tree);
157static tree fold_builtin_cos (location_t, tree, tree, tree);
158static tree fold_builtin_cosh (location_t, tree, tree, tree);
bffb7645 159static tree fold_builtin_tan (tree, tree);
389dd41b 160static tree fold_builtin_trunc (location_t, tree, tree);
161static tree fold_builtin_floor (location_t, tree, tree);
162static tree fold_builtin_ceil (location_t, tree, tree);
163static tree fold_builtin_round (location_t, tree, tree);
164static tree fold_builtin_int_roundingfn (location_t, tree, tree);
10b9666f 165static tree fold_builtin_bitop (tree, tree);
389dd41b 166static tree fold_builtin_memory_op (location_t, tree, tree, tree, tree, bool, int);
167static tree fold_builtin_strchr (location_t, tree, tree, tree);
168static tree fold_builtin_memchr (location_t, tree, tree, tree, tree);
169static tree fold_builtin_memcmp (location_t, tree, tree, tree);
170static tree fold_builtin_strcmp (location_t, tree, tree);
171static tree fold_builtin_strncmp (location_t, tree, tree, tree);
172static tree fold_builtin_signbit (location_t, tree, tree);
173static tree fold_builtin_copysign (location_t, tree, tree, tree, tree);
174static tree fold_builtin_isascii (location_t, tree);
175static tree fold_builtin_toascii (location_t, tree);
176static tree fold_builtin_isdigit (location_t, tree);
177static tree fold_builtin_fabs (location_t, tree, tree);
178static tree fold_builtin_abs (location_t, tree, tree);
179static tree fold_builtin_unordered_cmp (location_t, tree, tree, tree, enum tree_code,
d5019fe8 180 enum tree_code);
389dd41b 181static tree fold_builtin_n (location_t, tree, tree *, int, bool);
182static tree fold_builtin_0 (location_t, tree, bool);
183static tree fold_builtin_1 (location_t, tree, tree, bool);
184static tree fold_builtin_2 (location_t, tree, tree, tree, bool);
185static tree fold_builtin_3 (location_t, tree, tree, tree, tree, bool);
186static tree fold_builtin_4 (location_t, tree, tree, tree, tree, tree, bool);
187static tree fold_builtin_varargs (location_t, tree, tree, bool);
188
189static tree fold_builtin_strpbrk (location_t, tree, tree, tree);
190static tree fold_builtin_strstr (location_t, tree, tree, tree);
191static tree fold_builtin_strrchr (location_t, tree, tree, tree);
192static tree fold_builtin_strcat (location_t, tree, tree);
193static tree fold_builtin_strncat (location_t, tree, tree, tree);
194static tree fold_builtin_strspn (location_t, tree, tree);
195static tree fold_builtin_strcspn (location_t, tree, tree);
196static tree fold_builtin_sprintf (location_t, tree, tree, tree, int);
4ee9c684 197
0a39fd54 198static rtx expand_builtin_object_size (tree);
199static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
200 enum built_in_function);
201static void maybe_emit_chk_warning (tree, enum built_in_function);
202static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
2c281b15 203static void maybe_emit_free_warning (tree);
c2f47e15 204static tree fold_builtin_object_size (tree, tree);
389dd41b 205static tree fold_builtin_strcat_chk (location_t, tree, tree, tree, tree);
206static tree fold_builtin_strncat_chk (location_t, tree, tree, tree, tree, tree);
207static tree fold_builtin_sprintf_chk (location_t, tree, enum built_in_function);
208static tree fold_builtin_printf (location_t, tree, tree, tree, bool, enum built_in_function);
209static tree fold_builtin_fprintf (location_t, tree, tree, tree, tree, bool,
c2f47e15 210 enum built_in_function);
99eabcc1 211static bool init_target_chars (void);
212
213static unsigned HOST_WIDE_INT target_newline;
214static unsigned HOST_WIDE_INT target_percent;
215static unsigned HOST_WIDE_INT target_c;
216static unsigned HOST_WIDE_INT target_s;
217static char target_percent_c[3];
218static char target_percent_s[3];
219static char target_percent_s_newline[4];
728bac60 220static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
221 const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool);
f0c477f2 222static tree do_mpfr_arg2 (tree, tree, tree,
223 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
9917422b 224static tree do_mpfr_arg3 (tree, tree, tree, tree,
225 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
d92f994c 226static tree do_mpfr_sincos (tree, tree, tree);
65dd1378 227static tree do_mpfr_bessel_n (tree, tree, tree,
228 int (*)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
229 const REAL_VALUE_TYPE *, bool);
e5407ca6 230static tree do_mpfr_remquo (tree, tree, tree);
e84da7c1 231static tree do_mpfr_lgamma_r (tree, tree, tree);
0a39fd54 232
1c47b3e8 233bool
234is_builtin_name (const char *name)
b6a5fc45 235{
b6a5fc45 236 if (strncmp (name, "__builtin_", 10) == 0)
237 return true;
238 if (strncmp (name, "__sync_", 7) == 0)
239 return true;
240 return false;
241}
4ee9c684 242
1c47b3e8 243/* Return true if NODE should be considered for inline expansion regardless
244 of the optimization level. This means whenever a function is invoked with
245 its "internal" name, which normally contains the prefix "__builtin". */
246
247static bool
248called_as_built_in (tree node)
249{
250 /* Note that we must use DECL_NAME, not DECL_ASSEMBLER_NAME_SET_P since
251 we want the name used to call the function, not the name it
252 will have. */
253 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
254 return is_builtin_name (name);
255}
256
698537d1 257/* Return the alignment in bits of EXP, an object.
258 Don't return more than MAX_ALIGN no matter what, ALIGN is the inital
259 guessed alignment e.g. from type alignment. */
260
261int
262get_object_alignment (tree exp, unsigned int align, unsigned int max_align)
263{
264 unsigned int inner;
265
266 inner = max_align;
267 if (handled_component_p (exp))
268 {
269 HOST_WIDE_INT bitsize, bitpos;
270 tree offset;
271 enum machine_mode mode;
272 int unsignedp, volatilep;
273
274 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
275 &mode, &unsignedp, &volatilep, true);
276 if (bitpos)
277 inner = MIN (inner, (unsigned) (bitpos & -bitpos));
278 while (offset)
279 {
280 tree next_offset;
281
282 if (TREE_CODE (offset) == PLUS_EXPR)
283 {
284 next_offset = TREE_OPERAND (offset, 0);
285 offset = TREE_OPERAND (offset, 1);
286 }
287 else
288 next_offset = NULL;
289 if (host_integerp (offset, 1))
290 {
291 /* Any overflow in calculating offset_bits won't change
292 the alignment. */
293 unsigned offset_bits
294 = ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT);
295
296 if (offset_bits)
297 inner = MIN (inner, (offset_bits & -offset_bits));
298 }
299 else if (TREE_CODE (offset) == MULT_EXPR
300 && host_integerp (TREE_OPERAND (offset, 1), 1))
301 {
302 /* Any overflow in calculating offset_factor won't change
303 the alignment. */
304 unsigned offset_factor
305 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
306 * BITS_PER_UNIT);
307
308 if (offset_factor)
309 inner = MIN (inner, (offset_factor & -offset_factor));
310 }
311 else
312 {
313 inner = MIN (inner, BITS_PER_UNIT);
314 break;
315 }
316 offset = next_offset;
317 }
318 }
319 if (DECL_P (exp))
320 align = MIN (inner, DECL_ALIGN (exp));
321#ifdef CONSTANT_ALIGNMENT
322 else if (CONSTANT_CLASS_P (exp))
323 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
324#endif
325 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
326 || TREE_CODE (exp) == INDIRECT_REF)
327 align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
328 else
329 align = MIN (align, inner);
330 return MIN (align, max_align);
331}
332
7abca321 333/* Returns true iff we can trust that alignment information has been
334 calculated properly. */
335
336bool
337can_trust_pointer_alignment (void)
338{
339 /* We rely on TER to compute accurate alignment information. */
340 return (optimize && flag_tree_ter);
341}
342
53800dbe 343/* Return the alignment in bits of EXP, a pointer valued expression.
344 But don't return more than MAX_ALIGN no matter what.
345 The alignment returned is, by default, the alignment of the thing that
27d0c333 346 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
53800dbe 347
348 Otherwise, look at the expression to see if we can do better, i.e., if the
349 expression is actually pointing at an object whose alignment is tighter. */
350
f656b751 351int
aecda0d6 352get_pointer_alignment (tree exp, unsigned int max_align)
53800dbe 353{
27d0c333 354 unsigned int align, inner;
53800dbe 355
7abca321 356 if (!can_trust_pointer_alignment ())
189575ff 357 return 0;
358
535e2026 359 if (!POINTER_TYPE_P (TREE_TYPE (exp)))
360 return 0;
361
53800dbe 362 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
363 align = MIN (align, max_align);
364
365 while (1)
366 {
367 switch (TREE_CODE (exp))
368 {
72dd6141 369 CASE_CONVERT:
53800dbe 370 exp = TREE_OPERAND (exp, 0);
552752f7 371 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
53800dbe 372 return align;
325d1c45 373
53800dbe 374 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
375 align = MIN (inner, max_align);
376 break;
377
0de36bdb 378 case POINTER_PLUS_EXPR:
53800dbe 379 /* If sum of pointer + int, restrict our maximum alignment to that
380 imposed by the integer. If not, we can't do any better than
381 ALIGN. */
325d1c45 382 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
53800dbe 383 return align;
384
0994d2ed 385 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
386 & (max_align / BITS_PER_UNIT - 1))
53800dbe 387 != 0)
388 max_align >>= 1;
389
390 exp = TREE_OPERAND (exp, 0);
391 break;
392
393 case ADDR_EXPR:
394 /* See what we are pointing at and look at its alignment. */
698537d1 395 return get_object_alignment (TREE_OPERAND (exp, 0), align, max_align);
53800dbe 396
397 default:
398 return align;
399 }
400 }
401}
402
403/* Compute the length of a C string. TREE_STRING_LENGTH is not the right
404 way, because it could contain a zero byte in the middle.
405 TREE_STRING_LENGTH is the size of the character array, not the string.
406
4172d65e 407 ONLY_VALUE should be nonzero if the result is not going to be emitted
c09841f6 408 into the instruction stream and zero if it is going to be expanded.
4172d65e 409 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
681fab1e 410 is returned, otherwise NULL, since
411 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
412 evaluate the side-effects.
413
902de8ed 414 The value returned is of type `ssizetype'.
415
53800dbe 416 Unfortunately, string_constant can't access the values of const char
417 arrays with initializers, so neither can we do so here. */
418
4ee9c684 419tree
681fab1e 420c_strlen (tree src, int only_value)
53800dbe 421{
422 tree offset_node;
27d0c333 423 HOST_WIDE_INT offset;
424 int max;
44acf429 425 const char *ptr;
53800dbe 426
681fab1e 427 STRIP_NOPS (src);
428 if (TREE_CODE (src) == COND_EXPR
429 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
430 {
431 tree len1, len2;
432
433 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
434 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
0862b7e9 435 if (tree_int_cst_equal (len1, len2))
681fab1e 436 return len1;
437 }
438
439 if (TREE_CODE (src) == COMPOUND_EXPR
440 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
441 return c_strlen (TREE_OPERAND (src, 1), only_value);
442
53800dbe 443 src = string_constant (src, &offset_node);
444 if (src == 0)
c2f47e15 445 return NULL_TREE;
902de8ed 446
83d79705 447 max = TREE_STRING_LENGTH (src) - 1;
53800dbe 448 ptr = TREE_STRING_POINTER (src);
902de8ed 449
53800dbe 450 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
451 {
452 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
453 compute the offset to the following null if we don't know where to
454 start searching for it. */
455 int i;
902de8ed 456
53800dbe 457 for (i = 0; i < max; i++)
458 if (ptr[i] == 0)
c2f47e15 459 return NULL_TREE;
902de8ed 460
53800dbe 461 /* We don't know the starting offset, but we do know that the string
462 has no internal zero bytes. We can assume that the offset falls
463 within the bounds of the string; otherwise, the programmer deserves
464 what he gets. Subtract the offset from the length of the string,
902de8ed 465 and return that. This would perhaps not be valid if we were dealing
466 with named arrays in addition to literal string constants. */
467
389dd41b 468 return size_diffop_loc (input_location, size_int (max), offset_node);
53800dbe 469 }
470
471 /* We have a known offset into the string. Start searching there for
27d0c333 472 a null character if we can represent it as a single HOST_WIDE_INT. */
dabc4084 473 if (offset_node == 0)
53800dbe 474 offset = 0;
dabc4084 475 else if (! host_integerp (offset_node, 0))
476 offset = -1;
53800dbe 477 else
27d0c333 478 offset = tree_low_cst (offset_node, 0);
902de8ed 479
1f63a7d6 480 /* If the offset is known to be out of bounds, warn, and call strlen at
481 runtime. */
53800dbe 482 if (offset < 0 || offset > max)
483 {
1f63a7d6 484 /* Suppress multiple warnings for propagated constant strings. */
485 if (! TREE_NO_WARNING (src))
486 {
487 warning (0, "offset outside bounds of constant string");
488 TREE_NO_WARNING (src) = 1;
489 }
c2f47e15 490 return NULL_TREE;
53800dbe 491 }
902de8ed 492
53800dbe 493 /* Use strlen to search for the first zero byte. Since any strings
494 constructed with build_string will have nulls appended, we win even
495 if we get handed something like (char[4])"abcd".
496
497 Since OFFSET is our starting index into the string, no further
498 calculation is needed. */
902de8ed 499 return ssize_int (strlen (ptr + offset));
53800dbe 500}
501
83d79705 502/* Return a char pointer for a C string if it is a string constant
503 or sum of string constant and integer constant. */
504
505static const char *
aecda0d6 506c_getstr (tree src)
83d79705 507{
508 tree offset_node;
83d79705 509
510 src = string_constant (src, &offset_node);
511 if (src == 0)
512 return 0;
513
8c85fcb7 514 if (offset_node == 0)
515 return TREE_STRING_POINTER (src);
516 else if (!host_integerp (offset_node, 1)
517 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
83d79705 518 return 0;
83d79705 519
8c85fcb7 520 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
83d79705 521}
522
8c85fcb7 523/* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
524 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
ecc318ff 525
6840589f 526static rtx
aecda0d6 527c_readstr (const char *str, enum machine_mode mode)
6840589f 528{
529 HOST_WIDE_INT c[2];
530 HOST_WIDE_INT ch;
531 unsigned int i, j;
532
64db345d 533 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
7d3f6cc7 534
6840589f 535 c[0] = 0;
536 c[1] = 0;
537 ch = 1;
538 for (i = 0; i < GET_MODE_SIZE (mode); i++)
539 {
540 j = i;
541 if (WORDS_BIG_ENDIAN)
542 j = GET_MODE_SIZE (mode) - i - 1;
543 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
544 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
545 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
546 j *= BITS_PER_UNIT;
64db345d 547 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
7d3f6cc7 548
6840589f 549 if (ch)
550 ch = (unsigned char) str[i];
551 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
552 }
553 return immed_double_const (c[0], c[1], mode);
554}
555
ecc318ff 556/* Cast a target constant CST to target CHAR and if that value fits into
5206b159 557 host char type, return zero and put that value into variable pointed to by
ecc318ff 558 P. */
559
560static int
aecda0d6 561target_char_cast (tree cst, char *p)
ecc318ff 562{
563 unsigned HOST_WIDE_INT val, hostval;
564
27d0c333 565 if (!host_integerp (cst, 1)
ecc318ff 566 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
567 return 1;
568
27d0c333 569 val = tree_low_cst (cst, 1);
ecc318ff 570 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
571 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
572
573 hostval = val;
574 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
575 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
576
577 if (val != hostval)
578 return 1;
579
580 *p = hostval;
581 return 0;
582}
583
4ee9c684 584/* Similar to save_expr, but assumes that arbitrary code is not executed
585 in between the multiple evaluations. In particular, we assume that a
586 non-addressable local variable will not be modified. */
587
588static tree
589builtin_save_expr (tree exp)
590{
591 if (TREE_ADDRESSABLE (exp) == 0
592 && (TREE_CODE (exp) == PARM_DECL
593 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
594 return exp;
595
596 return save_expr (exp);
597}
598
53800dbe 599/* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
600 times to get the address of either a higher stack frame, or a return
601 address located within it (depending on FNDECL_CODE). */
902de8ed 602
c626df3d 603static rtx
869d0ef0 604expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
53800dbe 605{
606 int i;
607
869d0ef0 608#ifdef INITIAL_FRAME_ADDRESS_RTX
609 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
610#else
e3e15c50 611 rtx tem;
612
1b74fde7 613 /* For a zero count with __builtin_return_address, we don't care what
614 frame address we return, because target-specific definitions will
615 override us. Therefore frame pointer elimination is OK, and using
616 the soft frame pointer is OK.
617
fa7637bd 618 For a nonzero count, or a zero count with __builtin_frame_address,
1b74fde7 619 we require a stable offset from the current frame pointer to the
620 previous one, so we must use the hard frame pointer, and
e3e15c50 621 we must disable frame pointer elimination. */
1b74fde7 622 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
e3e15c50 623 tem = frame_pointer_rtx;
a0c938f0 624 else
e3e15c50 625 {
626 tem = hard_frame_pointer_rtx;
627
628 /* Tell reload not to eliminate the frame pointer. */
18d50ae6 629 crtl->accesses_prior_frames = 1;
e3e15c50 630 }
869d0ef0 631#endif
632
53800dbe 633 /* Some machines need special handling before we can access
3a69c60c 634 arbitrary frames. For example, on the SPARC, we must first flush
53800dbe 635 all register windows to the stack. */
636#ifdef SETUP_FRAME_ADDRESSES
637 if (count > 0)
638 SETUP_FRAME_ADDRESSES ();
639#endif
640
3a69c60c 641 /* On the SPARC, the return address is not in the frame, it is in a
53800dbe 642 register. There is no way to access it off of the current frame
643 pointer, but it can be accessed off the previous frame pointer by
644 reading the value from the register window save area. */
645#ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
646 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
647 count--;
648#endif
649
650 /* Scan back COUNT frames to the specified frame. */
651 for (i = 0; i < count; i++)
652 {
653 /* Assume the dynamic chain pointer is in the word that the
654 frame address points to, unless otherwise specified. */
655#ifdef DYNAMIC_CHAIN_ADDRESS
656 tem = DYNAMIC_CHAIN_ADDRESS (tem);
657#endif
658 tem = memory_address (Pmode, tem);
00060fc2 659 tem = gen_frame_mem (Pmode, tem);
83fc1478 660 tem = copy_to_reg (tem);
53800dbe 661 }
662
3a69c60c 663 /* For __builtin_frame_address, return what we've got. But, on
664 the SPARC for example, we may have to add a bias. */
53800dbe 665 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
3a69c60c 666#ifdef FRAME_ADDR_RTX
667 return FRAME_ADDR_RTX (tem);
668#else
53800dbe 669 return tem;
3a69c60c 670#endif
53800dbe 671
3a69c60c 672 /* For __builtin_return_address, get the return address from that frame. */
53800dbe 673#ifdef RETURN_ADDR_RTX
674 tem = RETURN_ADDR_RTX (count, tem);
675#else
676 tem = memory_address (Pmode,
677 plus_constant (tem, GET_MODE_SIZE (Pmode)));
00060fc2 678 tem = gen_frame_mem (Pmode, tem);
53800dbe 679#endif
680 return tem;
681}
682
f7c44134 683/* Alias set used for setjmp buffer. */
32c2fdea 684static alias_set_type setjmp_alias_set = -1;
f7c44134 685
6b7f6858 686/* Construct the leading half of a __builtin_setjmp call. Control will
2c8a1497 687 return to RECEIVER_LABEL. This is also called directly by the SJLJ
688 exception handling code. */
53800dbe 689
6b7f6858 690void
aecda0d6 691expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
53800dbe 692{
53800dbe 693 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
53800dbe 694 rtx stack_save;
f7c44134 695 rtx mem;
53800dbe 696
f7c44134 697 if (setjmp_alias_set == -1)
698 setjmp_alias_set = new_alias_set ();
699
85d654dd 700 buf_addr = convert_memory_address (Pmode, buf_addr);
53800dbe 701
37ae8504 702 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
53800dbe 703
6b7f6858 704 /* We store the frame pointer and the address of receiver_label in
705 the buffer and use the rest of it for the stack save area, which
706 is machine-dependent. */
53800dbe 707
f7c44134 708 mem = gen_rtx_MEM (Pmode, buf_addr);
ab6ab77e 709 set_mem_alias_set (mem, setjmp_alias_set);
e3e026e8 710 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
f7c44134 711
712 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
ab6ab77e 713 set_mem_alias_set (mem, setjmp_alias_set);
f7c44134 714
715 emit_move_insn (validize_mem (mem),
6b7f6858 716 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
53800dbe 717
718 stack_save = gen_rtx_MEM (sa_mode,
719 plus_constant (buf_addr,
720 2 * GET_MODE_SIZE (Pmode)));
ab6ab77e 721 set_mem_alias_set (stack_save, setjmp_alias_set);
53800dbe 722 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
723
724 /* If there is further processing to do, do it. */
725#ifdef HAVE_builtin_setjmp_setup
726 if (HAVE_builtin_setjmp_setup)
727 emit_insn (gen_builtin_setjmp_setup (buf_addr));
728#endif
729
6b7f6858 730 /* Tell optimize_save_area_alloca that extra work is going to
731 need to go on during alloca. */
18d50ae6 732 cfun->calls_setjmp = 1;
80ab81b9 733
29f09705 734 /* We have a nonlocal label. */
18d50ae6 735 cfun->has_nonlocal_label = 1;
6b7f6858 736}
53800dbe 737
2c8a1497 738/* Construct the trailing part of a __builtin_setjmp call. This is
739 also called directly by the SJLJ exception handling code. */
6b7f6858 740
741void
aecda0d6 742expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
6b7f6858 743{
82c7907c 744 rtx chain;
745
53800dbe 746 /* Clobber the FP when we get here, so we have to make sure it's
747 marked as used by this function. */
18b42941 748 emit_use (hard_frame_pointer_rtx);
53800dbe 749
750 /* Mark the static chain as clobbered here so life information
751 doesn't get messed up for it. */
82c7907c 752 chain = targetm.calls.static_chain (current_function_decl, true);
753 if (chain && REG_P (chain))
754 emit_clobber (chain);
53800dbe 755
756 /* Now put in the code to restore the frame pointer, and argument
491e04ef 757 pointer, if needed. */
53800dbe 758#ifdef HAVE_nonlocal_goto
759 if (! HAVE_nonlocal_goto)
760#endif
5a1c3f40 761 {
762 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
763 /* This might change the hard frame pointer in ways that aren't
764 apparent to early optimization passes, so force a clobber. */
18b42941 765 emit_clobber (hard_frame_pointer_rtx);
5a1c3f40 766 }
53800dbe 767
768#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
769 if (fixed_regs[ARG_POINTER_REGNUM])
770 {
771#ifdef ELIMINABLE_REGS
772 size_t i;
e99c3a1d 773 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
53800dbe 774
3098b2d3 775 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
53800dbe 776 if (elim_regs[i].from == ARG_POINTER_REGNUM
777 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
778 break;
779
3098b2d3 780 if (i == ARRAY_SIZE (elim_regs))
53800dbe 781#endif
782 {
783 /* Now restore our arg pointer from the address at which it
05927e40 784 was saved in our stack frame. */
27a7a23a 785 emit_move_insn (crtl->args.internal_arg_pointer,
b079a207 786 copy_to_reg (get_arg_pointer_save_area ()));
53800dbe 787 }
788 }
789#endif
790
791#ifdef HAVE_builtin_setjmp_receiver
792 if (HAVE_builtin_setjmp_receiver)
6b7f6858 793 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
53800dbe 794 else
795#endif
796#ifdef HAVE_nonlocal_goto_receiver
797 if (HAVE_nonlocal_goto_receiver)
798 emit_insn (gen_nonlocal_goto_receiver ());
799 else
800#endif
6b7f6858 801 { /* Nothing */ }
57f6bb94 802
3072d30e 803 /* We must not allow the code we just generated to be reordered by
804 scheduling. Specifically, the update of the frame pointer must
805 happen immediately, not later. */
806 emit_insn (gen_blockage ());
6b7f6858 807}
53800dbe 808
53800dbe 809/* __builtin_longjmp is passed a pointer to an array of five words (not
810 all will be used on all machines). It operates similarly to the C
811 library function of the same name, but is more efficient. Much of
2c8a1497 812 the code below is copied from the handling of non-local gotos. */
53800dbe 813
c626df3d 814static void
aecda0d6 815expand_builtin_longjmp (rtx buf_addr, rtx value)
53800dbe 816{
4712c7d6 817 rtx fp, lab, stack, insn, last;
53800dbe 818 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
819
27a7a23a 820 /* DRAP is needed for stack realign if longjmp is expanded to current
821 function */
822 if (SUPPORTS_STACK_ALIGNMENT)
823 crtl->need_drap = true;
824
f7c44134 825 if (setjmp_alias_set == -1)
826 setjmp_alias_set = new_alias_set ();
827
85d654dd 828 buf_addr = convert_memory_address (Pmode, buf_addr);
479e4d5e 829
53800dbe 830 buf_addr = force_reg (Pmode, buf_addr);
831
82c7907c 832 /* We require that the user must pass a second argument of 1, because
833 that is what builtin_setjmp will return. */
64db345d 834 gcc_assert (value == const1_rtx);
53800dbe 835
4712c7d6 836 last = get_last_insn ();
53800dbe 837#ifdef HAVE_builtin_longjmp
838 if (HAVE_builtin_longjmp)
839 emit_insn (gen_builtin_longjmp (buf_addr));
840 else
841#endif
842 {
843 fp = gen_rtx_MEM (Pmode, buf_addr);
844 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
845 GET_MODE_SIZE (Pmode)));
846
847 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
848 2 * GET_MODE_SIZE (Pmode)));
ab6ab77e 849 set_mem_alias_set (fp, setjmp_alias_set);
850 set_mem_alias_set (lab, setjmp_alias_set);
851 set_mem_alias_set (stack, setjmp_alias_set);
53800dbe 852
853 /* Pick up FP, label, and SP from the block and jump. This code is
854 from expand_goto in stmt.c; see there for detailed comments. */
03fd9d2c 855#ifdef HAVE_nonlocal_goto
53800dbe 856 if (HAVE_nonlocal_goto)
857 /* We have to pass a value to the nonlocal_goto pattern that will
858 get copied into the static_chain pointer, but it does not matter
859 what that value is, because builtin_setjmp does not use it. */
28d202a8 860 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
53800dbe 861 else
862#endif
863 {
864 lab = copy_to_reg (lab);
865
18b42941 866 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
867 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
2a871ad1 868
53800dbe 869 emit_move_insn (hard_frame_pointer_rtx, fp);
870 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
871
18b42941 872 emit_use (hard_frame_pointer_rtx);
873 emit_use (stack_pointer_rtx);
53800dbe 874 emit_indirect_jump (lab);
875 }
876 }
615166bb 877
878 /* Search backwards and mark the jump insn as a non-local goto.
879 Note that this precludes the use of __builtin_longjmp to a
880 __builtin_setjmp target in the same function. However, we've
881 already cautioned the user that these functions are for
882 internal exception handling use only. */
449c0509 883 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
884 {
64db345d 885 gcc_assert (insn != last);
7d3f6cc7 886
6d7dc5b9 887 if (JUMP_P (insn))
449c0509 888 {
a1ddb869 889 add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
449c0509 890 break;
891 }
6d7dc5b9 892 else if (CALL_P (insn))
9342ee68 893 break;
449c0509 894 }
53800dbe 895}
896
4ee9c684 897/* Expand a call to __builtin_nonlocal_goto. We're passed the target label
898 and the address of the save area. */
899
900static rtx
c2f47e15 901expand_builtin_nonlocal_goto (tree exp)
4ee9c684 902{
903 tree t_label, t_save_area;
904 rtx r_label, r_save_area, r_fp, r_sp, insn;
905
c2f47e15 906 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4ee9c684 907 return NULL_RTX;
908
c2f47e15 909 t_label = CALL_EXPR_ARG (exp, 0);
910 t_save_area = CALL_EXPR_ARG (exp, 1);
4ee9c684 911
8ec3c5c2 912 r_label = expand_normal (t_label);
3dce56cc 913 r_label = convert_memory_address (Pmode, r_label);
8ec3c5c2 914 r_save_area = expand_normal (t_save_area);
3dce56cc 915 r_save_area = convert_memory_address (Pmode, r_save_area);
51adbc8a 916 /* Copy the address of the save location to a register just in case it was based
917 on the frame pointer. */
918 r_save_area = copy_to_reg (r_save_area);
4ee9c684 919 r_fp = gen_rtx_MEM (Pmode, r_save_area);
920 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
921 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
922
18d50ae6 923 crtl->has_nonlocal_goto = 1;
4ee9c684 924
03fd9d2c 925#ifdef HAVE_nonlocal_goto
4ee9c684 926 /* ??? We no longer need to pass the static chain value, afaik. */
927 if (HAVE_nonlocal_goto)
928 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
929 else
930#endif
931 {
932 r_label = copy_to_reg (r_label);
933
18b42941 934 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
935 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
491e04ef 936
4ee9c684 937 /* Restore frame pointer for containing function.
938 This sets the actual hard register used for the frame pointer
939 to the location of the function's incoming static chain info.
940 The non-local goto handler will then adjust it to contain the
941 proper value and reload the argument pointer, if needed. */
942 emit_move_insn (hard_frame_pointer_rtx, r_fp);
943 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
491e04ef 944
4ee9c684 945 /* USE of hard_frame_pointer_rtx added for consistency;
946 not clear if really needed. */
18b42941 947 emit_use (hard_frame_pointer_rtx);
948 emit_use (stack_pointer_rtx);
ad0d0af8 949
950 /* If the architecture is using a GP register, we must
951 conservatively assume that the target function makes use of it.
952 The prologue of functions with nonlocal gotos must therefore
953 initialize the GP register to the appropriate value, and we
954 must then make sure that this value is live at the point
955 of the jump. (Note that this doesn't necessarily apply
956 to targets with a nonlocal_goto pattern; they are free
957 to implement it in their own way. Note also that this is
958 a no-op if the GP register is a global invariant.) */
959 if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
960 && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
18b42941 961 emit_use (pic_offset_table_rtx);
ad0d0af8 962
4ee9c684 963 emit_indirect_jump (r_label);
964 }
491e04ef 965
4ee9c684 966 /* Search backwards to the jump insn and mark it as a
967 non-local goto. */
968 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
969 {
6d7dc5b9 970 if (JUMP_P (insn))
4ee9c684 971 {
a1ddb869 972 add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
4ee9c684 973 break;
974 }
6d7dc5b9 975 else if (CALL_P (insn))
4ee9c684 976 break;
977 }
978
979 return const0_rtx;
980}
981
843d08a9 982/* __builtin_update_setjmp_buf is passed a pointer to an array of five words
983 (not all will be used on all machines) that was passed to __builtin_setjmp.
984 It updates the stack pointer in that block to correspond to the current
985 stack pointer. */
986
987static void
988expand_builtin_update_setjmp_buf (rtx buf_addr)
989{
990 enum machine_mode sa_mode = Pmode;
991 rtx stack_save;
992
993
994#ifdef HAVE_save_stack_nonlocal
995 if (HAVE_save_stack_nonlocal)
996 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
997#endif
998#ifdef STACK_SAVEAREA_MODE
999 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
1000#endif
1001
1002 stack_save
1003 = gen_rtx_MEM (sa_mode,
1004 memory_address
1005 (sa_mode,
1006 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
1007
1008#ifdef HAVE_setjmp
1009 if (HAVE_setjmp)
1010 emit_insn (gen_setjmp ());
1011#endif
1012
1013 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
1014}
1015
5e3608d8 1016/* Expand a call to __builtin_prefetch. For a target that does not support
1017 data prefetch, evaluate the memory address argument in case it has side
1018 effects. */
1019
1020static void
c2f47e15 1021expand_builtin_prefetch (tree exp)
5e3608d8 1022{
1023 tree arg0, arg1, arg2;
c2f47e15 1024 int nargs;
5e3608d8 1025 rtx op0, op1, op2;
1026
c2f47e15 1027 if (!validate_arglist (exp, POINTER_TYPE, 0))
26a5cadb 1028 return;
1029
c2f47e15 1030 arg0 = CALL_EXPR_ARG (exp, 0);
1031
26a5cadb 1032 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
1033 zero (read) and argument 2 (locality) defaults to 3 (high degree of
1034 locality). */
c2f47e15 1035 nargs = call_expr_nargs (exp);
1036 if (nargs > 1)
1037 arg1 = CALL_EXPR_ARG (exp, 1);
26a5cadb 1038 else
c2f47e15 1039 arg1 = integer_zero_node;
1040 if (nargs > 2)
1041 arg2 = CALL_EXPR_ARG (exp, 2);
1042 else
1043 arg2 = build_int_cst (NULL_TREE, 3);
5e3608d8 1044
1045 /* Argument 0 is an address. */
1046 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
1047
1048 /* Argument 1 (read/write flag) must be a compile-time constant int. */
1049 if (TREE_CODE (arg1) != INTEGER_CST)
1050 {
07e3a3d2 1051 error ("second argument to %<__builtin_prefetch%> must be a constant");
9342ee68 1052 arg1 = integer_zero_node;
5e3608d8 1053 }
8ec3c5c2 1054 op1 = expand_normal (arg1);
5e3608d8 1055 /* Argument 1 must be either zero or one. */
1056 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
1057 {
c3ceba8e 1058 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
07e3a3d2 1059 " using zero");
5e3608d8 1060 op1 = const0_rtx;
1061 }
1062
1063 /* Argument 2 (locality) must be a compile-time constant int. */
1064 if (TREE_CODE (arg2) != INTEGER_CST)
1065 {
07e3a3d2 1066 error ("third argument to %<__builtin_prefetch%> must be a constant");
5e3608d8 1067 arg2 = integer_zero_node;
1068 }
8ec3c5c2 1069 op2 = expand_normal (arg2);
5e3608d8 1070 /* Argument 2 must be 0, 1, 2, or 3. */
1071 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1072 {
c3ceba8e 1073 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
5e3608d8 1074 op2 = const0_rtx;
1075 }
1076
1077#ifdef HAVE_prefetch
1078 if (HAVE_prefetch)
1079 {
f0ce3b1f 1080 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
4cd21437 1081 (op0,
f0ce3b1f 1082 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
19bf118a 1083 || (GET_MODE (op0) != Pmode))
9342ee68 1084 {
85d654dd 1085 op0 = convert_memory_address (Pmode, op0);
9342ee68 1086 op0 = force_reg (Pmode, op0);
1087 }
5e3608d8 1088 emit_insn (gen_prefetch (op0, op1, op2));
1089 }
5e3608d8 1090#endif
0a534ba7 1091
f0ce3b1f 1092 /* Don't do anything with direct references to volatile memory, but
1093 generate code to handle other side effects. */
e16ceb8e 1094 if (!MEM_P (op0) && side_effects_p (op0))
f0ce3b1f 1095 emit_insn (op0);
5e3608d8 1096}
1097
f7c44134 1098/* Get a MEM rtx for expression EXP which is the address of an operand
d8ae1baa 1099 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1100 the maximum length of the block of memory that might be accessed or
1101 NULL if unknown. */
f7c44134 1102
53800dbe 1103static rtx
d8ae1baa 1104get_memory_rtx (tree exp, tree len)
53800dbe 1105{
ad0a178f 1106 tree orig_exp = exp;
1107 rtx addr, mem;
1108 HOST_WIDE_INT off;
1109
1110 /* When EXP is not resolved SAVE_EXPR, MEM_ATTRS can be still derived
1111 from its expression, for expr->a.b only <variable>.a.b is recorded. */
1112 if (TREE_CODE (exp) == SAVE_EXPR && !SAVE_EXPR_RESOLVED_P (exp))
1113 exp = TREE_OPERAND (exp, 0);
1114
1115 addr = expand_expr (orig_exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1116 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
2a631e19 1117
f7c44134 1118 /* Get an expression we can use to find the attributes to assign to MEM.
1119 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1120 we can. First remove any nops. */
72dd6141 1121 while (CONVERT_EXPR_P (exp)
f7c44134 1122 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1123 exp = TREE_OPERAND (exp, 0);
1124
ad0a178f 1125 off = 0;
1126 if (TREE_CODE (exp) == POINTER_PLUS_EXPR
1127 && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
1128 && host_integerp (TREE_OPERAND (exp, 1), 0)
1129 && (off = tree_low_cst (TREE_OPERAND (exp, 1), 0)) > 0)
1130 exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1131 else if (TREE_CODE (exp) == ADDR_EXPR)
a1a25d19 1132 exp = TREE_OPERAND (exp, 0);
f7c44134 1133 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
a1a25d19 1134 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1135 else
1136 exp = NULL;
1137
1138 /* Honor attributes derived from exp, except for the alias set
1139 (as builtin stringops may alias with anything) and the size
1140 (as stringops may access multiple array elements). */
1141 if (exp)
eec8e941 1142 {
a1a25d19 1143 set_mem_attributes (mem, exp, 0);
d8ae1baa 1144
ad0a178f 1145 if (off)
1146 mem = adjust_automodify_address_nv (mem, BLKmode, NULL, off);
1147
d8ae1baa 1148 /* Allow the string and memory builtins to overflow from one
1149 field into another, see http://gcc.gnu.org/PR23561.
1150 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1151 memory accessed by the string or memory builtin will fit
1152 within the field. */
1153 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1154 {
1155 tree mem_expr = MEM_EXPR (mem);
1156 HOST_WIDE_INT offset = -1, length = -1;
1157 tree inner = exp;
1158
1159 while (TREE_CODE (inner) == ARRAY_REF
72dd6141 1160 || CONVERT_EXPR_P (inner)
d8ae1baa 1161 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1162 || TREE_CODE (inner) == SAVE_EXPR)
1163 inner = TREE_OPERAND (inner, 0);
1164
1165 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1166
1167 if (MEM_OFFSET (mem)
971ba038 1168 && CONST_INT_P (MEM_OFFSET (mem)))
d8ae1baa 1169 offset = INTVAL (MEM_OFFSET (mem));
1170
1171 if (offset >= 0 && len && host_integerp (len, 0))
1172 length = tree_low_cst (len, 0);
1173
1174 while (TREE_CODE (inner) == COMPONENT_REF)
1175 {
1176 tree field = TREE_OPERAND (inner, 1);
d8ae1baa 1177 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1178 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1179
6933ebec 1180 /* Bitfields are generally not byte-addressable. */
1181 gcc_assert (!DECL_BIT_FIELD (field)
1182 || ((tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1183 % BITS_PER_UNIT) == 0
1184 && host_integerp (DECL_SIZE (field), 0)
1185 && (TREE_INT_CST_LOW (DECL_SIZE (field))
1186 % BITS_PER_UNIT) == 0));
1187
b2f0b2a3 1188 /* If we can prove that the memory starting at XEXP (mem, 0) and
1189 ending at XEXP (mem, 0) + LENGTH will fit into this field, we
1190 can keep the COMPONENT_REF in MEM_EXPR. But be careful with
1191 fields without DECL_SIZE_UNIT like flexible array members. */
d8ae1baa 1192 if (length >= 0
b2f0b2a3 1193 && DECL_SIZE_UNIT (field)
6933ebec 1194 && host_integerp (DECL_SIZE_UNIT (field), 0))
d8ae1baa 1195 {
1196 HOST_WIDE_INT size
6933ebec 1197 = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field));
d8ae1baa 1198 if (offset <= size
1199 && length <= size
1200 && offset + length <= size)
1201 break;
1202 }
1203
1204 if (offset >= 0
1205 && host_integerp (DECL_FIELD_OFFSET (field), 0))
6933ebec 1206 offset += TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field))
d8ae1baa 1207 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1208 / BITS_PER_UNIT;
1209 else
1210 {
1211 offset = -1;
1212 length = -1;
1213 }
1214
1215 mem_expr = TREE_OPERAND (mem_expr, 0);
1216 inner = TREE_OPERAND (inner, 0);
d8ae1baa 1217 }
1218
1219 if (mem_expr == NULL)
1220 offset = -1;
1221 if (mem_expr != MEM_EXPR (mem))
1222 {
1223 set_mem_expr (mem, mem_expr);
1224 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1225 }
1226 }
eec8e941 1227 set_mem_alias_set (mem, 0);
a1a25d19 1228 set_mem_size (mem, NULL_RTX);
eec8e941 1229 }
53800dbe 1230
53800dbe 1231 return mem;
1232}
1233\f
1234/* Built-in functions to perform an untyped call and return. */
1235
1236/* For each register that may be used for calling a function, this
1237 gives a mode used to copy the register's value. VOIDmode indicates
1238 the register is not used for calling a function. If the machine
1239 has register windows, this gives only the outbound registers.
1240 INCOMING_REGNO gives the corresponding inbound register. */
1241static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1242
1243/* For each register that may be used for returning values, this gives
1244 a mode used to copy the register's value. VOIDmode indicates the
1245 register is not used for returning values. If the machine has
1246 register windows, this gives only the outbound registers.
1247 INCOMING_REGNO gives the corresponding inbound register. */
1248static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1249
1250/* For each register that may be used for calling a function, this
1251 gives the offset of that register into the block returned by
1252 __builtin_apply_args. 0 indicates that the register is not
1253 used for calling a function. */
1254static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1255
53800dbe 1256/* Return the size required for the block returned by __builtin_apply_args,
1257 and initialize apply_args_mode. */
1258
1259static int
aecda0d6 1260apply_args_size (void)
53800dbe 1261{
1262 static int size = -1;
58e9ce8f 1263 int align;
1264 unsigned int regno;
53800dbe 1265 enum machine_mode mode;
1266
1267 /* The values computed by this function never change. */
1268 if (size < 0)
1269 {
1270 /* The first value is the incoming arg-pointer. */
1271 size = GET_MODE_SIZE (Pmode);
1272
1273 /* The second value is the structure value address unless this is
1274 passed as an "invisible" first argument. */
6812c89e 1275 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
53800dbe 1276 size += GET_MODE_SIZE (Pmode);
1277
1278 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1279 if (FUNCTION_ARG_REGNO_P (regno))
1280 {
0862b7e9 1281 mode = reg_raw_mode[regno];
1282
64db345d 1283 gcc_assert (mode != VOIDmode);
53800dbe 1284
1285 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1286 if (size % align != 0)
1287 size = CEIL (size, align) * align;
1288 apply_args_reg_offset[regno] = size;
1289 size += GET_MODE_SIZE (mode);
1290 apply_args_mode[regno] = mode;
1291 }
1292 else
1293 {
1294 apply_args_mode[regno] = VOIDmode;
1295 apply_args_reg_offset[regno] = 0;
1296 }
1297 }
1298 return size;
1299}
1300
1301/* Return the size required for the block returned by __builtin_apply,
1302 and initialize apply_result_mode. */
1303
1304static int
aecda0d6 1305apply_result_size (void)
53800dbe 1306{
1307 static int size = -1;
1308 int align, regno;
1309 enum machine_mode mode;
1310
1311 /* The values computed by this function never change. */
1312 if (size < 0)
1313 {
1314 size = 0;
1315
1316 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1317 if (FUNCTION_VALUE_REGNO_P (regno))
1318 {
0862b7e9 1319 mode = reg_raw_mode[regno];
1320
64db345d 1321 gcc_assert (mode != VOIDmode);
53800dbe 1322
1323 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1324 if (size % align != 0)
1325 size = CEIL (size, align) * align;
1326 size += GET_MODE_SIZE (mode);
1327 apply_result_mode[regno] = mode;
1328 }
1329 else
1330 apply_result_mode[regno] = VOIDmode;
1331
1332 /* Allow targets that use untyped_call and untyped_return to override
1333 the size so that machine-specific information can be stored here. */
1334#ifdef APPLY_RESULT_SIZE
1335 size = APPLY_RESULT_SIZE;
1336#endif
1337 }
1338 return size;
1339}
1340
1341#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1342/* Create a vector describing the result block RESULT. If SAVEP is true,
1343 the result block is used to save the values; otherwise it is used to
1344 restore the values. */
1345
1346static rtx
aecda0d6 1347result_vector (int savep, rtx result)
53800dbe 1348{
1349 int regno, size, align, nelts;
1350 enum machine_mode mode;
1351 rtx reg, mem;
364c0c59 1352 rtx *savevec = XALLOCAVEC (rtx, FIRST_PSEUDO_REGISTER);
bf8e3599 1353
53800dbe 1354 size = nelts = 0;
1355 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1356 if ((mode = apply_result_mode[regno]) != VOIDmode)
1357 {
1358 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1359 if (size % align != 0)
1360 size = CEIL (size, align) * align;
1361 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
e513d163 1362 mem = adjust_address (result, mode, size);
53800dbe 1363 savevec[nelts++] = (savep
1364 ? gen_rtx_SET (VOIDmode, mem, reg)
1365 : gen_rtx_SET (VOIDmode, reg, mem));
1366 size += GET_MODE_SIZE (mode);
1367 }
1368 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1369}
1370#endif /* HAVE_untyped_call or HAVE_untyped_return */
1371
1372/* Save the state required to perform an untyped call with the same
1373 arguments as were passed to the current function. */
1374
1375static rtx
aecda0d6 1376expand_builtin_apply_args_1 (void)
53800dbe 1377{
1c7e61a7 1378 rtx registers, tem;
53800dbe 1379 int size, align, regno;
1380 enum machine_mode mode;
6812c89e 1381 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
53800dbe 1382
1383 /* Create a block where the arg-pointer, structure value address,
1384 and argument registers can be saved. */
1385 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1386
1387 /* Walk past the arg-pointer and structure value address. */
1388 size = GET_MODE_SIZE (Pmode);
6812c89e 1389 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
53800dbe 1390 size += GET_MODE_SIZE (Pmode);
1391
1392 /* Save each register used in calling a function to the block. */
1393 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1394 if ((mode = apply_args_mode[regno]) != VOIDmode)
1395 {
53800dbe 1396 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1397 if (size % align != 0)
1398 size = CEIL (size, align) * align;
1399
1400 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1401
e513d163 1402 emit_move_insn (adjust_address (registers, mode, size), tem);
53800dbe 1403 size += GET_MODE_SIZE (mode);
1404 }
1405
1406 /* Save the arg pointer to the block. */
27a7a23a 1407 tem = copy_to_reg (crtl->args.internal_arg_pointer);
f083a92b 1408#ifdef STACK_GROWS_DOWNWARD
1c7e61a7 1409 /* We need the pointer as the caller actually passed them to us, not
9d4b544c 1410 as we might have pretended they were passed. Make sure it's a valid
1411 operand, as emit_move_insn isn't expected to handle a PLUS. */
1412 tem
abe32cce 1413 = force_operand (plus_constant (tem, crtl->args.pretend_args_size),
9d4b544c 1414 NULL_RTX);
1c7e61a7 1415#endif
1416 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
0862b7e9 1417
53800dbe 1418 size = GET_MODE_SIZE (Pmode);
1419
1420 /* Save the structure value address unless this is passed as an
1421 "invisible" first argument. */
45550790 1422 if (struct_incoming_value)
53800dbe 1423 {
e513d163 1424 emit_move_insn (adjust_address (registers, Pmode, size),
45550790 1425 copy_to_reg (struct_incoming_value));
53800dbe 1426 size += GET_MODE_SIZE (Pmode);
1427 }
1428
1429 /* Return the address of the block. */
1430 return copy_addr_to_reg (XEXP (registers, 0));
1431}
1432
1433/* __builtin_apply_args returns block of memory allocated on
1434 the stack into which is stored the arg pointer, structure
1435 value address, static chain, and all the registers that might
1436 possibly be used in performing a function call. The code is
1437 moved to the start of the function so the incoming values are
1438 saved. */
27d0c333 1439
53800dbe 1440static rtx
aecda0d6 1441expand_builtin_apply_args (void)
53800dbe 1442{
1443 /* Don't do __builtin_apply_args more than once in a function.
1444 Save the result of the first call and reuse it. */
1445 if (apply_args_value != 0)
1446 return apply_args_value;
1447 {
1448 /* When this function is called, it means that registers must be
1449 saved on entry to this function. So we migrate the
1450 call to the first insn of this function. */
1451 rtx temp;
1452 rtx seq;
1453
1454 start_sequence ();
1455 temp = expand_builtin_apply_args_1 ();
1456 seq = get_insns ();
1457 end_sequence ();
1458
1459 apply_args_value = temp;
1460
31d3e01c 1461 /* Put the insns after the NOTE that starts the function.
1462 If this is inside a start_sequence, make the outer-level insn
53800dbe 1463 chain current, so the code is placed at the start of the
0ef1a651 1464 function. If internal_arg_pointer is a non-virtual pseudo,
1465 it needs to be placed after the function that initializes
1466 that pseudo. */
53800dbe 1467 push_topmost_sequence ();
0ef1a651 1468 if (REG_P (crtl->args.internal_arg_pointer)
1469 && REGNO (crtl->args.internal_arg_pointer) > LAST_VIRTUAL_REGISTER)
1470 emit_insn_before (seq, parm_birth_insn);
1471 else
1472 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
53800dbe 1473 pop_topmost_sequence ();
1474 return temp;
1475 }
1476}
1477
1478/* Perform an untyped call and save the state required to perform an
1479 untyped return of whatever value was returned by the given function. */
1480
1481static rtx
aecda0d6 1482expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
53800dbe 1483{
1484 int size, align, regno;
1485 enum machine_mode mode;
2a631e19 1486 rtx incoming_args, result, reg, dest, src, call_insn;
53800dbe 1487 rtx old_stack_level = 0;
1488 rtx call_fusage = 0;
6812c89e 1489 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
53800dbe 1490
85d654dd 1491 arguments = convert_memory_address (Pmode, arguments);
726ec87c 1492
53800dbe 1493 /* Create a block where the return registers can be saved. */
1494 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1495
53800dbe 1496 /* Fetch the arg pointer from the ARGUMENTS block. */
1497 incoming_args = gen_reg_rtx (Pmode);
726ec87c 1498 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
53800dbe 1499#ifndef STACK_GROWS_DOWNWARD
ad99e708 1500 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1501 incoming_args, 0, OPTAB_LIB_WIDEN);
53800dbe 1502#endif
1503
04a46d40 1504 /* Push a new argument block and copy the arguments. Do not allow
1505 the (potential) memcpy call below to interfere with our stack
1506 manipulations. */
53800dbe 1507 do_pending_stack_adjust ();
04a46d40 1508 NO_DEFER_POP;
53800dbe 1509
2358393e 1510 /* Save the stack with nonlocal if available. */
53800dbe 1511#ifdef HAVE_save_stack_nonlocal
1512 if (HAVE_save_stack_nonlocal)
1513 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1514 else
1515#endif
1516 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1517
59647703 1518 /* Allocate a block of memory onto the stack and copy the memory
1519 arguments to the outgoing arguments address. */
1520 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
27a7a23a 1521
1522 /* Set DRAP flag to true, even though allocate_dynamic_stack_space
1523 may have already set current_function_calls_alloca to true.
1524 current_function_calls_alloca won't be set if argsize is zero,
1525 so we have to guarantee need_drap is true here. */
1526 if (SUPPORTS_STACK_ALIGNMENT)
1527 crtl->need_drap = true;
1528
59647703 1529 dest = virtual_outgoing_args_rtx;
1530#ifndef STACK_GROWS_DOWNWARD
971ba038 1531 if (CONST_INT_P (argsize))
59647703 1532 dest = plus_constant (dest, -INTVAL (argsize));
1533 else
1534 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1535#endif
2a631e19 1536 dest = gen_rtx_MEM (BLKmode, dest);
1537 set_mem_align (dest, PARM_BOUNDARY);
1538 src = gen_rtx_MEM (BLKmode, incoming_args);
1539 set_mem_align (src, PARM_BOUNDARY);
0378dbdc 1540 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
53800dbe 1541
1542 /* Refer to the argument block. */
1543 apply_args_size ();
1544 arguments = gen_rtx_MEM (BLKmode, arguments);
2a631e19 1545 set_mem_align (arguments, PARM_BOUNDARY);
53800dbe 1546
1547 /* Walk past the arg-pointer and structure value address. */
1548 size = GET_MODE_SIZE (Pmode);
45550790 1549 if (struct_value)
53800dbe 1550 size += GET_MODE_SIZE (Pmode);
1551
1552 /* Restore each of the registers previously saved. Make USE insns
1553 for each of these registers for use in making the call. */
1554 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1555 if ((mode = apply_args_mode[regno]) != VOIDmode)
1556 {
1557 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1558 if (size % align != 0)
1559 size = CEIL (size, align) * align;
1560 reg = gen_rtx_REG (mode, regno);
e513d163 1561 emit_move_insn (reg, adjust_address (arguments, mode, size));
53800dbe 1562 use_reg (&call_fusage, reg);
1563 size += GET_MODE_SIZE (mode);
1564 }
1565
1566 /* Restore the structure value address unless this is passed as an
1567 "invisible" first argument. */
1568 size = GET_MODE_SIZE (Pmode);
45550790 1569 if (struct_value)
53800dbe 1570 {
1571 rtx value = gen_reg_rtx (Pmode);
e513d163 1572 emit_move_insn (value, adjust_address (arguments, Pmode, size));
45550790 1573 emit_move_insn (struct_value, value);
8ad4c111 1574 if (REG_P (struct_value))
45550790 1575 use_reg (&call_fusage, struct_value);
53800dbe 1576 size += GET_MODE_SIZE (Pmode);
1577 }
1578
1579 /* All arguments and registers used for the call are set up by now! */
82c7907c 1580 function = prepare_call_address (NULL, function, NULL, &call_fusage, 0, 0);
53800dbe 1581
1582 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1583 and we don't want to load it into a register as an optimization,
1584 because prepare_call_address already did it if it should be done. */
1585 if (GET_CODE (function) != SYMBOL_REF)
1586 function = memory_address (FUNCTION_MODE, function);
1587
1588 /* Generate the actual call instruction and save the return value. */
1589#ifdef HAVE_untyped_call
1590 if (HAVE_untyped_call)
1591 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1592 result, result_vector (1, result)));
1593 else
1594#endif
1595#ifdef HAVE_call_value
1596 if (HAVE_call_value)
1597 {
1598 rtx valreg = 0;
1599
1600 /* Locate the unique return register. It is not possible to
1601 express a call that sets more than one return register using
1602 call_value; use untyped_call for that. In fact, untyped_call
1603 only needs to save the return registers in the given block. */
1604 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1605 if ((mode = apply_result_mode[regno]) != VOIDmode)
1606 {
64db345d 1607 gcc_assert (!valreg); /* HAVE_untyped_call required. */
7d3f6cc7 1608
53800dbe 1609 valreg = gen_rtx_REG (mode, regno);
1610 }
1611
2ed6c343 1612 emit_call_insn (GEN_CALL_VALUE (valreg,
53800dbe 1613 gen_rtx_MEM (FUNCTION_MODE, function),
1614 const0_rtx, NULL_RTX, const0_rtx));
1615
e513d163 1616 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
53800dbe 1617 }
1618 else
1619#endif
64db345d 1620 gcc_unreachable ();
53800dbe 1621
d5f9786f 1622 /* Find the CALL insn we just emitted, and attach the register usage
1623 information. */
1624 call_insn = last_call_insn ();
1625 add_function_usage_to (call_insn, call_fusage);
53800dbe 1626
1627 /* Restore the stack. */
1628#ifdef HAVE_save_stack_nonlocal
1629 if (HAVE_save_stack_nonlocal)
1630 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1631 else
1632#endif
1633 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1634
04a46d40 1635 OK_DEFER_POP;
1636
53800dbe 1637 /* Return the address of the result block. */
85d654dd 1638 result = copy_addr_to_reg (XEXP (result, 0));
1639 return convert_memory_address (ptr_mode, result);
53800dbe 1640}
1641
1642/* Perform an untyped return. */
1643
1644static void
aecda0d6 1645expand_builtin_return (rtx result)
53800dbe 1646{
1647 int size, align, regno;
1648 enum machine_mode mode;
1649 rtx reg;
1650 rtx call_fusage = 0;
1651
85d654dd 1652 result = convert_memory_address (Pmode, result);
726ec87c 1653
53800dbe 1654 apply_result_size ();
1655 result = gen_rtx_MEM (BLKmode, result);
1656
1657#ifdef HAVE_untyped_return
1658 if (HAVE_untyped_return)
1659 {
1660 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1661 emit_barrier ();
1662 return;
1663 }
1664#endif
1665
1666 /* Restore the return value and note that each value is used. */
1667 size = 0;
1668 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1669 if ((mode = apply_result_mode[regno]) != VOIDmode)
1670 {
1671 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1672 if (size % align != 0)
1673 size = CEIL (size, align) * align;
1674 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
e513d163 1675 emit_move_insn (reg, adjust_address (result, mode, size));
53800dbe 1676
1677 push_to_sequence (call_fusage);
18b42941 1678 emit_use (reg);
53800dbe 1679 call_fusage = get_insns ();
1680 end_sequence ();
1681 size += GET_MODE_SIZE (mode);
1682 }
1683
1684 /* Put the USE insns before the return. */
31d3e01c 1685 emit_insn (call_fusage);
53800dbe 1686
1687 /* Return whatever values was restored by jumping directly to the end
1688 of the function. */
62380d2d 1689 expand_naked_return ();
53800dbe 1690}
1691
539a3a92 1692/* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
27d0c333 1693
539a3a92 1694static enum type_class
aecda0d6 1695type_to_class (tree type)
539a3a92 1696{
1697 switch (TREE_CODE (type))
1698 {
1699 case VOID_TYPE: return void_type_class;
1700 case INTEGER_TYPE: return integer_type_class;
539a3a92 1701 case ENUMERAL_TYPE: return enumeral_type_class;
1702 case BOOLEAN_TYPE: return boolean_type_class;
1703 case POINTER_TYPE: return pointer_type_class;
1704 case REFERENCE_TYPE: return reference_type_class;
1705 case OFFSET_TYPE: return offset_type_class;
1706 case REAL_TYPE: return real_type_class;
1707 case COMPLEX_TYPE: return complex_type_class;
1708 case FUNCTION_TYPE: return function_type_class;
1709 case METHOD_TYPE: return method_type_class;
1710 case RECORD_TYPE: return record_type_class;
1711 case UNION_TYPE:
1712 case QUAL_UNION_TYPE: return union_type_class;
1713 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1714 ? string_type_class : array_type_class);
539a3a92 1715 case LANG_TYPE: return lang_type_class;
1716 default: return no_type_class;
1717 }
1718}
bf8e3599 1719
c2f47e15 1720/* Expand a call EXP to __builtin_classify_type. */
27d0c333 1721
53800dbe 1722static rtx
c2f47e15 1723expand_builtin_classify_type (tree exp)
53800dbe 1724{
c2f47e15 1725 if (call_expr_nargs (exp))
1726 return GEN_INT (type_to_class (TREE_TYPE (CALL_EXPR_ARG (exp, 0))));
53800dbe 1727 return GEN_INT (no_type_class);
1728}
1729
07976da7 1730/* This helper macro, meant to be used in mathfn_built_in below,
1731 determines which among a set of three builtin math functions is
1732 appropriate for a given type mode. The `F' and `L' cases are
1733 automatically generated from the `double' case. */
1734#define CASE_MATHFN(BUILT_IN_MATHFN) \
1735 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1736 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1737 fcodel = BUILT_IN_MATHFN##L ; break;
cd2656b0 1738/* Similar to above, but appends _R after any F/L suffix. */
1739#define CASE_MATHFN_REENT(BUILT_IN_MATHFN) \
1740 case BUILT_IN_MATHFN##_R: case BUILT_IN_MATHFN##F_R: case BUILT_IN_MATHFN##L_R: \
1741 fcode = BUILT_IN_MATHFN##_R; fcodef = BUILT_IN_MATHFN##F_R ; \
1742 fcodel = BUILT_IN_MATHFN##L_R ; break;
07976da7 1743
1744/* Return mathematic function equivalent to FN but operating directly
c319d56a 1745 on TYPE, if available. If IMPLICIT is true find the function in
1746 implicit_built_in_decls[], otherwise use built_in_decls[]. If we
1747 can't do the conversion, return zero. */
1748
1749static tree
1750mathfn_built_in_1 (tree type, enum built_in_function fn, bool implicit)
0a68165a 1751{
c319d56a 1752 tree const *const fn_arr
1753 = implicit ? implicit_built_in_decls : built_in_decls;
07976da7 1754 enum built_in_function fcode, fcodef, fcodel;
1755
1756 switch (fn)
1757 {
746114e8 1758 CASE_MATHFN (BUILT_IN_ACOS)
1759 CASE_MATHFN (BUILT_IN_ACOSH)
1760 CASE_MATHFN (BUILT_IN_ASIN)
1761 CASE_MATHFN (BUILT_IN_ASINH)
07976da7 1762 CASE_MATHFN (BUILT_IN_ATAN)
746114e8 1763 CASE_MATHFN (BUILT_IN_ATAN2)
1764 CASE_MATHFN (BUILT_IN_ATANH)
1765 CASE_MATHFN (BUILT_IN_CBRT)
07976da7 1766 CASE_MATHFN (BUILT_IN_CEIL)
d735c391 1767 CASE_MATHFN (BUILT_IN_CEXPI)
746114e8 1768 CASE_MATHFN (BUILT_IN_COPYSIGN)
07976da7 1769 CASE_MATHFN (BUILT_IN_COS)
746114e8 1770 CASE_MATHFN (BUILT_IN_COSH)
1771 CASE_MATHFN (BUILT_IN_DREM)
1772 CASE_MATHFN (BUILT_IN_ERF)
1773 CASE_MATHFN (BUILT_IN_ERFC)
07976da7 1774 CASE_MATHFN (BUILT_IN_EXP)
746114e8 1775 CASE_MATHFN (BUILT_IN_EXP10)
1776 CASE_MATHFN (BUILT_IN_EXP2)
1777 CASE_MATHFN (BUILT_IN_EXPM1)
1778 CASE_MATHFN (BUILT_IN_FABS)
1779 CASE_MATHFN (BUILT_IN_FDIM)
07976da7 1780 CASE_MATHFN (BUILT_IN_FLOOR)
746114e8 1781 CASE_MATHFN (BUILT_IN_FMA)
1782 CASE_MATHFN (BUILT_IN_FMAX)
1783 CASE_MATHFN (BUILT_IN_FMIN)
1784 CASE_MATHFN (BUILT_IN_FMOD)
1785 CASE_MATHFN (BUILT_IN_FREXP)
1786 CASE_MATHFN (BUILT_IN_GAMMA)
cd2656b0 1787 CASE_MATHFN_REENT (BUILT_IN_GAMMA) /* GAMMA_R */
746114e8 1788 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1789 CASE_MATHFN (BUILT_IN_HYPOT)
1790 CASE_MATHFN (BUILT_IN_ILOGB)
1791 CASE_MATHFN (BUILT_IN_INF)
69b779ea 1792 CASE_MATHFN (BUILT_IN_ISINF)
746114e8 1793 CASE_MATHFN (BUILT_IN_J0)
1794 CASE_MATHFN (BUILT_IN_J1)
1795 CASE_MATHFN (BUILT_IN_JN)
ac148751 1796 CASE_MATHFN (BUILT_IN_LCEIL)
746114e8 1797 CASE_MATHFN (BUILT_IN_LDEXP)
ad52b9b7 1798 CASE_MATHFN (BUILT_IN_LFLOOR)
746114e8 1799 CASE_MATHFN (BUILT_IN_LGAMMA)
cd2656b0 1800 CASE_MATHFN_REENT (BUILT_IN_LGAMMA) /* LGAMMA_R */
ac148751 1801 CASE_MATHFN (BUILT_IN_LLCEIL)
ad52b9b7 1802 CASE_MATHFN (BUILT_IN_LLFLOOR)
746114e8 1803 CASE_MATHFN (BUILT_IN_LLRINT)
1804 CASE_MATHFN (BUILT_IN_LLROUND)
07976da7 1805 CASE_MATHFN (BUILT_IN_LOG)
746114e8 1806 CASE_MATHFN (BUILT_IN_LOG10)
1807 CASE_MATHFN (BUILT_IN_LOG1P)
1808 CASE_MATHFN (BUILT_IN_LOG2)
1809 CASE_MATHFN (BUILT_IN_LOGB)
1810 CASE_MATHFN (BUILT_IN_LRINT)
1811 CASE_MATHFN (BUILT_IN_LROUND)
1812 CASE_MATHFN (BUILT_IN_MODF)
1813 CASE_MATHFN (BUILT_IN_NAN)
1814 CASE_MATHFN (BUILT_IN_NANS)
07976da7 1815 CASE_MATHFN (BUILT_IN_NEARBYINT)
746114e8 1816 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1817 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1818 CASE_MATHFN (BUILT_IN_POW)
757c219d 1819 CASE_MATHFN (BUILT_IN_POWI)
746114e8 1820 CASE_MATHFN (BUILT_IN_POW10)
1821 CASE_MATHFN (BUILT_IN_REMAINDER)
1822 CASE_MATHFN (BUILT_IN_REMQUO)
1823 CASE_MATHFN (BUILT_IN_RINT)
07976da7 1824 CASE_MATHFN (BUILT_IN_ROUND)
746114e8 1825 CASE_MATHFN (BUILT_IN_SCALB)
1826 CASE_MATHFN (BUILT_IN_SCALBLN)
1827 CASE_MATHFN (BUILT_IN_SCALBN)
c319d56a 1828 CASE_MATHFN (BUILT_IN_SIGNBIT)
746114e8 1829 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
07976da7 1830 CASE_MATHFN (BUILT_IN_SIN)
746114e8 1831 CASE_MATHFN (BUILT_IN_SINCOS)
1832 CASE_MATHFN (BUILT_IN_SINH)
07976da7 1833 CASE_MATHFN (BUILT_IN_SQRT)
1834 CASE_MATHFN (BUILT_IN_TAN)
746114e8 1835 CASE_MATHFN (BUILT_IN_TANH)
1836 CASE_MATHFN (BUILT_IN_TGAMMA)
07976da7 1837 CASE_MATHFN (BUILT_IN_TRUNC)
746114e8 1838 CASE_MATHFN (BUILT_IN_Y0)
1839 CASE_MATHFN (BUILT_IN_Y1)
1840 CASE_MATHFN (BUILT_IN_YN)
07976da7 1841
0a68165a 1842 default:
c2f47e15 1843 return NULL_TREE;
0a68165a 1844 }
07976da7 1845
96b9f485 1846 if (TYPE_MAIN_VARIANT (type) == double_type_node)
c319d56a 1847 return fn_arr[fcode];
96b9f485 1848 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
c319d56a 1849 return fn_arr[fcodef];
96b9f485 1850 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
c319d56a 1851 return fn_arr[fcodel];
07976da7 1852 else
c2f47e15 1853 return NULL_TREE;
0a68165a 1854}
1855
c319d56a 1856/* Like mathfn_built_in_1(), but always use the implicit array. */
1857
1858tree
1859mathfn_built_in (tree type, enum built_in_function fn)
1860{
1861 return mathfn_built_in_1 (type, fn, /*implicit=*/ 1);
1862}
1863
0fd605a5 1864/* If errno must be maintained, expand the RTL to check if the result,
1865 TARGET, of a built-in function call, EXP, is NaN, and if so set
1866 errno to EDOM. */
1867
1868static void
aecda0d6 1869expand_errno_check (tree exp, rtx target)
0fd605a5 1870{
7f05340e 1871 rtx lab = gen_label_rtx ();
0fd605a5 1872
7f05340e 1873 /* Test the result; if it is NaN, set errno=EDOM because
1874 the argument was not in the domain. */
3fcf767f 1875 do_compare_rtx_and_jump (target, target, EQ, 0, GET_MODE (target),
1876 NULL_RTX, NULL_RTX, lab);
0fd605a5 1877
1878#ifdef TARGET_EDOM
7f05340e 1879 /* If this built-in doesn't throw an exception, set errno directly. */
c2f47e15 1880 if (TREE_NOTHROW (TREE_OPERAND (CALL_EXPR_FN (exp), 0)))
7f05340e 1881 {
0fd605a5 1882#ifdef GEN_ERRNO_RTX
7f05340e 1883 rtx errno_rtx = GEN_ERRNO_RTX;
0fd605a5 1884#else
7f05340e 1885 rtx errno_rtx
0fd605a5 1886 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1887#endif
7f05340e 1888 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
0fd605a5 1889 emit_label (lab);
7f05340e 1890 return;
0fd605a5 1891 }
7f05340e 1892#endif
1893
08491912 1894 /* Make sure the library call isn't expanded as a tail call. */
1895 CALL_EXPR_TAILCALL (exp) = 0;
1896
7f05340e 1897 /* We can't set errno=EDOM directly; let the library call do it.
1898 Pop the arguments right away in case the call gets deleted. */
1899 NO_DEFER_POP;
1900 expand_call (exp, target, 0);
1901 OK_DEFER_POP;
1902 emit_label (lab);
0fd605a5 1903}
1904
6b43bae4 1905/* Expand a call to one of the builtin math functions (sqrt, exp, or log).
c2f47e15 1906 Return NULL_RTX if a normal call should be emitted rather than expanding
1907 the function in-line. EXP is the expression that is a call to the builtin
53800dbe 1908 function; if convenient, the result should be placed in TARGET.
1909 SUBTARGET may be used as the target for computing one of EXP's operands. */
27d0c333 1910
53800dbe 1911static rtx
aecda0d6 1912expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
53800dbe 1913{
bf8e3599 1914 optab builtin_optab;
bd421108 1915 rtx op0, insns, before_call;
c6e6ecb1 1916 tree fndecl = get_callee_fndecl (exp);
7f05340e 1917 enum machine_mode mode;
528ee710 1918 bool errno_set = false;
abfea505 1919 tree arg;
53800dbe 1920
c2f47e15 1921 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
1922 return NULL_RTX;
53800dbe 1923
c2f47e15 1924 arg = CALL_EXPR_ARG (exp, 0);
53800dbe 1925
1926 switch (DECL_FUNCTION_CODE (fndecl))
1927 {
4f35b1fc 1928 CASE_FLT_FN (BUILT_IN_SQRT):
7f05340e 1929 errno_set = ! tree_expr_nonnegative_p (arg);
1930 builtin_optab = sqrt_optab;
1931 break;
4f35b1fc 1932 CASE_FLT_FN (BUILT_IN_EXP):
528ee710 1933 errno_set = true; builtin_optab = exp_optab; break;
4f35b1fc 1934 CASE_FLT_FN (BUILT_IN_EXP10):
1935 CASE_FLT_FN (BUILT_IN_POW10):
750ef9f5 1936 errno_set = true; builtin_optab = exp10_optab; break;
4f35b1fc 1937 CASE_FLT_FN (BUILT_IN_EXP2):
750ef9f5 1938 errno_set = true; builtin_optab = exp2_optab; break;
4f35b1fc 1939 CASE_FLT_FN (BUILT_IN_EXPM1):
a6b4eed2 1940 errno_set = true; builtin_optab = expm1_optab; break;
4f35b1fc 1941 CASE_FLT_FN (BUILT_IN_LOGB):
4efbc641 1942 errno_set = true; builtin_optab = logb_optab; break;
4f35b1fc 1943 CASE_FLT_FN (BUILT_IN_LOG):
528ee710 1944 errno_set = true; builtin_optab = log_optab; break;
4f35b1fc 1945 CASE_FLT_FN (BUILT_IN_LOG10):
d3cd9bde 1946 errno_set = true; builtin_optab = log10_optab; break;
4f35b1fc 1947 CASE_FLT_FN (BUILT_IN_LOG2):
d3cd9bde 1948 errno_set = true; builtin_optab = log2_optab; break;
4f35b1fc 1949 CASE_FLT_FN (BUILT_IN_LOG1P):
f474cd93 1950 errno_set = true; builtin_optab = log1p_optab; break;
4f35b1fc 1951 CASE_FLT_FN (BUILT_IN_ASIN):
8de2f465 1952 builtin_optab = asin_optab; break;
4f35b1fc 1953 CASE_FLT_FN (BUILT_IN_ACOS):
8de2f465 1954 builtin_optab = acos_optab; break;
4f35b1fc 1955 CASE_FLT_FN (BUILT_IN_TAN):
528ee710 1956 builtin_optab = tan_optab; break;
4f35b1fc 1957 CASE_FLT_FN (BUILT_IN_ATAN):
528ee710 1958 builtin_optab = atan_optab; break;
4f35b1fc 1959 CASE_FLT_FN (BUILT_IN_FLOOR):
528ee710 1960 builtin_optab = floor_optab; break;
4f35b1fc 1961 CASE_FLT_FN (BUILT_IN_CEIL):
528ee710 1962 builtin_optab = ceil_optab; break;
4f35b1fc 1963 CASE_FLT_FN (BUILT_IN_TRUNC):
a7cc195f 1964 builtin_optab = btrunc_optab; break;
4f35b1fc 1965 CASE_FLT_FN (BUILT_IN_ROUND):
528ee710 1966 builtin_optab = round_optab; break;
4f35b1fc 1967 CASE_FLT_FN (BUILT_IN_NEARBYINT):
0ddf4ad9 1968 builtin_optab = nearbyint_optab;
1969 if (flag_trapping_math)
1970 break;
1971 /* Else fallthrough and expand as rint. */
4f35b1fc 1972 CASE_FLT_FN (BUILT_IN_RINT):
aef94a0f 1973 builtin_optab = rint_optab; break;
b3154a1f 1974 CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
1975 builtin_optab = significand_optab; break;
42721db0 1976 default:
64db345d 1977 gcc_unreachable ();
53800dbe 1978 }
1979
7f05340e 1980 /* Make a suitable register to place result in. */
1981 mode = TYPE_MODE (TREE_TYPE (exp));
fc4eef90 1982
7f05340e 1983 if (! flag_errno_math || ! HONOR_NANS (mode))
1984 errno_set = false;
1985
bd421108 1986 /* Before working hard, check whether the instruction is available. */
99bdde56 1987 if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing)
68e6cb9d 1988 {
bd421108 1989 target = gen_reg_rtx (mode);
7f05340e 1990
bd421108 1991 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1992 need to expand the argument again. This way, we will not perform
1993 side-effects more the once. */
abfea505 1994 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
7f05340e 1995
1db6d067 1996 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
7f05340e 1997
bd421108 1998 start_sequence ();
53800dbe 1999
bd421108 2000 /* Compute into TARGET.
2001 Set TARGET to wherever the result comes back. */
2002 target = expand_unop (mode, builtin_optab, op0, target, 0);
2003
2004 if (target != 0)
2005 {
2006 if (errno_set)
2007 expand_errno_check (exp, target);
2008
2009 /* Output the entire sequence. */
2010 insns = get_insns ();
2011 end_sequence ();
2012 emit_insn (insns);
2013 return target;
2014 }
2015
2016 /* If we were unable to expand via the builtin, stop the sequence
2017 (without outputting the insns) and call to the library function
2018 with the stabilized argument list. */
53800dbe 2019 end_sequence ();
53800dbe 2020 }
2021
bd421108 2022 before_call = get_last_insn ();
2023
1e5b92fa 2024 return expand_call (exp, target, target == const0_rtx);
0fd605a5 2025}
2026
2027/* Expand a call to the builtin binary math functions (pow and atan2).
c2f47e15 2028 Return NULL_RTX if a normal call should be emitted rather than expanding the
0fd605a5 2029 function in-line. EXP is the expression that is a call to the builtin
2030 function; if convenient, the result should be placed in TARGET.
2031 SUBTARGET may be used as the target for computing one of EXP's
2032 operands. */
2033
2034static rtx
aecda0d6 2035expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
0fd605a5 2036{
2037 optab builtin_optab;
2038 rtx op0, op1, insns;
4737caf2 2039 int op1_type = REAL_TYPE;
c6e6ecb1 2040 tree fndecl = get_callee_fndecl (exp);
abfea505 2041 tree arg0, arg1;
7f05340e 2042 enum machine_mode mode;
0fd605a5 2043 bool errno_set = true;
0fd605a5 2044
73a954a1 2045 switch (DECL_FUNCTION_CODE (fndecl))
2046 {
2047 CASE_FLT_FN (BUILT_IN_SCALBN):
2048 CASE_FLT_FN (BUILT_IN_SCALBLN):
2049 CASE_FLT_FN (BUILT_IN_LDEXP):
2050 op1_type = INTEGER_TYPE;
2051 default:
2052 break;
2053 }
4737caf2 2054
c2f47e15 2055 if (!validate_arglist (exp, REAL_TYPE, op1_type, VOID_TYPE))
2056 return NULL_RTX;
0fd605a5 2057
c2f47e15 2058 arg0 = CALL_EXPR_ARG (exp, 0);
2059 arg1 = CALL_EXPR_ARG (exp, 1);
0fd605a5 2060
0fd605a5 2061 switch (DECL_FUNCTION_CODE (fndecl))
2062 {
4f35b1fc 2063 CASE_FLT_FN (BUILT_IN_POW):
0fd605a5 2064 builtin_optab = pow_optab; break;
4f35b1fc 2065 CASE_FLT_FN (BUILT_IN_ATAN2):
0fd605a5 2066 builtin_optab = atan2_optab; break;
73a954a1 2067 CASE_FLT_FN (BUILT_IN_SCALB):
2068 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2069 return 0;
2070 builtin_optab = scalb_optab; break;
2071 CASE_FLT_FN (BUILT_IN_SCALBN):
2072 CASE_FLT_FN (BUILT_IN_SCALBLN):
2073 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2074 return 0;
2075 /* Fall through... */
4f35b1fc 2076 CASE_FLT_FN (BUILT_IN_LDEXP):
4737caf2 2077 builtin_optab = ldexp_optab; break;
4f35b1fc 2078 CASE_FLT_FN (BUILT_IN_FMOD):
80ed5c06 2079 builtin_optab = fmod_optab; break;
ef722005 2080 CASE_FLT_FN (BUILT_IN_REMAINDER):
4f35b1fc 2081 CASE_FLT_FN (BUILT_IN_DREM):
ef722005 2082 builtin_optab = remainder_optab; break;
0fd605a5 2083 default:
64db345d 2084 gcc_unreachable ();
0fd605a5 2085 }
2086
7f05340e 2087 /* Make a suitable register to place result in. */
2088 mode = TYPE_MODE (TREE_TYPE (exp));
fc4eef90 2089
2090 /* Before working hard, check whether the instruction is available. */
99bdde56 2091 if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing)
c2f47e15 2092 return NULL_RTX;
fc4eef90 2093
7f05340e 2094 target = gen_reg_rtx (mode);
2095
2096 if (! flag_errno_math || ! HONOR_NANS (mode))
2097 errno_set = false;
2098
4ee9c684 2099 /* Always stabilize the argument list. */
abfea505 2100 CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
2101 CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1);
7f05340e 2102
8ec3c5c2 2103 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2104 op1 = expand_normal (arg1);
7f05340e 2105
7f05340e 2106 start_sequence ();
2107
0fd605a5 2108 /* Compute into TARGET.
2109 Set TARGET to wherever the result comes back. */
7f05340e 2110 target = expand_binop (mode, builtin_optab, op0, op1,
0fd605a5 2111 target, 0, OPTAB_DIRECT);
53800dbe 2112
68e6cb9d 2113 /* If we were unable to expand via the builtin, stop the sequence
2114 (without outputting the insns) and call to the library function
2115 with the stabilized argument list. */
0fd605a5 2116 if (target == 0)
2117 {
2118 end_sequence ();
68e6cb9d 2119 return expand_call (exp, target, target == const0_rtx);
53800dbe 2120 }
2121
a4356fb9 2122 if (errno_set)
2123 expand_errno_check (exp, target);
0fd605a5 2124
53800dbe 2125 /* Output the entire sequence. */
2126 insns = get_insns ();
2127 end_sequence ();
31d3e01c 2128 emit_insn (insns);
bf8e3599 2129
53800dbe 2130 return target;
2131}
2132
6b43bae4 2133/* Expand a call to the builtin sin and cos math functions.
c2f47e15 2134 Return NULL_RTX if a normal call should be emitted rather than expanding the
6b43bae4 2135 function in-line. EXP is the expression that is a call to the builtin
2136 function; if convenient, the result should be placed in TARGET.
2137 SUBTARGET may be used as the target for computing one of EXP's
2138 operands. */
2139
2140static rtx
2141expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2142{
2143 optab builtin_optab;
7511b819 2144 rtx op0, insns;
6b43bae4 2145 tree fndecl = get_callee_fndecl (exp);
6b43bae4 2146 enum machine_mode mode;
abfea505 2147 tree arg;
6b43bae4 2148
c2f47e15 2149 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2150 return NULL_RTX;
6b43bae4 2151
c2f47e15 2152 arg = CALL_EXPR_ARG (exp, 0);
6b43bae4 2153
2154 switch (DECL_FUNCTION_CODE (fndecl))
2155 {
4f35b1fc 2156 CASE_FLT_FN (BUILT_IN_SIN):
2157 CASE_FLT_FN (BUILT_IN_COS):
6b43bae4 2158 builtin_optab = sincos_optab; break;
2159 default:
64db345d 2160 gcc_unreachable ();
6b43bae4 2161 }
2162
2163 /* Make a suitable register to place result in. */
2164 mode = TYPE_MODE (TREE_TYPE (exp));
2165
6b43bae4 2166 /* Check if sincos insn is available, otherwise fallback
0bed3869 2167 to sin or cos insn. */
99bdde56 2168 if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing)
6b43bae4 2169 switch (DECL_FUNCTION_CODE (fndecl))
2170 {
4f35b1fc 2171 CASE_FLT_FN (BUILT_IN_SIN):
6b43bae4 2172 builtin_optab = sin_optab; break;
4f35b1fc 2173 CASE_FLT_FN (BUILT_IN_COS):
6b43bae4 2174 builtin_optab = cos_optab; break;
2175 default:
64db345d 2176 gcc_unreachable ();
6b43bae4 2177 }
6b43bae4 2178
2179 /* Before working hard, check whether the instruction is available. */
99bdde56 2180 if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing)
6b43bae4 2181 {
2182 target = gen_reg_rtx (mode);
2183
2184 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2185 need to expand the argument again. This way, we will not perform
2186 side-effects more the once. */
abfea505 2187 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
6b43bae4 2188
1db6d067 2189 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
6b43bae4 2190
6b43bae4 2191 start_sequence ();
2192
2193 /* Compute into TARGET.
2194 Set TARGET to wherever the result comes back. */
2195 if (builtin_optab == sincos_optab)
2196 {
64db345d 2197 int result;
7d3f6cc7 2198
6b43bae4 2199 switch (DECL_FUNCTION_CODE (fndecl))
2200 {
4f35b1fc 2201 CASE_FLT_FN (BUILT_IN_SIN):
64db345d 2202 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
6b43bae4 2203 break;
4f35b1fc 2204 CASE_FLT_FN (BUILT_IN_COS):
64db345d 2205 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
6b43bae4 2206 break;
2207 default:
64db345d 2208 gcc_unreachable ();
6b43bae4 2209 }
64db345d 2210 gcc_assert (result);
6b43bae4 2211 }
2212 else
2213 {
2214 target = expand_unop (mode, builtin_optab, op0, target, 0);
2215 }
2216
2217 if (target != 0)
2218 {
6b43bae4 2219 /* Output the entire sequence. */
2220 insns = get_insns ();
2221 end_sequence ();
2222 emit_insn (insns);
2223 return target;
2224 }
2225
2226 /* If we were unable to expand via the builtin, stop the sequence
2227 (without outputting the insns) and call to the library function
2228 with the stabilized argument list. */
2229 end_sequence ();
2230 }
2231
6b43bae4 2232 target = expand_call (exp, target, target == const0_rtx);
2233
2234 return target;
2235}
2236
a65c4d64 2237/* Given an interclass math builtin decl FNDECL and it's argument ARG
2238 return an RTL instruction code that implements the functionality.
2239 If that isn't possible or available return CODE_FOR_nothing. */
a67a90e5 2240
a65c4d64 2241static enum insn_code
2242interclass_mathfn_icode (tree arg, tree fndecl)
a67a90e5 2243{
a65c4d64 2244 bool errno_set = false;
cde061c1 2245 optab builtin_optab = 0;
a67a90e5 2246 enum machine_mode mode;
a67a90e5 2247
2248 switch (DECL_FUNCTION_CODE (fndecl))
2249 {
2250 CASE_FLT_FN (BUILT_IN_ILOGB):
2251 errno_set = true; builtin_optab = ilogb_optab; break;
69b779ea 2252 CASE_FLT_FN (BUILT_IN_ISINF):
2253 builtin_optab = isinf_optab; break;
8a1a9cb7 2254 case BUILT_IN_ISNORMAL:
cde061c1 2255 case BUILT_IN_ISFINITE:
2256 CASE_FLT_FN (BUILT_IN_FINITE):
a65c4d64 2257 case BUILT_IN_FINITED32:
2258 case BUILT_IN_FINITED64:
2259 case BUILT_IN_FINITED128:
2260 case BUILT_IN_ISINFD32:
2261 case BUILT_IN_ISINFD64:
2262 case BUILT_IN_ISINFD128:
cde061c1 2263 /* These builtins have no optabs (yet). */
2264 break;
a67a90e5 2265 default:
2266 gcc_unreachable ();
2267 }
2268
2269 /* There's no easy way to detect the case we need to set EDOM. */
2270 if (flag_errno_math && errno_set)
a65c4d64 2271 return CODE_FOR_nothing;
a67a90e5 2272
2273 /* Optab mode depends on the mode of the input argument. */
2274 mode = TYPE_MODE (TREE_TYPE (arg));
2275
cde061c1 2276 if (builtin_optab)
a65c4d64 2277 return optab_handler (builtin_optab, mode)->insn_code;
2278 return CODE_FOR_nothing;
2279}
2280
2281/* Expand a call to one of the builtin math functions that operate on
2282 floating point argument and output an integer result (ilogb, isinf,
2283 isnan, etc).
2284 Return 0 if a normal call should be emitted rather than expanding the
2285 function in-line. EXP is the expression that is a call to the builtin
2286 function; if convenient, the result should be placed in TARGET.
2287 SUBTARGET may be used as the target for computing one of EXP's operands. */
2288
2289static rtx
2290expand_builtin_interclass_mathfn (tree exp, rtx target, rtx subtarget)
2291{
2292 enum insn_code icode = CODE_FOR_nothing;
2293 rtx op0;
2294 tree fndecl = get_callee_fndecl (exp);
2295 enum machine_mode mode;
2296 tree arg;
2297
2298 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2299 return NULL_RTX;
2300
2301 arg = CALL_EXPR_ARG (exp, 0);
2302 icode = interclass_mathfn_icode (arg, fndecl);
2303 mode = TYPE_MODE (TREE_TYPE (arg));
2304
a67a90e5 2305 if (icode != CODE_FOR_nothing)
2306 {
2307 /* Make a suitable register to place result in. */
2308 if (!target
2309 || GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
2310 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
2311
2312 gcc_assert (insn_data[icode].operand[0].predicate
2313 (target, GET_MODE (target)));
2314
2315 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2316 need to expand the argument again. This way, we will not perform
2317 side-effects more the once. */
abfea505 2318 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
a67a90e5 2319
1db6d067 2320 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
a67a90e5 2321
2322 if (mode != GET_MODE (op0))
2323 op0 = convert_to_mode (mode, op0, 0);
2324
2325 /* Compute into TARGET.
2326 Set TARGET to wherever the result comes back. */
2327 emit_unop_insn (icode, target, op0, UNKNOWN);
2328 return target;
2329 }
2330
a65c4d64 2331 return NULL_RTX;
a67a90e5 2332}
2333
c3147c1a 2334/* Expand a call to the builtin sincos math function.
c2f47e15 2335 Return NULL_RTX if a normal call should be emitted rather than expanding the
c3147c1a 2336 function in-line. EXP is the expression that is a call to the builtin
2337 function. */
2338
2339static rtx
2340expand_builtin_sincos (tree exp)
2341{
2342 rtx op0, op1, op2, target1, target2;
c3147c1a 2343 enum machine_mode mode;
2344 tree arg, sinp, cosp;
2345 int result;
389dd41b 2346 location_t loc = EXPR_LOCATION (exp);
c3147c1a 2347
c2f47e15 2348 if (!validate_arglist (exp, REAL_TYPE,
2349 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2350 return NULL_RTX;
c3147c1a 2351
c2f47e15 2352 arg = CALL_EXPR_ARG (exp, 0);
2353 sinp = CALL_EXPR_ARG (exp, 1);
2354 cosp = CALL_EXPR_ARG (exp, 2);
c3147c1a 2355
2356 /* Make a suitable register to place result in. */
2357 mode = TYPE_MODE (TREE_TYPE (arg));
2358
2359 /* Check if sincos insn is available, otherwise emit the call. */
99bdde56 2360 if (optab_handler (sincos_optab, mode)->insn_code == CODE_FOR_nothing)
c3147c1a 2361 return NULL_RTX;
2362
2363 target1 = gen_reg_rtx (mode);
2364 target2 = gen_reg_rtx (mode);
2365
8ec3c5c2 2366 op0 = expand_normal (arg);
389dd41b 2367 op1 = expand_normal (build_fold_indirect_ref_loc (loc, sinp));
2368 op2 = expand_normal (build_fold_indirect_ref_loc (loc, cosp));
c3147c1a 2369
2370 /* Compute into target1 and target2.
2371 Set TARGET to wherever the result comes back. */
2372 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2373 gcc_assert (result);
2374
2375 /* Move target1 and target2 to the memory locations indicated
2376 by op1 and op2. */
2377 emit_move_insn (op1, target1);
2378 emit_move_insn (op2, target2);
2379
2380 return const0_rtx;
2381}
2382
d735c391 2383/* Expand a call to the internal cexpi builtin to the sincos math function.
2384 EXP is the expression that is a call to the builtin function; if convenient,
2385 the result should be placed in TARGET. SUBTARGET may be used as the target
2386 for computing one of EXP's operands. */
2387
2388static rtx
2389expand_builtin_cexpi (tree exp, rtx target, rtx subtarget)
2390{
2391 tree fndecl = get_callee_fndecl (exp);
d735c391 2392 tree arg, type;
c2f47e15 2393 enum machine_mode mode;
d735c391 2394 rtx op0, op1, op2;
389dd41b 2395 location_t loc = EXPR_LOCATION (exp);
d735c391 2396
c2f47e15 2397 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2398 return NULL_RTX;
d735c391 2399
c2f47e15 2400 arg = CALL_EXPR_ARG (exp, 0);
d735c391 2401 type = TREE_TYPE (arg);
2402 mode = TYPE_MODE (TREE_TYPE (arg));
2403
2404 /* Try expanding via a sincos optab, fall back to emitting a libcall
18b8d8ae 2405 to sincos or cexp. We are sure we have sincos or cexp because cexpi
2406 is only generated from sincos, cexp or if we have either of them. */
99bdde56 2407 if (optab_handler (sincos_optab, mode)->insn_code != CODE_FOR_nothing)
d735c391 2408 {
2409 op1 = gen_reg_rtx (mode);
2410 op2 = gen_reg_rtx (mode);
2411
1db6d067 2412 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
d735c391 2413
2414 /* Compute into op1 and op2. */
2415 expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
2416 }
18b8d8ae 2417 else if (TARGET_HAS_SINCOS)
d735c391 2418 {
c2f47e15 2419 tree call, fn = NULL_TREE;
d735c391 2420 tree top1, top2;
2421 rtx op1a, op2a;
2422
2423 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2424 fn = built_in_decls[BUILT_IN_SINCOSF];
2425 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2426 fn = built_in_decls[BUILT_IN_SINCOS];
2427 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2428 fn = built_in_decls[BUILT_IN_SINCOSL];
c2f47e15 2429 else
2430 gcc_unreachable ();
d735c391 2431
2432 op1 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2433 op2 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2434 op1a = copy_to_mode_reg (Pmode, XEXP (op1, 0));
2435 op2a = copy_to_mode_reg (Pmode, XEXP (op2, 0));
2436 top1 = make_tree (build_pointer_type (TREE_TYPE (arg)), op1a);
2437 top2 = make_tree (build_pointer_type (TREE_TYPE (arg)), op2a);
2438
d735c391 2439 /* Make sure not to fold the sincos call again. */
2440 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
c2f47e15 2441 expand_normal (build_call_nary (TREE_TYPE (TREE_TYPE (fn)),
2442 call, 3, arg, top1, top2));
d735c391 2443 }
18b8d8ae 2444 else
2445 {
0ecbc158 2446 tree call, fn = NULL_TREE, narg;
18b8d8ae 2447 tree ctype = build_complex_type (type);
2448
0ecbc158 2449 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2450 fn = built_in_decls[BUILT_IN_CEXPF];
2451 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2452 fn = built_in_decls[BUILT_IN_CEXP];
2453 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2454 fn = built_in_decls[BUILT_IN_CEXPL];
c2f47e15 2455 else
2456 gcc_unreachable ();
fc0dfa6e 2457
2458 /* If we don't have a decl for cexp create one. This is the
2459 friendliest fallback if the user calls __builtin_cexpi
2460 without full target C99 function support. */
2461 if (fn == NULL_TREE)
2462 {
2463 tree fntype;
2464 const char *name = NULL;
2465
2466 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2467 name = "cexpf";
2468 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2469 name = "cexp";
2470 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2471 name = "cexpl";
2472
2473 fntype = build_function_type_list (ctype, ctype, NULL_TREE);
2474 fn = build_fn_decl (name, fntype);
2475 }
2476
389dd41b 2477 narg = fold_build2_loc (loc, COMPLEX_EXPR, ctype,
18b8d8ae 2478 build_real (type, dconst0), arg);
2479
2480 /* Make sure not to fold the cexp call again. */
2481 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
3737e769 2482 return expand_expr (build_call_nary (ctype, call, 1, narg),
1db6d067 2483 target, VOIDmode, EXPAND_NORMAL);
18b8d8ae 2484 }
d735c391 2485
2486 /* Now build the proper return type. */
2487 return expand_expr (build2 (COMPLEX_EXPR, build_complex_type (type),
2488 make_tree (TREE_TYPE (arg), op2),
2489 make_tree (TREE_TYPE (arg), op1)),
1db6d067 2490 target, VOIDmode, EXPAND_NORMAL);
d735c391 2491}
2492
a65c4d64 2493/* Conveniently construct a function call expression. FNDECL names the
2494 function to be called, N is the number of arguments, and the "..."
2495 parameters are the argument expressions. Unlike build_call_exr
2496 this doesn't fold the call, hence it will always return a CALL_EXPR. */
2497
2498static tree
2499build_call_nofold_loc (location_t loc, tree fndecl, int n, ...)
2500{
2501 va_list ap;
2502 tree fntype = TREE_TYPE (fndecl);
2503 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
2504
2505 va_start (ap, n);
2506 fn = build_call_valist (TREE_TYPE (fntype), fn, n, ap);
2507 va_end (ap);
2508 SET_EXPR_LOCATION (fn, loc);
2509 return fn;
2510}
2511#define build_call_nofold(...) \
2512 build_call_nofold_loc (UNKNOWN_LOCATION, __VA_ARGS__)
2513
7d3afc77 2514/* Expand a call to one of the builtin rounding functions gcc defines
2515 as an extension (lfloor and lceil). As these are gcc extensions we
2516 do not need to worry about setting errno to EDOM.
ad52b9b7 2517 If expanding via optab fails, lower expression to (int)(floor(x)).
2518 EXP is the expression that is a call to the builtin function;
ff1b14e4 2519 if convenient, the result should be placed in TARGET. */
ad52b9b7 2520
2521static rtx
ff1b14e4 2522expand_builtin_int_roundingfn (tree exp, rtx target)
ad52b9b7 2523{
9c42dd28 2524 convert_optab builtin_optab;
ad52b9b7 2525 rtx op0, insns, tmp;
2526 tree fndecl = get_callee_fndecl (exp);
ad52b9b7 2527 enum built_in_function fallback_fn;
2528 tree fallback_fndecl;
2529 enum machine_mode mode;
4de0924f 2530 tree arg;
ad52b9b7 2531
c2f47e15 2532 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
ad52b9b7 2533 gcc_unreachable ();
2534
c2f47e15 2535 arg = CALL_EXPR_ARG (exp, 0);
ad52b9b7 2536
2537 switch (DECL_FUNCTION_CODE (fndecl))
2538 {
4f35b1fc 2539 CASE_FLT_FN (BUILT_IN_LCEIL):
2540 CASE_FLT_FN (BUILT_IN_LLCEIL):
ac148751 2541 builtin_optab = lceil_optab;
2542 fallback_fn = BUILT_IN_CEIL;
2543 break;
2544
4f35b1fc 2545 CASE_FLT_FN (BUILT_IN_LFLOOR):
2546 CASE_FLT_FN (BUILT_IN_LLFLOOR):
ad52b9b7 2547 builtin_optab = lfloor_optab;
2548 fallback_fn = BUILT_IN_FLOOR;
2549 break;
2550
2551 default:
2552 gcc_unreachable ();
2553 }
2554
2555 /* Make a suitable register to place result in. */
2556 mode = TYPE_MODE (TREE_TYPE (exp));
2557
9c42dd28 2558 target = gen_reg_rtx (mode);
ad52b9b7 2559
9c42dd28 2560 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2561 need to expand the argument again. This way, we will not perform
2562 side-effects more the once. */
abfea505 2563 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
ad52b9b7 2564
ff1b14e4 2565 op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
ad52b9b7 2566
9c42dd28 2567 start_sequence ();
ad52b9b7 2568
9c42dd28 2569 /* Compute into TARGET. */
2570 if (expand_sfix_optab (target, op0, builtin_optab))
2571 {
2572 /* Output the entire sequence. */
2573 insns = get_insns ();
ad52b9b7 2574 end_sequence ();
9c42dd28 2575 emit_insn (insns);
2576 return target;
ad52b9b7 2577 }
2578
9c42dd28 2579 /* If we were unable to expand via the builtin, stop the sequence
2580 (without outputting the insns). */
2581 end_sequence ();
2582
ad52b9b7 2583 /* Fall back to floating point rounding optab. */
2584 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
fc0dfa6e 2585
2586 /* For non-C99 targets we may end up without a fallback fndecl here
2587 if the user called __builtin_lfloor directly. In this case emit
2588 a call to the floor/ceil variants nevertheless. This should result
2589 in the best user experience for not full C99 targets. */
2590 if (fallback_fndecl == NULL_TREE)
2591 {
2592 tree fntype;
2593 const char *name = NULL;
2594
2595 switch (DECL_FUNCTION_CODE (fndecl))
2596 {
2597 case BUILT_IN_LCEIL:
2598 case BUILT_IN_LLCEIL:
2599 name = "ceil";
2600 break;
2601 case BUILT_IN_LCEILF:
2602 case BUILT_IN_LLCEILF:
2603 name = "ceilf";
2604 break;
2605 case BUILT_IN_LCEILL:
2606 case BUILT_IN_LLCEILL:
2607 name = "ceill";
2608 break;
2609 case BUILT_IN_LFLOOR:
2610 case BUILT_IN_LLFLOOR:
2611 name = "floor";
2612 break;
2613 case BUILT_IN_LFLOORF:
2614 case BUILT_IN_LLFLOORF:
2615 name = "floorf";
2616 break;
2617 case BUILT_IN_LFLOORL:
2618 case BUILT_IN_LLFLOORL:
2619 name = "floorl";
2620 break;
2621 default:
2622 gcc_unreachable ();
2623 }
2624
2625 fntype = build_function_type_list (TREE_TYPE (arg),
2626 TREE_TYPE (arg), NULL_TREE);
2627 fallback_fndecl = build_fn_decl (name, fntype);
2628 }
2629
a65c4d64 2630 exp = build_call_nofold (fallback_fndecl, 1, arg);
ad52b9b7 2631
d4c690af 2632 tmp = expand_normal (exp);
ad52b9b7 2633
2634 /* Truncate the result of floating point optab to integer
2635 via expand_fix (). */
2636 target = gen_reg_rtx (mode);
2637 expand_fix (target, tmp, 0);
2638
2639 return target;
2640}
2641
7d3afc77 2642/* Expand a call to one of the builtin math functions doing integer
2643 conversion (lrint).
2644 Return 0 if a normal call should be emitted rather than expanding the
2645 function in-line. EXP is the expression that is a call to the builtin
ff1b14e4 2646 function; if convenient, the result should be placed in TARGET. */
7d3afc77 2647
2648static rtx
ff1b14e4 2649expand_builtin_int_roundingfn_2 (tree exp, rtx target)
7d3afc77 2650{
5f51ee59 2651 convert_optab builtin_optab;
7d3afc77 2652 rtx op0, insns;
2653 tree fndecl = get_callee_fndecl (exp);
4de0924f 2654 tree arg;
c2f47e15 2655 enum machine_mode mode;
7d3afc77 2656
2657 /* There's no easy way to detect the case we need to set EDOM. */
2658 if (flag_errno_math)
2659 return NULL_RTX;
2660
c2f47e15 2661 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2662 gcc_unreachable ();
2663
2664 arg = CALL_EXPR_ARG (exp, 0);
7d3afc77 2665
2666 switch (DECL_FUNCTION_CODE (fndecl))
2667 {
2668 CASE_FLT_FN (BUILT_IN_LRINT):
2669 CASE_FLT_FN (BUILT_IN_LLRINT):
2670 builtin_optab = lrint_optab; break;
ef2f1a10 2671 CASE_FLT_FN (BUILT_IN_LROUND):
2672 CASE_FLT_FN (BUILT_IN_LLROUND):
2673 builtin_optab = lround_optab; break;
7d3afc77 2674 default:
2675 gcc_unreachable ();
2676 }
2677
2678 /* Make a suitable register to place result in. */
2679 mode = TYPE_MODE (TREE_TYPE (exp));
2680
5f51ee59 2681 target = gen_reg_rtx (mode);
7d3afc77 2682
5f51ee59 2683 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2684 need to expand the argument again. This way, we will not perform
2685 side-effects more the once. */
abfea505 2686 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
7d3afc77 2687
ff1b14e4 2688 op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
7d3afc77 2689
5f51ee59 2690 start_sequence ();
7d3afc77 2691
5f51ee59 2692 if (expand_sfix_optab (target, op0, builtin_optab))
2693 {
2694 /* Output the entire sequence. */
2695 insns = get_insns ();
7d3afc77 2696 end_sequence ();
5f51ee59 2697 emit_insn (insns);
2698 return target;
7d3afc77 2699 }
2700
5f51ee59 2701 /* If we were unable to expand via the builtin, stop the sequence
2702 (without outputting the insns) and call to the library function
2703 with the stabilized argument list. */
2704 end_sequence ();
2705
7d3afc77 2706 target = expand_call (exp, target, target == const0_rtx);
2707
2708 return target;
2709}
2710
f1b844c6 2711/* To evaluate powi(x,n), the floating point value x raised to the
2712 constant integer exponent n, we use a hybrid algorithm that
2713 combines the "window method" with look-up tables. For an
2714 introduction to exponentiation algorithms and "addition chains",
2715 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2716 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2717 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2718 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2719
2720/* Provide a default value for POWI_MAX_MULTS, the maximum number of
2721 multiplications to inline before calling the system library's pow
2722 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2723 so this default never requires calling pow, powf or powl. */
0862b7e9 2724
f1b844c6 2725#ifndef POWI_MAX_MULTS
2726#define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2727#endif
2728
2729/* The size of the "optimal power tree" lookup table. All
2730 exponents less than this value are simply looked up in the
2731 powi_table below. This threshold is also used to size the
2732 cache of pseudo registers that hold intermediate results. */
2733#define POWI_TABLE_SIZE 256
2734
2735/* The size, in bits of the window, used in the "window method"
2736 exponentiation algorithm. This is equivalent to a radix of
2737 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2738#define POWI_WINDOW_SIZE 3
2739
2740/* The following table is an efficient representation of an
2741 "optimal power tree". For each value, i, the corresponding
2742 value, j, in the table states than an optimal evaluation
2743 sequence for calculating pow(x,i) can be found by evaluating
2744 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2745 100 integers is given in Knuth's "Seminumerical algorithms". */
2746
2747static const unsigned char powi_table[POWI_TABLE_SIZE] =
2748 {
2749 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2750 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2751 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2752 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2753 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2754 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2755 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2756 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2757 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2758 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2759 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2760 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2761 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2762 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2763 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2764 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2765 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2766 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2767 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2768 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2769 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2770 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2771 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2772 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2773 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2774 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2775 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2776 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2777 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2778 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2779 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2780 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2781 };
2782
2783
2784/* Return the number of multiplications required to calculate
2785 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2786 subroutine of powi_cost. CACHE is an array indicating
2787 which exponents have already been calculated. */
2788
2789static int
2790powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2791{
2792 /* If we've already calculated this exponent, then this evaluation
2793 doesn't require any additional multiplications. */
2794 if (cache[n])
2795 return 0;
2796
2797 cache[n] = true;
2798 return powi_lookup_cost (n - powi_table[n], cache)
2799 + powi_lookup_cost (powi_table[n], cache) + 1;
2800}
2801
2802/* Return the number of multiplications required to calculate
2803 powi(x,n) for an arbitrary x, given the exponent N. This
2804 function needs to be kept in sync with expand_powi below. */
2805
2806static int
2807powi_cost (HOST_WIDE_INT n)
2808{
2809 bool cache[POWI_TABLE_SIZE];
2810 unsigned HOST_WIDE_INT digit;
2811 unsigned HOST_WIDE_INT val;
2812 int result;
2813
2814 if (n == 0)
2815 return 0;
2816
2817 /* Ignore the reciprocal when calculating the cost. */
2818 val = (n < 0) ? -n : n;
2819
2820 /* Initialize the exponent cache. */
2821 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2822 cache[1] = true;
2823
2824 result = 0;
2825
2826 while (val >= POWI_TABLE_SIZE)
2827 {
2828 if (val & 1)
2829 {
2830 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2831 result += powi_lookup_cost (digit, cache)
2832 + POWI_WINDOW_SIZE + 1;
2833 val >>= POWI_WINDOW_SIZE;
2834 }
2835 else
2836 {
2837 val >>= 1;
2838 result++;
2839 }
2840 }
0862b7e9 2841
6881dbab 2842 return result + powi_lookup_cost (val, cache);
f1b844c6 2843}
2844
2845/* Recursive subroutine of expand_powi. This function takes the array,
2846 CACHE, of already calculated exponents and an exponent N and returns
2847 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2848
2849static rtx
2850expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2851{
2852 unsigned HOST_WIDE_INT digit;
2853 rtx target, result;
2854 rtx op0, op1;
2855
2856 if (n < POWI_TABLE_SIZE)
2857 {
2858 if (cache[n])
a0c938f0 2859 return cache[n];
f1b844c6 2860
2861 target = gen_reg_rtx (mode);
2862 cache[n] = target;
2863
2864 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2865 op1 = expand_powi_1 (mode, powi_table[n], cache);
2866 }
2867 else if (n & 1)
2868 {
2869 target = gen_reg_rtx (mode);
2870 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2871 op0 = expand_powi_1 (mode, n - digit, cache);
2872 op1 = expand_powi_1 (mode, digit, cache);
2873 }
2874 else
2875 {
2876 target = gen_reg_rtx (mode);
2877 op0 = expand_powi_1 (mode, n >> 1, cache);
2878 op1 = op0;
2879 }
2880
2881 result = expand_mult (mode, op0, op1, target, 0);
2882 if (result != target)
2883 emit_move_insn (target, result);
2884 return target;
2885}
2886
2887/* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2888 floating point operand in mode MODE, and N is the exponent. This
2889 function needs to be kept in sync with powi_cost above. */
0862b7e9 2890
f1b844c6 2891static rtx
2892expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2893{
2894 unsigned HOST_WIDE_INT val;
2895 rtx cache[POWI_TABLE_SIZE];
2896 rtx result;
2897
2898 if (n == 0)
2899 return CONST1_RTX (mode);
2900
2901 val = (n < 0) ? -n : n;
2902
19bf118a 2903 memset (cache, 0, sizeof (cache));
f1b844c6 2904 cache[1] = x;
2905
2906 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2907
2908 /* If the original exponent was negative, reciprocate the result. */
2909 if (n < 0)
2910 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2911 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2912
2913 return result;
2914}
2915
c2f47e15 2916/* Expand a call to the pow built-in mathematical function. Return NULL_RTX if
f1b844c6 2917 a normal call should be emitted rather than expanding the function
2918 in-line. EXP is the expression that is a call to the builtin
2919 function; if convenient, the result should be placed in TARGET. */
2920
2921static rtx
2922expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2923{
c2f47e15 2924 tree arg0, arg1;
2925 tree fn, narg0;
1c4709b4 2926 tree type = TREE_TYPE (exp);
2927 REAL_VALUE_TYPE cint, c, c2;
2928 HOST_WIDE_INT n;
2929 rtx op, op2;
2930 enum machine_mode mode = TYPE_MODE (type);
f1b844c6 2931
c2f47e15 2932 if (! validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2933 return NULL_RTX;
f1b844c6 2934
c2f47e15 2935 arg0 = CALL_EXPR_ARG (exp, 0);
2936 arg1 = CALL_EXPR_ARG (exp, 1);
f1b844c6 2937
1c4709b4 2938 if (TREE_CODE (arg1) != REAL_CST
f96bd2bf 2939 || TREE_OVERFLOW (arg1))
1c4709b4 2940 return expand_builtin_mathfn_2 (exp, target, subtarget);
2941
2942 /* Handle constant exponents. */
2943
2944 /* For integer valued exponents we can expand to an optimal multiplication
2945 sequence using expand_powi. */
2946 c = TREE_REAL_CST (arg1);
2947 n = real_to_integer (&c);
2948 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2949 if (real_identical (&c, &cint)
2950 && ((n >= -1 && n <= 2)
2951 || (flag_unsafe_math_optimizations
a0d18cec 2952 && optimize_insn_for_speed_p ()
1c4709b4 2953 && powi_cost (n) <= POWI_MAX_MULTS)))
f1b844c6 2954 {
1db6d067 2955 op = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
1c4709b4 2956 if (n != 1)
2957 {
2958 op = force_reg (mode, op);
2959 op = expand_powi (op, mode, n);
2960 }
2961 return op;
2962 }
2963
2964 narg0 = builtin_save_expr (arg0);
f1b844c6 2965
1c4709b4 2966 /* If the exponent is not integer valued, check if it is half of an integer.
2967 In this case we can expand to sqrt (x) * x**(n/2). */
2968 fn = mathfn_built_in (type, BUILT_IN_SQRT);
2969 if (fn != NULL_TREE)
2970 {
2971 real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
2972 n = real_to_integer (&c2);
f1b844c6 2973 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
1c4709b4 2974 if (real_identical (&c2, &cint)
2975 && ((flag_unsafe_math_optimizations
a0d18cec 2976 && optimize_insn_for_speed_p ()
1c4709b4 2977 && powi_cost (n/2) <= POWI_MAX_MULTS)
2978 || n == 1))
f1b844c6 2979 {
a65c4d64 2980 tree call_expr = build_call_nofold (fn, 1, narg0);
8697cf4d 2981 /* Use expand_expr in case the newly built call expression
2982 was folded to a non-call. */
2983 op = expand_expr (call_expr, subtarget, mode, EXPAND_NORMAL);
1c4709b4 2984 if (n != 1)
8c5cac78 2985 {
1db6d067 2986 op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL);
1c4709b4 2987 op2 = force_reg (mode, op2);
2988 op2 = expand_powi (op2, mode, abs (n / 2));
2989 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
2990 0, OPTAB_LIB_WIDEN);
2991 /* If the original exponent was negative, reciprocate the
2992 result. */
2993 if (n < 0)
2994 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2995 op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
8c5cac78 2996 }
1c4709b4 2997 return op;
f1b844c6 2998 }
2999 }
b613c2a6 3000
1c4709b4 3001 /* Try if the exponent is a third of an integer. In this case
5a84ba55 3002 we can expand to x**(n/3) * cbrt(x)**(n%3). As cbrt (x) is
3003 different from pow (x, 1./3.) due to rounding and behavior
3004 with negative x we need to constrain this transformation to
3005 unsafe math and positive x or finite math. */
1c4709b4 3006 fn = mathfn_built_in (type, BUILT_IN_CBRT);
5a84ba55 3007 if (fn != NULL_TREE
3008 && flag_unsafe_math_optimizations
3009 && (tree_expr_nonnegative_p (arg0)
3010 || !HONOR_NANS (mode)))
1c4709b4 3011 {
3fa759a9 3012 REAL_VALUE_TYPE dconst3;
3013 real_from_integer (&dconst3, VOIDmode, 3, 0, 0);
1c4709b4 3014 real_arithmetic (&c2, MULT_EXPR, &c, &dconst3);
3015 real_round (&c2, mode, &c2);
3016 n = real_to_integer (&c2);
3017 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
3018 real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
3019 real_convert (&c2, mode, &c2);
3020 if (real_identical (&c2, &c)
a0d18cec 3021 && ((optimize_insn_for_speed_p ()
1c4709b4 3022 && powi_cost (n/3) <= POWI_MAX_MULTS)
3023 || n == 1))
3024 {
a65c4d64 3025 tree call_expr = build_call_nofold (fn, 1,narg0);
1c4709b4 3026 op = expand_builtin (call_expr, NULL_RTX, subtarget, mode, 0);
3027 if (abs (n) % 3 == 2)
3028 op = expand_simple_binop (mode, MULT, op, op, op,
3029 0, OPTAB_LIB_WIDEN);
3030 if (n != 1)
3031 {
1db6d067 3032 op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL);
1c4709b4 3033 op2 = force_reg (mode, op2);
3034 op2 = expand_powi (op2, mode, abs (n / 3));
3035 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
3036 0, OPTAB_LIB_WIDEN);
3037 /* If the original exponent was negative, reciprocate the
3038 result. */
3039 if (n < 0)
3040 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
3041 op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
3042 }
3043 return op;
3044 }
3045 }
3046
3047 /* Fall back to optab expansion. */
b613c2a6 3048 return expand_builtin_mathfn_2 (exp, target, subtarget);
f1b844c6 3049}
3050
c2f47e15 3051/* Expand a call to the powi built-in mathematical function. Return NULL_RTX if
757c219d 3052 a normal call should be emitted rather than expanding the function
3053 in-line. EXP is the expression that is a call to the builtin
3054 function; if convenient, the result should be placed in TARGET. */
3055
3056static rtx
3057expand_builtin_powi (tree exp, rtx target, rtx subtarget)
3058{
757c219d 3059 tree arg0, arg1;
3060 rtx op0, op1;
3061 enum machine_mode mode;
d0405f40 3062 enum machine_mode mode2;
757c219d 3063
c2f47e15 3064 if (! validate_arglist (exp, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
3065 return NULL_RTX;
757c219d 3066
c2f47e15 3067 arg0 = CALL_EXPR_ARG (exp, 0);
3068 arg1 = CALL_EXPR_ARG (exp, 1);
757c219d 3069 mode = TYPE_MODE (TREE_TYPE (exp));
3070
3071 /* Handle constant power. */
3072
3073 if (TREE_CODE (arg1) == INTEGER_CST
f96bd2bf 3074 && !TREE_OVERFLOW (arg1))
757c219d 3075 {
3076 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
3077
3078 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
3079 Otherwise, check the number of multiplications required. */
3080 if ((TREE_INT_CST_HIGH (arg1) == 0
3081 || TREE_INT_CST_HIGH (arg1) == -1)
3082 && ((n >= -1 && n <= 2)
a0d18cec 3083 || (optimize_insn_for_speed_p ()
757c219d 3084 && powi_cost (n) <= POWI_MAX_MULTS)))
3085 {
1db6d067 3086 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
757c219d 3087 op0 = force_reg (mode, op0);
3088 return expand_powi (op0, mode, n);
3089 }
3090 }
3091
3092 /* Emit a libcall to libgcc. */
3093
c2f47e15 3094 /* Mode of the 2nd argument must match that of an int. */
d0405f40 3095 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
3096
757c219d 3097 if (target == NULL_RTX)
3098 target = gen_reg_rtx (mode);
3099
1db6d067 3100 op0 = expand_expr (arg0, subtarget, mode, EXPAND_NORMAL);
757c219d 3101 if (GET_MODE (op0) != mode)
3102 op0 = convert_to_mode (mode, op0, 0);
1db6d067 3103 op1 = expand_expr (arg1, NULL_RTX, mode2, EXPAND_NORMAL);
d0405f40 3104 if (GET_MODE (op1) != mode2)
3105 op1 = convert_to_mode (mode2, op1, 0);
757c219d 3106
f36b9f69 3107 target = emit_library_call_value (optab_libfunc (powi_optab, mode),
2dd6f9ed 3108 target, LCT_CONST, mode, 2,
d0405f40 3109 op0, mode, op1, mode2);
757c219d 3110
3111 return target;
3112}
3113
c2f47e15 3114/* Expand expression EXP which is a call to the strlen builtin. Return
3115 NULL_RTX if we failed the caller should emit a normal call, otherwise
aed0bd19 3116 try to get the result in TARGET, if convenient. */
f7c44134 3117
53800dbe 3118static rtx
c2f47e15 3119expand_builtin_strlen (tree exp, rtx target,
aecda0d6 3120 enum machine_mode target_mode)
53800dbe 3121{
c2f47e15 3122 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
3123 return NULL_RTX;
53800dbe 3124 else
3125 {
911c0150 3126 rtx pat;
c2f47e15 3127 tree len;
3128 tree src = CALL_EXPR_ARG (exp, 0);
911c0150 3129 rtx result, src_reg, char_rtx, before_strlen;
80cd7a5e 3130 enum machine_mode insn_mode = target_mode, char_mode;
ef2c4a29 3131 enum insn_code icode = CODE_FOR_nothing;
6248e345 3132 int align;
3133
3134 /* If the length can be computed at compile-time, return it. */
681fab1e 3135 len = c_strlen (src, 0);
6248e345 3136 if (len)
80cd7a5e 3137 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
6248e345 3138
681fab1e 3139 /* If the length can be computed at compile-time and is constant
3140 integer, but there are side-effects in src, evaluate
3141 src for side-effects, then return len.
3142 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
3143 can be optimized into: i++; x = 3; */
3144 len = c_strlen (src, 1);
3145 if (len && TREE_CODE (len) == INTEGER_CST)
3146 {
3147 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3148 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
3149 }
3150
6248e345 3151 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
53800dbe 3152
53800dbe 3153 /* If SRC is not a pointer type, don't do this operation inline. */
3154 if (align == 0)
c2f47e15 3155 return NULL_RTX;
53800dbe 3156
911c0150 3157 /* Bail out if we can't compute strlen in the right mode. */
53800dbe 3158 while (insn_mode != VOIDmode)
3159 {
99bdde56 3160 icode = optab_handler (strlen_optab, insn_mode)->insn_code;
53800dbe 3161 if (icode != CODE_FOR_nothing)
c28ae87f 3162 break;
53800dbe 3163
3164 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
3165 }
3166 if (insn_mode == VOIDmode)
c2f47e15 3167 return NULL_RTX;
53800dbe 3168
3169 /* Make a place to write the result of the instruction. */
3170 result = target;
3171 if (! (result != 0
8ad4c111 3172 && REG_P (result)
53800dbe 3173 && GET_MODE (result) == insn_mode
3174 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3175 result = gen_reg_rtx (insn_mode);
3176
911c0150 3177 /* Make a place to hold the source address. We will not expand
3178 the actual source until we are sure that the expansion will
3179 not fail -- there are trees that cannot be expanded twice. */
3180 src_reg = gen_reg_rtx (Pmode);
53800dbe 3181
911c0150 3182 /* Mark the beginning of the strlen sequence so we can emit the
3183 source operand later. */
f0ce3b1f 3184 before_strlen = get_last_insn ();
53800dbe 3185
53800dbe 3186 char_rtx = const0_rtx;
f7c44134 3187 char_mode = insn_data[(int) icode].operand[2].mode;
3188 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
3189 char_mode))
53800dbe 3190 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
3191
911c0150 3192 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
3193 char_rtx, GEN_INT (align));
3194 if (! pat)
c2f47e15 3195 return NULL_RTX;
911c0150 3196 emit_insn (pat);
3197
3198 /* Now that we are assured of success, expand the source. */
3199 start_sequence ();
c5aba89c 3200 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
911c0150 3201 if (pat != src_reg)
3202 emit_move_insn (src_reg, pat);
31d3e01c 3203 pat = get_insns ();
911c0150 3204 end_sequence ();
bceb0d1f 3205
3206 if (before_strlen)
3207 emit_insn_after (pat, before_strlen);
3208 else
3209 emit_insn_before (pat, get_insns ());
53800dbe 3210
3211 /* Return the value in the proper mode for this function. */
80cd7a5e 3212 if (GET_MODE (result) == target_mode)
911c0150 3213 target = result;
53800dbe 3214 else if (target != 0)
911c0150 3215 convert_move (target, result, 0);
53800dbe 3216 else
80cd7a5e 3217 target = convert_to_mode (target_mode, result, 0);
911c0150 3218
3219 return target;
53800dbe 3220 }
3221}
3222
6840589f 3223/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3224 bytes from constant string DATA + OFFSET and return it as target
3225 constant. */
3226
3227static rtx
aecda0d6 3228builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
3229 enum machine_mode mode)
6840589f 3230{
3231 const char *str = (const char *) data;
3232
64db345d 3233 gcc_assert (offset >= 0
3234 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
3235 <= strlen (str) + 1));
6840589f 3236
3237 return c_readstr (str + offset, mode);
3238}
3239
c2f47e15 3240/* Expand a call EXP to the memcpy builtin.
3241 Return NULL_RTX if we failed, the caller should emit a normal call,
3b824fa6 3242 otherwise try to get the result in TARGET, if convenient (and in
9fe0e1b8 3243 mode MODE if that's convenient). */
c2f47e15 3244
53800dbe 3245static rtx
a65c4d64 3246expand_builtin_memcpy (tree exp, rtx target)
53800dbe 3247{
c2f47e15 3248 if (!validate_arglist (exp,
3249 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3250 return NULL_RTX;
53800dbe 3251 else
3252 {
c2f47e15 3253 tree dest = CALL_EXPR_ARG (exp, 0);
3254 tree src = CALL_EXPR_ARG (exp, 1);
3255 tree len = CALL_EXPR_ARG (exp, 2);
6840589f 3256 const char *src_str;
27d0c333 3257 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3258 unsigned int dest_align
3259 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
53800dbe 3260 rtx dest_mem, src_mem, dest_addr, len_rtx;
162719b3 3261 HOST_WIDE_INT expected_size = -1;
3262 unsigned int expected_align = 0;
75a70cf9 3263 tree_ann_common_t ann;
5a0de151 3264
6f428e8b 3265 /* If DEST is not a pointer type, call the normal function. */
3266 if (dest_align == 0)
c2f47e15 3267 return NULL_RTX;
6f428e8b 3268
6f428e8b 3269 /* If either SRC is not a pointer type, don't do this
a0c938f0 3270 operation in-line. */
6f428e8b 3271 if (src_align == 0)
c2f47e15 3272 return NULL_RTX;
162719b3 3273
75a70cf9 3274 ann = tree_common_ann (exp);
3275 if (ann)
3276 stringop_block_profile (ann->stmt, &expected_align, &expected_size);
3277
162719b3 3278 if (expected_align < dest_align)
3279 expected_align = dest_align;
d8ae1baa 3280 dest_mem = get_memory_rtx (dest, len);
2a631e19 3281 set_mem_align (dest_mem, dest_align);
8ec3c5c2 3282 len_rtx = expand_normal (len);
6840589f 3283 src_str = c_getstr (src);
3284
3285 /* If SRC is a string constant and block move would be done
3286 by pieces, we can avoid loading the string from memory
3287 and only stored the computed constants. */
3288 if (src_str
971ba038 3289 && CONST_INT_P (len_rtx)
6840589f 3290 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3291 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
364c0c59 3292 CONST_CAST (char *, src_str),
3293 dest_align, false))
6840589f 3294 {
9fe0e1b8 3295 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3296 builtin_memcpy_read_str,
364c0c59 3297 CONST_CAST (char *, src_str),
3298 dest_align, false, 0);
a65c4d64 3299 dest_mem = force_operand (XEXP (dest_mem, 0), target);
85d654dd 3300 dest_mem = convert_memory_address (ptr_mode, dest_mem);
9fe0e1b8 3301 return dest_mem;
6840589f 3302 }
3303
d8ae1baa 3304 src_mem = get_memory_rtx (src, len);
2a631e19 3305 set_mem_align (src_mem, src_align);
53800dbe 3306
53800dbe 3307 /* Copy word part most expediently. */
162719b3 3308 dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx,
3309 CALL_EXPR_TAILCALL (exp)
3310 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3311 expected_align, expected_size);
53800dbe 3312
3313 if (dest_addr == 0)
e5716f7e 3314 {
a65c4d64 3315 dest_addr = force_operand (XEXP (dest_mem, 0), target);
85d654dd 3316 dest_addr = convert_memory_address (ptr_mode, dest_addr);
e5716f7e 3317 }
9fe0e1b8 3318 return dest_addr;
53800dbe 3319 }
3320}
3321
c2f47e15 3322/* Expand a call EXP to the mempcpy builtin.
3323 Return NULL_RTX if we failed; the caller should emit a normal call,
647661c6 3324 otherwise try to get the result in TARGET, if convenient (and in
9fe0e1b8 3325 mode MODE if that's convenient). If ENDP is 0 return the
3326 destination pointer, if ENDP is 1 return the end pointer ala
3327 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3328 stpcpy. */
647661c6 3329
3330static rtx
c8b17b2e 3331expand_builtin_mempcpy (tree exp, rtx target, enum machine_mode mode)
647661c6 3332{
c2f47e15 3333 if (!validate_arglist (exp,
3334 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3335 return NULL_RTX;
3336 else
3337 {
3338 tree dest = CALL_EXPR_ARG (exp, 0);
3339 tree src = CALL_EXPR_ARG (exp, 1);
3340 tree len = CALL_EXPR_ARG (exp, 2);
3341 return expand_builtin_mempcpy_args (dest, src, len,
c2f47e15 3342 target, mode, /*endp=*/ 1);
3343 }
3344}
3345
3346/* Helper function to do the actual work for expand_builtin_mempcpy. The
3347 arguments to the builtin_mempcpy call DEST, SRC, and LEN are broken out
3348 so that this can also be called without constructing an actual CALL_EXPR.
a65c4d64 3349 The other arguments and return value are the same as for
3350 expand_builtin_mempcpy. */
c2f47e15 3351
3352static rtx
a65c4d64 3353expand_builtin_mempcpy_args (tree dest, tree src, tree len,
c2f47e15 3354 rtx target, enum machine_mode mode, int endp)
3355{
3356 /* If return value is ignored, transform mempcpy into memcpy. */
c8b17b2e 3357 if (target == const0_rtx && implicit_built_in_decls[BUILT_IN_MEMCPY])
9fe0e1b8 3358 {
3359 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
a65c4d64 3360 tree result = build_call_nofold (fn, 3, dest, src, len);
c8b17b2e 3361 return expand_expr (result, target, mode, EXPAND_NORMAL);
9fe0e1b8 3362 }
647661c6 3363 else
3364 {
9fe0e1b8 3365 const char *src_str;
3366 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3367 unsigned int dest_align
3368 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3369 rtx dest_mem, src_mem, len_rtx;
a0c938f0 3370
7da1412b 3371 /* If either SRC or DEST is not a pointer type, don't do this
a0c938f0 3372 operation in-line. */
7da1412b 3373 if (dest_align == 0 || src_align == 0)
c2f47e15 3374 return NULL_RTX;
9fe0e1b8 3375
6217c238 3376 /* If LEN is not constant, call the normal function. */
3377 if (! host_integerp (len, 1))
c2f47e15 3378 return NULL_RTX;
0862b7e9 3379
8ec3c5c2 3380 len_rtx = expand_normal (len);
9fe0e1b8 3381 src_str = c_getstr (src);
647661c6 3382
9fe0e1b8 3383 /* If SRC is a string constant and block move would be done
3384 by pieces, we can avoid loading the string from memory
3385 and only stored the computed constants. */
3386 if (src_str
971ba038 3387 && CONST_INT_P (len_rtx)
9fe0e1b8 3388 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3389 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
364c0c59 3390 CONST_CAST (char *, src_str),
3391 dest_align, false))
9fe0e1b8 3392 {
d8ae1baa 3393 dest_mem = get_memory_rtx (dest, len);
9fe0e1b8 3394 set_mem_align (dest_mem, dest_align);
3395 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3396 builtin_memcpy_read_str,
364c0c59 3397 CONST_CAST (char *, src_str),
3398 dest_align, false, endp);
9fe0e1b8 3399 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3400 dest_mem = convert_memory_address (ptr_mode, dest_mem);
9fe0e1b8 3401 return dest_mem;
647661c6 3402 }
3403
971ba038 3404 if (CONST_INT_P (len_rtx)
9fe0e1b8 3405 && can_move_by_pieces (INTVAL (len_rtx),
3406 MIN (dest_align, src_align)))
3407 {
d8ae1baa 3408 dest_mem = get_memory_rtx (dest, len);
9fe0e1b8 3409 set_mem_align (dest_mem, dest_align);
d8ae1baa 3410 src_mem = get_memory_rtx (src, len);
9fe0e1b8 3411 set_mem_align (src_mem, src_align);
3412 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3413 MIN (dest_align, src_align), endp);
3414 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3415 dest_mem = convert_memory_address (ptr_mode, dest_mem);
9fe0e1b8 3416 return dest_mem;
3417 }
3418
c2f47e15 3419 return NULL_RTX;
647661c6 3420 }
3421}
3422
727c62dd 3423#ifndef HAVE_movstr
3424# define HAVE_movstr 0
3425# define CODE_FOR_movstr CODE_FOR_nothing
3426#endif
3427
c2f47e15 3428/* Expand into a movstr instruction, if one is available. Return NULL_RTX if
727c62dd 3429 we failed, the caller should emit a normal call, otherwise try to
3430 get the result in TARGET, if convenient. If ENDP is 0 return the
3431 destination pointer, if ENDP is 1 return the end pointer ala
3432 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3433 stpcpy. */
3434
3435static rtx
3436expand_movstr (tree dest, tree src, rtx target, int endp)
3437{
3438 rtx end;
3439 rtx dest_mem;
3440 rtx src_mem;
3441 rtx insn;
3442 const struct insn_data * data;
3443
3444 if (!HAVE_movstr)
c2f47e15 3445 return NULL_RTX;
727c62dd 3446
d8ae1baa 3447 dest_mem = get_memory_rtx (dest, NULL);
3448 src_mem = get_memory_rtx (src, NULL);
727c62dd 3449 if (!endp)
3450 {
3451 target = force_reg (Pmode, XEXP (dest_mem, 0));
3452 dest_mem = replace_equiv_address (dest_mem, target);
3453 end = gen_reg_rtx (Pmode);
3454 }
3455 else
3456 {
3457 if (target == 0 || target == const0_rtx)
3458 {
3459 end = gen_reg_rtx (Pmode);
3460 if (target == 0)
3461 target = end;
3462 }
3463 else
3464 end = target;
3465 }
3466
3467 data = insn_data + CODE_FOR_movstr;
3468
3469 if (data->operand[0].mode != VOIDmode)
3470 end = gen_lowpart (data->operand[0].mode, end);
3471
3472 insn = data->genfun (end, dest_mem, src_mem);
3473
64db345d 3474 gcc_assert (insn);
727c62dd 3475
3476 emit_insn (insn);
3477
3478 /* movstr is supposed to set end to the address of the NUL
3479 terminator. If the caller requested a mempcpy-like return value,
3480 adjust it. */
3481 if (endp == 1 && target != const0_rtx)
c5aba89c 3482 {
3483 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3484 emit_move_insn (target, force_operand (tem, NULL_RTX));
3485 }
727c62dd 3486
3487 return target;
3488}
3489
c2f47e15 3490/* Expand expression EXP, which is a call to the strcpy builtin. Return
3491 NULL_RTX if we failed the caller should emit a normal call, otherwise
3492 try to get the result in TARGET, if convenient (and in mode MODE if that's
6f428e8b 3493 convenient). */
902de8ed 3494
53800dbe 3495static rtx
a65c4d64 3496expand_builtin_strcpy (tree exp, rtx target)
53800dbe 3497{
c2f47e15 3498 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3499 {
3500 tree dest = CALL_EXPR_ARG (exp, 0);
3501 tree src = CALL_EXPR_ARG (exp, 1);
a65c4d64 3502 return expand_builtin_strcpy_args (dest, src, target);
c2f47e15 3503 }
3504 return NULL_RTX;
3505}
3506
3507/* Helper function to do the actual work for expand_builtin_strcpy. The
3508 arguments to the builtin_strcpy call DEST and SRC are broken out
3509 so that this can also be called without constructing an actual CALL_EXPR.
3510 The other arguments and return value are the same as for
3511 expand_builtin_strcpy. */
3512
3513static rtx
a65c4d64 3514expand_builtin_strcpy_args (tree dest, tree src, rtx target)
c2f47e15 3515{
c2f47e15 3516 return expand_movstr (dest, src, target, /*endp=*/0);
53800dbe 3517}
3518
c2f47e15 3519/* Expand a call EXP to the stpcpy builtin.
3520 Return NULL_RTX if we failed the caller should emit a normal call,
3b824fa6 3521 otherwise try to get the result in TARGET, if convenient (and in
3522 mode MODE if that's convenient). */
3523
3524static rtx
dc369150 3525expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3b824fa6 3526{
c2f47e15 3527 tree dst, src;
389dd41b 3528 location_t loc = EXPR_LOCATION (exp);
c2f47e15 3529
3530 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3531 return NULL_RTX;
3532
3533 dst = CALL_EXPR_ARG (exp, 0);
3534 src = CALL_EXPR_ARG (exp, 1);
3535
727c62dd 3536 /* If return value is ignored, transform stpcpy into strcpy. */
c8b17b2e 3537 if (target == const0_rtx && implicit_built_in_decls[BUILT_IN_STRCPY])
978836e5 3538 {
3539 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
a65c4d64 3540 tree result = build_call_nofold (fn, 2, dst, src);
c8b17b2e 3541 return expand_expr (result, target, mode, EXPAND_NORMAL);
978836e5 3542 }
3b824fa6 3543 else
3544 {
c2f47e15 3545 tree len, lenp1;
727c62dd 3546 rtx ret;
647661c6 3547
9fe0e1b8 3548 /* Ensure we get an actual string whose length can be evaluated at
a0c938f0 3549 compile-time, not an expression containing a string. This is
3550 because the latter will potentially produce pessimized code
3551 when used to produce the return value. */
681fab1e 3552 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
c2f47e15 3553 return expand_movstr (dst, src, target, /*endp=*/2);
3b824fa6 3554
389dd41b 3555 lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
a65c4d64 3556 ret = expand_builtin_mempcpy_args (dst, src, lenp1,
c2f47e15 3557 target, mode, /*endp=*/2);
727c62dd 3558
3559 if (ret)
3560 return ret;
3561
3562 if (TREE_CODE (len) == INTEGER_CST)
3563 {
8ec3c5c2 3564 rtx len_rtx = expand_normal (len);
727c62dd 3565
971ba038 3566 if (CONST_INT_P (len_rtx))
727c62dd 3567 {
a65c4d64 3568 ret = expand_builtin_strcpy_args (dst, src, target);
727c62dd 3569
3570 if (ret)
3571 {
3572 if (! target)
7ac87324 3573 {
3574 if (mode != VOIDmode)
3575 target = gen_reg_rtx (mode);
3576 else
3577 target = gen_reg_rtx (GET_MODE (ret));
3578 }
727c62dd 3579 if (GET_MODE (target) != GET_MODE (ret))
3580 ret = gen_lowpart (GET_MODE (target), ret);
3581
c5aba89c 3582 ret = plus_constant (ret, INTVAL (len_rtx));
3583 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
64db345d 3584 gcc_assert (ret);
727c62dd 3585
3586 return target;
3587 }
3588 }
3589 }
3590
c2f47e15 3591 return expand_movstr (dst, src, target, /*endp=*/2);
3b824fa6 3592 }
3593}
3594
6840589f 3595/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3596 bytes from constant string DATA + OFFSET and return it as target
3597 constant. */
3598
09879952 3599rtx
aecda0d6 3600builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3601 enum machine_mode mode)
6840589f 3602{
3603 const char *str = (const char *) data;
3604
3605 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3606 return const0_rtx;
3607
3608 return c_readstr (str + offset, mode);
3609}
3610
c2f47e15 3611/* Expand expression EXP, which is a call to the strncpy builtin. Return
3612 NULL_RTX if we failed the caller should emit a normal call. */
ed09096d 3613
3614static rtx
a65c4d64 3615expand_builtin_strncpy (tree exp, rtx target)
ed09096d 3616{
389dd41b 3617 location_t loc = EXPR_LOCATION (exp);
c2f47e15 3618
3619 if (validate_arglist (exp,
3620 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
ed09096d 3621 {
c2f47e15 3622 tree dest = CALL_EXPR_ARG (exp, 0);
3623 tree src = CALL_EXPR_ARG (exp, 1);
3624 tree len = CALL_EXPR_ARG (exp, 2);
3625 tree slen = c_strlen (src, 1);
6840589f 3626
8ff6a5cd 3627 /* We must be passed a constant len and src parameter. */
3628 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
c2f47e15 3629 return NULL_RTX;
ed09096d 3630
389dd41b 3631 slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
ed09096d 3632
3633 /* We're required to pad with trailing zeros if the requested
a0c938f0 3634 len is greater than strlen(s2)+1. In that case try to
6840589f 3635 use store_by_pieces, if it fails, punt. */
ed09096d 3636 if (tree_int_cst_lt (slen, len))
6840589f 3637 {
27d0c333 3638 unsigned int dest_align
3639 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
c2f47e15 3640 const char *p = c_getstr (src);
6840589f 3641 rtx dest_mem;
3642
27d0c333 3643 if (!p || dest_align == 0 || !host_integerp (len, 1)
3644 || !can_store_by_pieces (tree_low_cst (len, 1),
6840589f 3645 builtin_strncpy_read_str,
364c0c59 3646 CONST_CAST (char *, p),
3647 dest_align, false))
c2f47e15 3648 return NULL_RTX;
6840589f 3649
d8ae1baa 3650 dest_mem = get_memory_rtx (dest, len);
27d0c333 3651 store_by_pieces (dest_mem, tree_low_cst (len, 1),
6840589f 3652 builtin_strncpy_read_str,
364c0c59 3653 CONST_CAST (char *, p), dest_align, false, 0);
a65c4d64 3654 dest_mem = force_operand (XEXP (dest_mem, 0), target);
85d654dd 3655 dest_mem = convert_memory_address (ptr_mode, dest_mem);
e5716f7e 3656 return dest_mem;
6840589f 3657 }
ed09096d 3658 }
c2f47e15 3659 return NULL_RTX;
ed09096d 3660}
3661
ecc318ff 3662/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3663 bytes from constant string DATA + OFFSET and return it as target
3664 constant. */
3665
f656b751 3666rtx
aecda0d6 3667builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3668 enum machine_mode mode)
ecc318ff 3669{
3670 const char *c = (const char *) data;
364c0c59 3671 char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
ecc318ff 3672
3673 memset (p, *c, GET_MODE_SIZE (mode));
3674
3675 return c_readstr (p, mode);
3676}
3677
a7ec6974 3678/* Callback routine for store_by_pieces. Return the RTL of a register
3679 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3680 char value given in the RTL register data. For example, if mode is
3681 4 bytes wide, return the RTL for 0x01010101*data. */
3682
3683static rtx
aecda0d6 3684builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3685 enum machine_mode mode)
a7ec6974 3686{
3687 rtx target, coeff;
3688 size_t size;
3689 char *p;
3690
3691 size = GET_MODE_SIZE (mode);
f0ce3b1f 3692 if (size == 1)
3693 return (rtx) data;
a7ec6974 3694
364c0c59 3695 p = XALLOCAVEC (char, size);
a7ec6974 3696 memset (p, 1, size);
3697 coeff = c_readstr (p, mode);
3698
f0ce3b1f 3699 target = convert_to_mode (mode, (rtx) data, 1);
a7ec6974 3700 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3701 return force_reg (mode, target);
3702}
3703
c2f47e15 3704/* Expand expression EXP, which is a call to the memset builtin. Return
3705 NULL_RTX if we failed the caller should emit a normal call, otherwise
3706 try to get the result in TARGET, if convenient (and in mode MODE if that's
6f428e8b 3707 convenient). */
902de8ed 3708
53800dbe 3709static rtx
c2f47e15 3710expand_builtin_memset (tree exp, rtx target, enum machine_mode mode)
53800dbe 3711{
c2f47e15 3712 if (!validate_arglist (exp,
3713 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3714 return NULL_RTX;
53800dbe 3715 else
3716 {
c2f47e15 3717 tree dest = CALL_EXPR_ARG (exp, 0);
3718 tree val = CALL_EXPR_ARG (exp, 1);
3719 tree len = CALL_EXPR_ARG (exp, 2);
3720 return expand_builtin_memset_args (dest, val, len, target, mode, exp);
3721 }
3722}
53800dbe 3723
c2f47e15 3724/* Helper function to do the actual work for expand_builtin_memset. The
3725 arguments to the builtin_memset call DEST, VAL, and LEN are broken out
3726 so that this can also be called without constructing an actual CALL_EXPR.
3727 The other arguments and return value are the same as for
3728 expand_builtin_memset. */
6b961939 3729
c2f47e15 3730static rtx
3731expand_builtin_memset_args (tree dest, tree val, tree len,
3732 rtx target, enum machine_mode mode, tree orig_exp)
3733{
3734 tree fndecl, fn;
3735 enum built_in_function fcode;
3736 char c;
3737 unsigned int dest_align;
3738 rtx dest_mem, dest_addr, len_rtx;
3739 HOST_WIDE_INT expected_size = -1;
3740 unsigned int expected_align = 0;
75a70cf9 3741 tree_ann_common_t ann;
53800dbe 3742
c2f47e15 3743 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
162719b3 3744
c2f47e15 3745 /* If DEST is not a pointer type, don't do this operation in-line. */
3746 if (dest_align == 0)
3747 return NULL_RTX;
6f428e8b 3748
75a70cf9 3749 ann = tree_common_ann (orig_exp);
3750 if (ann)
3751 stringop_block_profile (ann->stmt, &expected_align, &expected_size);
3752
c2f47e15 3753 if (expected_align < dest_align)
3754 expected_align = dest_align;
6b961939 3755
c2f47e15 3756 /* If the LEN parameter is zero, return DEST. */
3757 if (integer_zerop (len))
3758 {
3759 /* Evaluate and ignore VAL in case it has side-effects. */
3760 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3761 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3762 }
7a3e5564 3763
c2f47e15 3764 /* Stabilize the arguments in case we fail. */
3765 dest = builtin_save_expr (dest);
3766 val = builtin_save_expr (val);
3767 len = builtin_save_expr (len);
a7ec6974 3768
c2f47e15 3769 len_rtx = expand_normal (len);
3770 dest_mem = get_memory_rtx (dest, len);
a7ec6974 3771
c2f47e15 3772 if (TREE_CODE (val) != INTEGER_CST)
3773 {
3774 rtx val_rtx;
a7ec6974 3775
c2f47e15 3776 val_rtx = expand_normal (val);
3777 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3778 val_rtx, 0);
53800dbe 3779
c2f47e15 3780 /* Assume that we can memset by pieces if we can store
3781 * the coefficients by pieces (in the required modes).
3782 * We can't pass builtin_memset_gen_str as that emits RTL. */
3783 c = 1;
3784 if (host_integerp (len, 1)
c2f47e15 3785 && can_store_by_pieces (tree_low_cst (len, 1),
4b297e2e 3786 builtin_memset_read_str, &c, dest_align,
3787 true))
c2f47e15 3788 {
3789 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3790 val_rtx);
3791 store_by_pieces (dest_mem, tree_low_cst (len, 1),
4b297e2e 3792 builtin_memset_gen_str, val_rtx, dest_align,
3793 true, 0);
c2f47e15 3794 }
3795 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3796 dest_align, expected_align,
3797 expected_size))
6b961939 3798 goto do_libcall;
c2f47e15 3799
3800 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3801 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3802 return dest_mem;
3803 }
53800dbe 3804
c2f47e15 3805 if (target_char_cast (val, &c))
3806 goto do_libcall;
ecc318ff 3807
c2f47e15 3808 if (c)
3809 {
3810 if (host_integerp (len, 1)
c2f47e15 3811 && can_store_by_pieces (tree_low_cst (len, 1),
4b297e2e 3812 builtin_memset_read_str, &c, dest_align,
3813 true))
c2f47e15 3814 store_by_pieces (dest_mem, tree_low_cst (len, 1),
4b297e2e 3815 builtin_memset_read_str, &c, dest_align, true, 0);
c2f47e15 3816 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3817 dest_align, expected_align,
3818 expected_size))
3819 goto do_libcall;
3820
3821 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3822 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3823 return dest_mem;
3824 }
ecc318ff 3825
c2f47e15 3826 set_mem_align (dest_mem, dest_align);
3827 dest_addr = clear_storage_hints (dest_mem, len_rtx,
3828 CALL_EXPR_TAILCALL (orig_exp)
3829 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3830 expected_align, expected_size);
53800dbe 3831
c2f47e15 3832 if (dest_addr == 0)
3833 {
3834 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3835 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3836 }
53800dbe 3837
c2f47e15 3838 return dest_addr;
6b961939 3839
c2f47e15 3840 do_libcall:
3841 fndecl = get_callee_fndecl (orig_exp);
3842 fcode = DECL_FUNCTION_CODE (fndecl);
3843 if (fcode == BUILT_IN_MEMSET)
a65c4d64 3844 fn = build_call_nofold (fndecl, 3, dest, val, len);
c2f47e15 3845 else if (fcode == BUILT_IN_BZERO)
a65c4d64 3846 fn = build_call_nofold (fndecl, 2, dest, len);
c2f47e15 3847 else
3848 gcc_unreachable ();
a65c4d64 3849 gcc_assert (TREE_CODE (fn) == CALL_EXPR);
3850 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
c2f47e15 3851 return expand_call (fn, target, target == const0_rtx);
53800dbe 3852}
3853
c2f47e15 3854/* Expand expression EXP, which is a call to the bzero builtin. Return
3855 NULL_RTX if we failed the caller should emit a normal call. */
27d0c333 3856
ffc83088 3857static rtx
0b25db21 3858expand_builtin_bzero (tree exp)
ffc83088 3859{
c2f47e15 3860 tree dest, size;
389dd41b 3861 location_t loc = EXPR_LOCATION (exp);
ffc83088 3862
c2f47e15 3863 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7369e7ba 3864 return NULL_RTX;
ffc83088 3865
c2f47e15 3866 dest = CALL_EXPR_ARG (exp, 0);
3867 size = CALL_EXPR_ARG (exp, 1);
bf8e3599 3868
7369e7ba 3869 /* New argument list transforming bzero(ptr x, int y) to
6f428e8b 3870 memset(ptr x, int 0, size_t y). This is done this way
3871 so that if it isn't expanded inline, we fallback to
3872 calling bzero instead of memset. */
bf8e3599 3873
c2f47e15 3874 return expand_builtin_memset_args (dest, integer_zero_node,
389dd41b 3875 fold_convert_loc (loc, sizetype, size),
c2f47e15 3876 const0_rtx, VOIDmode, exp);
ffc83088 3877}
3878
7a3f89b5 3879/* Expand expression EXP, which is a call to the memcmp built-in function.
c2f47e15 3880 Return NULL_RTX if we failed and the
53800dbe 3881 caller should emit a normal call, otherwise try to get the result in
6f428e8b 3882 TARGET, if convenient (and in mode MODE, if that's convenient). */
27d0c333 3883
53800dbe 3884static rtx
a65c4d64 3885expand_builtin_memcmp (tree exp, ATTRIBUTE_UNUSED rtx target,
3886 ATTRIBUTE_UNUSED enum machine_mode mode)
53800dbe 3887{
a65c4d64 3888 location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp);
389dd41b 3889
c2f47e15 3890 if (!validate_arglist (exp,
3891 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3892 return NULL_RTX;
6f428e8b 3893
6ac5504b 3894#if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
53800dbe 3895 {
0cd832f0 3896 rtx arg1_rtx, arg2_rtx, arg3_rtx;
53800dbe 3897 rtx result;
0cd832f0 3898 rtx insn;
c2f47e15 3899 tree arg1 = CALL_EXPR_ARG (exp, 0);
3900 tree arg2 = CALL_EXPR_ARG (exp, 1);
3901 tree len = CALL_EXPR_ARG (exp, 2);
53800dbe 3902
3903 int arg1_align
3904 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3905 int arg2_align
3906 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
b428c0a5 3907 enum machine_mode insn_mode;
3908
3909#ifdef HAVE_cmpmemsi
3910 if (HAVE_cmpmemsi)
3911 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3912 else
3913#endif
6ac5504b 3914#ifdef HAVE_cmpstrnsi
3915 if (HAVE_cmpstrnsi)
3916 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
b428c0a5 3917 else
3918#endif
c2f47e15 3919 return NULL_RTX;
53800dbe 3920
3921 /* If we don't have POINTER_TYPE, call the function. */
3922 if (arg1_align == 0 || arg2_align == 0)
c2f47e15 3923 return NULL_RTX;
53800dbe 3924
3925 /* Make a place to write the result of the instruction. */
3926 result = target;
3927 if (! (result != 0
8ad4c111 3928 && REG_P (result) && GET_MODE (result) == insn_mode
53800dbe 3929 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3930 result = gen_reg_rtx (insn_mode);
3931
d8ae1baa 3932 arg1_rtx = get_memory_rtx (arg1, len);
3933 arg2_rtx = get_memory_rtx (arg2, len);
389dd41b 3934 arg3_rtx = expand_normal (fold_convert_loc (loc, sizetype, len));
83f88f8e 3935
3936 /* Set MEM_SIZE as appropriate. */
971ba038 3937 if (CONST_INT_P (arg3_rtx))
83f88f8e 3938 {
3939 set_mem_size (arg1_rtx, arg3_rtx);
3940 set_mem_size (arg2_rtx, arg3_rtx);
3941 }
3942
b428c0a5 3943#ifdef HAVE_cmpmemsi
3944 if (HAVE_cmpmemsi)
3945 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3946 GEN_INT (MIN (arg1_align, arg2_align)));
0cd832f0 3947 else
b428c0a5 3948#endif
6ac5504b 3949#ifdef HAVE_cmpstrnsi
3950 if (HAVE_cmpstrnsi)
3951 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3952 GEN_INT (MIN (arg1_align, arg2_align)));
b428c0a5 3953 else
3954#endif
64db345d 3955 gcc_unreachable ();
0cd832f0 3956
3957 if (insn)
3958 emit_insn (insn);
3959 else
2dd6f9ed 3960 emit_library_call_value (memcmp_libfunc, result, LCT_PURE,
0cd832f0 3961 TYPE_MODE (integer_type_node), 3,
3962 XEXP (arg1_rtx, 0), Pmode,
3963 XEXP (arg2_rtx, 0), Pmode,
3964 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
78a8ed03 3965 TYPE_UNSIGNED (sizetype)),
0cd832f0 3966 TYPE_MODE (sizetype));
53800dbe 3967
3968 /* Return the value in the proper mode for this function. */
3969 mode = TYPE_MODE (TREE_TYPE (exp));
3970 if (GET_MODE (result) == mode)
3971 return result;
3972 else if (target != 0)
3973 {
3974 convert_move (target, result, 0);
3975 return target;
3976 }
3977 else
3978 return convert_to_mode (mode, result, 0);
3979 }
83d79705 3980#endif
53800dbe 3981
c2f47e15 3982 return NULL_RTX;
6f428e8b 3983}
3984
c2f47e15 3985/* Expand expression EXP, which is a call to the strcmp builtin. Return NULL_RTX
53800dbe 3986 if we failed the caller should emit a normal call, otherwise try to get
3987 the result in TARGET, if convenient. */
902de8ed 3988
53800dbe 3989static rtx
a65c4d64 3990expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target)
53800dbe 3991{
c2f47e15 3992 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3993 return NULL_RTX;
bf8e3599 3994
6ac5504b 3995#if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3996 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3997 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3998 {
3999 rtx arg1_rtx, arg2_rtx;
4000 rtx result, insn = NULL_RTX;
4001 tree fndecl, fn;
c2f47e15 4002 tree arg1 = CALL_EXPR_ARG (exp, 0);
4003 tree arg2 = CALL_EXPR_ARG (exp, 1);
a0c938f0 4004
6ac5504b 4005 int arg1_align
4006 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4007 int arg2_align
4008 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4009
4010 /* If we don't have POINTER_TYPE, call the function. */
4011 if (arg1_align == 0 || arg2_align == 0)
c2f47e15 4012 return NULL_RTX;
7a3f89b5 4013
6ac5504b 4014 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
4015 arg1 = builtin_save_expr (arg1);
4016 arg2 = builtin_save_expr (arg2);
7a3f89b5 4017
d8ae1baa 4018 arg1_rtx = get_memory_rtx (arg1, NULL);
4019 arg2_rtx = get_memory_rtx (arg2, NULL);
53800dbe 4020
6ac5504b 4021#ifdef HAVE_cmpstrsi
4022 /* Try to call cmpstrsi. */
4023 if (HAVE_cmpstrsi)
4024 {
a0c938f0 4025 enum machine_mode insn_mode
6ac5504b 4026 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
4027
4028 /* Make a place to write the result of the instruction. */
4029 result = target;
4030 if (! (result != 0
4031 && REG_P (result) && GET_MODE (result) == insn_mode
4032 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4033 result = gen_reg_rtx (insn_mode);
4034
4035 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
4036 GEN_INT (MIN (arg1_align, arg2_align)));
4037 }
4038#endif
03fd9d2c 4039#ifdef HAVE_cmpstrnsi
6ac5504b 4040 /* Try to determine at least one length and call cmpstrnsi. */
a0c938f0 4041 if (!insn && HAVE_cmpstrnsi)
6ac5504b 4042 {
4043 tree len;
4044 rtx arg3_rtx;
4045
a0c938f0 4046 enum machine_mode insn_mode
6ac5504b 4047 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
4048 tree len1 = c_strlen (arg1, 1);
4049 tree len2 = c_strlen (arg2, 1);
4050
4051 if (len1)
4052 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
4053 if (len2)
4054 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
4055
4056 /* If we don't have a constant length for the first, use the length
4057 of the second, if we know it. We don't require a constant for
4058 this case; some cost analysis could be done if both are available
4059 but neither is constant. For now, assume they're equally cheap,
4060 unless one has side effects. If both strings have constant lengths,
4061 use the smaller. */
4062
4063 if (!len1)
4064 len = len2;
4065 else if (!len2)
4066 len = len1;
4067 else if (TREE_SIDE_EFFECTS (len1))
4068 len = len2;
4069 else if (TREE_SIDE_EFFECTS (len2))
4070 len = len1;
4071 else if (TREE_CODE (len1) != INTEGER_CST)
4072 len = len2;
4073 else if (TREE_CODE (len2) != INTEGER_CST)
4074 len = len1;
4075 else if (tree_int_cst_lt (len1, len2))
4076 len = len1;
4077 else
4078 len = len2;
4079
4080 /* If both arguments have side effects, we cannot optimize. */
4081 if (!len || TREE_SIDE_EFFECTS (len))
6b961939 4082 goto do_libcall;
53800dbe 4083
8ec3c5c2 4084 arg3_rtx = expand_normal (len);
902de8ed 4085
6ac5504b 4086 /* Make a place to write the result of the instruction. */
4087 result = target;
4088 if (! (result != 0
4089 && REG_P (result) && GET_MODE (result) == insn_mode
4090 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4091 result = gen_reg_rtx (insn_mode);
53800dbe 4092
6ac5504b 4093 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4094 GEN_INT (MIN (arg1_align, arg2_align)));
4095 }
4096#endif
3f8aefe2 4097
6ac5504b 4098 if (insn)
4099 {
a65c4d64 4100 enum machine_mode mode;
6ac5504b 4101 emit_insn (insn);
3f8aefe2 4102
6ac5504b 4103 /* Return the value in the proper mode for this function. */
4104 mode = TYPE_MODE (TREE_TYPE (exp));
4105 if (GET_MODE (result) == mode)
4106 return result;
4107 if (target == 0)
4108 return convert_to_mode (mode, result, 0);
4109 convert_move (target, result, 0);
4110 return target;
4111 }
902de8ed 4112
6ac5504b 4113 /* Expand the library call ourselves using a stabilized argument
4114 list to avoid re-evaluating the function's arguments twice. */
2694880e 4115#ifdef HAVE_cmpstrnsi
6b961939 4116 do_libcall:
2694880e 4117#endif
6ac5504b 4118 fndecl = get_callee_fndecl (exp);
a65c4d64 4119 fn = build_call_nofold (fndecl, 2, arg1, arg2);
4120 gcc_assert (TREE_CODE (fn) == CALL_EXPR);
4121 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
6ac5504b 4122 return expand_call (fn, target, target == const0_rtx);
4123 }
7a3f89b5 4124#endif
c2f47e15 4125 return NULL_RTX;
83d79705 4126}
53800dbe 4127
c2f47e15 4128/* Expand expression EXP, which is a call to the strncmp builtin. Return
4129 NULL_RTX if we failed the caller should emit a normal call, otherwise try to get
ed09096d 4130 the result in TARGET, if convenient. */
27d0c333 4131
ed09096d 4132static rtx
a65c4d64 4133expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
4134 ATTRIBUTE_UNUSED enum machine_mode mode)
ed09096d 4135{
a65c4d64 4136 location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp);
389dd41b 4137
c2f47e15 4138 if (!validate_arglist (exp,
4139 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4140 return NULL_RTX;
ed09096d 4141
6e34e617 4142 /* If c_strlen can determine an expression for one of the string
6ac5504b 4143 lengths, and it doesn't have side effects, then emit cmpstrnsi
7a3f89b5 4144 using length MIN(strlen(string)+1, arg3). */
6ac5504b 4145#ifdef HAVE_cmpstrnsi
4146 if (HAVE_cmpstrnsi)
7a3f89b5 4147 {
4148 tree len, len1, len2;
4149 rtx arg1_rtx, arg2_rtx, arg3_rtx;
4150 rtx result, insn;
0b25db21 4151 tree fndecl, fn;
c2f47e15 4152 tree arg1 = CALL_EXPR_ARG (exp, 0);
4153 tree arg2 = CALL_EXPR_ARG (exp, 1);
4154 tree arg3 = CALL_EXPR_ARG (exp, 2);
6f428e8b 4155
7a3f89b5 4156 int arg1_align
4157 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4158 int arg2_align
4159 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4160 enum machine_mode insn_mode
6ac5504b 4161 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
bf8e3599 4162
681fab1e 4163 len1 = c_strlen (arg1, 1);
4164 len2 = c_strlen (arg2, 1);
7a3f89b5 4165
4166 if (len1)
389dd41b 4167 len1 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len1);
7a3f89b5 4168 if (len2)
389dd41b 4169 len2 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len2);
7a3f89b5 4170
4171 /* If we don't have a constant length for the first, use the length
4172 of the second, if we know it. We don't require a constant for
4173 this case; some cost analysis could be done if both are available
4174 but neither is constant. For now, assume they're equally cheap,
4175 unless one has side effects. If both strings have constant lengths,
4176 use the smaller. */
4177
4178 if (!len1)
4179 len = len2;
4180 else if (!len2)
4181 len = len1;
4182 else if (TREE_SIDE_EFFECTS (len1))
4183 len = len2;
4184 else if (TREE_SIDE_EFFECTS (len2))
4185 len = len1;
4186 else if (TREE_CODE (len1) != INTEGER_CST)
4187 len = len2;
4188 else if (TREE_CODE (len2) != INTEGER_CST)
4189 len = len1;
4190 else if (tree_int_cst_lt (len1, len2))
4191 len = len1;
4192 else
4193 len = len2;
6e34e617 4194
7a3f89b5 4195 /* If both arguments have side effects, we cannot optimize. */
4196 if (!len || TREE_SIDE_EFFECTS (len))
c2f47e15 4197 return NULL_RTX;
bf8e3599 4198
7a3f89b5 4199 /* The actual new length parameter is MIN(len,arg3). */
389dd41b 4200 len = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (len), len,
4201 fold_convert_loc (loc, TREE_TYPE (len), arg3));
7a3f89b5 4202
4203 /* If we don't have POINTER_TYPE, call the function. */
4204 if (arg1_align == 0 || arg2_align == 0)
c2f47e15 4205 return NULL_RTX;
7a3f89b5 4206
4207 /* Make a place to write the result of the instruction. */
4208 result = target;
4209 if (! (result != 0
8ad4c111 4210 && REG_P (result) && GET_MODE (result) == insn_mode
7a3f89b5 4211 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4212 result = gen_reg_rtx (insn_mode);
4213
a65c4d64 4214 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
4215 arg1 = builtin_save_expr (arg1);
4216 arg2 = builtin_save_expr (arg2);
4217 len = builtin_save_expr (len);
27d0c333 4218
a65c4d64 4219 arg1_rtx = get_memory_rtx (arg1, len);
4220 arg2_rtx = get_memory_rtx (arg2, len);
4221 arg3_rtx = expand_normal (len);
4222 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4223 GEN_INT (MIN (arg1_align, arg2_align)));
4224 if (insn)
4225 {
4226 emit_insn (insn);
49f0327b 4227
a65c4d64 4228 /* Return the value in the proper mode for this function. */
4229 mode = TYPE_MODE (TREE_TYPE (exp));
4230 if (GET_MODE (result) == mode)
4231 return result;
4232 if (target == 0)
4233 return convert_to_mode (mode, result, 0);
4234 convert_move (target, result, 0);
4235 return target;
4236 }
27d0c333 4237
a65c4d64 4238 /* Expand the library call ourselves using a stabilized argument
4239 list to avoid re-evaluating the function's arguments twice. */
4240 fndecl = get_callee_fndecl (exp);
4241 fn = build_call_nofold (fndecl, 3, arg1, arg2, len);
4242 gcc_assert (TREE_CODE (fn) == CALL_EXPR);
4243 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4244 return expand_call (fn, target, target == const0_rtx);
4245 }
4246#endif
c2f47e15 4247 return NULL_RTX;
49f0327b 4248}
4249
a66c9326 4250/* Expand a call to __builtin_saveregs, generating the result in TARGET,
4251 if that's convenient. */
902de8ed 4252
a66c9326 4253rtx
aecda0d6 4254expand_builtin_saveregs (void)
53800dbe 4255{
a66c9326 4256 rtx val, seq;
53800dbe 4257
4258 /* Don't do __builtin_saveregs more than once in a function.
4259 Save the result of the first call and reuse it. */
4260 if (saveregs_value != 0)
4261 return saveregs_value;
53800dbe 4262
a66c9326 4263 /* When this function is called, it means that registers must be
4264 saved on entry to this function. So we migrate the call to the
4265 first insn of this function. */
4266
4267 start_sequence ();
53800dbe 4268
a66c9326 4269 /* Do whatever the machine needs done in this case. */
45550790 4270 val = targetm.calls.expand_builtin_saveregs ();
53800dbe 4271
a66c9326 4272 seq = get_insns ();
4273 end_sequence ();
53800dbe 4274
a66c9326 4275 saveregs_value = val;
53800dbe 4276
31d3e01c 4277 /* Put the insns after the NOTE that starts the function. If this
4278 is inside a start_sequence, make the outer-level insn chain current, so
a66c9326 4279 the code is placed at the start of the function. */
4280 push_topmost_sequence ();
0ec80471 4281 emit_insn_after (seq, entry_of_function ());
a66c9326 4282 pop_topmost_sequence ();
4283
4284 return val;
53800dbe 4285}
4286
4287/* __builtin_args_info (N) returns word N of the arg space info
4288 for the current function. The number and meanings of words
4289 is controlled by the definition of CUMULATIVE_ARGS. */
f7c44134 4290
53800dbe 4291static rtx
c2f47e15 4292expand_builtin_args_info (tree exp)
53800dbe 4293{
53800dbe 4294 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
abe32cce 4295 int *word_ptr = (int *) &crtl->args.info;
53800dbe 4296
64db345d 4297 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
53800dbe 4298
c2f47e15 4299 if (call_expr_nargs (exp) != 0)
53800dbe 4300 {
c2f47e15 4301 if (!host_integerp (CALL_EXPR_ARG (exp, 0), 0))
eb586f2c 4302 error ("argument of %<__builtin_args_info%> must be constant");
53800dbe 4303 else
4304 {
c2f47e15 4305 HOST_WIDE_INT wordnum = tree_low_cst (CALL_EXPR_ARG (exp, 0), 0);
53800dbe 4306
27d0c333 4307 if (wordnum < 0 || wordnum >= nwords)
eb586f2c 4308 error ("argument of %<__builtin_args_info%> out of range");
53800dbe 4309 else
4310 return GEN_INT (word_ptr[wordnum]);
4311 }
4312 }
4313 else
eb586f2c 4314 error ("missing argument in %<__builtin_args_info%>");
53800dbe 4315
4316 return const0_rtx;
53800dbe 4317}
4318
79012a9d 4319/* Expand a call to __builtin_next_arg. */
27d0c333 4320
53800dbe 4321static rtx
79012a9d 4322expand_builtin_next_arg (void)
53800dbe 4323{
79012a9d 4324 /* Checking arguments is already done in fold_builtin_next_arg
4325 that must be called before this function. */
940ddc5c 4326 return expand_binop (ptr_mode, add_optab,
abe32cce 4327 crtl->args.internal_arg_pointer,
4328 crtl->args.arg_offset_rtx,
53800dbe 4329 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4330}
4331
a66c9326 4332/* Make it easier for the backends by protecting the valist argument
4333 from multiple evaluations. */
4334
4335static tree
389dd41b 4336stabilize_va_list_loc (location_t loc, tree valist, int needs_lvalue)
a66c9326 4337{
5f57a8b1 4338 tree vatype = targetm.canonical_va_list_type (TREE_TYPE (valist));
4339
4340 gcc_assert (vatype != NULL_TREE);
4341
4342 if (TREE_CODE (vatype) == ARRAY_TYPE)
a66c9326 4343 {
2d47cc32 4344 if (TREE_SIDE_EFFECTS (valist))
4345 valist = save_expr (valist);
11a61dea 4346
2d47cc32 4347 /* For this case, the backends will be expecting a pointer to
5f57a8b1 4348 vatype, but it's possible we've actually been given an array
4349 (an actual TARGET_CANONICAL_VA_LIST_TYPE (valist)).
2d47cc32 4350 So fix it. */
4351 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
8a15c04a 4352 {
5f57a8b1 4353 tree p1 = build_pointer_type (TREE_TYPE (vatype));
389dd41b 4354 valist = build_fold_addr_expr_with_type_loc (loc, valist, p1);
8a15c04a 4355 }
a66c9326 4356 }
11a61dea 4357 else
a66c9326 4358 {
2d47cc32 4359 tree pt;
11a61dea 4360
2d47cc32 4361 if (! needs_lvalue)
4362 {
11a61dea 4363 if (! TREE_SIDE_EFFECTS (valist))
4364 return valist;
bf8e3599 4365
5f57a8b1 4366 pt = build_pointer_type (vatype);
389dd41b 4367 valist = fold_build1_loc (loc, ADDR_EXPR, pt, valist);
a66c9326 4368 TREE_SIDE_EFFECTS (valist) = 1;
a66c9326 4369 }
2d47cc32 4370
11a61dea 4371 if (TREE_SIDE_EFFECTS (valist))
2d47cc32 4372 valist = save_expr (valist);
389dd41b 4373 valist = build_fold_indirect_ref_loc (loc, valist);
a66c9326 4374 }
4375
4376 return valist;
4377}
4378
2e15d750 4379/* The "standard" definition of va_list is void*. */
4380
4381tree
4382std_build_builtin_va_list (void)
4383{
4384 return ptr_type_node;
4385}
4386
5f57a8b1 4387/* The "standard" abi va_list is va_list_type_node. */
4388
4389tree
4390std_fn_abi_va_list (tree fndecl ATTRIBUTE_UNUSED)
4391{
4392 return va_list_type_node;
4393}
4394
4395/* The "standard" type of va_list is va_list_type_node. */
4396
4397tree
4398std_canonical_va_list_type (tree type)
4399{
4400 tree wtype, htype;
4401
4402 if (INDIRECT_REF_P (type))
4403 type = TREE_TYPE (type);
4404 else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE(type)))
4405 type = TREE_TYPE (type);
5f57a8b1 4406 wtype = va_list_type_node;
4407 htype = type;
7b36f9ab 4408 /* Treat structure va_list types. */
4409 if (TREE_CODE (wtype) == RECORD_TYPE && POINTER_TYPE_P (htype))
4410 htype = TREE_TYPE (htype);
4411 else if (TREE_CODE (wtype) == ARRAY_TYPE)
5f57a8b1 4412 {
4413 /* If va_list is an array type, the argument may have decayed
4414 to a pointer type, e.g. by being passed to another function.
4415 In that case, unwrap both types so that we can compare the
4416 underlying records. */
4417 if (TREE_CODE (htype) == ARRAY_TYPE
4418 || POINTER_TYPE_P (htype))
4419 {
4420 wtype = TREE_TYPE (wtype);
4421 htype = TREE_TYPE (htype);
4422 }
4423 }
4424 if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
4425 return va_list_type_node;
4426
4427 return NULL_TREE;
4428}
4429
a66c9326 4430/* The "standard" implementation of va_start: just assign `nextarg' to
4431 the variable. */
27d0c333 4432
a66c9326 4433void
aecda0d6 4434std_expand_builtin_va_start (tree valist, rtx nextarg)
a66c9326 4435{
f03c17bc 4436 rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
4437 convert_move (va_r, nextarg, 0);
a66c9326 4438}
4439
c2f47e15 4440/* Expand EXP, a call to __builtin_va_start. */
27d0c333 4441
a66c9326 4442static rtx
c2f47e15 4443expand_builtin_va_start (tree exp)
a66c9326 4444{
4445 rtx nextarg;
c2f47e15 4446 tree valist;
389dd41b 4447 location_t loc = EXPR_LOCATION (exp);
a66c9326 4448
c2f47e15 4449 if (call_expr_nargs (exp) < 2)
cb166087 4450 {
389dd41b 4451 error_at (loc, "too few arguments to function %<va_start%>");
cb166087 4452 return const0_rtx;
4453 }
a66c9326 4454
c2f47e15 4455 if (fold_builtin_next_arg (exp, true))
79012a9d 4456 return const0_rtx;
7c2f0500 4457
79012a9d 4458 nextarg = expand_builtin_next_arg ();
389dd41b 4459 valist = stabilize_va_list_loc (loc, CALL_EXPR_ARG (exp, 0), 1);
a66c9326 4460
8a58ed0a 4461 if (targetm.expand_builtin_va_start)
4462 targetm.expand_builtin_va_start (valist, nextarg);
4463 else
4464 std_expand_builtin_va_start (valist, nextarg);
a66c9326 4465
4466 return const0_rtx;
4467}
4468
a66c9326 4469/* The "standard" implementation of va_arg: read the value from the
4470 current (padded) address and increment by the (padded) size. */
f7c44134 4471
e0eca1fa 4472tree
75a70cf9 4473std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
4474 gimple_seq *post_p)
fcdd3ab3 4475{
52cc2eeb 4476 tree addr, t, type_size, rounded_size, valist_tmp;
b8e8e485 4477 unsigned HOST_WIDE_INT align, boundary;
bef380a4 4478 bool indirect;
52cc2eeb 4479
4480#ifdef ARGS_GROW_DOWNWARD
4481 /* All of the alignment and movement below is for args-grow-up machines.
4482 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4483 implement their own specialized gimplify_va_arg_expr routines. */
64db345d 4484 gcc_unreachable ();
52cc2eeb 4485#endif
fcdd3ab3 4486
bef380a4 4487 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4488 if (indirect)
4489 type = build_pointer_type (type);
4490
52cc2eeb 4491 align = PARM_BOUNDARY / BITS_PER_UNIT;
c8b779eb 4492 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
4493
4494 /* When we align parameter on stack for caller, if the parameter
befa808c 4495 alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
4496 aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
c8b779eb 4497 here with caller. */
befa808c 4498 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
4499 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
c8b779eb 4500
4501 boundary /= BITS_PER_UNIT;
fcdd3ab3 4502
52cc2eeb 4503 /* Hoist the valist value into a temporary for the moment. */
ecdeeb37 4504 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4505
fcdd3ab3 4506 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4507 requires greater alignment, we must perform dynamic alignment. */
85c1f587 4508 if (boundary > align
4509 && !integer_zerop (TYPE_SIZE (type)))
fcdd3ab3 4510 {
41076ef6 4511 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
389dd41b 4512 fold_build2 (POINTER_PLUS_EXPR,
4513 TREE_TYPE (valist),
0de36bdb 4514 valist_tmp, size_int (boundary - 1)));
52cc2eeb 4515 gimplify_and_add (t, pre_p);
4516
0de36bdb 4517 t = fold_convert (sizetype, valist_tmp);
41076ef6 4518 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
0de36bdb 4519 fold_convert (TREE_TYPE (valist),
4520 fold_build2 (BIT_AND_EXPR, sizetype, t,
4521 size_int (-boundary))));
ecdeeb37 4522 gimplify_and_add (t, pre_p);
fcdd3ab3 4523 }
c5dc0c32 4524 else
4525 boundary = align;
4526
4527 /* If the actual alignment is less than the alignment of the type,
4528 adjust the type accordingly so that we don't assume strict alignment
f0b5f617 4529 when dereferencing the pointer. */
c5dc0c32 4530 boundary *= BITS_PER_UNIT;
4531 if (boundary < TYPE_ALIGN (type))
4532 {
4533 type = build_variant_type_copy (type);
4534 TYPE_ALIGN (type) = boundary;
4535 }
fcdd3ab3 4536
bcff3604 4537 /* Compute the rounded size of the type. */
52cc2eeb 4538 type_size = size_in_bytes (type);
4539 rounded_size = round_up (type_size, align);
4540
fcdd3ab3 4541 /* Reduce rounded_size so it's sharable with the postqueue. */
4542 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4543
4544 /* Get AP. */
ecdeeb37 4545 addr = valist_tmp;
52cc2eeb 4546 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
fcdd3ab3 4547 {
4548 /* Small args are padded downward. */
389dd41b 4549 t = fold_build2_loc (input_location, GT_EXPR, sizetype,
4550 rounded_size, size_int (align));
49d00087 4551 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4552 size_binop (MINUS_EXPR, rounded_size, type_size));
389dd41b 4553 addr = fold_build2 (POINTER_PLUS_EXPR,
4554 TREE_TYPE (addr), addr, t);
fcdd3ab3 4555 }
4556
fcdd3ab3 4557 /* Compute new value for AP. */
0de36bdb 4558 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (valist), valist_tmp, rounded_size);
41076ef6 4559 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
ecdeeb37 4560 gimplify_and_add (t, pre_p);
e0eca1fa 4561
4562 addr = fold_convert (build_pointer_type (type), addr);
fcdd3ab3 4563
bef380a4 4564 if (indirect)
f2462d6c 4565 addr = build_va_arg_indirect_ref (addr);
4566
4567 return build_va_arg_indirect_ref (addr);
4568}
a0930a69 4569
f2462d6c 4570/* Build an indirect-ref expression over the given TREE, which represents a
4571 piece of a va_arg() expansion. */
4572tree
4573build_va_arg_indirect_ref (tree addr)
4574{
389dd41b 4575 addr = build_fold_indirect_ref_loc (EXPR_LOCATION (addr), addr);
f2462d6c 4576
a0930a69 4577 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4578 mf_mark (addr);
bef380a4 4579
a0930a69 4580 return addr;
433006a9 4581}
4582
fcdd3ab3 4583/* Return a dummy expression of type TYPE in order to keep going after an
4584 error. */
4585
4586static tree
4587dummy_object (tree type)
4588{
535664e3 4589 tree t = build_int_cst (build_pointer_type (type), 0);
fcdd3ab3 4590 return build1 (INDIRECT_REF, type, t);
4591}
4592
2799a2b7 4593/* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4594 builtin function, but a very special sort of operator. */
fcdd3ab3 4595
4596enum gimplify_status
75a70cf9 4597gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
fcdd3ab3 4598{
5f57a8b1 4599 tree promoted_type, have_va_type;
fcdd3ab3 4600 tree valist = TREE_OPERAND (*expr_p, 0);
4601 tree type = TREE_TYPE (*expr_p);
4602 tree t;
389dd41b 4603 location_t loc = EXPR_LOCATION (*expr_p);
fcdd3ab3 4604
4605 /* Verify that valist is of the proper type. */
fcdd3ab3 4606 have_va_type = TREE_TYPE (valist);
f43dda35 4607 if (have_va_type == error_mark_node)
4608 return GS_ERROR;
5f57a8b1 4609 have_va_type = targetm.canonical_va_list_type (have_va_type);
f43dda35 4610
5f57a8b1 4611 if (have_va_type == NULL_TREE)
fcdd3ab3 4612 {
e60a6f7b 4613 error_at (loc, "first argument to %<va_arg%> not of type %<va_list%>");
e0eca1fa 4614 return GS_ERROR;
fcdd3ab3 4615 }
4616
4617 /* Generate a diagnostic for requesting data of a type that cannot
4618 be passed through `...' due to type promotion at the call site. */
5f57a8b1 4619 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
fcdd3ab3 4620 != type)
4621 {
4622 static bool gave_help;
a52d5726 4623 bool warned;
fcdd3ab3 4624
4625 /* Unfortunately, this is merely undefined, rather than a constraint
4626 violation, so we cannot make this an error. If this call is never
4627 executed, the program is still strictly conforming. */
e60a6f7b 4628 warned = warning_at (loc, 0,
4629 "%qT is promoted to %qT when passed through %<...%>",
4630 type, promoted_type);
a52d5726 4631 if (!gave_help && warned)
fcdd3ab3 4632 {
4633 gave_help = true;
e60a6f7b 4634 inform (loc, "(so you should pass %qT not %qT to %<va_arg%>)",
4635 promoted_type, type);
fcdd3ab3 4636 }
4637
4638 /* We can, however, treat "undefined" any way we please.
4639 Call abort to encourage the user to fix the program. */
a52d5726 4640 if (warned)
e60a6f7b 4641 inform (loc, "if this code is reached, the program will abort");
ad0e7a06 4642 /* Before the abort, allow the evaluation of the va_list
4643 expression to exit or longjmp. */
4644 gimplify_and_add (valist, pre_p);
389dd41b 4645 t = build_call_expr_loc (loc,
4646 implicit_built_in_decls[BUILT_IN_TRAP], 0);
75a70cf9 4647 gimplify_and_add (t, pre_p);
fcdd3ab3 4648
4649 /* This is dead code, but go ahead and finish so that the
4650 mode of the result comes out right. */
4651 *expr_p = dummy_object (type);
4652 return GS_ALL_DONE;
4653 }
4654 else
4655 {
4656 /* Make it easier for the backends by protecting the valist argument
a0c938f0 4657 from multiple evaluations. */
5f57a8b1 4658 if (TREE_CODE (have_va_type) == ARRAY_TYPE)
e0eca1fa 4659 {
4660 /* For this case, the backends will be expecting a pointer to
5f57a8b1 4661 TREE_TYPE (abi), but it's possible we've
4662 actually been given an array (an actual TARGET_FN_ABI_VA_LIST).
e0eca1fa 4663 So fix it. */
4664 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4665 {
5f57a8b1 4666 tree p1 = build_pointer_type (TREE_TYPE (have_va_type));
389dd41b 4667 valist = fold_convert_loc (loc, p1,
4668 build_fold_addr_expr_loc (loc, valist));
e0eca1fa 4669 }
75a70cf9 4670
e0eca1fa 4671 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4672 }
4673 else
4674 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
fcdd3ab3 4675
17a6380d 4676 if (!targetm.gimplify_va_arg_expr)
75a70cf9 4677 /* FIXME: Once most targets are converted we should merely
89f18f73 4678 assert this is non-null. */
fcdd3ab3 4679 return GS_ALL_DONE;
4680
17a6380d 4681 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
fcdd3ab3 4682 return GS_OK;
4683 }
4684}
4685
c2f47e15 4686/* Expand EXP, a call to __builtin_va_end. */
f7c44134 4687
a66c9326 4688static rtx
c2f47e15 4689expand_builtin_va_end (tree exp)
a66c9326 4690{
c2f47e15 4691 tree valist = CALL_EXPR_ARG (exp, 0);
8a15c04a 4692
8a15c04a 4693 /* Evaluate for side effects, if needed. I hate macros that don't
4694 do that. */
4695 if (TREE_SIDE_EFFECTS (valist))
4696 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
a66c9326 4697
4698 return const0_rtx;
4699}
4700
c2f47e15 4701/* Expand EXP, a call to __builtin_va_copy. We do this as a
a66c9326 4702 builtin rather than just as an assignment in stdarg.h because of the
4703 nastiness of array-type va_list types. */
f7c44134 4704
a66c9326 4705static rtx
c2f47e15 4706expand_builtin_va_copy (tree exp)
a66c9326 4707{
4708 tree dst, src, t;
389dd41b 4709 location_t loc = EXPR_LOCATION (exp);
a66c9326 4710
c2f47e15 4711 dst = CALL_EXPR_ARG (exp, 0);
4712 src = CALL_EXPR_ARG (exp, 1);
a66c9326 4713
389dd41b 4714 dst = stabilize_va_list_loc (loc, dst, 1);
4715 src = stabilize_va_list_loc (loc, src, 0);
a66c9326 4716
5f57a8b1 4717 gcc_assert (cfun != NULL && cfun->decl != NULL_TREE);
4718
4719 if (TREE_CODE (targetm.fn_abi_va_list (cfun->decl)) != ARRAY_TYPE)
a66c9326 4720 {
5f57a8b1 4721 t = build2 (MODIFY_EXPR, targetm.fn_abi_va_list (cfun->decl), dst, src);
a66c9326 4722 TREE_SIDE_EFFECTS (t) = 1;
4723 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4724 }
4725 else
4726 {
11a61dea 4727 rtx dstb, srcb, size;
4728
4729 /* Evaluate to pointers. */
4730 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4731 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
5f57a8b1 4732 size = expand_expr (TYPE_SIZE_UNIT (targetm.fn_abi_va_list (cfun->decl)),
4733 NULL_RTX, VOIDmode, EXPAND_NORMAL);
11a61dea 4734
85d654dd 4735 dstb = convert_memory_address (Pmode, dstb);
4736 srcb = convert_memory_address (Pmode, srcb);
726ec87c 4737
11a61dea 4738 /* "Dereference" to BLKmode memories. */
4739 dstb = gen_rtx_MEM (BLKmode, dstb);
ab6ab77e 4740 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
5f57a8b1 4741 set_mem_align (dstb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
11a61dea 4742 srcb = gen_rtx_MEM (BLKmode, srcb);
ab6ab77e 4743 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
5f57a8b1 4744 set_mem_align (srcb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
11a61dea 4745
4746 /* Copy. */
0378dbdc 4747 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
a66c9326 4748 }
4749
4750 return const0_rtx;
4751}
4752
53800dbe 4753/* Expand a call to one of the builtin functions __builtin_frame_address or
4754 __builtin_return_address. */
27d0c333 4755
53800dbe 4756static rtx
c2f47e15 4757expand_builtin_frame_address (tree fndecl, tree exp)
53800dbe 4758{
53800dbe 4759 /* The argument must be a nonnegative integer constant.
4760 It counts the number of frames to scan up the stack.
4761 The value is the return address saved in that frame. */
c2f47e15 4762 if (call_expr_nargs (exp) == 0)
53800dbe 4763 /* Warning about missing arg was already issued. */
4764 return const0_rtx;
c2f47e15 4765 else if (! host_integerp (CALL_EXPR_ARG (exp, 0), 1))
53800dbe 4766 {
4767 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
07e3a3d2 4768 error ("invalid argument to %<__builtin_frame_address%>");
53800dbe 4769 else
07e3a3d2 4770 error ("invalid argument to %<__builtin_return_address%>");
53800dbe 4771 return const0_rtx;
4772 }
4773 else
4774 {
27d0c333 4775 rtx tem
4776 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
c2f47e15 4777 tree_low_cst (CALL_EXPR_ARG (exp, 0), 1));
53800dbe 4778
4779 /* Some ports cannot access arbitrary stack frames. */
4780 if (tem == NULL)
4781 {
4782 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
c3ceba8e 4783 warning (0, "unsupported argument to %<__builtin_frame_address%>");
53800dbe 4784 else
c3ceba8e 4785 warning (0, "unsupported argument to %<__builtin_return_address%>");
53800dbe 4786 return const0_rtx;
4787 }
4788
4789 /* For __builtin_frame_address, return what we've got. */
4790 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4791 return tem;
4792
8ad4c111 4793 if (!REG_P (tem)
53800dbe 4794 && ! CONSTANT_P (tem))
4795 tem = copy_to_mode_reg (Pmode, tem);
4796 return tem;
4797 }
4798}
4799
c2f47e15 4800/* Expand EXP, a call to the alloca builtin. Return NULL_RTX if
53800dbe 4801 we failed and the caller should emit a normal call, otherwise try to get
4802 the result in TARGET, if convenient. */
15c6cf6b 4803
53800dbe 4804static rtx
c2f47e15 4805expand_builtin_alloca (tree exp, rtx target)
53800dbe 4806{
4807 rtx op0;
15c6cf6b 4808 rtx result;
53800dbe 4809
f9fa0459 4810 /* Emit normal call if marked not-inlineable. */
4811 if (CALL_CANNOT_INLINE_P (exp))
c2f47e15 4812 return NULL_RTX;
4ee9c684 4813
c2f47e15 4814 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
4815 return NULL_RTX;
53800dbe 4816
4817 /* Compute the argument. */
c2f47e15 4818 op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
53800dbe 4819
4820 /* Allocate the desired space. */
15c6cf6b 4821 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
85d654dd 4822 result = convert_memory_address (ptr_mode, result);
15c6cf6b 4823
4824 return result;
53800dbe 4825}
4826
c2f47e15 4827/* Expand a call to a bswap builtin with argument ARG0. MODE
42791117 4828 is the mode to expand with. */
4829
4830static rtx
c2f47e15 4831expand_builtin_bswap (tree exp, rtx target, rtx subtarget)
42791117 4832{
4833 enum machine_mode mode;
4834 tree arg;
4835 rtx op0;
4836
c2f47e15 4837 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
4838 return NULL_RTX;
42791117 4839
c2f47e15 4840 arg = CALL_EXPR_ARG (exp, 0);
42791117 4841 mode = TYPE_MODE (TREE_TYPE (arg));
1db6d067 4842 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
42791117 4843
4844 target = expand_unop (mode, bswap_optab, op0, target, 1);
4845
4846 gcc_assert (target);
4847
4848 return convert_to_mode (mode, target, 0);
4849}
4850
c2f47e15 4851/* Expand a call to a unary builtin in EXP.
4852 Return NULL_RTX if a normal call should be emitted rather than expanding the
53800dbe 4853 function in-line. If convenient, the result should be placed in TARGET.
4854 SUBTARGET may be used as the target for computing one of EXP's operands. */
15c6cf6b 4855
53800dbe 4856static rtx
c2f47e15 4857expand_builtin_unop (enum machine_mode target_mode, tree exp, rtx target,
aecda0d6 4858 rtx subtarget, optab op_optab)
53800dbe 4859{
4860 rtx op0;
c2f47e15 4861
4862 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
4863 return NULL_RTX;
53800dbe 4864
4865 /* Compute the argument. */
1db6d067 4866 op0 = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
4867 VOIDmode, EXPAND_NORMAL);
6a08d0ab 4868 /* Compute op, into TARGET if possible.
53800dbe 4869 Set TARGET to wherever the result comes back. */
c2f47e15 4870 target = expand_unop (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0))),
6a08d0ab 4871 op_optab, op0, target, 1);
64db345d 4872 gcc_assert (target);
7d3f6cc7 4873
efb070c8 4874 return convert_to_mode (target_mode, target, 0);
53800dbe 4875}
89cfe6e5 4876
5a74f77e 4877/* Expand a call to __builtin_expect. We just return our argument
4878 as the builtin_expect semantic should've been already executed by
4879 tree branch prediction pass. */
89cfe6e5 4880
4881static rtx
c2f47e15 4882expand_builtin_expect (tree exp, rtx target)
89cfe6e5 4883{
c2f47e15 4884 tree arg, c;
89cfe6e5 4885
c2f47e15 4886 if (call_expr_nargs (exp) < 2)
89cfe6e5 4887 return const0_rtx;
c2f47e15 4888 arg = CALL_EXPR_ARG (exp, 0);
4889 c = CALL_EXPR_ARG (exp, 1);
89cfe6e5 4890
c2f47e15 4891 target = expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5a74f77e 4892 /* When guessing was done, the hints should be already stripped away. */
07311427 4893 gcc_assert (!flag_guess_branch_prob
4894 || optimize == 0 || errorcount || sorrycount);
89cfe6e5 4895 return target;
4896}
689df48e 4897
c22de3f0 4898void
aecda0d6 4899expand_builtin_trap (void)
a0ef1725 4900{
4901#ifdef HAVE_trap
4902 if (HAVE_trap)
4903 emit_insn (gen_trap ());
4904 else
4905#endif
4906 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4907 emit_barrier ();
4908}
78a74442 4909
d2b48f0c 4910/* Expand a call to __builtin_unreachable. We do nothing except emit
4911 a barrier saying that control flow will not pass here.
4912
4913 It is the responsibility of the program being compiled to ensure
4914 that control flow does never reach __builtin_unreachable. */
4915static void
4916expand_builtin_unreachable (void)
4917{
4918 emit_barrier ();
4919}
4920
c2f47e15 4921/* Expand EXP, a call to fabs, fabsf or fabsl.
4922 Return NULL_RTX if a normal call should be emitted rather than expanding
78a74442 4923 the function inline. If convenient, the result should be placed
4924 in TARGET. SUBTARGET may be used as the target for computing
4925 the operand. */
4926
4927static rtx
c2f47e15 4928expand_builtin_fabs (tree exp, rtx target, rtx subtarget)
78a74442 4929{
4930 enum machine_mode mode;
4931 tree arg;
4932 rtx op0;
4933
c2f47e15 4934 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
4935 return NULL_RTX;
78a74442 4936
c2f47e15 4937 arg = CALL_EXPR_ARG (exp, 0);
c7f617c2 4938 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
78a74442 4939 mode = TYPE_MODE (TREE_TYPE (arg));
1db6d067 4940 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
78a74442 4941 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4942}
4943
c2f47e15 4944/* Expand EXP, a call to copysign, copysignf, or copysignl.
270436f3 4945 Return NULL is a normal call should be emitted rather than expanding the
4946 function inline. If convenient, the result should be placed in TARGET.
4947 SUBTARGET may be used as the target for computing the operand. */
4948
4949static rtx
c2f47e15 4950expand_builtin_copysign (tree exp, rtx target, rtx subtarget)
270436f3 4951{
4952 rtx op0, op1;
4953 tree arg;
4954
c2f47e15 4955 if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4956 return NULL_RTX;
270436f3 4957
c2f47e15 4958 arg = CALL_EXPR_ARG (exp, 0);
8ec3c5c2 4959 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
270436f3 4960
c2f47e15 4961 arg = CALL_EXPR_ARG (exp, 1);
8ec3c5c2 4962 op1 = expand_normal (arg);
270436f3 4963
4964 return expand_copysign (op0, op1, target);
4965}
4966
19bf118a 4967/* Create a new constant string literal and return a char* pointer to it.
4968 The STRING_CST value is the LEN characters at STR. */
1e8e9920 4969tree
19bf118a 4970build_string_literal (int len, const char *str)
4971{
4972 tree t, elem, index, type;
4973
4974 t = build_string (len, str);
4975 elem = build_type_variant (char_type_node, 1, 0);
40238f64 4976 index = build_index_type (size_int (len - 1));
19bf118a 4977 type = build_array_type (elem, index);
4978 TREE_TYPE (t) = type;
4979 TREE_CONSTANT (t) = 1;
4980 TREE_READONLY (t) = 1;
4981 TREE_STATIC (t) = 1;
4982
19bf118a 4983 type = build_pointer_type (elem);
40238f64 4984 t = build1 (ADDR_EXPR, type,
4985 build4 (ARRAY_REF, elem,
4986 t, integer_zero_node, NULL_TREE, NULL_TREE));
19bf118a 4987 return t;
4988}
4989
0b25db21 4990/* Expand EXP, a call to printf or printf_unlocked.
c2f47e15 4991 Return NULL_RTX if a normal call should be emitted rather than transforming
19bf118a 4992 the function inline. If convenient, the result should be placed in
0862b7e9 4993 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
19bf118a 4994 call. */
4995static rtx
0b25db21 4996expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
19bf118a 4997 bool unlocked)
4998{
6d77ed92 4999 /* If we're using an unlocked function, assume the other unlocked
5000 functions exist explicitly. */
5001 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
5002 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
5003 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
5004 : implicit_built_in_decls[BUILT_IN_PUTS];
19bf118a 5005 const char *fmt_str;
c2f47e15 5006 tree fn = 0;
5007 tree fmt, arg;
5008 int nargs = call_expr_nargs (exp);
19bf118a 5009
5010 /* If the return value is used, don't do the transformation. */
5011 if (target != const0_rtx)
c2f47e15 5012 return NULL_RTX;
19bf118a 5013
5014 /* Verify the required arguments in the original call. */
c2f47e15 5015 if (nargs == 0)
5016 return NULL_RTX;
5017 fmt = CALL_EXPR_ARG (exp, 0);
552752f7 5018 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
c2f47e15 5019 return NULL_RTX;
19bf118a 5020
5021 /* Check whether the format is a literal string constant. */
5022 fmt_str = c_getstr (fmt);
5023 if (fmt_str == NULL)
c2f47e15 5024 return NULL_RTX;
19bf118a 5025
d4473c84 5026 if (!init_target_chars ())
c2f47e15 5027 return NULL_RTX;
a0c938f0 5028
19bf118a 5029 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
99eabcc1 5030 if (strcmp (fmt_str, target_percent_s_newline) == 0)
19bf118a 5031 {
c2f47e15 5032 if ((nargs != 2)
5033 || ! POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (exp, 1))))
5034 return NULL_RTX;
5035 if (fn_puts)
a65c4d64 5036 fn = build_call_nofold (fn_puts, 1, CALL_EXPR_ARG (exp, 1));
19bf118a 5037 }
5038 /* If the format specifier was "%c", call __builtin_putchar(arg). */
99eabcc1 5039 else if (strcmp (fmt_str, target_percent_c) == 0)
19bf118a 5040 {
c2f47e15 5041 if ((nargs != 2)
5042 || TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1))) != INTEGER_TYPE)
5043 return NULL_RTX;
5044 if (fn_putchar)
a65c4d64 5045 fn = build_call_nofold (fn_putchar, 1, CALL_EXPR_ARG (exp, 1));
19bf118a 5046 }
5047 else
5048 {
5049 /* We can't handle anything else with % args or %% ... yet. */
99eabcc1 5050 if (strchr (fmt_str, target_percent))
c2f47e15 5051 return NULL_RTX;
19bf118a 5052
c2f47e15 5053 if (nargs > 1)
5054 return NULL_RTX;
19bf118a 5055
5056 /* If the format specifier was "", printf does nothing. */
5057 if (fmt_str[0] == '\0')
5058 return const0_rtx;
5059 /* If the format specifier has length of 1, call putchar. */
5060 if (fmt_str[1] == '\0')
5061 {
5062 /* Given printf("c"), (where c is any one character,)
5063 convert "c"[0] to an int and pass that to the replacement
5064 function. */
7016c612 5065 arg = build_int_cst (NULL_TREE, fmt_str[0]);
c2f47e15 5066 if (fn_putchar)
a65c4d64 5067 fn = build_call_nofold (fn_putchar, 1, arg);
19bf118a 5068 }
5069 else
5070 {
5071 /* If the format specifier was "string\n", call puts("string"). */
5072 size_t len = strlen (fmt_str);
99eabcc1 5073 if ((unsigned char)fmt_str[len - 1] == target_newline)
19bf118a 5074 {
91c82c20 5075 /* Create a NUL-terminated string that's one char shorter
19bf118a 5076 than the original, stripping off the trailing '\n'. */
364c0c59 5077 char *newstr = XALLOCAVEC (char, len);
19bf118a 5078 memcpy (newstr, fmt_str, len - 1);
5079 newstr[len - 1] = 0;
19bf118a 5080 arg = build_string_literal (len, newstr);
c2f47e15 5081 if (fn_puts)
a65c4d64 5082 fn = build_call_nofold (fn_puts, 1, arg);
19bf118a 5083 }
5084 else
5085 /* We'd like to arrange to call fputs(string,stdout) here,
5086 but we need stdout and don't have a way to get it yet. */
c2f47e15 5087 return NULL_RTX;
19bf118a 5088 }
5089 }
5090
5091 if (!fn)
c2f47e15 5092 return NULL_RTX;
a65c4d64 5093 gcc_assert (TREE_CODE (fn) == CALL_EXPR);
5094 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
0b25db21 5095 return expand_expr (fn, target, mode, EXPAND_NORMAL);
19bf118a 5096}
5097
0b25db21 5098/* Expand EXP, a call to fprintf or fprintf_unlocked.
c2f47e15 5099 Return NULL_RTX if a normal call should be emitted rather than transforming
19bf118a 5100 the function inline. If convenient, the result should be placed in
0862b7e9 5101 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
19bf118a 5102 call. */
5103static rtx
0b25db21 5104expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
a0c938f0 5105 bool unlocked)
19bf118a 5106{
6d77ed92 5107 /* If we're using an unlocked function, assume the other unlocked
5108 functions exist explicitly. */
5109 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5110 : implicit_built_in_decls[BUILT_IN_FPUTC];
5111 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5112 : implicit_built_in_decls[BUILT_IN_FPUTS];
19bf118a 5113 const char *fmt_str;
c2f47e15 5114 tree fn = 0;
5115 tree fmt, fp, arg;
5116 int nargs = call_expr_nargs (exp);
19bf118a 5117
5118 /* If the return value is used, don't do the transformation. */
5119 if (target != const0_rtx)
c2f47e15 5120 return NULL_RTX;
19bf118a 5121
5122 /* Verify the required arguments in the original call. */
c2f47e15 5123 if (nargs < 2)
5124 return NULL_RTX;
5125 fp = CALL_EXPR_ARG (exp, 0);
552752f7 5126 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
c2f47e15 5127 return NULL_RTX;
5128 fmt = CALL_EXPR_ARG (exp, 1);
552752f7 5129 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
c2f47e15 5130 return NULL_RTX;
19bf118a 5131
5132 /* Check whether the format is a literal string constant. */
5133 fmt_str = c_getstr (fmt);
5134 if (fmt_str == NULL)
c2f47e15 5135 return NULL_RTX;
19bf118a 5136
d4473c84 5137 if (!init_target_chars ())
c2f47e15 5138 return NULL_RTX;
a0c938f0 5139
19bf118a 5140 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
99eabcc1 5141 if (strcmp (fmt_str, target_percent_s) == 0)
19bf118a 5142 {
c2f47e15 5143 if ((nargs != 3)
5144 || ! POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (exp, 2))))
5145 return NULL_RTX;
5146 arg = CALL_EXPR_ARG (exp, 2);
5147 if (fn_fputs)
a65c4d64 5148 fn = build_call_nofold (fn_fputs, 2, arg, fp);
19bf118a 5149 }
5150 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
99eabcc1 5151 else if (strcmp (fmt_str, target_percent_c) == 0)
19bf118a 5152 {
c2f47e15 5153 if ((nargs != 3)
5154 || TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2))) != INTEGER_TYPE)
5155 return NULL_RTX;
5156 arg = CALL_EXPR_ARG (exp, 2);
5157 if (fn_fputc)
a65c4d64 5158 fn = build_call_nofold (fn_fputc, 2, arg, fp);
19bf118a 5159 }
5160 else
5161 {
5162 /* We can't handle anything else with % args or %% ... yet. */
99eabcc1 5163 if (strchr (fmt_str, target_percent))
c2f47e15 5164 return NULL_RTX;
19bf118a 5165
c2f47e15 5166 if (nargs > 2)
5167 return NULL_RTX;
19bf118a 5168
5169 /* If the format specifier was "", fprintf does nothing. */
5170 if (fmt_str[0] == '\0')
5171 {
5172 /* Evaluate and ignore FILE* argument for side-effects. */
5173 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5174 return const0_rtx;
5175 }
5176
5177 /* When "string" doesn't contain %, replace all cases of
5178 fprintf(stream,string) with fputs(string,stream). The fputs
5179 builtin will take care of special cases like length == 1. */
c2f47e15 5180 if (fn_fputs)
a65c4d64 5181 fn = build_call_nofold (fn_fputs, 2, fmt, fp);
19bf118a 5182 }
5183
5184 if (!fn)
c2f47e15 5185 return NULL_RTX;
a65c4d64 5186 gcc_assert (TREE_CODE (fn) == CALL_EXPR);
5187 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
0b25db21 5188 return expand_expr (fn, target, mode, EXPAND_NORMAL);
19bf118a 5189}
5190
c2f47e15 5191/* Expand a call EXP to sprintf. Return NULL_RTX if
6411575e 5192 a normal call should be emitted rather than expanding the function
5193 inline. If convenient, the result should be placed in TARGET with
5194 mode MODE. */
5195
5196static rtx
c2f47e15 5197expand_builtin_sprintf (tree exp, rtx target, enum machine_mode mode)
6411575e 5198{
c2f47e15 5199 tree dest, fmt;
a7a723f0 5200 const char *fmt_str;
c2f47e15 5201 int nargs = call_expr_nargs (exp);
6411575e 5202
5203 /* Verify the required arguments in the original call. */
c2f47e15 5204 if (nargs < 2)
5205 return NULL_RTX;
5206 dest = CALL_EXPR_ARG (exp, 0);
552752f7 5207 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
c2f47e15 5208 return NULL_RTX;
5209 fmt = CALL_EXPR_ARG (exp, 0);
552752f7 5210 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
c2f47e15 5211 return NULL_RTX;
6411575e 5212
5213 /* Check whether the format is a literal string constant. */
a7a723f0 5214 fmt_str = c_getstr (fmt);
5215 if (fmt_str == NULL)
c2f47e15 5216 return NULL_RTX;
6411575e 5217
d4473c84 5218 if (!init_target_chars ())
c2f47e15 5219 return NULL_RTX;
99eabcc1 5220
6411575e 5221 /* If the format doesn't contain % args or %%, use strcpy. */
99eabcc1 5222 if (strchr (fmt_str, target_percent) == 0)
6411575e 5223 {
5224 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5225 tree exp;
5226
c2f47e15 5227 if ((nargs > 2) || ! fn)
5228 return NULL_RTX;
a65c4d64 5229 expand_expr (build_call_nofold (fn, 2, dest, fmt),
6411575e 5230 const0_rtx, VOIDmode, EXPAND_NORMAL);
5231 if (target == const0_rtx)
5232 return const0_rtx;
7016c612 5233 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
6411575e 5234 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5235 }
a7a723f0 5236 /* If the format is "%s", use strcpy if the result isn't used. */
99eabcc1 5237 else if (strcmp (fmt_str, target_percent_s) == 0)
6411575e 5238 {
a7a723f0 5239 tree fn, arg, len;
5240 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
6411575e 5241
a7a723f0 5242 if (! fn)
c2f47e15 5243 return NULL_RTX;
5244 if (nargs != 3)
5245 return NULL_RTX;
5246 arg = CALL_EXPR_ARG (exp, 2);
552752f7 5247 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
c2f47e15 5248 return NULL_RTX;
6411575e 5249
5250 if (target != const0_rtx)
5251 {
681fab1e 5252 len = c_strlen (arg, 1);
a7a723f0 5253 if (! len || TREE_CODE (len) != INTEGER_CST)
c2f47e15 5254 return NULL_RTX;
6411575e 5255 }
5256 else
a7a723f0 5257 len = NULL_TREE;
6411575e 5258
a65c4d64 5259 expand_expr (build_call_nofold (fn, 2, dest, arg),
6411575e 5260 const0_rtx, VOIDmode, EXPAND_NORMAL);
5261
5262 if (target == const0_rtx)
5263 return const0_rtx;
a7a723f0 5264 return expand_expr (len, target, mode, EXPAND_NORMAL);
6411575e 5265 }
5266
c2f47e15 5267 return NULL_RTX;
6411575e 5268}
27f261ef 5269
4ee9c684 5270/* Expand a call to either the entry or exit function profiler. */
5271
5272static rtx
5273expand_builtin_profile_func (bool exitp)
5274{
f4e36c33 5275 rtx this_rtx, which;
4ee9c684 5276
f4e36c33 5277 this_rtx = DECL_RTL (current_function_decl);
5278 gcc_assert (MEM_P (this_rtx));
5279 this_rtx = XEXP (this_rtx, 0);
4ee9c684 5280
5281 if (exitp)
5282 which = profile_function_exit_libfunc;
5283 else
5284 which = profile_function_entry_libfunc;
5285
f4e36c33 5286 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this_rtx, Pmode,
4ee9c684 5287 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
869d0ef0 5288 0),
4ee9c684 5289 Pmode);
5290
5291 return const0_rtx;
5292}
5293
ac8fb6db 5294/* Expand a call to __builtin___clear_cache. */
5295
5296static rtx
5297expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED)
5298{
5299#ifndef HAVE_clear_cache
5300#ifdef CLEAR_INSN_CACHE
5301 /* There is no "clear_cache" insn, and __clear_cache() in libgcc
5302 does something. Just do the default expansion to a call to
5303 __clear_cache(). */
5304 return NULL_RTX;
5305#else
5306 /* There is no "clear_cache" insn, and __clear_cache() in libgcc
5307 does nothing. There is no need to call it. Do nothing. */
5308 return const0_rtx;
5309#endif /* CLEAR_INSN_CACHE */
5310#else
5311 /* We have a "clear_cache" insn, and it will handle everything. */
5312 tree begin, end;
5313 rtx begin_rtx, end_rtx;
5314 enum insn_code icode;
5315
5316 /* We must not expand to a library call. If we did, any
5317 fallback library function in libgcc that might contain a call to
5318 __builtin___clear_cache() would recurse infinitely. */
5319 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
5320 {
5321 error ("both arguments to %<__builtin___clear_cache%> must be pointers");
5322 return const0_rtx;
5323 }
5324
5325 if (HAVE_clear_cache)
5326 {
5327 icode = CODE_FOR_clear_cache;
5328
5329 begin = CALL_EXPR_ARG (exp, 0);
5330 begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL);
5331 begin_rtx = convert_memory_address (Pmode, begin_rtx);
5332 if (!insn_data[icode].operand[0].predicate (begin_rtx, Pmode))
5333 begin_rtx = copy_to_mode_reg (Pmode, begin_rtx);
5334
5335 end = CALL_EXPR_ARG (exp, 1);
5336 end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL);
5337 end_rtx = convert_memory_address (Pmode, end_rtx);
5338 if (!insn_data[icode].operand[1].predicate (end_rtx, Pmode))
5339 end_rtx = copy_to_mode_reg (Pmode, end_rtx);
5340
5341 emit_insn (gen_clear_cache (begin_rtx, end_rtx));
5342 }
5343 return const0_rtx;
5344#endif /* HAVE_clear_cache */
5345}
5346
4ee9c684 5347/* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5348
5349static rtx
5350round_trampoline_addr (rtx tramp)
5351{
5352 rtx temp, addend, mask;
5353
5354 /* If we don't need too much alignment, we'll have been guaranteed
5355 proper alignment by get_trampoline_type. */
5356 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5357 return tramp;
5358
5359 /* Round address up to desired boundary. */
5360 temp = gen_reg_rtx (Pmode);
5361 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5362 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5363
5364 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5365 temp, 0, OPTAB_LIB_WIDEN);
5366 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5367 temp, 0, OPTAB_LIB_WIDEN);
5368
5369 return tramp;
5370}
5371
5372static rtx
c2f47e15 5373expand_builtin_init_trampoline (tree exp)
4ee9c684 5374{
5375 tree t_tramp, t_func, t_chain;
82c7907c 5376 rtx m_tramp, r_tramp, r_chain, tmp;
4ee9c684 5377
c2f47e15 5378 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE,
4ee9c684 5379 POINTER_TYPE, VOID_TYPE))
5380 return NULL_RTX;
5381
c2f47e15 5382 t_tramp = CALL_EXPR_ARG (exp, 0);
5383 t_func = CALL_EXPR_ARG (exp, 1);
5384 t_chain = CALL_EXPR_ARG (exp, 2);
4ee9c684 5385
8ec3c5c2 5386 r_tramp = expand_normal (t_tramp);
82c7907c 5387 m_tramp = gen_rtx_MEM (BLKmode, r_tramp);
5388 MEM_NOTRAP_P (m_tramp) = 1;
5389
5390 /* The TRAMP argument should be the address of a field within the
5391 local function's FRAME decl. Let's see if we can fill in the
5392 to fill in the MEM_ATTRs for this memory. */
5393 if (TREE_CODE (t_tramp) == ADDR_EXPR)
5394 set_mem_attributes_minus_bitpos (m_tramp, TREE_OPERAND (t_tramp, 0),
5395 true, 0);
5396
5397 tmp = round_trampoline_addr (r_tramp);
5398 if (tmp != r_tramp)
5399 {
5400 m_tramp = change_address (m_tramp, BLKmode, tmp);
5401 set_mem_align (m_tramp, TRAMPOLINE_ALIGNMENT);
5402 set_mem_size (m_tramp, GEN_INT (TRAMPOLINE_SIZE));
5403 }
5404
5405 /* The FUNC argument should be the address of the nested function.
5406 Extract the actual function decl to pass to the hook. */
5407 gcc_assert (TREE_CODE (t_func) == ADDR_EXPR);
5408 t_func = TREE_OPERAND (t_func, 0);
5409 gcc_assert (TREE_CODE (t_func) == FUNCTION_DECL);
5410
8ec3c5c2 5411 r_chain = expand_normal (t_chain);
4ee9c684 5412
5413 /* Generate insns to initialize the trampoline. */
82c7907c 5414 targetm.calls.trampoline_init (m_tramp, t_func, r_chain);
4ee9c684 5415
82c7907c 5416 trampolines_created = 1;
4ee9c684 5417 return const0_rtx;
5418}
5419
5420static rtx
c2f47e15 5421expand_builtin_adjust_trampoline (tree exp)
4ee9c684 5422{
5423 rtx tramp;
5424
c2f47e15 5425 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
4ee9c684 5426 return NULL_RTX;
5427
c2f47e15 5428 tramp = expand_normal (CALL_EXPR_ARG (exp, 0));
4ee9c684 5429 tramp = round_trampoline_addr (tramp);
82c7907c 5430 if (targetm.calls.trampoline_adjust_address)
5431 tramp = targetm.calls.trampoline_adjust_address (tramp);
4ee9c684 5432
5433 return tramp;
5434}
5435
93f564d6 5436/* Expand the call EXP to the built-in signbit, signbitf or signbitl
5437 function. The function first checks whether the back end provides
5438 an insn to implement signbit for the respective mode. If not, it
5439 checks whether the floating point format of the value is such that
5440 the sign bit can be extracted. If that is not the case, the
5441 function returns NULL_RTX to indicate that a normal call should be
5442 emitted rather than expanding the function in-line. EXP is the
5443 expression that is a call to the builtin function; if convenient,
5444 the result should be placed in TARGET. */
27f261ef 5445static rtx
5446expand_builtin_signbit (tree exp, rtx target)
5447{
5448 const struct real_format *fmt;
5449 enum machine_mode fmode, imode, rmode;
5450 HOST_WIDE_INT hi, lo;
c2f47e15 5451 tree arg;
ca4f1f5b 5452 int word, bitpos;
27eda240 5453 enum insn_code icode;
27f261ef 5454 rtx temp;
389dd41b 5455 location_t loc = EXPR_LOCATION (exp);
27f261ef 5456
c2f47e15 5457 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
5458 return NULL_RTX;
27f261ef 5459
c2f47e15 5460 arg = CALL_EXPR_ARG (exp, 0);
27f261ef 5461 fmode = TYPE_MODE (TREE_TYPE (arg));
5462 rmode = TYPE_MODE (TREE_TYPE (exp));
5463 fmt = REAL_MODE_FORMAT (fmode);
5464
93f564d6 5465 arg = builtin_save_expr (arg);
5466
5467 /* Expand the argument yielding a RTX expression. */
5468 temp = expand_normal (arg);
5469
5470 /* Check if the back end provides an insn that handles signbit for the
5471 argument's mode. */
27eda240 5472 icode = signbit_optab->handlers [(int) fmode].insn_code;
5473 if (icode != CODE_FOR_nothing)
93f564d6 5474 {
5475 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
27eda240 5476 emit_unop_insn (icode, target, temp, UNKNOWN);
93f564d6 5477 return target;
5478 }
5479
27f261ef 5480 /* For floating point formats without a sign bit, implement signbit
5481 as "ARG < 0.0". */
8d564692 5482 bitpos = fmt->signbit_ro;
ca4f1f5b 5483 if (bitpos < 0)
27f261ef 5484 {
5485 /* But we can't do this if the format supports signed zero. */
5486 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
c2f47e15 5487 return NULL_RTX;
27f261ef 5488
389dd41b 5489 arg = fold_build2_loc (loc, LT_EXPR, TREE_TYPE (exp), arg,
49d00087 5490 build_real (TREE_TYPE (arg), dconst0));
27f261ef 5491 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5492 }
5493
ca4f1f5b 5494 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
27f261ef 5495 {
ca4f1f5b 5496 imode = int_mode_for_mode (fmode);
5497 if (imode == BLKmode)
c2f47e15 5498 return NULL_RTX;
ca4f1f5b 5499 temp = gen_lowpart (imode, temp);
24fd4260 5500 }
5501 else
5502 {
ca4f1f5b 5503 imode = word_mode;
5504 /* Handle targets with different FP word orders. */
5505 if (FLOAT_WORDS_BIG_ENDIAN)
a0c938f0 5506 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
ca4f1f5b 5507 else
a0c938f0 5508 word = bitpos / BITS_PER_WORD;
ca4f1f5b 5509 temp = operand_subword_force (temp, word, fmode);
5510 bitpos = bitpos % BITS_PER_WORD;
5511 }
5512
44b0f1d0 5513 /* Force the intermediate word_mode (or narrower) result into a
5514 register. This avoids attempting to create paradoxical SUBREGs
5515 of floating point modes below. */
5516 temp = force_reg (imode, temp);
5517
ca4f1f5b 5518 /* If the bitpos is within the "result mode" lowpart, the operation
5519 can be implement with a single bitwise AND. Otherwise, we need
5520 a right shift and an AND. */
5521
5522 if (bitpos < GET_MODE_BITSIZE (rmode))
5523 {
24fd4260 5524 if (bitpos < HOST_BITS_PER_WIDE_INT)
27f261ef 5525 {
24fd4260 5526 hi = 0;
5527 lo = (HOST_WIDE_INT) 1 << bitpos;
27f261ef 5528 }
5529 else
24fd4260 5530 {
5531 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5532 lo = 0;
5533 }
27f261ef 5534
4a46f016 5535 if (GET_MODE_SIZE (imode) > GET_MODE_SIZE (rmode))
ca4f1f5b 5536 temp = gen_lowpart (rmode, temp);
24fd4260 5537 temp = expand_binop (rmode, and_optab, temp,
5538 immed_double_const (lo, hi, rmode),
ca4f1f5b 5539 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27f261ef 5540 }
ca4f1f5b 5541 else
5542 {
5543 /* Perform a logical right shift to place the signbit in the least
a0c938f0 5544 significant bit, then truncate the result to the desired mode
ca4f1f5b 5545 and mask just this bit. */
5546 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5547 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5548 temp = gen_lowpart (rmode, temp);
5549 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5550 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5551 }
5552
27f261ef 5553 return temp;
5554}
73673831 5555
5556/* Expand fork or exec calls. TARGET is the desired target of the
c2f47e15 5557 call. EXP is the call. FN is the
73673831 5558 identificator of the actual function. IGNORE is nonzero if the
5559 value is to be ignored. */
5560
5561static rtx
c2f47e15 5562expand_builtin_fork_or_exec (tree fn, tree exp, rtx target, int ignore)
73673831 5563{
5564 tree id, decl;
5565 tree call;
5566
5567 /* If we are not profiling, just call the function. */
5568 if (!profile_arc_flag)
5569 return NULL_RTX;
5570
5571 /* Otherwise call the wrapper. This should be equivalent for the rest of
5572 compiler, so the code does not diverge, and the wrapper may run the
9c9bad97 5573 code necessary for keeping the profiling sane. */
73673831 5574
5575 switch (DECL_FUNCTION_CODE (fn))
5576 {
5577 case BUILT_IN_FORK:
5578 id = get_identifier ("__gcov_fork");
5579 break;
5580
5581 case BUILT_IN_EXECL:
5582 id = get_identifier ("__gcov_execl");
5583 break;
5584
5585 case BUILT_IN_EXECV:
5586 id = get_identifier ("__gcov_execv");
5587 break;
5588
5589 case BUILT_IN_EXECLP:
5590 id = get_identifier ("__gcov_execlp");
5591 break;
5592
5593 case BUILT_IN_EXECLE:
5594 id = get_identifier ("__gcov_execle");
5595 break;
5596
5597 case BUILT_IN_EXECVP:
5598 id = get_identifier ("__gcov_execvp");
5599 break;
5600
5601 case BUILT_IN_EXECVE:
5602 id = get_identifier ("__gcov_execve");
5603 break;
5604
5605 default:
64db345d 5606 gcc_unreachable ();
73673831 5607 }
5608
e60a6f7b 5609 decl = build_decl (DECL_SOURCE_LOCATION (fn),
5610 FUNCTION_DECL, id, TREE_TYPE (fn));
73673831 5611 DECL_EXTERNAL (decl) = 1;
5612 TREE_PUBLIC (decl) = 1;
5613 DECL_ARTIFICIAL (decl) = 1;
5614 TREE_NOTHROW (decl) = 1;
e82d310b 5615 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5616 DECL_VISIBILITY_SPECIFIED (decl) = 1;
389dd41b 5617 call = rewrite_call_expr (EXPR_LOCATION (exp), exp, 0, decl, 0);
73673831 5618 return expand_call (call, target, ignore);
c2f47e15 5619 }
5620
b6a5fc45 5621
5622\f
3e272de8 5623/* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5624 the pointer in these functions is void*, the tree optimizers may remove
5625 casts. The mode computed in expand_builtin isn't reliable either, due
5626 to __sync_bool_compare_and_swap.
5627
5628 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5629 group of builtins. This gives us log2 of the mode size. */
5630
5631static inline enum machine_mode
5632get_builtin_sync_mode (int fcode_diff)
5633{
ad3a13b5 5634 /* The size is not negotiable, so ask not to get BLKmode in return
5635 if the target indicates that a smaller size would be better. */
5636 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
3e272de8 5637}
5638
041e0215 5639/* Expand the memory expression LOC and return the appropriate memory operand
5640 for the builtin_sync operations. */
5641
5642static rtx
5643get_builtin_sync_mem (tree loc, enum machine_mode mode)
5644{
5645 rtx addr, mem;
5646
1db6d067 5647 addr = expand_expr (loc, NULL_RTX, Pmode, EXPAND_SUM);
041e0215 5648
5649 /* Note that we explicitly do not want any alias information for this
5650 memory, so that we kill all other live memories. Otherwise we don't
5651 satisfy the full barrier semantics of the intrinsic. */
5652 mem = validize_mem (gen_rtx_MEM (mode, addr));
5653
5654 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
c94cfd1c 5655 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
041e0215 5656 MEM_VOLATILE_P (mem) = 1;
5657
5658 return mem;
5659}
5660
b6a5fc45 5661/* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
c2f47e15 5662 EXP is the CALL_EXPR. CODE is the rtx code
b6a5fc45 5663 that corresponds to the arithmetic or logical operation from the name;
5664 an exception here is that NOT actually means NAND. TARGET is an optional
5665 place for us to store the results; AFTER is true if this is the
5666 fetch_and_xxx form. IGNORE is true if we don't actually care about
5667 the result of the operation at all. */
5668
5669static rtx
c2f47e15 5670expand_builtin_sync_operation (enum machine_mode mode, tree exp,
3e272de8 5671 enum rtx_code code, bool after,
b6a5fc45 5672 rtx target, bool ignore)
5673{
041e0215 5674 rtx val, mem;
a8bb7059 5675 enum machine_mode old_mode;
e60a6f7b 5676 location_t loc = EXPR_LOCATION (exp);
b6a5fc45 5677
cf73e559 5678 if (code == NOT && warn_sync_nand)
5679 {
5680 tree fndecl = get_callee_fndecl (exp);
5681 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5682
5683 static bool warned_f_a_n, warned_n_a_f;
5684
5685 switch (fcode)
5686 {
5687 case BUILT_IN_FETCH_AND_NAND_1:
5688 case BUILT_IN_FETCH_AND_NAND_2:
5689 case BUILT_IN_FETCH_AND_NAND_4:
5690 case BUILT_IN_FETCH_AND_NAND_8:
5691 case BUILT_IN_FETCH_AND_NAND_16:
5692
5693 if (warned_f_a_n)
5694 break;
5695
5696 fndecl = implicit_built_in_decls[BUILT_IN_FETCH_AND_NAND_N];
e60a6f7b 5697 inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
cf73e559 5698 warned_f_a_n = true;
5699 break;
5700
5701 case BUILT_IN_NAND_AND_FETCH_1:
5702 case BUILT_IN_NAND_AND_FETCH_2:
5703 case BUILT_IN_NAND_AND_FETCH_4:
5704 case BUILT_IN_NAND_AND_FETCH_8:
5705 case BUILT_IN_NAND_AND_FETCH_16:
5706
5707 if (warned_n_a_f)
5708 break;
5709
5710 fndecl = implicit_built_in_decls[BUILT_IN_NAND_AND_FETCH_N];
e60a6f7b 5711 inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
cf73e559 5712 warned_n_a_f = true;
5713 break;
5714
5715 default:
5716 gcc_unreachable ();
5717 }
5718 }
5719
b6a5fc45 5720 /* Expand the operands. */
c2f47e15 5721 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
b6a5fc45 5722
1db6d067 5723 val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
a8bb7059 5724 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
5725 of CONST_INTs, where we know the old_mode only from the call argument. */
5726 old_mode = GET_MODE (val);
5727 if (old_mode == VOIDmode)
5728 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
5729 val = convert_modes (mode, old_mode, val, 1);
b6a5fc45 5730
b6a5fc45 5731 if (ignore)
5732 return expand_sync_operation (mem, val, code);
5733 else
5734 return expand_sync_fetch_operation (mem, val, code, after, target);
5735}
5736
5737/* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
c2f47e15 5738 intrinsics. EXP is the CALL_EXPR. IS_BOOL is
b6a5fc45 5739 true if this is the boolean form. TARGET is a place for us to store the
5740 results; this is NOT optional if IS_BOOL is true. */
5741
5742static rtx
c2f47e15 5743expand_builtin_compare_and_swap (enum machine_mode mode, tree exp,
3e272de8 5744 bool is_bool, rtx target)
b6a5fc45 5745{
041e0215 5746 rtx old_val, new_val, mem;
a8bb7059 5747 enum machine_mode old_mode;
b6a5fc45 5748
5749 /* Expand the operands. */
c2f47e15 5750 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
b6a5fc45 5751
c2f47e15 5752
1db6d067 5753 old_val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX,
5754 mode, EXPAND_NORMAL);
a8bb7059 5755 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
5756 of CONST_INTs, where we know the old_mode only from the call argument. */
5757 old_mode = GET_MODE (old_val);
5758 if (old_mode == VOIDmode)
5759 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
5760 old_val = convert_modes (mode, old_mode, old_val, 1);
b6a5fc45 5761
1db6d067 5762 new_val = expand_expr (CALL_EXPR_ARG (exp, 2), NULL_RTX,
5763 mode, EXPAND_NORMAL);
a8bb7059 5764 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
5765 of CONST_INTs, where we know the old_mode only from the call argument. */
5766 old_mode = GET_MODE (new_val);
5767 if (old_mode == VOIDmode)
5768 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2)));
5769 new_val = convert_modes (mode, old_mode, new_val, 1);
b6a5fc45 5770
b6a5fc45 5771 if (is_bool)
5772 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5773 else
5774 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5775}
5776
5777/* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5778 general form is actually an atomic exchange, and some targets only
5779 support a reduced form with the second argument being a constant 1.
c2f47e15 5780 EXP is the CALL_EXPR; TARGET is an optional place for us to store
5781 the results. */
b6a5fc45 5782
5783static rtx
c2f47e15 5784expand_builtin_lock_test_and_set (enum machine_mode mode, tree exp,
3e272de8 5785 rtx target)
b6a5fc45 5786{
041e0215 5787 rtx val, mem;
a8bb7059 5788 enum machine_mode old_mode;
b6a5fc45 5789
5790 /* Expand the operands. */
c2f47e15 5791 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
1db6d067 5792 val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
a8bb7059 5793 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
5794 of CONST_INTs, where we know the old_mode only from the call argument. */
5795 old_mode = GET_MODE (val);
5796 if (old_mode == VOIDmode)
5797 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
5798 val = convert_modes (mode, old_mode, val, 1);
b6a5fc45 5799
b6a5fc45 5800 return expand_sync_lock_test_and_set (mem, val, target);
5801}
5802
5803/* Expand the __sync_synchronize intrinsic. */
5804
5805static void
5806expand_builtin_synchronize (void)
5807{
16c9337c 5808 gimple x;
78f55ca8 5809 VEC (tree, gc) *v_clobbers;
b6a5fc45 5810
5811#ifdef HAVE_memory_barrier
5812 if (HAVE_memory_barrier)
5813 {
5814 emit_insn (gen_memory_barrier ());
5815 return;
5816 }
5817#endif
5818
047a7e40 5819 if (synchronize_libfunc != NULL_RTX)
5820 {
5821 emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
5822 return;
5823 }
5824
82e58396 5825 /* If no explicit memory barrier instruction is available, create an
5826 empty asm stmt with a memory clobber. */
78f55ca8 5827 v_clobbers = VEC_alloc (tree, gc, 1);
5828 VEC_quick_push (tree, v_clobbers,
5829 tree_cons (NULL, build_string (6, "memory"), NULL));
5830 x = gimple_build_asm_vec ("", NULL, NULL, v_clobbers, NULL);
16c9337c 5831 gimple_asm_set_volatile (x, true);
5832 expand_asm_stmt (x);
b6a5fc45 5833}
5834
c2f47e15 5835/* Expand the __sync_lock_release intrinsic. EXP is the CALL_EXPR. */
b6a5fc45 5836
5837static void
c2f47e15 5838expand_builtin_lock_release (enum machine_mode mode, tree exp)
b6a5fc45 5839{
b6a5fc45 5840 enum insn_code icode;
041e0215 5841 rtx mem, insn;
3e272de8 5842 rtx val = const0_rtx;
b6a5fc45 5843
5844 /* Expand the operands. */
c2f47e15 5845 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
b6a5fc45 5846
5847 /* If there is an explicit operation in the md file, use it. */
5848 icode = sync_lock_release[mode];
5849 if (icode != CODE_FOR_nothing)
5850 {
5851 if (!insn_data[icode].operand[1].predicate (val, mode))
5852 val = force_reg (mode, val);
5853
5854 insn = GEN_FCN (icode) (mem, val);
5855 if (insn)
5856 {
5857 emit_insn (insn);
5858 return;
5859 }
5860 }
5861
5862 /* Otherwise we can implement this operation by emitting a barrier
5863 followed by a store of zero. */
5864 expand_builtin_synchronize ();
5865 emit_move_insn (mem, val);
5866}
53800dbe 5867\f
5868/* Expand an expression EXP that calls a built-in function,
5869 with result going to TARGET if that's convenient
5870 (and in mode MODE if that's convenient).
5871 SUBTARGET may be used as the target for computing one of EXP's operands.
5872 IGNORE is nonzero if the value is to be ignored. */
5873
5874rtx
aecda0d6 5875expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5876 int ignore)
53800dbe 5877{
c6e6ecb1 5878 tree fndecl = get_callee_fndecl (exp);
53800dbe 5879 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
efb070c8 5880 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
53800dbe 5881
8305149e 5882 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
883b2e73 5883 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
bf8e3599 5884
53800dbe 5885 /* When not optimizing, generate calls to library functions for a certain
5886 set of builtins. */
cd9ff771 5887 if (!optimize
b6a5fc45 5888 && !called_as_built_in (fndecl)
cd9ff771 5889 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
2c281b15 5890 && fcode != BUILT_IN_ALLOCA
5891 && fcode != BUILT_IN_FREE)
cd9ff771 5892 return expand_call (exp, target, ignore);
53800dbe 5893
8d6d7930 5894 /* The built-in function expanders test for target == const0_rtx
5895 to determine whether the function's result will be ignored. */
5896 if (ignore)
5897 target = const0_rtx;
5898
5899 /* If the result of a pure or const built-in function is ignored, and
5900 none of its arguments are volatile, we can avoid expanding the
5901 built-in call and just evaluate the arguments for side-effects. */
5902 if (target == const0_rtx
9c2a0c05 5903 && (DECL_PURE_P (fndecl) || TREE_READONLY (fndecl)))
8d6d7930 5904 {
5905 bool volatilep = false;
5906 tree arg;
c2f47e15 5907 call_expr_arg_iterator iter;
8d6d7930 5908
c2f47e15 5909 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
5910 if (TREE_THIS_VOLATILE (arg))
8d6d7930 5911 {
5912 volatilep = true;
5913 break;
5914 }
5915
5916 if (! volatilep)
5917 {
c2f47e15 5918 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
5919 expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL);
8d6d7930 5920 return const0_rtx;
5921 }
5922 }
5923
53800dbe 5924 switch (fcode)
5925 {
4f35b1fc 5926 CASE_FLT_FN (BUILT_IN_FABS):
c2f47e15 5927 target = expand_builtin_fabs (exp, target, subtarget);
78a74442 5928 if (target)
a0c938f0 5929 return target;
78a74442 5930 break;
5931
4f35b1fc 5932 CASE_FLT_FN (BUILT_IN_COPYSIGN):
c2f47e15 5933 target = expand_builtin_copysign (exp, target, subtarget);
270436f3 5934 if (target)
5935 return target;
5936 break;
5937
7d3f6cc7 5938 /* Just do a normal library call if we were unable to fold
5939 the values. */
4f35b1fc 5940 CASE_FLT_FN (BUILT_IN_CABS):
78a74442 5941 break;
53800dbe 5942
4f35b1fc 5943 CASE_FLT_FN (BUILT_IN_EXP):
5944 CASE_FLT_FN (BUILT_IN_EXP10):
5945 CASE_FLT_FN (BUILT_IN_POW10):
5946 CASE_FLT_FN (BUILT_IN_EXP2):
5947 CASE_FLT_FN (BUILT_IN_EXPM1):
5948 CASE_FLT_FN (BUILT_IN_LOGB):
4f35b1fc 5949 CASE_FLT_FN (BUILT_IN_LOG):
5950 CASE_FLT_FN (BUILT_IN_LOG10):
5951 CASE_FLT_FN (BUILT_IN_LOG2):
5952 CASE_FLT_FN (BUILT_IN_LOG1P):
5953 CASE_FLT_FN (BUILT_IN_TAN):
5954 CASE_FLT_FN (BUILT_IN_ASIN):
5955 CASE_FLT_FN (BUILT_IN_ACOS):
5956 CASE_FLT_FN (BUILT_IN_ATAN):
b3154a1f 5957 CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
7f3be425 5958 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5959 because of possible accuracy problems. */
5960 if (! flag_unsafe_math_optimizations)
53800dbe 5961 break;
4f35b1fc 5962 CASE_FLT_FN (BUILT_IN_SQRT):
5963 CASE_FLT_FN (BUILT_IN_FLOOR):
5964 CASE_FLT_FN (BUILT_IN_CEIL):
5965 CASE_FLT_FN (BUILT_IN_TRUNC):
5966 CASE_FLT_FN (BUILT_IN_ROUND):
5967 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5968 CASE_FLT_FN (BUILT_IN_RINT):
53800dbe 5969 target = expand_builtin_mathfn (exp, target, subtarget);
5970 if (target)
5971 return target;
5972 break;
5973
a67a90e5 5974 CASE_FLT_FN (BUILT_IN_ILOGB):
5975 if (! flag_unsafe_math_optimizations)
5976 break;
69b779ea 5977 CASE_FLT_FN (BUILT_IN_ISINF):
cde061c1 5978 CASE_FLT_FN (BUILT_IN_FINITE):
5979 case BUILT_IN_ISFINITE:
8a1a9cb7 5980 case BUILT_IN_ISNORMAL:
a67a90e5 5981 target = expand_builtin_interclass_mathfn (exp, target, subtarget);
5982 if (target)
5983 return target;
5984 break;
5985
4f35b1fc 5986 CASE_FLT_FN (BUILT_IN_LCEIL):
5987 CASE_FLT_FN (BUILT_IN_LLCEIL):
5988 CASE_FLT_FN (BUILT_IN_LFLOOR):
5989 CASE_FLT_FN (BUILT_IN_LLFLOOR):
ff1b14e4 5990 target = expand_builtin_int_roundingfn (exp, target);
ad52b9b7 5991 if (target)
5992 return target;
5993 break;
5994
7d3afc77 5995 CASE_FLT_FN (BUILT_IN_LRINT):
5996 CASE_FLT_FN (BUILT_IN_LLRINT):
ef2f1a10 5997 CASE_FLT_FN (BUILT_IN_LROUND):
5998 CASE_FLT_FN (BUILT_IN_LLROUND):
ff1b14e4 5999 target = expand_builtin_int_roundingfn_2 (exp, target);
7d3afc77 6000 if (target)
6001 return target;
6002 break;
6003
4f35b1fc 6004 CASE_FLT_FN (BUILT_IN_POW):
f1b844c6 6005 target = expand_builtin_pow (exp, target, subtarget);
6006 if (target)
6007 return target;
6008 break;
6009
4f35b1fc 6010 CASE_FLT_FN (BUILT_IN_POWI):
757c219d 6011 target = expand_builtin_powi (exp, target, subtarget);
6012 if (target)
6013 return target;
6014 break;
6015
4f35b1fc 6016 CASE_FLT_FN (BUILT_IN_ATAN2):
6017 CASE_FLT_FN (BUILT_IN_LDEXP):
73a954a1 6018 CASE_FLT_FN (BUILT_IN_SCALB):
6019 CASE_FLT_FN (BUILT_IN_SCALBN):
6020 CASE_FLT_FN (BUILT_IN_SCALBLN):
0fd605a5 6021 if (! flag_unsafe_math_optimizations)
6022 break;
ef722005 6023
6024 CASE_FLT_FN (BUILT_IN_FMOD):
6025 CASE_FLT_FN (BUILT_IN_REMAINDER):
6026 CASE_FLT_FN (BUILT_IN_DREM):
0fd605a5 6027 target = expand_builtin_mathfn_2 (exp, target, subtarget);
6028 if (target)
6029 return target;
6030 break;
6031
d735c391 6032 CASE_FLT_FN (BUILT_IN_CEXPI):
6033 target = expand_builtin_cexpi (exp, target, subtarget);
6034 gcc_assert (target);
6035 return target;
6036
4f35b1fc 6037 CASE_FLT_FN (BUILT_IN_SIN):
6038 CASE_FLT_FN (BUILT_IN_COS):
6b43bae4 6039 if (! flag_unsafe_math_optimizations)
6040 break;
6041 target = expand_builtin_mathfn_3 (exp, target, subtarget);
6042 if (target)
6043 return target;
6044 break;
6045
c3147c1a 6046 CASE_FLT_FN (BUILT_IN_SINCOS):
6047 if (! flag_unsafe_math_optimizations)
6048 break;
6049 target = expand_builtin_sincos (exp);
6050 if (target)
6051 return target;
6052 break;
6053
53800dbe 6054 case BUILT_IN_APPLY_ARGS:
6055 return expand_builtin_apply_args ();
6056
6057 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
6058 FUNCTION with a copy of the parameters described by
6059 ARGUMENTS, and ARGSIZE. It returns a block of memory
6060 allocated on the stack into which is stored all the registers
6061 that might possibly be used for returning the result of a
6062 function. ARGUMENTS is the value returned by
6063 __builtin_apply_args. ARGSIZE is the number of bytes of
6064 arguments that must be copied. ??? How should this value be
6065 computed? We'll also need a safe worst case value for varargs
6066 functions. */
6067 case BUILT_IN_APPLY:
c2f47e15 6068 if (!validate_arglist (exp, POINTER_TYPE,
0eb671f7 6069 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
c2f47e15 6070 && !validate_arglist (exp, REFERENCE_TYPE,
0eb671f7 6071 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
53800dbe 6072 return const0_rtx;
6073 else
6074 {
53800dbe 6075 rtx ops[3];
6076
c2f47e15 6077 ops[0] = expand_normal (CALL_EXPR_ARG (exp, 0));
6078 ops[1] = expand_normal (CALL_EXPR_ARG (exp, 1));
6079 ops[2] = expand_normal (CALL_EXPR_ARG (exp, 2));
53800dbe 6080
6081 return expand_builtin_apply (ops[0], ops[1], ops[2]);
6082 }
6083
6084 /* __builtin_return (RESULT) causes the function to return the
6085 value described by RESULT. RESULT is address of the block of
6086 memory returned by __builtin_apply. */
6087 case BUILT_IN_RETURN:
c2f47e15 6088 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6089 expand_builtin_return (expand_normal (CALL_EXPR_ARG (exp, 0)));
53800dbe 6090 return const0_rtx;
6091
6092 case BUILT_IN_SAVEREGS:
a66c9326 6093 return expand_builtin_saveregs ();
53800dbe 6094
6095 case BUILT_IN_ARGS_INFO:
c2f47e15 6096 return expand_builtin_args_info (exp);
53800dbe 6097
48dc2227 6098 case BUILT_IN_VA_ARG_PACK:
6099 /* All valid uses of __builtin_va_arg_pack () are removed during
6100 inlining. */
b8c23db3 6101 error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp);
48dc2227 6102 return const0_rtx;
6103
4e1d7ea4 6104 case BUILT_IN_VA_ARG_PACK_LEN:
6105 /* All valid uses of __builtin_va_arg_pack_len () are removed during
6106 inlining. */
b8c23db3 6107 error ("%Kinvalid use of %<__builtin_va_arg_pack_len ()%>", exp);
4e1d7ea4 6108 return const0_rtx;
6109
53800dbe 6110 /* Return the address of the first anonymous stack arg. */
6111 case BUILT_IN_NEXT_ARG:
c2f47e15 6112 if (fold_builtin_next_arg (exp, false))
a0c938f0 6113 return const0_rtx;
79012a9d 6114 return expand_builtin_next_arg ();
53800dbe 6115
ac8fb6db 6116 case BUILT_IN_CLEAR_CACHE:
6117 target = expand_builtin___clear_cache (exp);
6118 if (target)
6119 return target;
6120 break;
6121
53800dbe 6122 case BUILT_IN_CLASSIFY_TYPE:
c2f47e15 6123 return expand_builtin_classify_type (exp);
53800dbe 6124
6125 case BUILT_IN_CONSTANT_P:
4ee9c684 6126 return const0_rtx;
53800dbe 6127
6128 case BUILT_IN_FRAME_ADDRESS:
6129 case BUILT_IN_RETURN_ADDRESS:
c2f47e15 6130 return expand_builtin_frame_address (fndecl, exp);
53800dbe 6131
6132 /* Returns the address of the area where the structure is returned.
6133 0 otherwise. */
6134 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
c2f47e15 6135 if (call_expr_nargs (exp) != 0
9342ee68 6136 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
e16ceb8e 6137 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
9342ee68 6138 return const0_rtx;
53800dbe 6139 else
9342ee68 6140 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
53800dbe 6141
6142 case BUILT_IN_ALLOCA:
c2f47e15 6143 target = expand_builtin_alloca (exp, target);
53800dbe 6144 if (target)
6145 return target;
6146 break;
6147
4ee9c684 6148 case BUILT_IN_STACK_SAVE:
6149 return expand_stack_save ();
6150
6151 case BUILT_IN_STACK_RESTORE:
c2f47e15 6152 expand_stack_restore (CALL_EXPR_ARG (exp, 0));
4ee9c684 6153 return const0_rtx;
6154
42791117 6155 case BUILT_IN_BSWAP32:
6156 case BUILT_IN_BSWAP64:
c2f47e15 6157 target = expand_builtin_bswap (exp, target, subtarget);
42791117 6158
6159 if (target)
6160 return target;
6161 break;
6162
4f35b1fc 6163 CASE_INT_FN (BUILT_IN_FFS):
5053259b 6164 case BUILT_IN_FFSIMAX:
c2f47e15 6165 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6166 subtarget, ffs_optab);
6a08d0ab 6167 if (target)
6168 return target;
6169 break;
6170
4f35b1fc 6171 CASE_INT_FN (BUILT_IN_CLZ):
5053259b 6172 case BUILT_IN_CLZIMAX:
c2f47e15 6173 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6174 subtarget, clz_optab);
6a08d0ab 6175 if (target)
6176 return target;
6177 break;
6178
4f35b1fc 6179 CASE_INT_FN (BUILT_IN_CTZ):
5053259b 6180 case BUILT_IN_CTZIMAX:
c2f47e15 6181 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6182 subtarget, ctz_optab);
6a08d0ab 6183 if (target)
6184 return target;
6185 break;
6186
4f35b1fc 6187 CASE_INT_FN (BUILT_IN_POPCOUNT):
5053259b 6188 case BUILT_IN_POPCOUNTIMAX:
c2f47e15 6189 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6190 subtarget, popcount_optab);
6a08d0ab 6191 if (target)
6192 return target;
6193 break;
6194
4f35b1fc 6195 CASE_INT_FN (BUILT_IN_PARITY):
5053259b 6196 case BUILT_IN_PARITYIMAX:
c2f47e15 6197 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6198 subtarget, parity_optab);
53800dbe 6199 if (target)
6200 return target;
6201 break;
6202
6203 case BUILT_IN_STRLEN:
c2f47e15 6204 target = expand_builtin_strlen (exp, target, target_mode);
53800dbe 6205 if (target)
6206 return target;
6207 break;
6208
6209 case BUILT_IN_STRCPY:
a65c4d64 6210 target = expand_builtin_strcpy (exp, target);
53800dbe 6211 if (target)
6212 return target;
6213 break;
bf8e3599 6214
ed09096d 6215 case BUILT_IN_STRNCPY:
a65c4d64 6216 target = expand_builtin_strncpy (exp, target);
ed09096d 6217 if (target)
6218 return target;
6219 break;
bf8e3599 6220
3b824fa6 6221 case BUILT_IN_STPCPY:
dc369150 6222 target = expand_builtin_stpcpy (exp, target, mode);
3b824fa6 6223 if (target)
6224 return target;
6225 break;
6226
53800dbe 6227 case BUILT_IN_MEMCPY:
a65c4d64 6228 target = expand_builtin_memcpy (exp, target);
3b824fa6 6229 if (target)
6230 return target;
6231 break;
6232
6233 case BUILT_IN_MEMPCPY:
c2f47e15 6234 target = expand_builtin_mempcpy (exp, target, mode);
53800dbe 6235 if (target)
6236 return target;
6237 break;
6238
6239 case BUILT_IN_MEMSET:
c2f47e15 6240 target = expand_builtin_memset (exp, target, mode);
53800dbe 6241 if (target)
6242 return target;
6243 break;
6244
ffc83088 6245 case BUILT_IN_BZERO:
0b25db21 6246 target = expand_builtin_bzero (exp);
ffc83088 6247 if (target)
6248 return target;
6249 break;
6250
53800dbe 6251 case BUILT_IN_STRCMP:
a65c4d64 6252 target = expand_builtin_strcmp (exp, target);
53800dbe 6253 if (target)
6254 return target;
6255 break;
6256
ed09096d 6257 case BUILT_IN_STRNCMP:
6258 target = expand_builtin_strncmp (exp, target, mode);
6259 if (target)
6260 return target;
6261 break;
6262
071f1696 6263 case BUILT_IN_BCMP:
53800dbe 6264 case BUILT_IN_MEMCMP:
c2f47e15 6265 target = expand_builtin_memcmp (exp, target, mode);
53800dbe 6266 if (target)
6267 return target;
6268 break;
53800dbe 6269
6270 case BUILT_IN_SETJMP:
2c8a1497 6271 /* This should have been lowered to the builtins below. */
6272 gcc_unreachable ();
6273
6274 case BUILT_IN_SETJMP_SETUP:
6275 /* __builtin_setjmp_setup is passed a pointer to an array of five words
6276 and the receiver label. */
c2f47e15 6277 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2c8a1497 6278 {
c2f47e15 6279 rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
2c8a1497 6280 VOIDmode, EXPAND_NORMAL);
c2f47e15 6281 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 1), 0);
2c8a1497 6282 rtx label_r = label_rtx (label);
6283
6284 /* This is copied from the handling of non-local gotos. */
6285 expand_builtin_setjmp_setup (buf_addr, label_r);
6286 nonlocal_goto_handler_labels
6287 = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6288 nonlocal_goto_handler_labels);
6289 /* ??? Do not let expand_label treat us as such since we would
6290 not want to be both on the list of non-local labels and on
6291 the list of forced labels. */
6292 FORCED_LABEL (label) = 0;
6293 return const0_rtx;
6294 }
6295 break;
6296
6297 case BUILT_IN_SETJMP_DISPATCHER:
6298 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */
c2f47e15 6299 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
2c8a1497 6300 {
c2f47e15 6301 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
2c8a1497 6302 rtx label_r = label_rtx (label);
6303
6304 /* Remove the dispatcher label from the list of non-local labels
6305 since the receiver labels have been added to it above. */
6306 remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6307 return const0_rtx;
6308 }
6309 break;
6310
6311 case BUILT_IN_SETJMP_RECEIVER:
6312 /* __builtin_setjmp_receiver is passed the receiver label. */
c2f47e15 6313 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
2c8a1497 6314 {
c2f47e15 6315 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
2c8a1497 6316 rtx label_r = label_rtx (label);
6317
6318 expand_builtin_setjmp_receiver (label_r);
6319 return const0_rtx;
6320 }
6b7f6858 6321 break;
53800dbe 6322
6323 /* __builtin_longjmp is passed a pointer to an array of five words.
6324 It's similar to the C library longjmp function but works with
6325 __builtin_setjmp above. */
6326 case BUILT_IN_LONGJMP:
c2f47e15 6327 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
53800dbe 6328 {
c2f47e15 6329 rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
8ec3c5c2 6330 VOIDmode, EXPAND_NORMAL);
c2f47e15 6331 rtx value = expand_normal (CALL_EXPR_ARG (exp, 1));
53800dbe 6332
6333 if (value != const1_rtx)
6334 {
1e5fcbe2 6335 error ("%<__builtin_longjmp%> second argument must be 1");
53800dbe 6336 return const0_rtx;
6337 }
6338
6339 expand_builtin_longjmp (buf_addr, value);
6340 return const0_rtx;
6341 }
2c8a1497 6342 break;
53800dbe 6343
4ee9c684 6344 case BUILT_IN_NONLOCAL_GOTO:
c2f47e15 6345 target = expand_builtin_nonlocal_goto (exp);
4ee9c684 6346 if (target)
6347 return target;
6348 break;
6349
843d08a9 6350 /* This updates the setjmp buffer that is its argument with the value
6351 of the current stack pointer. */
6352 case BUILT_IN_UPDATE_SETJMP_BUF:
c2f47e15 6353 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
843d08a9 6354 {
6355 rtx buf_addr
c2f47e15 6356 = expand_normal (CALL_EXPR_ARG (exp, 0));
843d08a9 6357
6358 expand_builtin_update_setjmp_buf (buf_addr);
6359 return const0_rtx;
6360 }
6361 break;
6362
53800dbe 6363 case BUILT_IN_TRAP:
a0ef1725 6364 expand_builtin_trap ();
53800dbe 6365 return const0_rtx;
6366
d2b48f0c 6367 case BUILT_IN_UNREACHABLE:
6368 expand_builtin_unreachable ();
6369 return const0_rtx;
6370
19bf118a 6371 case BUILT_IN_PRINTF:
0b25db21 6372 target = expand_builtin_printf (exp, target, mode, false);
19bf118a 6373 if (target)
6374 return target;
6375 break;
6376
6377 case BUILT_IN_PRINTF_UNLOCKED:
0b25db21 6378 target = expand_builtin_printf (exp, target, mode, true);
19bf118a 6379 if (target)
6380 return target;
6381 break;
6382
19bf118a 6383 case BUILT_IN_FPRINTF:
0b25db21 6384 target = expand_builtin_fprintf (exp, target, mode, false);
19bf118a 6385 if (target)
6386 return target;
6387 break;
6388
6389 case BUILT_IN_FPRINTF_UNLOCKED:
0b25db21 6390 target = expand_builtin_fprintf (exp, target, mode, true);
df94cd3b 6391 if (target)
6392 return target;
6393 break;
bf8e3599 6394
6411575e 6395 case BUILT_IN_SPRINTF:
c2f47e15 6396 target = expand_builtin_sprintf (exp, target, mode);
6411575e 6397 if (target)
6398 return target;
6399 break;
6400
4f35b1fc 6401 CASE_FLT_FN (BUILT_IN_SIGNBIT):
004e23c4 6402 case BUILT_IN_SIGNBITD32:
6403 case BUILT_IN_SIGNBITD64:
6404 case BUILT_IN_SIGNBITD128:
27f261ef 6405 target = expand_builtin_signbit (exp, target);
6406 if (target)
6407 return target;
6408 break;
6409
53800dbe 6410 /* Various hooks for the DWARF 2 __throw routine. */
6411 case BUILT_IN_UNWIND_INIT:
6412 expand_builtin_unwind_init ();
6413 return const0_rtx;
6414 case BUILT_IN_DWARF_CFA:
6415 return virtual_cfa_rtx;
6416#ifdef DWARF2_UNWIND_INFO
f8f023a5 6417 case BUILT_IN_DWARF_SP_COLUMN:
6418 return expand_builtin_dwarf_sp_column ();
695e919b 6419 case BUILT_IN_INIT_DWARF_REG_SIZES:
c2f47e15 6420 expand_builtin_init_dwarf_reg_sizes (CALL_EXPR_ARG (exp, 0));
695e919b 6421 return const0_rtx;
53800dbe 6422#endif
6423 case BUILT_IN_FROB_RETURN_ADDR:
c2f47e15 6424 return expand_builtin_frob_return_addr (CALL_EXPR_ARG (exp, 0));
53800dbe 6425 case BUILT_IN_EXTRACT_RETURN_ADDR:
c2f47e15 6426 return expand_builtin_extract_return_addr (CALL_EXPR_ARG (exp, 0));
53800dbe 6427 case BUILT_IN_EH_RETURN:
c2f47e15 6428 expand_builtin_eh_return (CALL_EXPR_ARG (exp, 0),
6429 CALL_EXPR_ARG (exp, 1));
53800dbe 6430 return const0_rtx;
df4b504c 6431#ifdef EH_RETURN_DATA_REGNO
6432 case BUILT_IN_EH_RETURN_DATA_REGNO:
c2f47e15 6433 return expand_builtin_eh_return_data_regno (exp);
df4b504c 6434#endif
26093bf4 6435 case BUILT_IN_EXTEND_POINTER:
c2f47e15 6436 return expand_builtin_extend_pointer (CALL_EXPR_ARG (exp, 0));
e38def9c 6437 case BUILT_IN_EH_POINTER:
6438 return expand_builtin_eh_pointer (exp);
6439 case BUILT_IN_EH_FILTER:
6440 return expand_builtin_eh_filter (exp);
6441 case BUILT_IN_EH_COPY_VALUES:
6442 return expand_builtin_eh_copy_values (exp);
26093bf4 6443
7ccc713a 6444 case BUILT_IN_VA_START:
c2f47e15 6445 return expand_builtin_va_start (exp);
a66c9326 6446 case BUILT_IN_VA_END:
c2f47e15 6447 return expand_builtin_va_end (exp);
a66c9326 6448 case BUILT_IN_VA_COPY:
c2f47e15 6449 return expand_builtin_va_copy (exp);
89cfe6e5 6450 case BUILT_IN_EXPECT:
c2f47e15 6451 return expand_builtin_expect (exp, target);
5e3608d8 6452 case BUILT_IN_PREFETCH:
c2f47e15 6453 expand_builtin_prefetch (exp);
5e3608d8 6454 return const0_rtx;
6455
4ee9c684 6456 case BUILT_IN_PROFILE_FUNC_ENTER:
6457 return expand_builtin_profile_func (false);
6458 case BUILT_IN_PROFILE_FUNC_EXIT:
6459 return expand_builtin_profile_func (true);
6460
6461 case BUILT_IN_INIT_TRAMPOLINE:
c2f47e15 6462 return expand_builtin_init_trampoline (exp);
4ee9c684 6463 case BUILT_IN_ADJUST_TRAMPOLINE:
c2f47e15 6464 return expand_builtin_adjust_trampoline (exp);
4ee9c684 6465
73673831 6466 case BUILT_IN_FORK:
6467 case BUILT_IN_EXECL:
6468 case BUILT_IN_EXECV:
6469 case BUILT_IN_EXECLP:
6470 case BUILT_IN_EXECLE:
6471 case BUILT_IN_EXECVP:
6472 case BUILT_IN_EXECVE:
c2f47e15 6473 target = expand_builtin_fork_or_exec (fndecl, exp, target, ignore);
73673831 6474 if (target)
6475 return target;
6476 break;
53800dbe 6477
b6a5fc45 6478 case BUILT_IN_FETCH_AND_ADD_1:
6479 case BUILT_IN_FETCH_AND_ADD_2:
6480 case BUILT_IN_FETCH_AND_ADD_4:
6481 case BUILT_IN_FETCH_AND_ADD_8:
27213ba3 6482 case BUILT_IN_FETCH_AND_ADD_16:
3e272de8 6483 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
c2f47e15 6484 target = expand_builtin_sync_operation (mode, exp, PLUS,
b6a5fc45 6485 false, target, ignore);
6486 if (target)
6487 return target;
6488 break;
6489
6490 case BUILT_IN_FETCH_AND_SUB_1:
6491 case BUILT_IN_FETCH_AND_SUB_2:
6492 case BUILT_IN_FETCH_AND_SUB_4:
6493 case BUILT_IN_FETCH_AND_SUB_8:
27213ba3 6494 case BUILT_IN_FETCH_AND_SUB_16:
3e272de8 6495 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
c2f47e15 6496 target = expand_builtin_sync_operation (mode, exp, MINUS,
b6a5fc45 6497 false, target, ignore);
6498 if (target)
6499 return target;
6500 break;
6501
6502 case BUILT_IN_FETCH_AND_OR_1:
6503 case BUILT_IN_FETCH_AND_OR_2:
6504 case BUILT_IN_FETCH_AND_OR_4:
6505 case BUILT_IN_FETCH_AND_OR_8:
27213ba3 6506 case BUILT_IN_FETCH_AND_OR_16:
3e272de8 6507 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
c2f47e15 6508 target = expand_builtin_sync_operation (mode, exp, IOR,
b6a5fc45 6509 false, target, ignore);
6510 if (target)
6511 return target;
6512 break;
6513
6514 case BUILT_IN_FETCH_AND_AND_1:
6515 case BUILT_IN_FETCH_AND_AND_2:
6516 case BUILT_IN_FETCH_AND_AND_4:
6517 case BUILT_IN_FETCH_AND_AND_8:
27213ba3 6518 case BUILT_IN_FETCH_AND_AND_16:
3e272de8 6519 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
c2f47e15 6520 target = expand_builtin_sync_operation (mode, exp, AND,
b6a5fc45 6521 false, target, ignore);
6522 if (target)
6523 return target;
6524 break;
6525
6526 case BUILT_IN_FETCH_AND_XOR_1:
6527 case BUILT_IN_FETCH_AND_XOR_2:
6528 case BUILT_IN_FETCH_AND_XOR_4:
6529 case BUILT_IN_FETCH_AND_XOR_8:
27213ba3 6530 case BUILT_IN_FETCH_AND_XOR_16:
3e272de8 6531 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
c2f47e15 6532 target = expand_builtin_sync_operation (mode, exp, XOR,
b6a5fc45 6533 false, target, ignore);
6534 if (target)
6535 return target;
6536 break;
6537
6538 case BUILT_IN_FETCH_AND_NAND_1:
6539 case BUILT_IN_FETCH_AND_NAND_2:
6540 case BUILT_IN_FETCH_AND_NAND_4:
6541 case BUILT_IN_FETCH_AND_NAND_8:
27213ba3 6542 case BUILT_IN_FETCH_AND_NAND_16:
3e272de8 6543 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
c2f47e15 6544 target = expand_builtin_sync_operation (mode, exp, NOT,
b6a5fc45 6545 false, target, ignore);
6546 if (target)
6547 return target;
6548 break;
6549
6550 case BUILT_IN_ADD_AND_FETCH_1:
6551 case BUILT_IN_ADD_AND_FETCH_2:
6552 case BUILT_IN_ADD_AND_FETCH_4:
6553 case BUILT_IN_ADD_AND_FETCH_8:
27213ba3 6554 case BUILT_IN_ADD_AND_FETCH_16:
3e272de8 6555 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
c2f47e15 6556 target = expand_builtin_sync_operation (mode, exp, PLUS,
b6a5fc45 6557 true, target, ignore);
6558 if (target)
6559 return target;
6560 break;
6561
6562 case BUILT_IN_SUB_AND_FETCH_1:
6563 case BUILT_IN_SUB_AND_FETCH_2:
6564 case BUILT_IN_SUB_AND_FETCH_4:
6565 case BUILT_IN_SUB_AND_FETCH_8:
27213ba3 6566 case BUILT_IN_SUB_AND_FETCH_16:
3e272de8 6567 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
c2f47e15 6568 target = expand_builtin_sync_operation (mode, exp, MINUS,
b6a5fc45 6569 true, target, ignore);
6570 if (target)
6571 return target;
6572 break;
6573
6574 case BUILT_IN_OR_AND_FETCH_1:
6575 case BUILT_IN_OR_AND_FETCH_2:
6576 case BUILT_IN_OR_AND_FETCH_4:
6577 case BUILT_IN_OR_AND_FETCH_8:
27213ba3 6578 case BUILT_IN_OR_AND_FETCH_16:
3e272de8 6579 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
c2f47e15 6580 target = expand_builtin_sync_operation (mode, exp, IOR,
b6a5fc45 6581 true, target, ignore);
6582 if (target)
6583 return target;
6584 break;
6585
6586 case BUILT_IN_AND_AND_FETCH_1:
6587 case BUILT_IN_AND_AND_FETCH_2:
6588 case BUILT_IN_AND_AND_FETCH_4:
6589 case BUILT_IN_AND_AND_FETCH_8:
27213ba3 6590 case BUILT_IN_AND_AND_FETCH_16:
3e272de8 6591 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
c2f47e15 6592 target = expand_builtin_sync_operation (mode, exp, AND,
b6a5fc45 6593 true, target, ignore);
6594 if (target)
6595 return target;
6596 break;
6597
6598 case BUILT_IN_XOR_AND_FETCH_1:
6599 case BUILT_IN_XOR_AND_FETCH_2:
6600 case BUILT_IN_XOR_AND_FETCH_4:
6601 case BUILT_IN_XOR_AND_FETCH_8:
27213ba3 6602 case BUILT_IN_XOR_AND_FETCH_16:
3e272de8 6603 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
c2f47e15 6604 target = expand_builtin_sync_operation (mode, exp, XOR,
b6a5fc45 6605 true, target, ignore);
6606 if (target)
6607 return target;
6608 break;
6609
6610 case BUILT_IN_NAND_AND_FETCH_1:
6611 case BUILT_IN_NAND_AND_FETCH_2:
6612 case BUILT_IN_NAND_AND_FETCH_4:
6613 case BUILT_IN_NAND_AND_FETCH_8:
27213ba3 6614 case BUILT_IN_NAND_AND_FETCH_16:
3e272de8 6615 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
c2f47e15 6616 target = expand_builtin_sync_operation (mode, exp, NOT,
b6a5fc45 6617 true, target, ignore);
6618 if (target)
6619 return target;
6620 break;
6621
6622 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6623 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6624 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6625 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
27213ba3 6626 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
a601d32a 6627 if (mode == VOIDmode)
6628 mode = TYPE_MODE (boolean_type_node);
b6a5fc45 6629 if (!target || !register_operand (target, mode))
6630 target = gen_reg_rtx (mode);
3e272de8 6631
6632 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
c2f47e15 6633 target = expand_builtin_compare_and_swap (mode, exp, true, target);
b6a5fc45 6634 if (target)
6635 return target;
6636 break;
6637
6638 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6639 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6640 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6641 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
27213ba3 6642 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
3e272de8 6643 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
c2f47e15 6644 target = expand_builtin_compare_and_swap (mode, exp, false, target);
b6a5fc45 6645 if (target)
6646 return target;
6647 break;
6648
6649 case BUILT_IN_LOCK_TEST_AND_SET_1:
6650 case BUILT_IN_LOCK_TEST_AND_SET_2:
6651 case BUILT_IN_LOCK_TEST_AND_SET_4:
6652 case BUILT_IN_LOCK_TEST_AND_SET_8:
27213ba3 6653 case BUILT_IN_LOCK_TEST_AND_SET_16:
3e272de8 6654 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
c2f47e15 6655 target = expand_builtin_lock_test_and_set (mode, exp, target);
b6a5fc45 6656 if (target)
6657 return target;
6658 break;
6659
6660 case BUILT_IN_LOCK_RELEASE_1:
6661 case BUILT_IN_LOCK_RELEASE_2:
6662 case BUILT_IN_LOCK_RELEASE_4:
6663 case BUILT_IN_LOCK_RELEASE_8:
27213ba3 6664 case BUILT_IN_LOCK_RELEASE_16:
3e272de8 6665 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
c2f47e15 6666 expand_builtin_lock_release (mode, exp);
b6a5fc45 6667 return const0_rtx;
6668
6669 case BUILT_IN_SYNCHRONIZE:
6670 expand_builtin_synchronize ();
6671 return const0_rtx;
6672
0a39fd54 6673 case BUILT_IN_OBJECT_SIZE:
6674 return expand_builtin_object_size (exp);
6675
6676 case BUILT_IN_MEMCPY_CHK:
6677 case BUILT_IN_MEMPCPY_CHK:
6678 case BUILT_IN_MEMMOVE_CHK:
6679 case BUILT_IN_MEMSET_CHK:
6680 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6681 if (target)
6682 return target;
6683 break;
6684
6685 case BUILT_IN_STRCPY_CHK:
6686 case BUILT_IN_STPCPY_CHK:
6687 case BUILT_IN_STRNCPY_CHK:
6688 case BUILT_IN_STRCAT_CHK:
b356dfef 6689 case BUILT_IN_STRNCAT_CHK:
0a39fd54 6690 case BUILT_IN_SNPRINTF_CHK:
6691 case BUILT_IN_VSNPRINTF_CHK:
6692 maybe_emit_chk_warning (exp, fcode);
6693 break;
6694
6695 case BUILT_IN_SPRINTF_CHK:
6696 case BUILT_IN_VSPRINTF_CHK:
6697 maybe_emit_sprintf_chk_warning (exp, fcode);
6698 break;
6699
2c281b15 6700 case BUILT_IN_FREE:
6701 maybe_emit_free_warning (exp);
6702 break;
6703
92482ee0 6704 default: /* just do library call, if unknown builtin */
146c1b4f 6705 break;
53800dbe 6706 }
6707
6708 /* The switch statement above can drop through to cause the function
6709 to be called normally. */
6710 return expand_call (exp, target, ignore);
6711}
650e4c94 6712
805e22b2 6713/* Determine whether a tree node represents a call to a built-in
52203a9d 6714 function. If the tree T is a call to a built-in function with
6715 the right number of arguments of the appropriate types, return
6716 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6717 Otherwise the return value is END_BUILTINS. */
aecda0d6 6718
805e22b2 6719enum built_in_function
b7bf20db 6720builtin_mathfn_code (const_tree t)
805e22b2 6721{
b7bf20db 6722 const_tree fndecl, arg, parmlist;
6723 const_tree argtype, parmtype;
6724 const_call_expr_arg_iterator iter;
805e22b2 6725
6726 if (TREE_CODE (t) != CALL_EXPR
c2f47e15 6727 || TREE_CODE (CALL_EXPR_FN (t)) != ADDR_EXPR)
805e22b2 6728 return END_BUILTINS;
6729
c6e6ecb1 6730 fndecl = get_callee_fndecl (t);
6731 if (fndecl == NULL_TREE
52203a9d 6732 || TREE_CODE (fndecl) != FUNCTION_DECL
805e22b2 6733 || ! DECL_BUILT_IN (fndecl)
6734 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6735 return END_BUILTINS;
6736
52203a9d 6737 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
b7bf20db 6738 init_const_call_expr_arg_iterator (t, &iter);
52203a9d 6739 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
e9f80ff5 6740 {
52203a9d 6741 /* If a function doesn't take a variable number of arguments,
6742 the last element in the list will have type `void'. */
6743 parmtype = TREE_VALUE (parmlist);
6744 if (VOID_TYPE_P (parmtype))
6745 {
b7bf20db 6746 if (more_const_call_expr_args_p (&iter))
52203a9d 6747 return END_BUILTINS;
6748 return DECL_FUNCTION_CODE (fndecl);
6749 }
6750
b7bf20db 6751 if (! more_const_call_expr_args_p (&iter))
e9f80ff5 6752 return END_BUILTINS;
c2f47e15 6753
b7bf20db 6754 arg = next_const_call_expr_arg (&iter);
c2f47e15 6755 argtype = TREE_TYPE (arg);
52203a9d 6756
6757 if (SCALAR_FLOAT_TYPE_P (parmtype))
6758 {
6759 if (! SCALAR_FLOAT_TYPE_P (argtype))
6760 return END_BUILTINS;
6761 }
6762 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6763 {
6764 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6765 return END_BUILTINS;
6766 }
6767 else if (POINTER_TYPE_P (parmtype))
6768 {
6769 if (! POINTER_TYPE_P (argtype))
6770 return END_BUILTINS;
6771 }
6772 else if (INTEGRAL_TYPE_P (parmtype))
6773 {
6774 if (! INTEGRAL_TYPE_P (argtype))
6775 return END_BUILTINS;
6776 }
6777 else
e9f80ff5 6778 return END_BUILTINS;
e9f80ff5 6779 }
6780
52203a9d 6781 /* Variable-length argument list. */
805e22b2 6782 return DECL_FUNCTION_CODE (fndecl);
6783}
6784
c2f47e15 6785/* Fold a call to __builtin_constant_p, if we know its argument ARG will
6786 evaluate to a constant. */
650e4c94 6787
6788static tree
c2f47e15 6789fold_builtin_constant_p (tree arg)
650e4c94 6790{
650e4c94 6791 /* We return 1 for a numeric type that's known to be a constant
6792 value at compile-time or for an aggregate type that's a
6793 literal constant. */
c2f47e15 6794 STRIP_NOPS (arg);
650e4c94 6795
6796 /* If we know this is a constant, emit the constant of one. */
c2f47e15 6797 if (CONSTANT_CLASS_P (arg)
6798 || (TREE_CODE (arg) == CONSTRUCTOR
6799 && TREE_CONSTANT (arg)))
650e4c94 6800 return integer_one_node;
c2f47e15 6801 if (TREE_CODE (arg) == ADDR_EXPR)
adcfa3a3 6802 {
c2f47e15 6803 tree op = TREE_OPERAND (arg, 0);
adcfa3a3 6804 if (TREE_CODE (op) == STRING_CST
6805 || (TREE_CODE (op) == ARRAY_REF
6806 && integer_zerop (TREE_OPERAND (op, 1))
6807 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6808 return integer_one_node;
6809 }
650e4c94 6810
1fb4300c 6811 /* If this expression has side effects, show we don't know it to be a
6812 constant. Likewise if it's a pointer or aggregate type since in
6813 those case we only want literals, since those are only optimized
f97c71a1 6814 when generating RTL, not later.
6815 And finally, if we are compiling an initializer, not code, we
6816 need to return a definite result now; there's not going to be any
6817 more optimization done. */
c2f47e15 6818 if (TREE_SIDE_EFFECTS (arg)
6819 || AGGREGATE_TYPE_P (TREE_TYPE (arg))
6820 || POINTER_TYPE_P (TREE_TYPE (arg))
47be647d 6821 || cfun == 0
6822 || folding_initializer)
650e4c94 6823 return integer_zero_node;
6824
c2f47e15 6825 return NULL_TREE;
650e4c94 6826}
6827
76f5a783 6828/* Create builtin_expect with PRED and EXPECTED as its arguments and
6829 return it as a truthvalue. */
4ee9c684 6830
6831static tree
389dd41b 6832build_builtin_expect_predicate (location_t loc, tree pred, tree expected)
4ee9c684 6833{
76f5a783 6834 tree fn, arg_types, pred_type, expected_type, call_expr, ret_type;
4ee9c684 6835
76f5a783 6836 fn = built_in_decls[BUILT_IN_EXPECT];
6837 arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
6838 ret_type = TREE_TYPE (TREE_TYPE (fn));
6839 pred_type = TREE_VALUE (arg_types);
6840 expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
6841
389dd41b 6842 pred = fold_convert_loc (loc, pred_type, pred);
6843 expected = fold_convert_loc (loc, expected_type, expected);
6844 call_expr = build_call_expr_loc (loc, fn, 2, pred, expected);
76f5a783 6845
6846 return build2 (NE_EXPR, TREE_TYPE (pred), call_expr,
6847 build_int_cst (ret_type, 0));
6848}
6849
6850/* Fold a call to builtin_expect with arguments ARG0 and ARG1. Return
6851 NULL_TREE if no simplification is possible. */
6852
6853static tree
389dd41b 6854fold_builtin_expect (location_t loc, tree arg0, tree arg1)
76f5a783 6855{
6856 tree inner, fndecl;
6857 enum tree_code code;
6858
6859 /* If this is a builtin_expect within a builtin_expect keep the
6860 inner one. See through a comparison against a constant. It
6861 might have been added to create a thruthvalue. */
6862 inner = arg0;
6863 if (COMPARISON_CLASS_P (inner)
6864 && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST)
6865 inner = TREE_OPERAND (inner, 0);
6866
6867 if (TREE_CODE (inner) == CALL_EXPR
6868 && (fndecl = get_callee_fndecl (inner))
6869 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
6870 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT)
6871 return arg0;
6872
6873 /* Distribute the expected value over short-circuiting operators.
6874 See through the cast from truthvalue_type_node to long. */
6875 inner = arg0;
6876 while (TREE_CODE (inner) == NOP_EXPR
6877 && INTEGRAL_TYPE_P (TREE_TYPE (inner))
6878 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (inner, 0))))
6879 inner = TREE_OPERAND (inner, 0);
6880
6881 code = TREE_CODE (inner);
6882 if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
6883 {
6884 tree op0 = TREE_OPERAND (inner, 0);
6885 tree op1 = TREE_OPERAND (inner, 1);
6886
389dd41b 6887 op0 = build_builtin_expect_predicate (loc, op0, arg1);
6888 op1 = build_builtin_expect_predicate (loc, op1, arg1);
76f5a783 6889 inner = build2 (code, TREE_TYPE (inner), op0, op1);
6890
389dd41b 6891 return fold_convert_loc (loc, TREE_TYPE (arg0), inner);
76f5a783 6892 }
6893
6894 /* If the argument isn't invariant then there's nothing else we can do. */
c7d4e749 6895 if (!TREE_CONSTANT (arg0))
c2f47e15 6896 return NULL_TREE;
4ee9c684 6897
76f5a783 6898 /* If we expect that a comparison against the argument will fold to
6899 a constant return the constant. In practice, this means a true
6900 constant or the address of a non-weak symbol. */
6901 inner = arg0;
4ee9c684 6902 STRIP_NOPS (inner);
6903 if (TREE_CODE (inner) == ADDR_EXPR)
6904 {
6905 do
6906 {
6907 inner = TREE_OPERAND (inner, 0);
6908 }
6909 while (TREE_CODE (inner) == COMPONENT_REF
6910 || TREE_CODE (inner) == ARRAY_REF);
062b4460 6911 if ((TREE_CODE (inner) == VAR_DECL
6912 || TREE_CODE (inner) == FUNCTION_DECL)
6913 && DECL_WEAK (inner))
c2f47e15 6914 return NULL_TREE;
4ee9c684 6915 }
6916
76f5a783 6917 /* Otherwise, ARG0 already has the proper type for the return value. */
6918 return arg0;
4ee9c684 6919}
6920
c2f47e15 6921/* Fold a call to __builtin_classify_type with argument ARG. */
27d0c333 6922
539a3a92 6923static tree
c2f47e15 6924fold_builtin_classify_type (tree arg)
539a3a92 6925{
c2f47e15 6926 if (arg == 0)
7016c612 6927 return build_int_cst (NULL_TREE, no_type_class);
539a3a92 6928
c2f47e15 6929 return build_int_cst (NULL_TREE, type_to_class (TREE_TYPE (arg)));
539a3a92 6930}
6931
c2f47e15 6932/* Fold a call to __builtin_strlen with argument ARG. */
e6e27594 6933
6934static tree
389dd41b 6935fold_builtin_strlen (location_t loc, tree arg)
e6e27594 6936{
c2f47e15 6937 if (!validate_arg (arg, POINTER_TYPE))
e6e27594 6938 return NULL_TREE;
6939 else
6940 {
c2f47e15 6941 tree len = c_strlen (arg, 0);
e6e27594 6942
6943 if (len)
6944 {
6945 /* Convert from the internal "sizetype" type to "size_t". */
6946 if (size_type_node)
389dd41b 6947 len = fold_convert_loc (loc, size_type_node, len);
e6e27594 6948 return len;
6949 }
6950
6951 return NULL_TREE;
6952 }
6953}
6954
92c43e3c 6955/* Fold a call to __builtin_inf or __builtin_huge_val. */
6956
6957static tree
389dd41b 6958fold_builtin_inf (location_t loc, tree type, int warn)
92c43e3c 6959{
aa870c1b 6960 REAL_VALUE_TYPE real;
6961
40f4dbd5 6962 /* __builtin_inff is intended to be usable to define INFINITY on all
6963 targets. If an infinity is not available, INFINITY expands "to a
6964 positive constant of type float that overflows at translation
6965 time", footnote "In this case, using INFINITY will violate the
6966 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6967 Thus we pedwarn to ensure this constraint violation is
6968 diagnosed. */
92c43e3c 6969 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
389dd41b 6970 pedwarn (loc, 0, "target format does not support infinity");
92c43e3c 6971
aa870c1b 6972 real_inf (&real);
6973 return build_real (type, real);
92c43e3c 6974}
6975
c2f47e15 6976/* Fold a call to __builtin_nan or __builtin_nans with argument ARG. */
b0db7939 6977
6978static tree
c2f47e15 6979fold_builtin_nan (tree arg, tree type, int quiet)
b0db7939 6980{
6981 REAL_VALUE_TYPE real;
6982 const char *str;
6983
c2f47e15 6984 if (!validate_arg (arg, POINTER_TYPE))
6985 return NULL_TREE;
6986 str = c_getstr (arg);
b0db7939 6987 if (!str)
c2f47e15 6988 return NULL_TREE;
b0db7939 6989
6990 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
c2f47e15 6991 return NULL_TREE;
b0db7939 6992
6993 return build_real (type, real);
6994}
6995
277f8dd2 6996/* Return true if the floating point expression T has an integer value.
6997 We also allow +Inf, -Inf and NaN to be considered integer values. */
6998
6999static bool
7000integer_valued_real_p (tree t)
7001{
7002 switch (TREE_CODE (t))
7003 {
7004 case FLOAT_EXPR:
7005 return true;
7006
7007 case ABS_EXPR:
7008 case SAVE_EXPR:
277f8dd2 7009 return integer_valued_real_p (TREE_OPERAND (t, 0));
7010
7011 case COMPOUND_EXPR:
41076ef6 7012 case MODIFY_EXPR:
277f8dd2 7013 case BIND_EXPR:
75a70cf9 7014 return integer_valued_real_p (TREE_OPERAND (t, 1));
277f8dd2 7015
7016 case PLUS_EXPR:
7017 case MINUS_EXPR:
7018 case MULT_EXPR:
7019 case MIN_EXPR:
7020 case MAX_EXPR:
7021 return integer_valued_real_p (TREE_OPERAND (t, 0))
7022 && integer_valued_real_p (TREE_OPERAND (t, 1));
7023
7024 case COND_EXPR:
7025 return integer_valued_real_p (TREE_OPERAND (t, 1))
7026 && integer_valued_real_p (TREE_OPERAND (t, 2));
7027
7028 case REAL_CST:
0570334c 7029 return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t)));
277f8dd2 7030
7031 case NOP_EXPR:
7032 {
7033 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
7034 if (TREE_CODE (type) == INTEGER_TYPE)
7035 return true;
7036 if (TREE_CODE (type) == REAL_TYPE)
7037 return integer_valued_real_p (TREE_OPERAND (t, 0));
7038 break;
7039 }
7040
7041 case CALL_EXPR:
7042 switch (builtin_mathfn_code (t))
7043 {
4f35b1fc 7044 CASE_FLT_FN (BUILT_IN_CEIL):
7045 CASE_FLT_FN (BUILT_IN_FLOOR):
7046 CASE_FLT_FN (BUILT_IN_NEARBYINT):
7047 CASE_FLT_FN (BUILT_IN_RINT):
7048 CASE_FLT_FN (BUILT_IN_ROUND):
7049 CASE_FLT_FN (BUILT_IN_TRUNC):
277f8dd2 7050 return true;
7051
d4a43a03 7052 CASE_FLT_FN (BUILT_IN_FMIN):
7053 CASE_FLT_FN (BUILT_IN_FMAX):
c2f47e15 7054 return integer_valued_real_p (CALL_EXPR_ARG (t, 0))
7055 && integer_valued_real_p (CALL_EXPR_ARG (t, 1));
d4a43a03 7056
277f8dd2 7057 default:
7058 break;
7059 }
7060 break;
7061
7062 default:
7063 break;
7064 }
7065 return false;
7066}
7067
c2f47e15 7068/* FNDECL is assumed to be a builtin where truncation can be propagated
6528f4f4 7069 across (for instance floor((double)f) == (double)floorf (f).
c2f47e15 7070 Do the transformation for a call with argument ARG. */
277f8dd2 7071
6528f4f4 7072static tree
389dd41b 7073fold_trunc_transparent_mathfn (location_t loc, tree fndecl, tree arg)
6528f4f4 7074{
6528f4f4 7075 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
277f8dd2 7076
c2f47e15 7077 if (!validate_arg (arg, REAL_TYPE))
7078 return NULL_TREE;
6528f4f4 7079
277f8dd2 7080 /* Integer rounding functions are idempotent. */
7081 if (fcode == builtin_mathfn_code (arg))
7082 return arg;
7083
7084 /* If argument is already integer valued, and we don't need to worry
7085 about setting errno, there's no need to perform rounding. */
7086 if (! flag_errno_math && integer_valued_real_p (arg))
7087 return arg;
7088
7089 if (optimize)
6528f4f4 7090 {
277f8dd2 7091 tree arg0 = strip_float_extensions (arg);
2426241c 7092 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6528f4f4 7093 tree newtype = TREE_TYPE (arg0);
7094 tree decl;
7095
7096 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7097 && (decl = mathfn_built_in (newtype, fcode)))
389dd41b 7098 return fold_convert_loc (loc, ftype,
7099 build_call_expr_loc (loc, decl, 1,
7100 fold_convert_loc (loc,
7101 newtype,
7102 arg0)));
6528f4f4 7103 }
c2f47e15 7104 return NULL_TREE;
6528f4f4 7105}
7106
c2f47e15 7107/* FNDECL is assumed to be builtin which can narrow the FP type of
7108 the argument, for instance lround((double)f) -> lroundf (f).
7109 Do the transformation for a call with argument ARG. */
9ed65c7f 7110
7111static tree
389dd41b 7112fold_fixed_mathfn (location_t loc, tree fndecl, tree arg)
9ed65c7f 7113{
9ed65c7f 7114 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
9ed65c7f 7115
c2f47e15 7116 if (!validate_arg (arg, REAL_TYPE))
7117 return NULL_TREE;
9ed65c7f 7118
7119 /* If argument is already integer valued, and we don't need to worry
7120 about setting errno, there's no need to perform rounding. */
7121 if (! flag_errno_math && integer_valued_real_p (arg))
389dd41b 7122 return fold_build1_loc (loc, FIX_TRUNC_EXPR,
7123 TREE_TYPE (TREE_TYPE (fndecl)), arg);
9ed65c7f 7124
7125 if (optimize)
7126 {
7127 tree ftype = TREE_TYPE (arg);
7128 tree arg0 = strip_float_extensions (arg);
7129 tree newtype = TREE_TYPE (arg0);
7130 tree decl;
7131
7132 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7133 && (decl = mathfn_built_in (newtype, fcode)))
389dd41b 7134 return build_call_expr_loc (loc, decl, 1,
7135 fold_convert_loc (loc, newtype, arg0));
9ed65c7f 7136 }
73a0da56 7137
7138 /* Canonicalize llround (x) to lround (x) on LP64 targets where
7139 sizeof (long long) == sizeof (long). */
7140 if (TYPE_PRECISION (long_long_integer_type_node)
7141 == TYPE_PRECISION (long_integer_type_node))
7142 {
7143 tree newfn = NULL_TREE;
7144 switch (fcode)
7145 {
7146 CASE_FLT_FN (BUILT_IN_LLCEIL):
7147 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7148 break;
7149
7150 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7151 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7152 break;
7153
7154 CASE_FLT_FN (BUILT_IN_LLROUND):
7155 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7156 break;
7157
7158 CASE_FLT_FN (BUILT_IN_LLRINT):
7159 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7160 break;
7161
7162 default:
7163 break;
7164 }
7165
7166 if (newfn)
7167 {
389dd41b 7168 tree newcall = build_call_expr_loc (loc, newfn, 1, arg);
7169 return fold_convert_loc (loc,
7170 TREE_TYPE (TREE_TYPE (fndecl)), newcall);
73a0da56 7171 }
7172 }
7173
c2f47e15 7174 return NULL_TREE;
9ed65c7f 7175}
7176
c2f47e15 7177/* Fold call to builtin cabs, cabsf or cabsl with argument ARG. TYPE is the
7178 return type. Return NULL_TREE if no simplification can be made. */
c63f4ad3 7179
7180static tree
389dd41b 7181fold_builtin_cabs (location_t loc, tree arg, tree type, tree fndecl)
c63f4ad3 7182{
c2f47e15 7183 tree res;
c63f4ad3 7184
c63f4ad3 7185 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
7186 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7187 return NULL_TREE;
7188
b4725390 7189 /* Calculate the result when the argument is a constant. */
7190 if (TREE_CODE (arg) == COMPLEX_CST
7191 && (res = do_mpfr_arg2 (TREE_REALPART (arg), TREE_IMAGPART (arg),
7192 type, mpfr_hypot)))
7193 return res;
7194
1af0d139 7195 if (TREE_CODE (arg) == COMPLEX_EXPR)
7196 {
7197 tree real = TREE_OPERAND (arg, 0);
7198 tree imag = TREE_OPERAND (arg, 1);
7199
7200 /* If either part is zero, cabs is fabs of the other. */
7201 if (real_zerop (real))
389dd41b 7202 return fold_build1_loc (loc, ABS_EXPR, type, imag);
1af0d139 7203 if (real_zerop (imag))
389dd41b 7204 return fold_build1_loc (loc, ABS_EXPR, type, real);
1af0d139 7205
7206 /* cabs(x+xi) -> fabs(x)*sqrt(2). */
7207 if (flag_unsafe_math_optimizations
7208 && operand_equal_p (real, imag, OEP_PURE_SAME))
7209 {
2e7ca27b 7210 const REAL_VALUE_TYPE sqrt2_trunc
7910b2fb 7211 = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
1af0d139 7212 STRIP_NOPS (real);
389dd41b 7213 return fold_build2_loc (loc, MULT_EXPR, type,
7214 fold_build1_loc (loc, ABS_EXPR, type, real),
2e7ca27b 7215 build_real (type, sqrt2_trunc));
1af0d139 7216 }
7217 }
c63f4ad3 7218
749891b2 7219 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
7220 if (TREE_CODE (arg) == NEGATE_EXPR
7221 || TREE_CODE (arg) == CONJ_EXPR)
389dd41b 7222 return build_call_expr_loc (loc, fndecl, 1, TREE_OPERAND (arg, 0));
749891b2 7223
7d3f6cc7 7224 /* Don't do this when optimizing for size. */
7225 if (flag_unsafe_math_optimizations
0bfd8d5c 7226 && optimize && optimize_function_for_speed_p (cfun))
c63f4ad3 7227 {
0da0dbfa 7228 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
c63f4ad3 7229
7230 if (sqrtfn != NULL_TREE)
7231 {
c2f47e15 7232 tree rpart, ipart, result;
c63f4ad3 7233
4ee9c684 7234 arg = builtin_save_expr (arg);
29a6518e 7235
389dd41b 7236 rpart = fold_build1_loc (loc, REALPART_EXPR, type, arg);
7237 ipart = fold_build1_loc (loc, IMAGPART_EXPR, type, arg);
c63f4ad3 7238
4ee9c684 7239 rpart = builtin_save_expr (rpart);
7240 ipart = builtin_save_expr (ipart);
c63f4ad3 7241
389dd41b 7242 result = fold_build2_loc (loc, PLUS_EXPR, type,
7243 fold_build2_loc (loc, MULT_EXPR, type,
49d00087 7244 rpart, rpart),
389dd41b 7245 fold_build2_loc (loc, MULT_EXPR, type,
49d00087 7246 ipart, ipart));
c63f4ad3 7247
389dd41b 7248 return build_call_expr_loc (loc, sqrtfn, 1, result);
c63f4ad3 7249 }
7250 }
7251
7252 return NULL_TREE;
7253}
7254
c2f47e15 7255/* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG.
7256 Return NULL_TREE if no simplification can be made. */
e6e27594 7257
7258static tree
389dd41b 7259fold_builtin_sqrt (location_t loc, tree arg, tree type)
e6e27594 7260{
7261
7262 enum built_in_function fcode;
b4e8ab0c 7263 tree res;
c2f47e15 7264
7265 if (!validate_arg (arg, REAL_TYPE))
e6e27594 7266 return NULL_TREE;
7267
b4e8ab0c 7268 /* Calculate the result when the argument is a constant. */
7269 if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst0, NULL, true)))
7270 return res;
7271
e6e27594 7272 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7273 fcode = builtin_mathfn_code (arg);
7274 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7275 {
c2f47e15 7276 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
389dd41b 7277 arg = fold_build2_loc (loc, MULT_EXPR, type,
c2f47e15 7278 CALL_EXPR_ARG (arg, 0),
49d00087 7279 build_real (type, dconsthalf));
389dd41b 7280 return build_call_expr_loc (loc, expfn, 1, arg);
e6e27594 7281 }
7282
7283 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7284 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7285 {
7286 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7287
7288 if (powfn)
7289 {
c2f47e15 7290 tree arg0 = CALL_EXPR_ARG (arg, 0);
e6e27594 7291 tree tree_root;
7292 /* The inner root was either sqrt or cbrt. */
57510da6 7293 /* This was a conditional expression but it triggered a bug
18381619 7294 in Sun C 5.5. */
ce6cd837 7295 REAL_VALUE_TYPE dconstroot;
7296 if (BUILTIN_SQRT_P (fcode))
7297 dconstroot = dconsthalf;
7298 else
7299 dconstroot = dconst_third ();
e6e27594 7300
7301 /* Adjust for the outer root. */
7302 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7303 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7304 tree_root = build_real (type, dconstroot);
389dd41b 7305 return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
e6e27594 7306 }
7307 }
7308
bc33117f 7309 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
e6e27594 7310 if (flag_unsafe_math_optimizations
7311 && (fcode == BUILT_IN_POW
7312 || fcode == BUILT_IN_POWF
7313 || fcode == BUILT_IN_POWL))
7314 {
c2f47e15 7315 tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7316 tree arg0 = CALL_EXPR_ARG (arg, 0);
7317 tree arg1 = CALL_EXPR_ARG (arg, 1);
bc33117f 7318 tree narg1;
7319 if (!tree_expr_nonnegative_p (arg0))
7320 arg0 = build1 (ABS_EXPR, type, arg0);
389dd41b 7321 narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
49d00087 7322 build_real (type, dconsthalf));
389dd41b 7323 return build_call_expr_loc (loc, powfn, 2, arg0, narg1);
e6e27594 7324 }
7325
7326 return NULL_TREE;
7327}
7328
c2f47e15 7329/* Fold a builtin function call to cbrt, cbrtf, or cbrtl with argument ARG.
7330 Return NULL_TREE if no simplification can be made. */
7331
e6e27594 7332static tree
389dd41b 7333fold_builtin_cbrt (location_t loc, tree arg, tree type)
e6e27594 7334{
e6e27594 7335 const enum built_in_function fcode = builtin_mathfn_code (arg);
29f4cd78 7336 tree res;
e6e27594 7337
c2f47e15 7338 if (!validate_arg (arg, REAL_TYPE))
e6e27594 7339 return NULL_TREE;
7340
29f4cd78 7341 /* Calculate the result when the argument is a constant. */
7342 if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7343 return res;
e6e27594 7344
cdfeb715 7345 if (flag_unsafe_math_optimizations)
e6e27594 7346 {
cdfeb715 7347 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7348 if (BUILTIN_EXPONENT_P (fcode))
a0c938f0 7349 {
c2f47e15 7350 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
cdfeb715 7351 const REAL_VALUE_TYPE third_trunc =
7910b2fb 7352 real_value_truncate (TYPE_MODE (type), dconst_third ());
389dd41b 7353 arg = fold_build2_loc (loc, MULT_EXPR, type,
c2f47e15 7354 CALL_EXPR_ARG (arg, 0),
49d00087 7355 build_real (type, third_trunc));
389dd41b 7356 return build_call_expr_loc (loc, expfn, 1, arg);
cdfeb715 7357 }
e6e27594 7358
cdfeb715 7359 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7360 if (BUILTIN_SQRT_P (fcode))
a0c938f0 7361 {
cdfeb715 7362 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
e6e27594 7363
cdfeb715 7364 if (powfn)
7365 {
c2f47e15 7366 tree arg0 = CALL_EXPR_ARG (arg, 0);
cdfeb715 7367 tree tree_root;
7910b2fb 7368 REAL_VALUE_TYPE dconstroot = dconst_third ();
cdfeb715 7369
7370 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7371 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7372 tree_root = build_real (type, dconstroot);
389dd41b 7373 return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
cdfeb715 7374 }
e6e27594 7375 }
7376
cdfeb715 7377 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7378 if (BUILTIN_CBRT_P (fcode))
a0c938f0 7379 {
c2f47e15 7380 tree arg0 = CALL_EXPR_ARG (arg, 0);
cdfeb715 7381 if (tree_expr_nonnegative_p (arg0))
7382 {
7383 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7384
7385 if (powfn)
a0c938f0 7386 {
cdfeb715 7387 tree tree_root;
7388 REAL_VALUE_TYPE dconstroot;
a0c938f0 7389
3fa759a9 7390 real_arithmetic (&dconstroot, MULT_EXPR,
7910b2fb 7391 dconst_third_ptr (), dconst_third_ptr ());
cdfeb715 7392 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7393 tree_root = build_real (type, dconstroot);
389dd41b 7394 return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
cdfeb715 7395 }
7396 }
7397 }
a0c938f0 7398
cdfeb715 7399 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
c2f47e15 7400 if (fcode == BUILT_IN_POW
7401 || fcode == BUILT_IN_POWF
cdfeb715 7402 || fcode == BUILT_IN_POWL)
a0c938f0 7403 {
c2f47e15 7404 tree arg00 = CALL_EXPR_ARG (arg, 0);
7405 tree arg01 = CALL_EXPR_ARG (arg, 1);
cdfeb715 7406 if (tree_expr_nonnegative_p (arg00))
7407 {
c2f47e15 7408 tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
cdfeb715 7409 const REAL_VALUE_TYPE dconstroot
7910b2fb 7410 = real_value_truncate (TYPE_MODE (type), dconst_third ());
389dd41b 7411 tree narg01 = fold_build2_loc (loc, MULT_EXPR, type, arg01,
49d00087 7412 build_real (type, dconstroot));
389dd41b 7413 return build_call_expr_loc (loc, powfn, 2, arg00, narg01);
cdfeb715 7414 }
7415 }
e6e27594 7416 }
7417 return NULL_TREE;
7418}
7419
c2f47e15 7420/* Fold function call to builtin cos, cosf, or cosl with argument ARG.
7421 TYPE is the type of the return value. Return NULL_TREE if no
7422 simplification can be made. */
7423
e6e27594 7424static tree
389dd41b 7425fold_builtin_cos (location_t loc,
7426 tree arg, tree type, tree fndecl)
e6e27594 7427{
e6ab33d8 7428 tree res, narg;
e6e27594 7429
c2f47e15 7430 if (!validate_arg (arg, REAL_TYPE))
e6e27594 7431 return NULL_TREE;
7432
bffb7645 7433 /* Calculate the result when the argument is a constant. */
728bac60 7434 if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
bffb7645 7435 return res;
7436
e6e27594 7437 /* Optimize cos(-x) into cos (x). */
e6ab33d8 7438 if ((narg = fold_strip_sign_ops (arg)))
389dd41b 7439 return build_call_expr_loc (loc, fndecl, 1, narg);
e6e27594 7440
7441 return NULL_TREE;
7442}
7443
c2f47e15 7444/* Fold function call to builtin cosh, coshf, or coshl with argument ARG.
7445 Return NULL_TREE if no simplification can be made. */
7446
cacdc1af 7447static tree
389dd41b 7448fold_builtin_cosh (location_t loc, tree arg, tree type, tree fndecl)
cacdc1af 7449{
c2f47e15 7450 if (validate_arg (arg, REAL_TYPE))
cacdc1af 7451 {
cacdc1af 7452 tree res, narg;
7453
7454 /* Calculate the result when the argument is a constant. */
7455 if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0)))
7456 return res;
7457
7458 /* Optimize cosh(-x) into cosh (x). */
7459 if ((narg = fold_strip_sign_ops (arg)))
389dd41b 7460 return build_call_expr_loc (loc, fndecl, 1, narg);
cacdc1af 7461 }
7462
7463 return NULL_TREE;
7464}
7465
239d491a 7466/* Fold function call to builtin ccos (or ccosh if HYPER is TRUE) with
7467 argument ARG. TYPE is the type of the return value. Return
7468 NULL_TREE if no simplification can be made. */
7469
7470static tree
389dd41b 7471fold_builtin_ccos (location_t loc,
7472 tree arg, tree type ATTRIBUTE_UNUSED, tree fndecl,
239d491a 7473 bool hyper ATTRIBUTE_UNUSED)
7474{
7475 if (validate_arg (arg, COMPLEX_TYPE)
7476 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
7477 {
7478 tree tmp;
7479
7480#ifdef HAVE_mpc
7481 /* Calculate the result when the argument is a constant. */
7482 if ((tmp = do_mpc_arg1 (arg, type, (hyper ? mpc_cosh : mpc_cos))))
7483 return tmp;
7484#endif
7485
7486 /* Optimize fn(-x) into fn(x). */
7487 if ((tmp = fold_strip_sign_ops (arg)))
389dd41b 7488 return build_call_expr_loc (loc, fndecl, 1, tmp);
239d491a 7489 }
7490
7491 return NULL_TREE;
7492}
7493
c2f47e15 7494/* Fold function call to builtin tan, tanf, or tanl with argument ARG.
7495 Return NULL_TREE if no simplification can be made. */
7496
e6e27594 7497static tree
c2f47e15 7498fold_builtin_tan (tree arg, tree type)
e6e27594 7499{
7500 enum built_in_function fcode;
29f4cd78 7501 tree res;
e6e27594 7502
c2f47e15 7503 if (!validate_arg (arg, REAL_TYPE))
e6e27594 7504 return NULL_TREE;
7505
bffb7645 7506 /* Calculate the result when the argument is a constant. */
728bac60 7507 if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0)))
bffb7645 7508 return res;
7509
e6e27594 7510 /* Optimize tan(atan(x)) = x. */
7511 fcode = builtin_mathfn_code (arg);
7512 if (flag_unsafe_math_optimizations
7513 && (fcode == BUILT_IN_ATAN
7514 || fcode == BUILT_IN_ATANF
7515 || fcode == BUILT_IN_ATANL))
c2f47e15 7516 return CALL_EXPR_ARG (arg, 0);
e6e27594 7517
7518 return NULL_TREE;
7519}
7520
d735c391 7521/* Fold function call to builtin sincos, sincosf, or sincosl. Return
7522 NULL_TREE if no simplification can be made. */
7523
7524static tree
389dd41b 7525fold_builtin_sincos (location_t loc,
7526 tree arg0, tree arg1, tree arg2)
d735c391 7527{
c2f47e15 7528 tree type;
d735c391 7529 tree res, fn, call;
7530
c2f47e15 7531 if (!validate_arg (arg0, REAL_TYPE)
7532 || !validate_arg (arg1, POINTER_TYPE)
7533 || !validate_arg (arg2, POINTER_TYPE))
d735c391 7534 return NULL_TREE;
7535
d735c391 7536 type = TREE_TYPE (arg0);
d735c391 7537
7538 /* Calculate the result when the argument is a constant. */
7539 if ((res = do_mpfr_sincos (arg0, arg1, arg2)))
7540 return res;
7541
7542 /* Canonicalize sincos to cexpi. */
2a6b4c77 7543 if (!TARGET_C99_FUNCTIONS)
7544 return NULL_TREE;
d735c391 7545 fn = mathfn_built_in (type, BUILT_IN_CEXPI);
7546 if (!fn)
7547 return NULL_TREE;
7548
389dd41b 7549 call = build_call_expr_loc (loc, fn, 1, arg0);
d735c391 7550 call = builtin_save_expr (call);
7551
a75b1c71 7552 return build2 (COMPOUND_EXPR, void_type_node,
d735c391 7553 build2 (MODIFY_EXPR, void_type_node,
389dd41b 7554 build_fold_indirect_ref_loc (loc, arg1),
d735c391 7555 build1 (IMAGPART_EXPR, type, call)),
7556 build2 (MODIFY_EXPR, void_type_node,
389dd41b 7557 build_fold_indirect_ref_loc (loc, arg2),
d735c391 7558 build1 (REALPART_EXPR, type, call)));
7559}
7560
c5bb2c4b 7561/* Fold function call to builtin cexp, cexpf, or cexpl. Return
7562 NULL_TREE if no simplification can be made. */
7563
7564static tree
389dd41b 7565fold_builtin_cexp (location_t loc, tree arg0, tree type)
c5bb2c4b 7566{
c2f47e15 7567 tree rtype;
c5bb2c4b 7568 tree realp, imagp, ifn;
239d491a 7569#ifdef HAVE_mpc
7570 tree res;
7571#endif
c5bb2c4b 7572
239d491a 7573 if (!validate_arg (arg0, COMPLEX_TYPE)
7574 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
c5bb2c4b 7575 return NULL_TREE;
7576
239d491a 7577#ifdef HAVE_mpc
7578 /* Calculate the result when the argument is a constant. */
7579 if ((res = do_mpc_arg1 (arg0, type, mpc_exp)))
7580 return res;
7581#endif
7582
c5bb2c4b 7583 rtype = TREE_TYPE (TREE_TYPE (arg0));
7584
7585 /* In case we can figure out the real part of arg0 and it is constant zero
7586 fold to cexpi. */
2a6b4c77 7587 if (!TARGET_C99_FUNCTIONS)
7588 return NULL_TREE;
c5bb2c4b 7589 ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
7590 if (!ifn)
7591 return NULL_TREE;
7592
389dd41b 7593 if ((realp = fold_unary_loc (loc, REALPART_EXPR, rtype, arg0))
c5bb2c4b 7594 && real_zerop (realp))
7595 {
389dd41b 7596 tree narg = fold_build1_loc (loc, IMAGPART_EXPR, rtype, arg0);
7597 return build_call_expr_loc (loc, ifn, 1, narg);
c5bb2c4b 7598 }
7599
7600 /* In case we can easily decompose real and imaginary parts split cexp
7601 to exp (r) * cexpi (i). */
7602 if (flag_unsafe_math_optimizations
7603 && realp)
7604 {
7605 tree rfn, rcall, icall;
7606
7607 rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
7608 if (!rfn)
7609 return NULL_TREE;
7610
389dd41b 7611 imagp = fold_unary_loc (loc, IMAGPART_EXPR, rtype, arg0);
c5bb2c4b 7612 if (!imagp)
7613 return NULL_TREE;
7614
389dd41b 7615 icall = build_call_expr_loc (loc, ifn, 1, imagp);
c5bb2c4b 7616 icall = builtin_save_expr (icall);
389dd41b 7617 rcall = build_call_expr_loc (loc, rfn, 1, realp);
c5bb2c4b 7618 rcall = builtin_save_expr (rcall);
389dd41b 7619 return fold_build2_loc (loc, COMPLEX_EXPR, type,
7620 fold_build2_loc (loc, MULT_EXPR, rtype,
71bf42bb 7621 rcall,
389dd41b 7622 fold_build1_loc (loc, REALPART_EXPR,
7623 rtype, icall)),
7624 fold_build2_loc (loc, MULT_EXPR, rtype,
71bf42bb 7625 rcall,
389dd41b 7626 fold_build1_loc (loc, IMAGPART_EXPR,
7627 rtype, icall)));
c5bb2c4b 7628 }
7629
7630 return NULL_TREE;
7631}
7632
c2f47e15 7633/* Fold function call to builtin trunc, truncf or truncl with argument ARG.
7634 Return NULL_TREE if no simplification can be made. */
277f8dd2 7635
7636static tree
389dd41b 7637fold_builtin_trunc (location_t loc, tree fndecl, tree arg)
277f8dd2 7638{
c2f47e15 7639 if (!validate_arg (arg, REAL_TYPE))
7640 return NULL_TREE;
277f8dd2 7641
7642 /* Optimize trunc of constant value. */
f96bd2bf 7643 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
277f8dd2 7644 {
7645 REAL_VALUE_TYPE r, x;
2426241c 7646 tree type = TREE_TYPE (TREE_TYPE (fndecl));
277f8dd2 7647
7648 x = TREE_REAL_CST (arg);
7649 real_trunc (&r, TYPE_MODE (type), &x);
7650 return build_real (type, r);
7651 }
7652
389dd41b 7653 return fold_trunc_transparent_mathfn (loc, fndecl, arg);
277f8dd2 7654}
7655
c2f47e15 7656/* Fold function call to builtin floor, floorf or floorl with argument ARG.
7657 Return NULL_TREE if no simplification can be made. */
277f8dd2 7658
7659static tree
389dd41b 7660fold_builtin_floor (location_t loc, tree fndecl, tree arg)
277f8dd2 7661{
c2f47e15 7662 if (!validate_arg (arg, REAL_TYPE))
7663 return NULL_TREE;
277f8dd2 7664
7665 /* Optimize floor of constant value. */
f96bd2bf 7666 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
277f8dd2 7667 {
7668 REAL_VALUE_TYPE x;
7669
7670 x = TREE_REAL_CST (arg);
7671 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7672 {
2426241c 7673 tree type = TREE_TYPE (TREE_TYPE (fndecl));
277f8dd2 7674 REAL_VALUE_TYPE r;
7675
7676 real_floor (&r, TYPE_MODE (type), &x);
7677 return build_real (type, r);
7678 }
7679 }
7680
acc2b92e 7681 /* Fold floor (x) where x is nonnegative to trunc (x). */
7682 if (tree_expr_nonnegative_p (arg))
30fe8286 7683 {
7684 tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
7685 if (truncfn)
389dd41b 7686 return build_call_expr_loc (loc, truncfn, 1, arg);
30fe8286 7687 }
acc2b92e 7688
389dd41b 7689 return fold_trunc_transparent_mathfn (loc, fndecl, arg);
277f8dd2 7690}
7691
c2f47e15 7692/* Fold function call to builtin ceil, ceilf or ceill with argument ARG.
7693 Return NULL_TREE if no simplification can be made. */
277f8dd2 7694
7695static tree
389dd41b 7696fold_builtin_ceil (location_t loc, tree fndecl, tree arg)
277f8dd2 7697{
c2f47e15 7698 if (!validate_arg (arg, REAL_TYPE))
7699 return NULL_TREE;
277f8dd2 7700
7701 /* Optimize ceil of constant value. */
f96bd2bf 7702 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
277f8dd2 7703 {
7704 REAL_VALUE_TYPE x;
7705
7706 x = TREE_REAL_CST (arg);
7707 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7708 {
2426241c 7709 tree type = TREE_TYPE (TREE_TYPE (fndecl));
277f8dd2 7710 REAL_VALUE_TYPE r;
7711
7712 real_ceil (&r, TYPE_MODE (type), &x);
7713 return build_real (type, r);
7714 }
7715 }
7716
389dd41b 7717 return fold_trunc_transparent_mathfn (loc, fndecl, arg);
277f8dd2 7718}
7719
c2f47e15 7720/* Fold function call to builtin round, roundf or roundl with argument ARG.
7721 Return NULL_TREE if no simplification can be made. */
89ab3887 7722
7723static tree
389dd41b 7724fold_builtin_round (location_t loc, tree fndecl, tree arg)
89ab3887 7725{
c2f47e15 7726 if (!validate_arg (arg, REAL_TYPE))
7727 return NULL_TREE;
89ab3887 7728
34f17811 7729 /* Optimize round of constant value. */
f96bd2bf 7730 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
89ab3887 7731 {
7732 REAL_VALUE_TYPE x;
7733
7734 x = TREE_REAL_CST (arg);
7735 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7736 {
2426241c 7737 tree type = TREE_TYPE (TREE_TYPE (fndecl));
89ab3887 7738 REAL_VALUE_TYPE r;
7739
7740 real_round (&r, TYPE_MODE (type), &x);
7741 return build_real (type, r);
7742 }
7743 }
7744
389dd41b 7745 return fold_trunc_transparent_mathfn (loc, fndecl, arg);
89ab3887 7746}
7747
34f17811 7748/* Fold function call to builtin lround, lroundf or lroundl (or the
c2f47e15 7749 corresponding long long versions) and other rounding functions. ARG
7750 is the argument to the call. Return NULL_TREE if no simplification
7751 can be made. */
34f17811 7752
7753static tree
389dd41b 7754fold_builtin_int_roundingfn (location_t loc, tree fndecl, tree arg)
34f17811 7755{
c2f47e15 7756 if (!validate_arg (arg, REAL_TYPE))
7757 return NULL_TREE;
34f17811 7758
7759 /* Optimize lround of constant value. */
f96bd2bf 7760 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
34f17811 7761 {
7762 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7763
776a7bab 7764 if (real_isfinite (&x))
34f17811 7765 {
2426241c 7766 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
ca9b061d 7767 tree ftype = TREE_TYPE (arg);
7768 unsigned HOST_WIDE_INT lo2;
34f17811 7769 HOST_WIDE_INT hi, lo;
7770 REAL_VALUE_TYPE r;
7771
ad52b9b7 7772 switch (DECL_FUNCTION_CODE (fndecl))
7773 {
4f35b1fc 7774 CASE_FLT_FN (BUILT_IN_LFLOOR):
7775 CASE_FLT_FN (BUILT_IN_LLFLOOR):
ad52b9b7 7776 real_floor (&r, TYPE_MODE (ftype), &x);
7777 break;
7778
4f35b1fc 7779 CASE_FLT_FN (BUILT_IN_LCEIL):
7780 CASE_FLT_FN (BUILT_IN_LLCEIL):
ac148751 7781 real_ceil (&r, TYPE_MODE (ftype), &x);
7782 break;
7783
4f35b1fc 7784 CASE_FLT_FN (BUILT_IN_LROUND):
7785 CASE_FLT_FN (BUILT_IN_LLROUND):
ad52b9b7 7786 real_round (&r, TYPE_MODE (ftype), &x);
7787 break;
7788
7789 default:
7790 gcc_unreachable ();
7791 }
7792
34f17811 7793 REAL_VALUE_TO_INT (&lo, &hi, r);
ca9b061d 7794 if (!fit_double_type (lo, hi, &lo2, &hi, itype))
7795 return build_int_cst_wide (itype, lo2, hi);
34f17811 7796 }
7797 }
7798
acc2b92e 7799 switch (DECL_FUNCTION_CODE (fndecl))
7800 {
7801 CASE_FLT_FN (BUILT_IN_LFLOOR):
7802 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7803 /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x). */
7804 if (tree_expr_nonnegative_p (arg))
389dd41b 7805 return fold_build1_loc (loc, FIX_TRUNC_EXPR,
7806 TREE_TYPE (TREE_TYPE (fndecl)), arg);
acc2b92e 7807 break;
7808 default:;
7809 }
7810
389dd41b 7811 return fold_fixed_mathfn (loc, fndecl, arg);
34f17811 7812}
7813
70fb4c07 7814/* Fold function call to builtin ffs, clz, ctz, popcount and parity
c2f47e15 7815 and their long and long long variants (i.e. ffsl and ffsll). ARG is
7816 the argument to the call. Return NULL_TREE if no simplification can
7817 be made. */
70fb4c07 7818
7819static tree
c2f47e15 7820fold_builtin_bitop (tree fndecl, tree arg)
70fb4c07 7821{
c2f47e15 7822 if (!validate_arg (arg, INTEGER_TYPE))
70fb4c07 7823 return NULL_TREE;
7824
7825 /* Optimize for constant argument. */
f96bd2bf 7826 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
70fb4c07 7827 {
7828 HOST_WIDE_INT hi, width, result;
7829 unsigned HOST_WIDE_INT lo;
7c446c95 7830 tree type;
70fb4c07 7831
7832 type = TREE_TYPE (arg);
7833 width = TYPE_PRECISION (type);
7834 lo = TREE_INT_CST_LOW (arg);
7835
7836 /* Clear all the bits that are beyond the type's precision. */
7837 if (width > HOST_BITS_PER_WIDE_INT)
7838 {
7839 hi = TREE_INT_CST_HIGH (arg);
7840 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7841 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7842 }
7843 else
7844 {
7845 hi = 0;
7846 if (width < HOST_BITS_PER_WIDE_INT)
7847 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7848 }
7849
7850 switch (DECL_FUNCTION_CODE (fndecl))
7851 {
4f35b1fc 7852 CASE_INT_FN (BUILT_IN_FFS):
70fb4c07 7853 if (lo != 0)
7854 result = exact_log2 (lo & -lo) + 1;
7855 else if (hi != 0)
7856 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7857 else
7858 result = 0;
7859 break;
7860
4f35b1fc 7861 CASE_INT_FN (BUILT_IN_CLZ):
70fb4c07 7862 if (hi != 0)
7863 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7864 else if (lo != 0)
7865 result = width - floor_log2 (lo) - 1;
7866 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7867 result = width;
7868 break;
7869
4f35b1fc 7870 CASE_INT_FN (BUILT_IN_CTZ):
70fb4c07 7871 if (lo != 0)
7872 result = exact_log2 (lo & -lo);
7873 else if (hi != 0)
7874 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7875 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7876 result = width;
7877 break;
7878
4f35b1fc 7879 CASE_INT_FN (BUILT_IN_POPCOUNT):
70fb4c07 7880 result = 0;
7881 while (lo)
7882 result++, lo &= lo - 1;
7883 while (hi)
7884 result++, hi &= hi - 1;
7885 break;
7886
4f35b1fc 7887 CASE_INT_FN (BUILT_IN_PARITY):
70fb4c07 7888 result = 0;
7889 while (lo)
7890 result++, lo &= lo - 1;
7891 while (hi)
7892 result++, hi &= hi - 1;
7893 result &= 1;
7894 break;
7895
7896 default:
64db345d 7897 gcc_unreachable ();
70fb4c07 7898 }
7899
2426241c 7900 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
70fb4c07 7901 }
7902
7903 return NULL_TREE;
7904}
7905
42791117 7906/* Fold function call to builtin_bswap and the long and long long
7907 variants. Return NULL_TREE if no simplification can be made. */
7908static tree
c2f47e15 7909fold_builtin_bswap (tree fndecl, tree arg)
42791117 7910{
c2f47e15 7911 if (! validate_arg (arg, INTEGER_TYPE))
7912 return NULL_TREE;
42791117 7913
7914 /* Optimize constant value. */
f96bd2bf 7915 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
42791117 7916 {
7917 HOST_WIDE_INT hi, width, r_hi = 0;
7918 unsigned HOST_WIDE_INT lo, r_lo = 0;
7919 tree type;
7920
7921 type = TREE_TYPE (arg);
7922 width = TYPE_PRECISION (type);
7923 lo = TREE_INT_CST_LOW (arg);
7924 hi = TREE_INT_CST_HIGH (arg);
7925
7926 switch (DECL_FUNCTION_CODE (fndecl))
7927 {
7928 case BUILT_IN_BSWAP32:
7929 case BUILT_IN_BSWAP64:
7930 {
7931 int s;
7932
7933 for (s = 0; s < width; s += 8)
7934 {
7935 int d = width - s - 8;
7936 unsigned HOST_WIDE_INT byte;
7937
7938 if (s < HOST_BITS_PER_WIDE_INT)
7939 byte = (lo >> s) & 0xff;
7940 else
7941 byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
7942
7943 if (d < HOST_BITS_PER_WIDE_INT)
7944 r_lo |= byte << d;
7945 else
7946 r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
7947 }
7948 }
7949
7950 break;
7951
7952 default:
7953 gcc_unreachable ();
7954 }
7955
7956 if (width < HOST_BITS_PER_WIDE_INT)
7957 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo);
7958 else
7959 return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi);
7960 }
7961
7962 return NULL_TREE;
7963}
c2f47e15 7964
8918c507 7965/* A subroutine of fold_builtin to fold the various logarithmic
29f4cd78 7966 functions. Return NULL_TREE if no simplification can me made.
7967 FUNC is the corresponding MPFR logarithm function. */
8918c507 7968
7969static tree
389dd41b 7970fold_builtin_logarithm (location_t loc, tree fndecl, tree arg,
29f4cd78 7971 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8918c507 7972{
c2f47e15 7973 if (validate_arg (arg, REAL_TYPE))
8918c507 7974 {
8918c507 7975 tree type = TREE_TYPE (TREE_TYPE (fndecl));
29f4cd78 7976 tree res;
8918c507 7977 const enum built_in_function fcode = builtin_mathfn_code (arg);
0862b7e9 7978
29f4cd78 7979 /* Calculate the result when the argument is a constant. */
7980 if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
7981 return res;
7982
8918c507 7983 /* Special case, optimize logN(expN(x)) = x. */
7984 if (flag_unsafe_math_optimizations
29f4cd78 7985 && ((func == mpfr_log
8918c507 7986 && (fcode == BUILT_IN_EXP
7987 || fcode == BUILT_IN_EXPF
7988 || fcode == BUILT_IN_EXPL))
29f4cd78 7989 || (func == mpfr_log2
8918c507 7990 && (fcode == BUILT_IN_EXP2
7991 || fcode == BUILT_IN_EXP2F
7992 || fcode == BUILT_IN_EXP2L))
29f4cd78 7993 || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
389dd41b 7994 return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0));
8918c507 7995
ca273d4a 7996 /* Optimize logN(func()) for various exponential functions. We
a0c938f0 7997 want to determine the value "x" and the power "exponent" in
7998 order to transform logN(x**exponent) into exponent*logN(x). */
8918c507 7999 if (flag_unsafe_math_optimizations)
a0c938f0 8000 {
8918c507 8001 tree exponent = 0, x = 0;
0862b7e9 8002
8918c507 8003 switch (fcode)
8004 {
4f35b1fc 8005 CASE_FLT_FN (BUILT_IN_EXP):
8918c507 8006 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7910b2fb 8007 x = build_real (type, real_value_truncate (TYPE_MODE (type),
8008 dconst_e ()));
c2f47e15 8009 exponent = CALL_EXPR_ARG (arg, 0);
8918c507 8010 break;
4f35b1fc 8011 CASE_FLT_FN (BUILT_IN_EXP2):
8918c507 8012 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
8013 x = build_real (type, dconst2);
c2f47e15 8014 exponent = CALL_EXPR_ARG (arg, 0);
8918c507 8015 break;
4f35b1fc 8016 CASE_FLT_FN (BUILT_IN_EXP10):
8017 CASE_FLT_FN (BUILT_IN_POW10):
8918c507 8018 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
3fa759a9 8019 {
8020 REAL_VALUE_TYPE dconst10;
8021 real_from_integer (&dconst10, VOIDmode, 10, 0, 0);
8022 x = build_real (type, dconst10);
8023 }
c2f47e15 8024 exponent = CALL_EXPR_ARG (arg, 0);
8918c507 8025 break;
4f35b1fc 8026 CASE_FLT_FN (BUILT_IN_SQRT):
8918c507 8027 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
c2f47e15 8028 x = CALL_EXPR_ARG (arg, 0);
8918c507 8029 exponent = build_real (type, dconsthalf);
8030 break;
4f35b1fc 8031 CASE_FLT_FN (BUILT_IN_CBRT):
8918c507 8032 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
c2f47e15 8033 x = CALL_EXPR_ARG (arg, 0);
8918c507 8034 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7910b2fb 8035 dconst_third ()));
8918c507 8036 break;
4f35b1fc 8037 CASE_FLT_FN (BUILT_IN_POW):
8918c507 8038 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
c2f47e15 8039 x = CALL_EXPR_ARG (arg, 0);
8040 exponent = CALL_EXPR_ARG (arg, 1);
8918c507 8041 break;
8042 default:
8043 break;
8044 }
8045
8046 /* Now perform the optimization. */
8047 if (x && exponent)
8048 {
389dd41b 8049 tree logfn = build_call_expr_loc (loc, fndecl, 1, x);
8050 return fold_build2_loc (loc, MULT_EXPR, type, exponent, logfn);
8918c507 8051 }
8052 }
8053 }
8054
c2f47e15 8055 return NULL_TREE;
8918c507 8056}
0862b7e9 8057
f0c477f2 8058/* Fold a builtin function call to hypot, hypotf, or hypotl. Return
8059 NULL_TREE if no simplification can be made. */
8060
8061static tree
389dd41b 8062fold_builtin_hypot (location_t loc, tree fndecl,
8063 tree arg0, tree arg1, tree type)
f0c477f2 8064{
e6ab33d8 8065 tree res, narg0, narg1;
f0c477f2 8066
c2f47e15 8067 if (!validate_arg (arg0, REAL_TYPE)
8068 || !validate_arg (arg1, REAL_TYPE))
f0c477f2 8069 return NULL_TREE;
8070
8071 /* Calculate the result when the argument is a constant. */
8072 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
8073 return res;
8074
6c95f21c 8075 /* If either argument to hypot has a negate or abs, strip that off.
8076 E.g. hypot(-x,fabs(y)) -> hypot(x,y). */
e6ab33d8 8077 narg0 = fold_strip_sign_ops (arg0);
8078 narg1 = fold_strip_sign_ops (arg1);
8079 if (narg0 || narg1)
8080 {
389dd41b 8081 return build_call_expr_loc (loc, fndecl, 2, narg0 ? narg0 : arg0,
c2f47e15 8082 narg1 ? narg1 : arg1);
6c95f21c 8083 }
8084
f0c477f2 8085 /* If either argument is zero, hypot is fabs of the other. */
8086 if (real_zerop (arg0))
389dd41b 8087 return fold_build1_loc (loc, ABS_EXPR, type, arg1);
f0c477f2 8088 else if (real_zerop (arg1))
389dd41b 8089 return fold_build1_loc (loc, ABS_EXPR, type, arg0);
f0c477f2 8090
6c95f21c 8091 /* hypot(x,x) -> fabs(x)*sqrt(2). */
8092 if (flag_unsafe_math_optimizations
8093 && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
f0c477f2 8094 {
2e7ca27b 8095 const REAL_VALUE_TYPE sqrt2_trunc
7910b2fb 8096 = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
389dd41b 8097 return fold_build2_loc (loc, MULT_EXPR, type,
8098 fold_build1_loc (loc, ABS_EXPR, type, arg0),
2e7ca27b 8099 build_real (type, sqrt2_trunc));
f0c477f2 8100 }
8101
f0c477f2 8102 return NULL_TREE;
8103}
8104
8105
e6e27594 8106/* Fold a builtin function call to pow, powf, or powl. Return
8107 NULL_TREE if no simplification can be made. */
8108static tree
389dd41b 8109fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
e6e27594 8110{
f0c477f2 8111 tree res;
e6e27594 8112
c2f47e15 8113 if (!validate_arg (arg0, REAL_TYPE)
8114 || !validate_arg (arg1, REAL_TYPE))
e6e27594 8115 return NULL_TREE;
8116
f0c477f2 8117 /* Calculate the result when the argument is a constant. */
8118 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
8119 return res;
8120
e6e27594 8121 /* Optimize pow(1.0,y) = 1.0. */
8122 if (real_onep (arg0))
389dd41b 8123 return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
e6e27594 8124
8125 if (TREE_CODE (arg1) == REAL_CST
f96bd2bf 8126 && !TREE_OVERFLOW (arg1))
e6e27594 8127 {
198d9bbe 8128 REAL_VALUE_TYPE cint;
e6e27594 8129 REAL_VALUE_TYPE c;
198d9bbe 8130 HOST_WIDE_INT n;
8131
e6e27594 8132 c = TREE_REAL_CST (arg1);
8133
8134 /* Optimize pow(x,0.0) = 1.0. */
8135 if (REAL_VALUES_EQUAL (c, dconst0))
389dd41b 8136 return omit_one_operand_loc (loc, type, build_real (type, dconst1),
e6e27594 8137 arg0);
8138
8139 /* Optimize pow(x,1.0) = x. */
8140 if (REAL_VALUES_EQUAL (c, dconst1))
8141 return arg0;
8142
8143 /* Optimize pow(x,-1.0) = 1.0/x. */
8144 if (REAL_VALUES_EQUAL (c, dconstm1))
389dd41b 8145 return fold_build2_loc (loc, RDIV_EXPR, type,
49d00087 8146 build_real (type, dconst1), arg0);
e6e27594 8147
8148 /* Optimize pow(x,0.5) = sqrt(x). */
8149 if (flag_unsafe_math_optimizations
8150 && REAL_VALUES_EQUAL (c, dconsthalf))
8151 {
8152 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8153
8154 if (sqrtfn != NULL_TREE)
389dd41b 8155 return build_call_expr_loc (loc, sqrtfn, 1, arg0);
e6e27594 8156 }
8157
feb5b3eb 8158 /* Optimize pow(x,1.0/3.0) = cbrt(x). */
8159 if (flag_unsafe_math_optimizations)
8160 {
8161 const REAL_VALUE_TYPE dconstroot
7910b2fb 8162 = real_value_truncate (TYPE_MODE (type), dconst_third ());
feb5b3eb 8163
8164 if (REAL_VALUES_EQUAL (c, dconstroot))
8165 {
8166 tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
8167 if (cbrtfn != NULL_TREE)
389dd41b 8168 return build_call_expr_loc (loc, cbrtfn, 1, arg0);
feb5b3eb 8169 }
8170 }
8171
198d9bbe 8172 /* Check for an integer exponent. */
8173 n = real_to_integer (&c);
8174 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
8175 if (real_identical (&c, &cint))
e6e27594 8176 {
a2b30b48 8177 /* Attempt to evaluate pow at compile-time, unless this should
8178 raise an exception. */
198d9bbe 8179 if (TREE_CODE (arg0) == REAL_CST
a2b30b48 8180 && !TREE_OVERFLOW (arg0)
8181 && (n > 0
8182 || (!flag_trapping_math && !flag_errno_math)
8183 || !REAL_VALUES_EQUAL (TREE_REAL_CST (arg0), dconst0)))
e6e27594 8184 {
8185 REAL_VALUE_TYPE x;
8186 bool inexact;
8187
8188 x = TREE_REAL_CST (arg0);
8189 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8190 if (flag_unsafe_math_optimizations || !inexact)
8191 return build_real (type, x);
8192 }
198d9bbe 8193
8194 /* Strip sign ops from even integer powers. */
8195 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
8196 {
8197 tree narg0 = fold_strip_sign_ops (arg0);
8198 if (narg0)
389dd41b 8199 return build_call_expr_loc (loc, fndecl, 2, narg0, arg1);
198d9bbe 8200 }
e6e27594 8201 }
8202 }
8203
cdfeb715 8204 if (flag_unsafe_math_optimizations)
e6e27594 8205 {
cdfeb715 8206 const enum built_in_function fcode = builtin_mathfn_code (arg0);
e6e27594 8207
cdfeb715 8208 /* Optimize pow(expN(x),y) = expN(x*y). */
8209 if (BUILTIN_EXPONENT_P (fcode))
a0c938f0 8210 {
c2f47e15 8211 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0);
8212 tree arg = CALL_EXPR_ARG (arg0, 0);
389dd41b 8213 arg = fold_build2_loc (loc, MULT_EXPR, type, arg, arg1);
8214 return build_call_expr_loc (loc, expfn, 1, arg);
cdfeb715 8215 }
e6e27594 8216
cdfeb715 8217 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
8218 if (BUILTIN_SQRT_P (fcode))
a0c938f0 8219 {
c2f47e15 8220 tree narg0 = CALL_EXPR_ARG (arg0, 0);
389dd41b 8221 tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
49d00087 8222 build_real (type, dconsthalf));
389dd41b 8223 return build_call_expr_loc (loc, fndecl, 2, narg0, narg1);
cdfeb715 8224 }
8225
8226 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
8227 if (BUILTIN_CBRT_P (fcode))
a0c938f0 8228 {
c2f47e15 8229 tree arg = CALL_EXPR_ARG (arg0, 0);
cdfeb715 8230 if (tree_expr_nonnegative_p (arg))
8231 {
8232 const REAL_VALUE_TYPE dconstroot
7910b2fb 8233 = real_value_truncate (TYPE_MODE (type), dconst_third ());
389dd41b 8234 tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
49d00087 8235 build_real (type, dconstroot));
389dd41b 8236 return build_call_expr_loc (loc, fndecl, 2, arg, narg1);
cdfeb715 8237 }
8238 }
a0c938f0 8239
49e436b5 8240 /* Optimize pow(pow(x,y),z) = pow(x,y*z) iff x is nonnegative. */
c2f47e15 8241 if (fcode == BUILT_IN_POW
8242 || fcode == BUILT_IN_POWF
8243 || fcode == BUILT_IN_POWL)
a0c938f0 8244 {
c2f47e15 8245 tree arg00 = CALL_EXPR_ARG (arg0, 0);
49e436b5 8246 if (tree_expr_nonnegative_p (arg00))
8247 {
8248 tree arg01 = CALL_EXPR_ARG (arg0, 1);
8249 tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg01, arg1);
8250 return build_call_expr_loc (loc, fndecl, 2, arg00, narg1);
8251 }
cdfeb715 8252 }
e6e27594 8253 }
cdfeb715 8254
e6e27594 8255 return NULL_TREE;
8256}
8257
c2f47e15 8258/* Fold a builtin function call to powi, powif, or powil with argument ARG.
8259 Return NULL_TREE if no simplification can be made. */
b4d0c20c 8260static tree
389dd41b 8261fold_builtin_powi (location_t loc, tree fndecl ATTRIBUTE_UNUSED,
c2f47e15 8262 tree arg0, tree arg1, tree type)
b4d0c20c 8263{
c2f47e15 8264 if (!validate_arg (arg0, REAL_TYPE)
8265 || !validate_arg (arg1, INTEGER_TYPE))
b4d0c20c 8266 return NULL_TREE;
8267
8268 /* Optimize pow(1.0,y) = 1.0. */
8269 if (real_onep (arg0))
389dd41b 8270 return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
b4d0c20c 8271
8272 if (host_integerp (arg1, 0))
8273 {
8274 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
8275
8276 /* Evaluate powi at compile-time. */
8277 if (TREE_CODE (arg0) == REAL_CST
f96bd2bf 8278 && !TREE_OVERFLOW (arg0))
b4d0c20c 8279 {
8280 REAL_VALUE_TYPE x;
8281 x = TREE_REAL_CST (arg0);
8282 real_powi (&x, TYPE_MODE (type), &x, c);
8283 return build_real (type, x);
8284 }
8285
8286 /* Optimize pow(x,0) = 1.0. */
8287 if (c == 0)
389dd41b 8288 return omit_one_operand_loc (loc, type, build_real (type, dconst1),
b4d0c20c 8289 arg0);
8290
8291 /* Optimize pow(x,1) = x. */
8292 if (c == 1)
8293 return arg0;
8294
8295 /* Optimize pow(x,-1) = 1.0/x. */
8296 if (c == -1)
389dd41b 8297 return fold_build2_loc (loc, RDIV_EXPR, type,
49d00087 8298 build_real (type, dconst1), arg0);
b4d0c20c 8299 }
8300
8301 return NULL_TREE;
8302}
8303
8918c507 8304/* A subroutine of fold_builtin to fold the various exponent
c2f47e15 8305 functions. Return NULL_TREE if no simplification can be made.
debf9994 8306 FUNC is the corresponding MPFR exponent function. */
8918c507 8307
8308static tree
389dd41b 8309fold_builtin_exponent (location_t loc, tree fndecl, tree arg,
debf9994 8310 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8918c507 8311{
c2f47e15 8312 if (validate_arg (arg, REAL_TYPE))
8918c507 8313 {
8918c507 8314 tree type = TREE_TYPE (TREE_TYPE (fndecl));
29f4cd78 8315 tree res;
debf9994 8316
8317 /* Calculate the result when the argument is a constant. */
728bac60 8318 if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
debf9994 8319 return res;
8918c507 8320
8321 /* Optimize expN(logN(x)) = x. */
8322 if (flag_unsafe_math_optimizations)
a0c938f0 8323 {
8918c507 8324 const enum built_in_function fcode = builtin_mathfn_code (arg);
8325
debf9994 8326 if ((func == mpfr_exp
8918c507 8327 && (fcode == BUILT_IN_LOG
8328 || fcode == BUILT_IN_LOGF
8329 || fcode == BUILT_IN_LOGL))
debf9994 8330 || (func == mpfr_exp2
8918c507 8331 && (fcode == BUILT_IN_LOG2
8332 || fcode == BUILT_IN_LOG2F
8333 || fcode == BUILT_IN_LOG2L))
debf9994 8334 || (func == mpfr_exp10
8918c507 8335 && (fcode == BUILT_IN_LOG10
8336 || fcode == BUILT_IN_LOG10F
8337 || fcode == BUILT_IN_LOG10L)))
389dd41b 8338 return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0));
8918c507 8339 }
8340 }
8341
c2f47e15 8342 return NULL_TREE;
8918c507 8343}
8344
e973ffcc 8345/* Return true if VAR is a VAR_DECL or a component thereof. */
8346
8347static bool
8348var_decl_component_p (tree var)
8349{
8350 tree inner = var;
8351 while (handled_component_p (inner))
8352 inner = TREE_OPERAND (inner, 0);
8353 return SSA_VAR_P (inner);
8354}
8355
4f46f2b9 8356/* Fold function call to builtin memset. Return
9c8a1629 8357 NULL_TREE if no simplification can be made. */
8358
8359static tree
389dd41b 8360fold_builtin_memset (location_t loc, tree dest, tree c, tree len,
8361 tree type, bool ignore)
9c8a1629 8362{
45bb3afb 8363 tree var, ret, etype;
4f46f2b9 8364 unsigned HOST_WIDE_INT length, cval;
9c8a1629 8365
c2f47e15 8366 if (! validate_arg (dest, POINTER_TYPE)
8367 || ! validate_arg (c, INTEGER_TYPE)
8368 || ! validate_arg (len, INTEGER_TYPE))
8369 return NULL_TREE;
9c8a1629 8370
4f46f2b9 8371 if (! host_integerp (len, 1))
c2f47e15 8372 return NULL_TREE;
4f46f2b9 8373
9c8a1629 8374 /* If the LEN parameter is zero, return DEST. */
8375 if (integer_zerop (len))
389dd41b 8376 return omit_one_operand_loc (loc, type, dest, c);
9c8a1629 8377
4f46f2b9 8378 if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
c2f47e15 8379 return NULL_TREE;
9c8a1629 8380
4f46f2b9 8381 var = dest;
8382 STRIP_NOPS (var);
8383 if (TREE_CODE (var) != ADDR_EXPR)
c2f47e15 8384 return NULL_TREE;
4f46f2b9 8385
8386 var = TREE_OPERAND (var, 0);
8387 if (TREE_THIS_VOLATILE (var))
c2f47e15 8388 return NULL_TREE;
4f46f2b9 8389
45bb3afb 8390 etype = TREE_TYPE (var);
8391 if (TREE_CODE (etype) == ARRAY_TYPE)
8392 etype = TREE_TYPE (etype);
8393
8394 if (!INTEGRAL_TYPE_P (etype)
8395 && !POINTER_TYPE_P (etype))
c2f47e15 8396 return NULL_TREE;
4f46f2b9 8397
e973ffcc 8398 if (! var_decl_component_p (var))
c2f47e15 8399 return NULL_TREE;
e973ffcc 8400
4f46f2b9 8401 length = tree_low_cst (len, 1);
45bb3afb 8402 if (GET_MODE_SIZE (TYPE_MODE (etype)) != length
4f46f2b9 8403 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8404 < (int) length)
c2f47e15 8405 return NULL_TREE;
4f46f2b9 8406
8407 if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
c2f47e15 8408 return NULL_TREE;
4f46f2b9 8409
8410 if (integer_zerop (c))
8411 cval = 0;
8412 else
8413 {
8414 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
c2f47e15 8415 return NULL_TREE;
4f46f2b9 8416
8417 cval = tree_low_cst (c, 1);
8418 cval &= 0xff;
8419 cval |= cval << 8;
8420 cval |= cval << 16;
8421 cval |= (cval << 31) << 1;
8422 }
8423
45bb3afb 8424 ret = build_int_cst_type (etype, cval);
389dd41b 8425 var = build_fold_indirect_ref_loc (loc,
8426 fold_convert_loc (loc,
8427 build_pointer_type (etype),
8428 dest));
45bb3afb 8429 ret = build2 (MODIFY_EXPR, etype, var, ret);
4f46f2b9 8430 if (ignore)
8431 return ret;
8432
389dd41b 8433 return omit_one_operand_loc (loc, type, dest, ret);
9c8a1629 8434}
8435
4f46f2b9 8436/* Fold function call to builtin memset. Return
9c8a1629 8437 NULL_TREE if no simplification can be made. */
8438
8439static tree
389dd41b 8440fold_builtin_bzero (location_t loc, tree dest, tree size, bool ignore)
9c8a1629 8441{
c2f47e15 8442 if (! validate_arg (dest, POINTER_TYPE)
8443 || ! validate_arg (size, INTEGER_TYPE))
8444 return NULL_TREE;
9c8a1629 8445
4f46f2b9 8446 if (!ignore)
c2f47e15 8447 return NULL_TREE;
a0c938f0 8448
4f46f2b9 8449 /* New argument list transforming bzero(ptr x, int y) to
8450 memset(ptr x, int 0, size_t y). This is done this way
8451 so that if it isn't expanded inline, we fallback to
8452 calling bzero instead of memset. */
8453
389dd41b 8454 return fold_builtin_memset (loc, dest, integer_zero_node,
8455 fold_convert_loc (loc, sizetype, size),
c2f47e15 8456 void_type_node, ignore);
9c8a1629 8457}
8458
4f46f2b9 8459/* Fold function call to builtin mem{{,p}cpy,move}. Return
8460 NULL_TREE if no simplification can be made.
8461 If ENDP is 0, return DEST (like memcpy).
8462 If ENDP is 1, return DEST+LEN (like mempcpy).
8463 If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8464 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8465 (memmove). */
9c8a1629 8466
8467static tree
389dd41b 8468fold_builtin_memory_op (location_t loc, tree dest, tree src,
8469 tree len, tree type, bool ignore, int endp)
9c8a1629 8470{
c2f47e15 8471 tree destvar, srcvar, expr;
9c8a1629 8472
c2f47e15 8473 if (! validate_arg (dest, POINTER_TYPE)
8474 || ! validate_arg (src, POINTER_TYPE)
8475 || ! validate_arg (len, INTEGER_TYPE))
8476 return NULL_TREE;
9c8a1629 8477
8478 /* If the LEN parameter is zero, return DEST. */
8479 if (integer_zerop (len))
389dd41b 8480 return omit_one_operand_loc (loc, type, dest, src);
9c8a1629 8481
4f46f2b9 8482 /* If SRC and DEST are the same (and not volatile), return
8483 DEST{,+LEN,+LEN-1}. */
9c8a1629 8484 if (operand_equal_p (src, dest, 0))
4f46f2b9 8485 expr = len;
8486 else
8487 {
5a84fdd6 8488 tree srctype, desttype;
5383fb56 8489 int src_align, dest_align;
8490
3b1757a2 8491 if (endp == 3)
8492 {
5383fb56 8493 src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
8494 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
5a84fdd6 8495
3b1757a2 8496 /* Both DEST and SRC must be pointer types.
8497 ??? This is what old code did. Is the testing for pointer types
8498 really mandatory?
8499
8500 If either SRC is readonly or length is 1, we can use memcpy. */
3f95c690 8501 if (!dest_align || !src_align)
8502 return NULL_TREE;
8503 if (readonly_data_expr (src)
8504 || (host_integerp (len, 1)
8505 && (MIN (src_align, dest_align) / BITS_PER_UNIT
8506 >= tree_low_cst (len, 1))))
3b1757a2 8507 {
8508 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8509 if (!fn)
c2f47e15 8510 return NULL_TREE;
389dd41b 8511 return build_call_expr_loc (loc, fn, 3, dest, src, len);
3b1757a2 8512 }
3f95c690 8513
8514 /* If *src and *dest can't overlap, optimize into memcpy as well. */
f85fb819 8515 srcvar = build_fold_indirect_ref_loc (loc, src);
8516 destvar = build_fold_indirect_ref_loc (loc, dest);
8517 if (srcvar
8518 && !TREE_THIS_VOLATILE (srcvar)
8519 && destvar
8520 && !TREE_THIS_VOLATILE (destvar))
3f95c690 8521 {
f85fb819 8522 tree src_base, dest_base, fn;
8523 HOST_WIDE_INT src_offset = 0, dest_offset = 0;
8524 HOST_WIDE_INT size = -1;
8525 HOST_WIDE_INT maxsize = -1;
8526
8527 src_base = srcvar;
8528 if (handled_component_p (src_base))
8529 src_base = get_ref_base_and_extent (src_base, &src_offset,
8530 &size, &maxsize);
8531 dest_base = destvar;
8532 if (handled_component_p (dest_base))
8533 dest_base = get_ref_base_and_extent (dest_base, &dest_offset,
8534 &size, &maxsize);
8535 if (host_integerp (len, 1))
8536 {
8537 maxsize = tree_low_cst (len, 1);
8538 if (maxsize
8539 > INTTYPE_MAXIMUM (HOST_WIDE_INT) / BITS_PER_UNIT)
8540 maxsize = -1;
8541 else
8542 maxsize *= BITS_PER_UNIT;
8543 }
8544 else
8545 maxsize = -1;
8546 if (SSA_VAR_P (src_base)
8547 && SSA_VAR_P (dest_base))
8548 {
8549 if (operand_equal_p (src_base, dest_base, 0)
8550 && ranges_overlap_p (src_offset, maxsize,
8551 dest_offset, maxsize))
8552 return NULL_TREE;
8553 }
8554 else if (TREE_CODE (src_base) == INDIRECT_REF
8555 && TREE_CODE (dest_base) == INDIRECT_REF)
8556 {
8557 if (! operand_equal_p (TREE_OPERAND (src_base, 0),
8558 TREE_OPERAND (dest_base, 0), 0)
8559 || ranges_overlap_p (src_offset, maxsize,
8560 dest_offset, maxsize))
8561 return NULL_TREE;
8562 }
8563 else
8564 return NULL_TREE;
8565
8566 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3f95c690 8567 if (!fn)
8568 return NULL_TREE;
389dd41b 8569 return build_call_expr_loc (loc, fn, 3, dest, src, len);
3f95c690 8570 }
c2f47e15 8571 return NULL_TREE;
3b1757a2 8572 }
4f46f2b9 8573
5a84fdd6 8574 if (!host_integerp (len, 0))
c2f47e15 8575 return NULL_TREE;
5a84fdd6 8576 /* FIXME:
8577 This logic lose for arguments like (type *)malloc (sizeof (type)),
8578 since we strip the casts of up to VOID return value from malloc.
8579 Perhaps we ought to inherit type from non-VOID argument here? */
8580 STRIP_NOPS (src);
8581 STRIP_NOPS (dest);
45bb3afb 8582 /* As we fold (void *)(p + CST) to (void *)p + CST undo this here. */
8583 if (TREE_CODE (src) == POINTER_PLUS_EXPR)
8584 {
8585 tree tem = TREE_OPERAND (src, 0);
8586 STRIP_NOPS (tem);
8587 if (tem != TREE_OPERAND (src, 0))
8588 src = build1 (NOP_EXPR, TREE_TYPE (tem), src);
8589 }
8590 if (TREE_CODE (dest) == POINTER_PLUS_EXPR)
8591 {
8592 tree tem = TREE_OPERAND (dest, 0);
8593 STRIP_NOPS (tem);
8594 if (tem != TREE_OPERAND (dest, 0))
8595 dest = build1 (NOP_EXPR, TREE_TYPE (tem), dest);
8596 }
5a84fdd6 8597 srctype = TREE_TYPE (TREE_TYPE (src));
45bb3afb 8598 if (srctype
97d4c6a6 8599 && TREE_CODE (srctype) == ARRAY_TYPE
8600 && !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
45bb3afb 8601 {
8602 srctype = TREE_TYPE (srctype);
8603 STRIP_NOPS (src);
8604 src = build1 (NOP_EXPR, build_pointer_type (srctype), src);
8605 }
5a84fdd6 8606 desttype = TREE_TYPE (TREE_TYPE (dest));
45bb3afb 8607 if (desttype
97d4c6a6 8608 && TREE_CODE (desttype) == ARRAY_TYPE
8609 && !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
45bb3afb 8610 {
8611 desttype = TREE_TYPE (desttype);
8612 STRIP_NOPS (dest);
8613 dest = build1 (NOP_EXPR, build_pointer_type (desttype), dest);
8614 }
5a84fdd6 8615 if (!srctype || !desttype
8616 || !TYPE_SIZE_UNIT (srctype)
8617 || !TYPE_SIZE_UNIT (desttype)
8618 || TREE_CODE (TYPE_SIZE_UNIT (srctype)) != INTEGER_CST
6f52ebeb 8619 || TREE_CODE (TYPE_SIZE_UNIT (desttype)) != INTEGER_CST
8620 || TYPE_VOLATILE (srctype)
8621 || TYPE_VOLATILE (desttype))
c2f47e15 8622 return NULL_TREE;
4f46f2b9 8623
5383fb56 8624 src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
8625 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
8626 if (dest_align < (int) TYPE_ALIGN (desttype)
8627 || src_align < (int) TYPE_ALIGN (srctype))
c2f47e15 8628 return NULL_TREE;
e973ffcc 8629
5a84fdd6 8630 if (!ignore)
8631 dest = builtin_save_expr (dest);
4f46f2b9 8632
5383fb56 8633 srcvar = NULL_TREE;
8634 if (tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
8635 {
389dd41b 8636 srcvar = build_fold_indirect_ref_loc (loc, src);
5383fb56 8637 if (TREE_THIS_VOLATILE (srcvar))
6f52ebeb 8638 return NULL_TREE;
92ddcd97 8639 else if (!tree_int_cst_equal (tree_expr_size (srcvar), len))
5383fb56 8640 srcvar = NULL_TREE;
8641 /* With memcpy, it is possible to bypass aliasing rules, so without
8642 this check i.e. execute/20060930-2.c would be misoptimized,
8643 because it use conflicting alias set to hold argument for the
8644 memcpy call. This check is probably unnecessary with
8645 -fno-strict-aliasing. Similarly for destvar. See also
8646 PR29286. */
8647 else if (!var_decl_component_p (srcvar))
8648 srcvar = NULL_TREE;
8649 }
4f46f2b9 8650
5383fb56 8651 destvar = NULL_TREE;
8652 if (tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8653 {
389dd41b 8654 destvar = build_fold_indirect_ref_loc (loc, dest);
5383fb56 8655 if (TREE_THIS_VOLATILE (destvar))
6f52ebeb 8656 return NULL_TREE;
92ddcd97 8657 else if (!tree_int_cst_equal (tree_expr_size (destvar), len))
5383fb56 8658 destvar = NULL_TREE;
8659 else if (!var_decl_component_p (destvar))
8660 destvar = NULL_TREE;
8661 }
8662
8663 if (srcvar == NULL_TREE && destvar == NULL_TREE)
c2f47e15 8664 return NULL_TREE;
4f46f2b9 8665
5383fb56 8666 if (srcvar == NULL_TREE)
8667 {
8668 tree srcptype;
8669 if (TREE_ADDRESSABLE (TREE_TYPE (destvar)))
8670 return NULL_TREE;
8671
6f52ebeb 8672 srctype = build_qualified_type (desttype, 0);
5383fb56 8673 if (src_align < (int) TYPE_ALIGN (srctype))
8674 {
8675 if (AGGREGATE_TYPE_P (srctype)
8676 || SLOW_UNALIGNED_ACCESS (TYPE_MODE (srctype), src_align))
8677 return NULL_TREE;
8678
8679 srctype = build_variant_type_copy (srctype);
8680 TYPE_ALIGN (srctype) = src_align;
8681 TYPE_USER_ALIGN (srctype) = 1;
8682 TYPE_PACKED (srctype) = 1;
8683 }
8684 srcptype = build_pointer_type_for_mode (srctype, ptr_mode, true);
389dd41b 8685 src = fold_convert_loc (loc, srcptype, src);
8686 srcvar = build_fold_indirect_ref_loc (loc, src);
5383fb56 8687 }
8688 else if (destvar == NULL_TREE)
8689 {
8690 tree destptype;
8691 if (TREE_ADDRESSABLE (TREE_TYPE (srcvar)))
8692 return NULL_TREE;
8693
6f52ebeb 8694 desttype = build_qualified_type (srctype, 0);
5383fb56 8695 if (dest_align < (int) TYPE_ALIGN (desttype))
8696 {
8697 if (AGGREGATE_TYPE_P (desttype)
8698 || SLOW_UNALIGNED_ACCESS (TYPE_MODE (desttype), dest_align))
8699 return NULL_TREE;
8700
8701 desttype = build_variant_type_copy (desttype);
8702 TYPE_ALIGN (desttype) = dest_align;
8703 TYPE_USER_ALIGN (desttype) = 1;
8704 TYPE_PACKED (desttype) = 1;
8705 }
8706 destptype = build_pointer_type_for_mode (desttype, ptr_mode, true);
389dd41b 8707 dest = fold_convert_loc (loc, destptype, dest);
8708 destvar = build_fold_indirect_ref_loc (loc, dest);
5383fb56 8709 }
8710
5a84fdd6 8711 if (srctype == desttype
2d04fd8d 8712 || (gimple_in_ssa_p (cfun)
548044d8 8713 && useless_type_conversion_p (desttype, srctype)))
5a84fdd6 8714 expr = srcvar;
8715 else if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
4f46f2b9 8716 || POINTER_TYPE_P (TREE_TYPE (srcvar)))
8717 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8718 || POINTER_TYPE_P (TREE_TYPE (destvar))))
389dd41b 8719 expr = fold_convert_loc (loc, TREE_TYPE (destvar), srcvar);
4f46f2b9 8720 else
389dd41b 8721 expr = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
8722 TREE_TYPE (destvar), srcvar);
41076ef6 8723 expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, expr);
4f46f2b9 8724 }
8725
8726 if (ignore)
8727 return expr;
8728
8729 if (endp == 0 || endp == 3)
389dd41b 8730 return omit_one_operand_loc (loc, type, dest, expr);
4f46f2b9 8731
8732 if (expr == len)
c2f47e15 8733 expr = NULL_TREE;
4f46f2b9 8734
8735 if (endp == 2)
389dd41b 8736 len = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (len), len,
4f46f2b9 8737 ssize_int (1));
8738
389dd41b 8739 len = fold_convert_loc (loc, sizetype, len);
8740 dest = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
8741 dest = fold_convert_loc (loc, type, dest);
4f46f2b9 8742 if (expr)
389dd41b 8743 dest = omit_one_operand_loc (loc, type, dest, expr);
4f46f2b9 8744 return dest;
8745}
8746
c2f47e15 8747/* Fold function call to builtin strcpy with arguments DEST and SRC.
8748 If LEN is not NULL, it represents the length of the string to be
8749 copied. Return NULL_TREE if no simplification can be made. */
9c8a1629 8750
f0613857 8751tree
389dd41b 8752fold_builtin_strcpy (location_t loc, tree fndecl, tree dest, tree src, tree len)
9c8a1629 8753{
c2f47e15 8754 tree fn;
9c8a1629 8755
c2f47e15 8756 if (!validate_arg (dest, POINTER_TYPE)
8757 || !validate_arg (src, POINTER_TYPE))
8758 return NULL_TREE;
9c8a1629 8759
8760 /* If SRC and DEST are the same (and not volatile), return DEST. */
8761 if (operand_equal_p (src, dest, 0))
389dd41b 8762 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest);
9c8a1629 8763
0bfd8d5c 8764 if (optimize_function_for_size_p (cfun))
c2f47e15 8765 return NULL_TREE;
f0613857 8766
8767 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8768 if (!fn)
c2f47e15 8769 return NULL_TREE;
f0613857 8770
8771 if (!len)
8772 {
8773 len = c_strlen (src, 1);
8774 if (! len || TREE_SIDE_EFFECTS (len))
c2f47e15 8775 return NULL_TREE;
f0613857 8776 }
8777
389dd41b 8778 len = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
8779 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
8780 build_call_expr_loc (loc, fn, 3, dest, src, len));
9c8a1629 8781}
8782
a65c4d64 8783/* Fold function call to builtin stpcpy with arguments DEST and SRC.
8784 Return NULL_TREE if no simplification can be made. */
8785
8786static tree
8787fold_builtin_stpcpy (location_t loc, tree fndecl, tree dest, tree src)
8788{
8789 tree fn, len, lenp1, call, type;
8790
8791 if (!validate_arg (dest, POINTER_TYPE)
8792 || !validate_arg (src, POINTER_TYPE))
8793 return NULL_TREE;
8794
8795 len = c_strlen (src, 1);
8796 if (!len
8797 || TREE_CODE (len) != INTEGER_CST)
8798 return NULL_TREE;
8799
8800 if (optimize_function_for_size_p (cfun)
8801 /* If length is zero it's small enough. */
8802 && !integer_zerop (len))
8803 return NULL_TREE;
8804
8805 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8806 if (!fn)
8807 return NULL_TREE;
8808
8809 lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
8810 /* We use dest twice in building our expression. Save it from
8811 multiple expansions. */
8812 dest = builtin_save_expr (dest);
8813 call = build_call_expr_loc (loc, fn, 3, dest, src, lenp1);
8814
8815 type = TREE_TYPE (TREE_TYPE (fndecl));
8816 len = fold_convert_loc (loc, sizetype, len);
8817 dest = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
8818 dest = fold_convert_loc (loc, type, dest);
8819 dest = omit_one_operand_loc (loc, type, dest, call);
8820 return dest;
8821}
8822
c2f47e15 8823/* Fold function call to builtin strncpy with arguments DEST, SRC, and LEN.
8824 If SLEN is not NULL, it represents the length of the source string.
8825 Return NULL_TREE if no simplification can be made. */
9c8a1629 8826
f0613857 8827tree
389dd41b 8828fold_builtin_strncpy (location_t loc, tree fndecl, tree dest,
8829 tree src, tree len, tree slen)
9c8a1629 8830{
c2f47e15 8831 tree fn;
9c8a1629 8832
c2f47e15 8833 if (!validate_arg (dest, POINTER_TYPE)
8834 || !validate_arg (src, POINTER_TYPE)
8835 || !validate_arg (len, INTEGER_TYPE))
8836 return NULL_TREE;
9c8a1629 8837
8838 /* If the LEN parameter is zero, return DEST. */
8839 if (integer_zerop (len))
389dd41b 8840 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
9c8a1629 8841
19226313 8842 /* We can't compare slen with len as constants below if len is not a
8843 constant. */
8844 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
c2f47e15 8845 return NULL_TREE;
19226313 8846
f0613857 8847 if (!slen)
8848 slen = c_strlen (src, 1);
8849
8850 /* Now, we must be passed a constant src ptr parameter. */
8851 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
c2f47e15 8852 return NULL_TREE;
f0613857 8853
389dd41b 8854 slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
f0613857 8855
8856 /* We do not support simplification of this case, though we do
8857 support it when expanding trees into RTL. */
8858 /* FIXME: generate a call to __builtin_memset. */
8859 if (tree_int_cst_lt (slen, len))
c2f47e15 8860 return NULL_TREE;
f0613857 8861
8862 /* OK transform into builtin memcpy. */
8863 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8864 if (!fn)
c2f47e15 8865 return NULL_TREE;
389dd41b 8866 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
8867 build_call_expr_loc (loc, fn, 3, dest, src, len));
9c8a1629 8868}
8869
7959b13b 8870/* Fold function call to builtin memchr. ARG1, ARG2 and LEN are the
8871 arguments to the call, and TYPE is its return type.
8872 Return NULL_TREE if no simplification can be made. */
8873
8874static tree
389dd41b 8875fold_builtin_memchr (location_t loc, tree arg1, tree arg2, tree len, tree type)
7959b13b 8876{
8877 if (!validate_arg (arg1, POINTER_TYPE)
8878 || !validate_arg (arg2, INTEGER_TYPE)
8879 || !validate_arg (len, INTEGER_TYPE))
8880 return NULL_TREE;
8881 else
8882 {
8883 const char *p1;
8884
8885 if (TREE_CODE (arg2) != INTEGER_CST
8886 || !host_integerp (len, 1))
8887 return NULL_TREE;
8888
8889 p1 = c_getstr (arg1);
8890 if (p1 && compare_tree_int (len, strlen (p1) + 1) <= 0)
8891 {
8892 char c;
8893 const char *r;
8894 tree tem;
8895
8896 if (target_char_cast (arg2, &c))
8897 return NULL_TREE;
8898
364c0c59 8899 r = (char *) memchr (p1, c, tree_low_cst (len, 1));
7959b13b 8900
8901 if (r == NULL)
8902 return build_int_cst (TREE_TYPE (arg1), 0);
8903
389dd41b 8904 tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (arg1), arg1,
0de36bdb 8905 size_int (r - p1));
389dd41b 8906 return fold_convert_loc (loc, type, tem);
7959b13b 8907 }
8908 return NULL_TREE;
8909 }
8910}
8911
c2f47e15 8912/* Fold function call to builtin memcmp with arguments ARG1 and ARG2.
8913 Return NULL_TREE if no simplification can be made. */
9c8a1629 8914
8915static tree
389dd41b 8916fold_builtin_memcmp (location_t loc, tree arg1, tree arg2, tree len)
9c8a1629 8917{
c4fef134 8918 const char *p1, *p2;
9c8a1629 8919
c2f47e15 8920 if (!validate_arg (arg1, POINTER_TYPE)
8921 || !validate_arg (arg2, POINTER_TYPE)
8922 || !validate_arg (len, INTEGER_TYPE))
8923 return NULL_TREE;
9c8a1629 8924
8925 /* If the LEN parameter is zero, return zero. */
8926 if (integer_zerop (len))
389dd41b 8927 return omit_two_operands_loc (loc, integer_type_node, integer_zero_node,
c4fef134 8928 arg1, arg2);
9c8a1629 8929
8930 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8931 if (operand_equal_p (arg1, arg2, 0))
389dd41b 8932 return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len);
c4fef134 8933
8934 p1 = c_getstr (arg1);
8935 p2 = c_getstr (arg2);
8936
8937 /* If all arguments are constant, and the value of len is not greater
8938 than the lengths of arg1 and arg2, evaluate at compile-time. */
8939 if (host_integerp (len, 1) && p1 && p2
8940 && compare_tree_int (len, strlen (p1) + 1) <= 0
8941 && compare_tree_int (len, strlen (p2) + 1) <= 0)
8942 {
8943 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8944
8945 if (r > 0)
8946 return integer_one_node;
8947 else if (r < 0)
8948 return integer_minus_one_node;
8949 else
8950 return integer_zero_node;
8951 }
8952
8953 /* If len parameter is one, return an expression corresponding to
8954 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8955 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8956 {
8957 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 8958 tree cst_uchar_ptr_node
8959 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8960
389dd41b 8961 tree ind1
8962 = fold_convert_loc (loc, integer_type_node,
8963 build1 (INDIRECT_REF, cst_uchar_node,
8964 fold_convert_loc (loc,
8965 cst_uchar_ptr_node,
c4fef134 8966 arg1)));
389dd41b 8967 tree ind2
8968 = fold_convert_loc (loc, integer_type_node,
8969 build1 (INDIRECT_REF, cst_uchar_node,
8970 fold_convert_loc (loc,
8971 cst_uchar_ptr_node,
c4fef134 8972 arg2)));
389dd41b 8973 return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2);
c4fef134 8974 }
9c8a1629 8975
c2f47e15 8976 return NULL_TREE;
9c8a1629 8977}
8978
c2f47e15 8979/* Fold function call to builtin strcmp with arguments ARG1 and ARG2.
8980 Return NULL_TREE if no simplification can be made. */
9c8a1629 8981
8982static tree
389dd41b 8983fold_builtin_strcmp (location_t loc, tree arg1, tree arg2)
9c8a1629 8984{
9c8a1629 8985 const char *p1, *p2;
8986
c2f47e15 8987 if (!validate_arg (arg1, POINTER_TYPE)
8988 || !validate_arg (arg2, POINTER_TYPE))
8989 return NULL_TREE;
9c8a1629 8990
8991 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8992 if (operand_equal_p (arg1, arg2, 0))
c4fef134 8993 return integer_zero_node;
9c8a1629 8994
8995 p1 = c_getstr (arg1);
8996 p2 = c_getstr (arg2);
8997
8998 if (p1 && p2)
8999 {
9c8a1629 9000 const int i = strcmp (p1, p2);
9001 if (i < 0)
c4fef134 9002 return integer_minus_one_node;
9c8a1629 9003 else if (i > 0)
c4fef134 9004 return integer_one_node;
9c8a1629 9005 else
c4fef134 9006 return integer_zero_node;
9007 }
9008
9009 /* If the second arg is "", return *(const unsigned char*)arg1. */
9010 if (p2 && *p2 == '\0')
9011 {
9012 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9013 tree cst_uchar_ptr_node
9014 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9015
389dd41b 9016 return fold_convert_loc (loc, integer_type_node,
9017 build1 (INDIRECT_REF, cst_uchar_node,
9018 fold_convert_loc (loc,
9019 cst_uchar_ptr_node,
9020 arg1)));
c4fef134 9021 }
9022
9023 /* If the first arg is "", return -*(const unsigned char*)arg2. */
9024 if (p1 && *p1 == '\0')
9025 {
9026 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9027 tree cst_uchar_ptr_node
9028 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9029
389dd41b 9030 tree temp
9031 = fold_convert_loc (loc, integer_type_node,
9032 build1 (INDIRECT_REF, cst_uchar_node,
9033 fold_convert_loc (loc,
9034 cst_uchar_ptr_node,
c4fef134 9035 arg2)));
389dd41b 9036 return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp);
9c8a1629 9037 }
9038
c2f47e15 9039 return NULL_TREE;
9c8a1629 9040}
9041
c2f47e15 9042/* Fold function call to builtin strncmp with arguments ARG1, ARG2, and LEN.
9043 Return NULL_TREE if no simplification can be made. */
9c8a1629 9044
9045static tree
389dd41b 9046fold_builtin_strncmp (location_t loc, tree arg1, tree arg2, tree len)
9c8a1629 9047{
9c8a1629 9048 const char *p1, *p2;
9049
c2f47e15 9050 if (!validate_arg (arg1, POINTER_TYPE)
9051 || !validate_arg (arg2, POINTER_TYPE)
9052 || !validate_arg (len, INTEGER_TYPE))
9053 return NULL_TREE;
9c8a1629 9054
9055 /* If the LEN parameter is zero, return zero. */
9056 if (integer_zerop (len))
389dd41b 9057 return omit_two_operands_loc (loc, integer_type_node, integer_zero_node,
c4fef134 9058 arg1, arg2);
9c8a1629 9059
9060 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
9061 if (operand_equal_p (arg1, arg2, 0))
389dd41b 9062 return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len);
9c8a1629 9063
9064 p1 = c_getstr (arg1);
9065 p2 = c_getstr (arg2);
9066
9067 if (host_integerp (len, 1) && p1 && p2)
9068 {
9c8a1629 9069 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
c4fef134 9070 if (i > 0)
9071 return integer_one_node;
9072 else if (i < 0)
9073 return integer_minus_one_node;
9c8a1629 9074 else
c4fef134 9075 return integer_zero_node;
9076 }
9077
9078 /* If the second arg is "", and the length is greater than zero,
9079 return *(const unsigned char*)arg1. */
9080 if (p2 && *p2 == '\0'
9081 && TREE_CODE (len) == INTEGER_CST
9082 && tree_int_cst_sgn (len) == 1)
9083 {
9084 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9085 tree cst_uchar_ptr_node
9086 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9087
389dd41b 9088 return fold_convert_loc (loc, integer_type_node,
9089 build1 (INDIRECT_REF, cst_uchar_node,
9090 fold_convert_loc (loc,
9091 cst_uchar_ptr_node,
9092 arg1)));
c4fef134 9093 }
9094
9095 /* If the first arg is "", and the length is greater than zero,
9096 return -*(const unsigned char*)arg2. */
9097 if (p1 && *p1 == '\0'
9098 && TREE_CODE (len) == INTEGER_CST
9099 && tree_int_cst_sgn (len) == 1)
9100 {
9101 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9102 tree cst_uchar_ptr_node
9103 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9104
389dd41b 9105 tree temp = fold_convert_loc (loc, integer_type_node,
9106 build1 (INDIRECT_REF, cst_uchar_node,
9107 fold_convert_loc (loc,
9108 cst_uchar_ptr_node,
9109 arg2)));
9110 return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp);
c4fef134 9111 }
9112
9113 /* If len parameter is one, return an expression corresponding to
9114 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
9115 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9116 {
9117 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9118 tree cst_uchar_ptr_node
9119 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9120
389dd41b 9121 tree ind1 = fold_convert_loc (loc, integer_type_node,
9122 build1 (INDIRECT_REF, cst_uchar_node,
9123 fold_convert_loc (loc,
9124 cst_uchar_ptr_node,
9125 arg1)));
9126 tree ind2 = fold_convert_loc (loc, integer_type_node,
9127 build1 (INDIRECT_REF, cst_uchar_node,
9128 fold_convert_loc (loc,
9129 cst_uchar_ptr_node,
9130 arg2)));
9131 return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2);
9c8a1629 9132 }
9133
c2f47e15 9134 return NULL_TREE;
9c8a1629 9135}
9136
c2f47e15 9137/* Fold function call to builtin signbit, signbitf or signbitl with argument
9138 ARG. Return NULL_TREE if no simplification can be made. */
27f261ef 9139
9140static tree
389dd41b 9141fold_builtin_signbit (location_t loc, tree arg, tree type)
27f261ef 9142{
c2f47e15 9143 tree temp;
27f261ef 9144
c2f47e15 9145 if (!validate_arg (arg, REAL_TYPE))
27f261ef 9146 return NULL_TREE;
9147
27f261ef 9148 /* If ARG is a compile-time constant, determine the result. */
9149 if (TREE_CODE (arg) == REAL_CST
f96bd2bf 9150 && !TREE_OVERFLOW (arg))
27f261ef 9151 {
9152 REAL_VALUE_TYPE c;
9153
9154 c = TREE_REAL_CST (arg);
9155 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
389dd41b 9156 return fold_convert_loc (loc, type, temp);
27f261ef 9157 }
9158
9159 /* If ARG is non-negative, the result is always zero. */
9160 if (tree_expr_nonnegative_p (arg))
389dd41b 9161 return omit_one_operand_loc (loc, type, integer_zero_node, arg);
27f261ef 9162
9163 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
9164 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
389dd41b 9165 return fold_build2_loc (loc, LT_EXPR, type, arg,
49d00087 9166 build_real (TREE_TYPE (arg), dconst0));
27f261ef 9167
9168 return NULL_TREE;
9169}
9170
c2f47e15 9171/* Fold function call to builtin copysign, copysignf or copysignl with
9172 arguments ARG1 and ARG2. Return NULL_TREE if no simplification can
9173 be made. */
467214fd 9174
9175static tree
389dd41b 9176fold_builtin_copysign (location_t loc, tree fndecl,
9177 tree arg1, tree arg2, tree type)
467214fd 9178{
c2f47e15 9179 tree tem;
467214fd 9180
c2f47e15 9181 if (!validate_arg (arg1, REAL_TYPE)
9182 || !validate_arg (arg2, REAL_TYPE))
467214fd 9183 return NULL_TREE;
9184
467214fd 9185 /* copysign(X,X) is X. */
9186 if (operand_equal_p (arg1, arg2, 0))
389dd41b 9187 return fold_convert_loc (loc, type, arg1);
467214fd 9188
9189 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
9190 if (TREE_CODE (arg1) == REAL_CST
9191 && TREE_CODE (arg2) == REAL_CST
f96bd2bf 9192 && !TREE_OVERFLOW (arg1)
9193 && !TREE_OVERFLOW (arg2))
467214fd 9194 {
9195 REAL_VALUE_TYPE c1, c2;
9196
9197 c1 = TREE_REAL_CST (arg1);
9198 c2 = TREE_REAL_CST (arg2);
749680e2 9199 /* c1.sign := c2.sign. */
467214fd 9200 real_copysign (&c1, &c2);
9201 return build_real (type, c1);
467214fd 9202 }
9203
9204 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
9205 Remember to evaluate Y for side-effects. */
9206 if (tree_expr_nonnegative_p (arg2))
389dd41b 9207 return omit_one_operand_loc (loc, type,
9208 fold_build1_loc (loc, ABS_EXPR, type, arg1),
467214fd 9209 arg2);
9210
198d9bbe 9211 /* Strip sign changing operations for the first argument. */
9212 tem = fold_strip_sign_ops (arg1);
9213 if (tem)
389dd41b 9214 return build_call_expr_loc (loc, fndecl, 2, tem, arg2);
198d9bbe 9215
467214fd 9216 return NULL_TREE;
9217}
9218
c2f47e15 9219/* Fold a call to builtin isascii with argument ARG. */
d49367d4 9220
9221static tree
389dd41b 9222fold_builtin_isascii (location_t loc, tree arg)
d49367d4 9223{
c2f47e15 9224 if (!validate_arg (arg, INTEGER_TYPE))
9225 return NULL_TREE;
d49367d4 9226 else
9227 {
9228 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
7c446c95 9229 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
9230 build_int_cst (NULL_TREE,
7016c612 9231 ~ (unsigned HOST_WIDE_INT) 0x7f));
389dd41b 9232 return fold_build2_loc (loc, EQ_EXPR, integer_type_node,
f2532264 9233 arg, integer_zero_node);
d49367d4 9234 }
9235}
9236
c2f47e15 9237/* Fold a call to builtin toascii with argument ARG. */
d49367d4 9238
9239static tree
389dd41b 9240fold_builtin_toascii (location_t loc, tree arg)
d49367d4 9241{
c2f47e15 9242 if (!validate_arg (arg, INTEGER_TYPE))
9243 return NULL_TREE;
9244
9245 /* Transform toascii(c) -> (c & 0x7f). */
389dd41b 9246 return fold_build2_loc (loc, BIT_AND_EXPR, integer_type_node, arg,
c2f47e15 9247 build_int_cst (NULL_TREE, 0x7f));
d49367d4 9248}
9249
c2f47e15 9250/* Fold a call to builtin isdigit with argument ARG. */
df1cf42e 9251
9252static tree
389dd41b 9253fold_builtin_isdigit (location_t loc, tree arg)
df1cf42e 9254{
c2f47e15 9255 if (!validate_arg (arg, INTEGER_TYPE))
9256 return NULL_TREE;
df1cf42e 9257 else
9258 {
9259 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
624d37a6 9260 /* According to the C standard, isdigit is unaffected by locale.
9261 However, it definitely is affected by the target character set. */
624d37a6 9262 unsigned HOST_WIDE_INT target_digit0
9263 = lang_hooks.to_target_charset ('0');
9264
9265 if (target_digit0 == 0)
9266 return NULL_TREE;
9267
389dd41b 9268 arg = fold_convert_loc (loc, unsigned_type_node, arg);
05abc81b 9269 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
624d37a6 9270 build_int_cst (unsigned_type_node, target_digit0));
389dd41b 9271 return fold_build2_loc (loc, LE_EXPR, integer_type_node, arg,
f2532264 9272 build_int_cst (unsigned_type_node, 9));
df1cf42e 9273 }
9274}
27f261ef 9275
c2f47e15 9276/* Fold a call to fabs, fabsf or fabsl with argument ARG. */
d1aade50 9277
9278static tree
389dd41b 9279fold_builtin_fabs (location_t loc, tree arg, tree type)
d1aade50 9280{
c2f47e15 9281 if (!validate_arg (arg, REAL_TYPE))
9282 return NULL_TREE;
d1aade50 9283
389dd41b 9284 arg = fold_convert_loc (loc, type, arg);
d1aade50 9285 if (TREE_CODE (arg) == REAL_CST)
9286 return fold_abs_const (arg, type);
389dd41b 9287 return fold_build1_loc (loc, ABS_EXPR, type, arg);
d1aade50 9288}
9289
c2f47e15 9290/* Fold a call to abs, labs, llabs or imaxabs with argument ARG. */
d1aade50 9291
9292static tree
389dd41b 9293fold_builtin_abs (location_t loc, tree arg, tree type)
d1aade50 9294{
c2f47e15 9295 if (!validate_arg (arg, INTEGER_TYPE))
9296 return NULL_TREE;
d1aade50 9297
389dd41b 9298 arg = fold_convert_loc (loc, type, arg);
d1aade50 9299 if (TREE_CODE (arg) == INTEGER_CST)
9300 return fold_abs_const (arg, type);
389dd41b 9301 return fold_build1_loc (loc, ABS_EXPR, type, arg);
d1aade50 9302}
9303
d4a43a03 9304/* Fold a call to builtin fmin or fmax. */
9305
9306static tree
389dd41b 9307fold_builtin_fmin_fmax (location_t loc, tree arg0, tree arg1,
9308 tree type, bool max)
d4a43a03 9309{
c2f47e15 9310 if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, REAL_TYPE))
d4a43a03 9311 {
d4a43a03 9312 /* Calculate the result when the argument is a constant. */
9313 tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
9314
9315 if (res)
9316 return res;
9317
61fe3555 9318 /* If either argument is NaN, return the other one. Avoid the
9319 transformation if we get (and honor) a signalling NaN. Using
9320 omit_one_operand() ensures we create a non-lvalue. */
9321 if (TREE_CODE (arg0) == REAL_CST
9322 && real_isnan (&TREE_REAL_CST (arg0))
9323 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
9324 || ! TREE_REAL_CST (arg0).signalling))
389dd41b 9325 return omit_one_operand_loc (loc, type, arg1, arg0);
61fe3555 9326 if (TREE_CODE (arg1) == REAL_CST
9327 && real_isnan (&TREE_REAL_CST (arg1))
9328 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
9329 || ! TREE_REAL_CST (arg1).signalling))
389dd41b 9330 return omit_one_operand_loc (loc, type, arg0, arg1);
61fe3555 9331
d4a43a03 9332 /* Transform fmin/fmax(x,x) -> x. */
9333 if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
389dd41b 9334 return omit_one_operand_loc (loc, type, arg0, arg1);
d4a43a03 9335
9336 /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR. C99 requires these
9337 functions to return the numeric arg if the other one is NaN.
9338 These tree codes don't honor that, so only transform if
9339 -ffinite-math-only is set. C99 doesn't require -0.0 to be
9340 handled, so we don't have to worry about it either. */
9341 if (flag_finite_math_only)
389dd41b 9342 return fold_build2_loc (loc, (max ? MAX_EXPR : MIN_EXPR), type,
9343 fold_convert_loc (loc, type, arg0),
9344 fold_convert_loc (loc, type, arg1));
d4a43a03 9345 }
9346 return NULL_TREE;
9347}
9348
abe4dcf6 9349/* Fold a call to builtin carg(a+bi) -> atan2(b,a). */
9350
9351static tree
389dd41b 9352fold_builtin_carg (location_t loc, tree arg, tree type)
abe4dcf6 9353{
239d491a 9354 if (validate_arg (arg, COMPLEX_TYPE)
9355 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
abe4dcf6 9356 {
9357 tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2);
9358
9359 if (atan2_fn)
9360 {
c2f47e15 9361 tree new_arg = builtin_save_expr (arg);
389dd41b 9362 tree r_arg = fold_build1_loc (loc, REALPART_EXPR, type, new_arg);
9363 tree i_arg = fold_build1_loc (loc, IMAGPART_EXPR, type, new_arg);
9364 return build_call_expr_loc (loc, atan2_fn, 2, i_arg, r_arg);
abe4dcf6 9365 }
9366 }
9367
9368 return NULL_TREE;
9369}
9370
cb2b9385 9371/* Fold a call to builtin logb/ilogb. */
9372
9373static tree
389dd41b 9374fold_builtin_logb (location_t loc, tree arg, tree rettype)
cb2b9385 9375{
9376 if (! validate_arg (arg, REAL_TYPE))
9377 return NULL_TREE;
9378
9379 STRIP_NOPS (arg);
9380
9381 if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9382 {
9383 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9384
9385 switch (value->cl)
9386 {
9387 case rvc_nan:
9388 case rvc_inf:
9389 /* If arg is Inf or NaN and we're logb, return it. */
9390 if (TREE_CODE (rettype) == REAL_TYPE)
389dd41b 9391 return fold_convert_loc (loc, rettype, arg);
cb2b9385 9392 /* Fall through... */
9393 case rvc_zero:
9394 /* Zero may set errno and/or raise an exception for logb, also
9395 for ilogb we don't know FP_ILOGB0. */
9396 return NULL_TREE;
9397 case rvc_normal:
9398 /* For normal numbers, proceed iff radix == 2. In GCC,
9399 normalized significands are in the range [0.5, 1.0). We
9400 want the exponent as if they were [1.0, 2.0) so get the
9401 exponent and subtract 1. */
9402 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
389dd41b 9403 return fold_convert_loc (loc, rettype,
9404 build_int_cst (NULL_TREE,
9405 REAL_EXP (value)-1));
cb2b9385 9406 break;
9407 }
9408 }
9409
9410 return NULL_TREE;
9411}
9412
9413/* Fold a call to builtin significand, if radix == 2. */
9414
9415static tree
389dd41b 9416fold_builtin_significand (location_t loc, tree arg, tree rettype)
cb2b9385 9417{
9418 if (! validate_arg (arg, REAL_TYPE))
9419 return NULL_TREE;
9420
9421 STRIP_NOPS (arg);
9422
9423 if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9424 {
9425 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9426
9427 switch (value->cl)
9428 {
9429 case rvc_zero:
9430 case rvc_nan:
9431 case rvc_inf:
9432 /* If arg is +-0, +-Inf or +-NaN, then return it. */
389dd41b 9433 return fold_convert_loc (loc, rettype, arg);
cb2b9385 9434 case rvc_normal:
9435 /* For normal numbers, proceed iff radix == 2. */
9436 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9437 {
9438 REAL_VALUE_TYPE result = *value;
9439 /* In GCC, normalized significands are in the range [0.5,
9440 1.0). We want them to be [1.0, 2.0) so set the
9441 exponent to 1. */
9442 SET_REAL_EXP (&result, 1);
9443 return build_real (rettype, result);
9444 }
9445 break;
9446 }
9447 }
9448
9449 return NULL_TREE;
9450}
9451
3838b9ae 9452/* Fold a call to builtin frexp, we can assume the base is 2. */
9453
9454static tree
389dd41b 9455fold_builtin_frexp (location_t loc, tree arg0, tree arg1, tree rettype)
3838b9ae 9456{
9457 if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9458 return NULL_TREE;
9459
9460 STRIP_NOPS (arg0);
9461
9462 if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9463 return NULL_TREE;
9464
389dd41b 9465 arg1 = build_fold_indirect_ref_loc (loc, arg1);
3838b9ae 9466
9467 /* Proceed if a valid pointer type was passed in. */
9468 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == integer_type_node)
9469 {
9470 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9471 tree frac, exp;
9472
9473 switch (value->cl)
9474 {
9475 case rvc_zero:
9476 /* For +-0, return (*exp = 0, +-0). */
9477 exp = integer_zero_node;
9478 frac = arg0;
9479 break;
9480 case rvc_nan:
9481 case rvc_inf:
9482 /* For +-NaN or +-Inf, *exp is unspecified, return arg0. */
389dd41b 9483 return omit_one_operand_loc (loc, rettype, arg0, arg1);
3838b9ae 9484 case rvc_normal:
9485 {
9486 /* Since the frexp function always expects base 2, and in
9487 GCC normalized significands are already in the range
9488 [0.5, 1.0), we have exactly what frexp wants. */
9489 REAL_VALUE_TYPE frac_rvt = *value;
9490 SET_REAL_EXP (&frac_rvt, 0);
9491 frac = build_real (rettype, frac_rvt);
9492 exp = build_int_cst (NULL_TREE, REAL_EXP (value));
9493 }
9494 break;
9495 default:
9496 gcc_unreachable ();
9497 }
9498
9499 /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
389dd41b 9500 arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1, exp);
3838b9ae 9501 TREE_SIDE_EFFECTS (arg1) = 1;
389dd41b 9502 return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1, frac);
3838b9ae 9503 }
9504
9505 return NULL_TREE;
9506}
9507
7587301b 9508/* Fold a call to builtin ldexp or scalbn/scalbln. If LDEXP is true
9509 then we can assume the base is two. If it's false, then we have to
9510 check the mode of the TYPE parameter in certain cases. */
9511
9512static tree
389dd41b 9513fold_builtin_load_exponent (location_t loc, tree arg0, tree arg1,
9514 tree type, bool ldexp)
7587301b 9515{
9516 if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, INTEGER_TYPE))
9517 {
9518 STRIP_NOPS (arg0);
9519 STRIP_NOPS (arg1);
9520
9521 /* If arg0 is 0, Inf or NaN, or if arg1 is 0, then return arg0. */
9522 if (real_zerop (arg0) || integer_zerop (arg1)
9523 || (TREE_CODE (arg0) == REAL_CST
776a7bab 9524 && !real_isfinite (&TREE_REAL_CST (arg0))))
389dd41b 9525 return omit_one_operand_loc (loc, type, arg0, arg1);
7587301b 9526
9527 /* If both arguments are constant, then try to evaluate it. */
9528 if ((ldexp || REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2)
9529 && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
9530 && host_integerp (arg1, 0))
9531 {
9532 /* Bound the maximum adjustment to twice the range of the
9533 mode's valid exponents. Use abs to ensure the range is
9534 positive as a sanity check. */
9535 const long max_exp_adj = 2 *
9536 labs (REAL_MODE_FORMAT (TYPE_MODE (type))->emax
9537 - REAL_MODE_FORMAT (TYPE_MODE (type))->emin);
9538
9539 /* Get the user-requested adjustment. */
9540 const HOST_WIDE_INT req_exp_adj = tree_low_cst (arg1, 0);
9541
9542 /* The requested adjustment must be inside this range. This
9543 is a preliminary cap to avoid things like overflow, we
9544 may still fail to compute the result for other reasons. */
9545 if (-max_exp_adj < req_exp_adj && req_exp_adj < max_exp_adj)
9546 {
9547 REAL_VALUE_TYPE initial_result;
9548
9549 real_ldexp (&initial_result, &TREE_REAL_CST (arg0), req_exp_adj);
9550
9551 /* Ensure we didn't overflow. */
9552 if (! real_isinf (&initial_result))
9553 {
9554 const REAL_VALUE_TYPE trunc_result
9555 = real_value_truncate (TYPE_MODE (type), initial_result);
9556
9557 /* Only proceed if the target mode can hold the
9558 resulting value. */
9559 if (REAL_VALUES_EQUAL (initial_result, trunc_result))
9560 return build_real (type, trunc_result);
9561 }
9562 }
9563 }
9564 }
9565
9566 return NULL_TREE;
9567}
9568
ebf8b4f5 9569/* Fold a call to builtin modf. */
9570
9571static tree
389dd41b 9572fold_builtin_modf (location_t loc, tree arg0, tree arg1, tree rettype)
ebf8b4f5 9573{
9574 if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9575 return NULL_TREE;
9576
9577 STRIP_NOPS (arg0);
9578
9579 if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9580 return NULL_TREE;
9581
389dd41b 9582 arg1 = build_fold_indirect_ref_loc (loc, arg1);
ebf8b4f5 9583
9584 /* Proceed if a valid pointer type was passed in. */
9585 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == TYPE_MAIN_VARIANT (rettype))
9586 {
9587 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9588 REAL_VALUE_TYPE trunc, frac;
9589
9590 switch (value->cl)
9591 {
9592 case rvc_nan:
9593 case rvc_zero:
9594 /* For +-NaN or +-0, return (*arg1 = arg0, arg0). */
9595 trunc = frac = *value;
9596 break;
9597 case rvc_inf:
9598 /* For +-Inf, return (*arg1 = arg0, +-0). */
9599 frac = dconst0;
9600 frac.sign = value->sign;
9601 trunc = *value;
9602 break;
9603 case rvc_normal:
9604 /* Return (*arg1 = trunc(arg0), arg0-trunc(arg0)). */
9605 real_trunc (&trunc, VOIDmode, value);
9606 real_arithmetic (&frac, MINUS_EXPR, value, &trunc);
9607 /* If the original number was negative and already
9608 integral, then the fractional part is -0.0. */
9609 if (value->sign && frac.cl == rvc_zero)
9610 frac.sign = value->sign;
9611 break;
9612 }
9613
9614 /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
389dd41b 9615 arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1,
ebf8b4f5 9616 build_real (rettype, trunc));
9617 TREE_SIDE_EFFECTS (arg1) = 1;
389dd41b 9618 return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1,
ebf8b4f5 9619 build_real (rettype, frac));
9620 }
9621
9622 return NULL_TREE;
9623}
9624
a65c4d64 9625/* Given a location LOC, an interclass builtin function decl FNDECL
9626 and its single argument ARG, return an folded expression computing
9627 the same, or NULL_TREE if we either couldn't or didn't want to fold
9628 (the latter happen if there's an RTL instruction available). */
9629
9630static tree
9631fold_builtin_interclass_mathfn (location_t loc, tree fndecl, tree arg)
9632{
9633 enum machine_mode mode;
9634
9635 if (!validate_arg (arg, REAL_TYPE))
9636 return NULL_TREE;
9637
9638 if (interclass_mathfn_icode (arg, fndecl) != CODE_FOR_nothing)
9639 return NULL_TREE;
9640
9641 mode = TYPE_MODE (TREE_TYPE (arg));
9642
9643 /* If there is no optab, try generic code. */
9644 switch (DECL_FUNCTION_CODE (fndecl))
9645 {
9646 tree result;
9647
9648 CASE_FLT_FN (BUILT_IN_ISINF):
9649 {
9650 /* isinf(x) -> isgreater(fabs(x),DBL_MAX). */
9651 tree const isgr_fn = built_in_decls[BUILT_IN_ISGREATER];
9652 tree const type = TREE_TYPE (arg);
9653 REAL_VALUE_TYPE r;
9654 char buf[128];
9655
9656 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9657 real_from_string (&r, buf);
9658 result = build_call_expr (isgr_fn, 2,
9659 fold_build1_loc (loc, ABS_EXPR, type, arg),
9660 build_real (type, r));
9661 return result;
9662 }
9663 CASE_FLT_FN (BUILT_IN_FINITE):
9664 case BUILT_IN_ISFINITE:
9665 {
9666 /* isfinite(x) -> islessequal(fabs(x),DBL_MAX). */
9667 tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
9668 tree const type = TREE_TYPE (arg);
9669 REAL_VALUE_TYPE r;
9670 char buf[128];
9671
9672 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9673 real_from_string (&r, buf);
9674 result = build_call_expr (isle_fn, 2,
9675 fold_build1_loc (loc, ABS_EXPR, type, arg),
9676 build_real (type, r));
9677 /*result = fold_build2_loc (loc, UNGT_EXPR,
9678 TREE_TYPE (TREE_TYPE (fndecl)),
9679 fold_build1_loc (loc, ABS_EXPR, type, arg),
9680 build_real (type, r));
9681 result = fold_build1_loc (loc, TRUTH_NOT_EXPR,
9682 TREE_TYPE (TREE_TYPE (fndecl)),
9683 result);*/
9684 return result;
9685 }
9686 case BUILT_IN_ISNORMAL:
9687 {
9688 /* isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) &
9689 islessequal(fabs(x),DBL_MAX). */
9690 tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
9691 tree const isge_fn = built_in_decls[BUILT_IN_ISGREATEREQUAL];
9692 tree const type = TREE_TYPE (arg);
9693 REAL_VALUE_TYPE rmax, rmin;
9694 char buf[128];
9695
9696 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9697 real_from_string (&rmax, buf);
9698 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
9699 real_from_string (&rmin, buf);
9700 arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg));
9701 result = build_call_expr (isle_fn, 2, arg,
9702 build_real (type, rmax));
9703 result = fold_build2 (BIT_AND_EXPR, integer_type_node, result,
9704 build_call_expr (isge_fn, 2, arg,
9705 build_real (type, rmin)));
9706 return result;
9707 }
9708 default:
9709 break;
9710 }
9711
9712 return NULL_TREE;
9713}
9714
726069ba 9715/* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
c2f47e15 9716 ARG is the argument for the call. */
726069ba 9717
9718static tree
389dd41b 9719fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index)
726069ba 9720{
726069ba 9721 tree type = TREE_TYPE (TREE_TYPE (fndecl));
726069ba 9722 REAL_VALUE_TYPE r;
9723
c2f47e15 9724 if (!validate_arg (arg, REAL_TYPE))
d43cee80 9725 return NULL_TREE;
726069ba 9726
726069ba 9727 switch (builtin_index)
9728 {
9729 case BUILT_IN_ISINF:
b70bfd00 9730 if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
389dd41b 9731 return omit_one_operand_loc (loc, type, integer_zero_node, arg);
726069ba 9732
9733 if (TREE_CODE (arg) == REAL_CST)
9734 {
9735 r = TREE_REAL_CST (arg);
9736 if (real_isinf (&r))
9737 return real_compare (GT_EXPR, &r, &dconst0)
9738 ? integer_one_node : integer_minus_one_node;
9739 else
9740 return integer_zero_node;
9741 }
9742
9743 return NULL_TREE;
9744
c319d56a 9745 case BUILT_IN_ISINF_SIGN:
9746 {
9747 /* isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 */
9748 /* In a boolean context, GCC will fold the inner COND_EXPR to
9749 1. So e.g. "if (isinf_sign(x))" would be folded to just
9750 "if (isinf(x) ? 1 : 0)" which becomes "if (isinf(x))". */
9751 tree signbit_fn = mathfn_built_in_1 (TREE_TYPE (arg), BUILT_IN_SIGNBIT, 0);
9752 tree isinf_fn = built_in_decls[BUILT_IN_ISINF];
9753 tree tmp = NULL_TREE;
9754
9755 arg = builtin_save_expr (arg);
9756
9757 if (signbit_fn && isinf_fn)
9758 {
389dd41b 9759 tree signbit_call = build_call_expr_loc (loc, signbit_fn, 1, arg);
9760 tree isinf_call = build_call_expr_loc (loc, isinf_fn, 1, arg);
c319d56a 9761
389dd41b 9762 signbit_call = fold_build2_loc (loc, NE_EXPR, integer_type_node,
c319d56a 9763 signbit_call, integer_zero_node);
389dd41b 9764 isinf_call = fold_build2_loc (loc, NE_EXPR, integer_type_node,
c319d56a 9765 isinf_call, integer_zero_node);
9766
389dd41b 9767 tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node, signbit_call,
c319d56a 9768 integer_minus_one_node, integer_one_node);
389dd41b 9769 tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node,
9770 isinf_call, tmp,
c319d56a 9771 integer_zero_node);
9772 }
9773
9774 return tmp;
9775 }
9776
cde061c1 9777 case BUILT_IN_ISFINITE:
b70bfd00 9778 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
9779 && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
389dd41b 9780 return omit_one_operand_loc (loc, type, integer_one_node, arg);
726069ba 9781
9782 if (TREE_CODE (arg) == REAL_CST)
9783 {
9784 r = TREE_REAL_CST (arg);
776a7bab 9785 return real_isfinite (&r) ? integer_one_node : integer_zero_node;
726069ba 9786 }
9787
9788 return NULL_TREE;
9789
9790 case BUILT_IN_ISNAN:
b70bfd00 9791 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
389dd41b 9792 return omit_one_operand_loc (loc, type, integer_zero_node, arg);
726069ba 9793
9794 if (TREE_CODE (arg) == REAL_CST)
9795 {
9796 r = TREE_REAL_CST (arg);
9797 return real_isnan (&r) ? integer_one_node : integer_zero_node;
9798 }
9799
9800 arg = builtin_save_expr (arg);
389dd41b 9801 return fold_build2_loc (loc, UNORDERED_EXPR, type, arg, arg);
726069ba 9802
9803 default:
64db345d 9804 gcc_unreachable ();
726069ba 9805 }
9806}
9807
19fbe3a4 9808/* Fold a call to __builtin_fpclassify(int, int, int, int, int, ...).
9809 This builtin will generate code to return the appropriate floating
9810 point classification depending on the value of the floating point
9811 number passed in. The possible return values must be supplied as
921b27c0 9812 int arguments to the call in the following order: FP_NAN, FP_INFINITE,
19fbe3a4 9813 FP_NORMAL, FP_SUBNORMAL and FP_ZERO. The ellipses is for exactly
9814 one floating point argument which is "type generic". */
9815
9816static tree
389dd41b 9817fold_builtin_fpclassify (location_t loc, tree exp)
19fbe3a4 9818{
921b27c0 9819 tree fp_nan, fp_infinite, fp_normal, fp_subnormal, fp_zero,
9820 arg, type, res, tmp;
19fbe3a4 9821 enum machine_mode mode;
9822 REAL_VALUE_TYPE r;
9823 char buf[128];
9824
9825 /* Verify the required arguments in the original call. */
9826 if (!validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE,
9827 INTEGER_TYPE, INTEGER_TYPE,
9828 INTEGER_TYPE, REAL_TYPE, VOID_TYPE))
9829 return NULL_TREE;
9830
9831 fp_nan = CALL_EXPR_ARG (exp, 0);
921b27c0 9832 fp_infinite = CALL_EXPR_ARG (exp, 1);
19fbe3a4 9833 fp_normal = CALL_EXPR_ARG (exp, 2);
9834 fp_subnormal = CALL_EXPR_ARG (exp, 3);
9835 fp_zero = CALL_EXPR_ARG (exp, 4);
9836 arg = CALL_EXPR_ARG (exp, 5);
9837 type = TREE_TYPE (arg);
9838 mode = TYPE_MODE (type);
389dd41b 9839 arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg));
19fbe3a4 9840
9841 /* fpclassify(x) ->
9842 isnan(x) ? FP_NAN :
921b27c0 9843 (fabs(x) == Inf ? FP_INFINITE :
19fbe3a4 9844 (fabs(x) >= DBL_MIN ? FP_NORMAL :
9845 (x == 0 ? FP_ZERO : FP_SUBNORMAL))). */
9846
389dd41b 9847 tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
19fbe3a4 9848 build_real (type, dconst0));
389dd41b 9849 res = fold_build3_loc (loc, COND_EXPR, integer_type_node,
9850 tmp, fp_zero, fp_subnormal);
19fbe3a4 9851
9852 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
9853 real_from_string (&r, buf);
389dd41b 9854 tmp = fold_build2_loc (loc, GE_EXPR, integer_type_node,
9855 arg, build_real (type, r));
9856 res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, fp_normal, res);
19fbe3a4 9857
9858 if (HONOR_INFINITIES (mode))
9859 {
9860 real_inf (&r);
389dd41b 9861 tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
19fbe3a4 9862 build_real (type, r));
389dd41b 9863 res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp,
9864 fp_infinite, res);
19fbe3a4 9865 }
9866
9867 if (HONOR_NANS (mode))
9868 {
389dd41b 9869 tmp = fold_build2_loc (loc, ORDERED_EXPR, integer_type_node, arg, arg);
9870 res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, res, fp_nan);
19fbe3a4 9871 }
9872
9873 return res;
9874}
9875
9bc9f15f 9876/* Fold a call to an unordered comparison function such as
d5019fe8 9877 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
c2f47e15 9878 being called and ARG0 and ARG1 are the arguments for the call.
726069ba 9879 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
9880 the opposite of the desired result. UNORDERED_CODE is used
9881 for modes that can hold NaNs and ORDERED_CODE is used for
9882 the rest. */
9bc9f15f 9883
9884static tree
389dd41b 9885fold_builtin_unordered_cmp (location_t loc, tree fndecl, tree arg0, tree arg1,
9bc9f15f 9886 enum tree_code unordered_code,
9887 enum tree_code ordered_code)
9888{
859f903a 9889 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9bc9f15f 9890 enum tree_code code;
6978db0d 9891 tree type0, type1;
9892 enum tree_code code0, code1;
9893 tree cmp_type = NULL_TREE;
9bc9f15f 9894
6978db0d 9895 type0 = TREE_TYPE (arg0);
9896 type1 = TREE_TYPE (arg1);
a0c938f0 9897
6978db0d 9898 code0 = TREE_CODE (type0);
9899 code1 = TREE_CODE (type1);
a0c938f0 9900
6978db0d 9901 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
9902 /* Choose the wider of two real types. */
9903 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
9904 ? type0 : type1;
9905 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
9906 cmp_type = type0;
9907 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
9908 cmp_type = type1;
a0c938f0 9909
389dd41b 9910 arg0 = fold_convert_loc (loc, cmp_type, arg0);
9911 arg1 = fold_convert_loc (loc, cmp_type, arg1);
859f903a 9912
9913 if (unordered_code == UNORDERED_EXPR)
9914 {
b70bfd00 9915 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
389dd41b 9916 return omit_two_operands_loc (loc, type, integer_zero_node, arg0, arg1);
9917 return fold_build2_loc (loc, UNORDERED_EXPR, type, arg0, arg1);
859f903a 9918 }
9bc9f15f 9919
b70bfd00 9920 code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
9921 : ordered_code;
389dd41b 9922 return fold_build1_loc (loc, TRUTH_NOT_EXPR, type,
9923 fold_build2_loc (loc, code, type, arg0, arg1));
9bc9f15f 9924}
9925
c2f47e15 9926/* Fold a call to built-in function FNDECL with 0 arguments.
9927 IGNORE is true if the result of the function call is ignored. This
9928 function returns NULL_TREE if no simplification was possible. */
650e4c94 9929
4ee9c684 9930static tree
389dd41b 9931fold_builtin_0 (location_t loc, tree fndecl, bool ignore ATTRIBUTE_UNUSED)
650e4c94 9932{
e9f80ff5 9933 tree type = TREE_TYPE (TREE_TYPE (fndecl));
c2f47e15 9934 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
189b3398 9935 switch (fcode)
650e4c94 9936 {
c2f47e15 9937 CASE_FLT_FN (BUILT_IN_INF):
9938 case BUILT_IN_INFD32:
9939 case BUILT_IN_INFD64:
9940 case BUILT_IN_INFD128:
389dd41b 9941 return fold_builtin_inf (loc, type, true);
7c2f0500 9942
c2f47e15 9943 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
389dd41b 9944 return fold_builtin_inf (loc, type, false);
7c2f0500 9945
c2f47e15 9946 case BUILT_IN_CLASSIFY_TYPE:
9947 return fold_builtin_classify_type (NULL_TREE);
7c2f0500 9948
c2f47e15 9949 default:
9950 break;
9951 }
9952 return NULL_TREE;
9953}
7c2f0500 9954
c2f47e15 9955/* Fold a call to built-in function FNDECL with 1 argument, ARG0.
9956 IGNORE is true if the result of the function call is ignored. This
9957 function returns NULL_TREE if no simplification was possible. */
7c2f0500 9958
c2f47e15 9959static tree
389dd41b 9960fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool ignore)
c2f47e15 9961{
9962 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9963 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
9964 switch (fcode)
9965 {
7c2f0500 9966
650e4c94 9967 case BUILT_IN_CONSTANT_P:
7c2f0500 9968 {
c2f47e15 9969 tree val = fold_builtin_constant_p (arg0);
7c2f0500 9970
7c2f0500 9971 /* Gimplification will pull the CALL_EXPR for the builtin out of
9972 an if condition. When not optimizing, we'll not CSE it back.
9973 To avoid link error types of regressions, return false now. */
9974 if (!val && !optimize)
9975 val = integer_zero_node;
9976
9977 return val;
9978 }
650e4c94 9979
539a3a92 9980 case BUILT_IN_CLASSIFY_TYPE:
c2f47e15 9981 return fold_builtin_classify_type (arg0);
539a3a92 9982
650e4c94 9983 case BUILT_IN_STRLEN:
389dd41b 9984 return fold_builtin_strlen (loc, arg0);
650e4c94 9985
4f35b1fc 9986 CASE_FLT_FN (BUILT_IN_FABS):
389dd41b 9987 return fold_builtin_fabs (loc, arg0, type);
d1aade50 9988
9989 case BUILT_IN_ABS:
9990 case BUILT_IN_LABS:
9991 case BUILT_IN_LLABS:
9992 case BUILT_IN_IMAXABS:
389dd41b 9993 return fold_builtin_abs (loc, arg0, type);
c63f4ad3 9994
4f35b1fc 9995 CASE_FLT_FN (BUILT_IN_CONJ):
239d491a 9996 if (validate_arg (arg0, COMPLEX_TYPE)
9997 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
389dd41b 9998 return fold_build1_loc (loc, CONJ_EXPR, type, arg0);
c2f47e15 9999 break;
36d3581d 10000
4f35b1fc 10001 CASE_FLT_FN (BUILT_IN_CREAL):
239d491a 10002 if (validate_arg (arg0, COMPLEX_TYPE)
10003 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
389dd41b 10004 return non_lvalue_loc (loc, fold_build1_loc (loc, REALPART_EXPR, type, arg0));;
c2f47e15 10005 break;
36d3581d 10006
4f35b1fc 10007 CASE_FLT_FN (BUILT_IN_CIMAG):
c2f47e15 10008 if (validate_arg (arg0, COMPLEX_TYPE))
389dd41b 10009 return non_lvalue_loc (loc, fold_build1_loc (loc, IMAGPART_EXPR, type, arg0));
c2f47e15 10010 break;
36d3581d 10011
503733d5 10012 CASE_FLT_FN (BUILT_IN_CCOS):
389dd41b 10013 return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ false);
239d491a 10014
503733d5 10015 CASE_FLT_FN (BUILT_IN_CCOSH):
389dd41b 10016 return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ true);
239d491a 10017
10018#ifdef HAVE_mpc
10019 CASE_FLT_FN (BUILT_IN_CSIN):
10020 if (validate_arg (arg0, COMPLEX_TYPE)
10021 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10022 return do_mpc_arg1 (arg0, type, mpc_sin);
c2f47e15 10023 break;
239d491a 10024
10025 CASE_FLT_FN (BUILT_IN_CSINH):
10026 if (validate_arg (arg0, COMPLEX_TYPE)
10027 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10028 return do_mpc_arg1 (arg0, type, mpc_sinh);
10029 break;
10030
10031 CASE_FLT_FN (BUILT_IN_CTAN):
10032 if (validate_arg (arg0, COMPLEX_TYPE)
10033 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10034 return do_mpc_arg1 (arg0, type, mpc_tan);
10035 break;
10036
10037 CASE_FLT_FN (BUILT_IN_CTANH):
10038 if (validate_arg (arg0, COMPLEX_TYPE)
10039 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10040 return do_mpc_arg1 (arg0, type, mpc_tanh);
10041 break;
10042
10043 CASE_FLT_FN (BUILT_IN_CLOG):
10044 if (validate_arg (arg0, COMPLEX_TYPE)
10045 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10046 return do_mpc_arg1 (arg0, type, mpc_log);
10047 break;
10048
10049 CASE_FLT_FN (BUILT_IN_CSQRT):
10050 if (validate_arg (arg0, COMPLEX_TYPE)
10051 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10052 return do_mpc_arg1 (arg0, type, mpc_sqrt);
10053 break;
10054#endif
10055
4f35b1fc 10056 CASE_FLT_FN (BUILT_IN_CABS):
389dd41b 10057 return fold_builtin_cabs (loc, arg0, type, fndecl);
c63f4ad3 10058
abe4dcf6 10059 CASE_FLT_FN (BUILT_IN_CARG):
389dd41b 10060 return fold_builtin_carg (loc, arg0, type);
abe4dcf6 10061
4f35b1fc 10062 CASE_FLT_FN (BUILT_IN_SQRT):
389dd41b 10063 return fold_builtin_sqrt (loc, arg0, type);
805e22b2 10064
4f35b1fc 10065 CASE_FLT_FN (BUILT_IN_CBRT):
389dd41b 10066 return fold_builtin_cbrt (loc, arg0, type);
3bc5c41b 10067
728bac60 10068 CASE_FLT_FN (BUILT_IN_ASIN):
c2f47e15 10069 if (validate_arg (arg0, REAL_TYPE))
10070 return do_mpfr_arg1 (arg0, type, mpfr_asin,
728bac60 10071 &dconstm1, &dconst1, true);
10072 break;
10073
10074 CASE_FLT_FN (BUILT_IN_ACOS):
c2f47e15 10075 if (validate_arg (arg0, REAL_TYPE))
10076 return do_mpfr_arg1 (arg0, type, mpfr_acos,
728bac60 10077 &dconstm1, &dconst1, true);
10078 break;
10079
10080 CASE_FLT_FN (BUILT_IN_ATAN):
c2f47e15 10081 if (validate_arg (arg0, REAL_TYPE))
10082 return do_mpfr_arg1 (arg0, type, mpfr_atan, NULL, NULL, 0);
728bac60 10083 break;
10084
10085 CASE_FLT_FN (BUILT_IN_ASINH):
c2f47e15 10086 if (validate_arg (arg0, REAL_TYPE))
10087 return do_mpfr_arg1 (arg0, type, mpfr_asinh, NULL, NULL, 0);
728bac60 10088 break;
10089
10090 CASE_FLT_FN (BUILT_IN_ACOSH):
c2f47e15 10091 if (validate_arg (arg0, REAL_TYPE))
10092 return do_mpfr_arg1 (arg0, type, mpfr_acosh,
728bac60 10093 &dconst1, NULL, true);
10094 break;
10095
10096 CASE_FLT_FN (BUILT_IN_ATANH):
c2f47e15 10097 if (validate_arg (arg0, REAL_TYPE))
10098 return do_mpfr_arg1 (arg0, type, mpfr_atanh,
728bac60 10099 &dconstm1, &dconst1, false);
10100 break;
10101
4f35b1fc 10102 CASE_FLT_FN (BUILT_IN_SIN):
c2f47e15 10103 if (validate_arg (arg0, REAL_TYPE))
10104 return do_mpfr_arg1 (arg0, type, mpfr_sin, NULL, NULL, 0);
728bac60 10105 break;
77e89269 10106
4f35b1fc 10107 CASE_FLT_FN (BUILT_IN_COS):
389dd41b 10108 return fold_builtin_cos (loc, arg0, type, fndecl);
77e89269 10109
728bac60 10110 CASE_FLT_FN (BUILT_IN_TAN):
c2f47e15 10111 return fold_builtin_tan (arg0, type);
d735c391 10112
c5bb2c4b 10113 CASE_FLT_FN (BUILT_IN_CEXP):
389dd41b 10114 return fold_builtin_cexp (loc, arg0, type);
c5bb2c4b 10115
d735c391 10116 CASE_FLT_FN (BUILT_IN_CEXPI):
c2f47e15 10117 if (validate_arg (arg0, REAL_TYPE))
10118 return do_mpfr_sincos (arg0, NULL_TREE, NULL_TREE);
10119 break;
d92f994c 10120
728bac60 10121 CASE_FLT_FN (BUILT_IN_SINH):
c2f47e15 10122 if (validate_arg (arg0, REAL_TYPE))
10123 return do_mpfr_arg1 (arg0, type, mpfr_sinh, NULL, NULL, 0);
728bac60 10124 break;
10125
10126 CASE_FLT_FN (BUILT_IN_COSH):
389dd41b 10127 return fold_builtin_cosh (loc, arg0, type, fndecl);
728bac60 10128
10129 CASE_FLT_FN (BUILT_IN_TANH):
c2f47e15 10130 if (validate_arg (arg0, REAL_TYPE))
10131 return do_mpfr_arg1 (arg0, type, mpfr_tanh, NULL, NULL, 0);
728bac60 10132 break;
10133
29f4cd78 10134 CASE_FLT_FN (BUILT_IN_ERF):
c2f47e15 10135 if (validate_arg (arg0, REAL_TYPE))
10136 return do_mpfr_arg1 (arg0, type, mpfr_erf, NULL, NULL, 0);
29f4cd78 10137 break;
10138
10139 CASE_FLT_FN (BUILT_IN_ERFC):
c2f47e15 10140 if (validate_arg (arg0, REAL_TYPE))
10141 return do_mpfr_arg1 (arg0, type, mpfr_erfc, NULL, NULL, 0);
29f4cd78 10142 break;
10143
32dba52b 10144 CASE_FLT_FN (BUILT_IN_TGAMMA):
c2f47e15 10145 if (validate_arg (arg0, REAL_TYPE))
10146 return do_mpfr_arg1 (arg0, type, mpfr_gamma, NULL, NULL, 0);
32dba52b 10147 break;
10148
4f35b1fc 10149 CASE_FLT_FN (BUILT_IN_EXP):
389dd41b 10150 return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp);
467214fd 10151
4f35b1fc 10152 CASE_FLT_FN (BUILT_IN_EXP2):
389dd41b 10153 return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp2);
467214fd 10154
4f35b1fc 10155 CASE_FLT_FN (BUILT_IN_EXP10):
10156 CASE_FLT_FN (BUILT_IN_POW10):
389dd41b 10157 return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp10);
467214fd 10158
29f4cd78 10159 CASE_FLT_FN (BUILT_IN_EXPM1):
c2f47e15 10160 if (validate_arg (arg0, REAL_TYPE))
10161 return do_mpfr_arg1 (arg0, type, mpfr_expm1, NULL, NULL, 0);
29f4cd78 10162 break;
10163
4f35b1fc 10164 CASE_FLT_FN (BUILT_IN_LOG):
389dd41b 10165 return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log);
467214fd 10166
4f35b1fc 10167 CASE_FLT_FN (BUILT_IN_LOG2):
389dd41b 10168 return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log2);
467214fd 10169
4f35b1fc 10170 CASE_FLT_FN (BUILT_IN_LOG10):
389dd41b 10171 return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log10);
29f4cd78 10172
10173 CASE_FLT_FN (BUILT_IN_LOG1P):
c2f47e15 10174 if (validate_arg (arg0, REAL_TYPE))
10175 return do_mpfr_arg1 (arg0, type, mpfr_log1p,
29f4cd78 10176 &dconstm1, NULL, false);
10177 break;
805e22b2 10178
65dd1378 10179 CASE_FLT_FN (BUILT_IN_J0):
10180 if (validate_arg (arg0, REAL_TYPE))
10181 return do_mpfr_arg1 (arg0, type, mpfr_j0,
10182 NULL, NULL, 0);
10183 break;
10184
10185 CASE_FLT_FN (BUILT_IN_J1):
10186 if (validate_arg (arg0, REAL_TYPE))
10187 return do_mpfr_arg1 (arg0, type, mpfr_j1,
10188 NULL, NULL, 0);
10189 break;
6ff9eeff 10190
10191 CASE_FLT_FN (BUILT_IN_Y0):
10192 if (validate_arg (arg0, REAL_TYPE))
10193 return do_mpfr_arg1 (arg0, type, mpfr_y0,
10194 &dconst0, NULL, false);
10195 break;
10196
10197 CASE_FLT_FN (BUILT_IN_Y1):
10198 if (validate_arg (arg0, REAL_TYPE))
10199 return do_mpfr_arg1 (arg0, type, mpfr_y1,
10200 &dconst0, NULL, false);
10201 break;
65dd1378 10202
4f35b1fc 10203 CASE_FLT_FN (BUILT_IN_NAN):
c4503c0a 10204 case BUILT_IN_NAND32:
10205 case BUILT_IN_NAND64:
10206 case BUILT_IN_NAND128:
c2f47e15 10207 return fold_builtin_nan (arg0, type, true);
b0db7939 10208
4f35b1fc 10209 CASE_FLT_FN (BUILT_IN_NANS):
c2f47e15 10210 return fold_builtin_nan (arg0, type, false);
b0db7939 10211
4f35b1fc 10212 CASE_FLT_FN (BUILT_IN_FLOOR):
389dd41b 10213 return fold_builtin_floor (loc, fndecl, arg0);
277f8dd2 10214
4f35b1fc 10215 CASE_FLT_FN (BUILT_IN_CEIL):
389dd41b 10216 return fold_builtin_ceil (loc, fndecl, arg0);
277f8dd2 10217
4f35b1fc 10218 CASE_FLT_FN (BUILT_IN_TRUNC):
389dd41b 10219 return fold_builtin_trunc (loc, fndecl, arg0);
277f8dd2 10220
4f35b1fc 10221 CASE_FLT_FN (BUILT_IN_ROUND):
389dd41b 10222 return fold_builtin_round (loc, fndecl, arg0);
89ab3887 10223
4f35b1fc 10224 CASE_FLT_FN (BUILT_IN_NEARBYINT):
10225 CASE_FLT_FN (BUILT_IN_RINT):
389dd41b 10226 return fold_trunc_transparent_mathfn (loc, fndecl, arg0);
6528f4f4 10227
4f35b1fc 10228 CASE_FLT_FN (BUILT_IN_LCEIL):
10229 CASE_FLT_FN (BUILT_IN_LLCEIL):
10230 CASE_FLT_FN (BUILT_IN_LFLOOR):
10231 CASE_FLT_FN (BUILT_IN_LLFLOOR):
a0c938f0 10232 CASE_FLT_FN (BUILT_IN_LROUND):
4f35b1fc 10233 CASE_FLT_FN (BUILT_IN_LLROUND):
389dd41b 10234 return fold_builtin_int_roundingfn (loc, fndecl, arg0);
34f17811 10235
4f35b1fc 10236 CASE_FLT_FN (BUILT_IN_LRINT):
10237 CASE_FLT_FN (BUILT_IN_LLRINT):
389dd41b 10238 return fold_fixed_mathfn (loc, fndecl, arg0);
9ed65c7f 10239
42791117 10240 case BUILT_IN_BSWAP32:
10241 case BUILT_IN_BSWAP64:
c2f47e15 10242 return fold_builtin_bswap (fndecl, arg0);
42791117 10243
4f35b1fc 10244 CASE_INT_FN (BUILT_IN_FFS):
10245 CASE_INT_FN (BUILT_IN_CLZ):
10246 CASE_INT_FN (BUILT_IN_CTZ):
10247 CASE_INT_FN (BUILT_IN_POPCOUNT):
10248 CASE_INT_FN (BUILT_IN_PARITY):
c2f47e15 10249 return fold_builtin_bitop (fndecl, arg0);
9c8a1629 10250
4f35b1fc 10251 CASE_FLT_FN (BUILT_IN_SIGNBIT):
389dd41b 10252 return fold_builtin_signbit (loc, arg0, type);
27f261ef 10253
cb2b9385 10254 CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
389dd41b 10255 return fold_builtin_significand (loc, arg0, type);
cb2b9385 10256
10257 CASE_FLT_FN (BUILT_IN_ILOGB):
10258 CASE_FLT_FN (BUILT_IN_LOGB):
389dd41b 10259 return fold_builtin_logb (loc, arg0, type);
cb2b9385 10260
d49367d4 10261 case BUILT_IN_ISASCII:
389dd41b 10262 return fold_builtin_isascii (loc, arg0);
d49367d4 10263
10264 case BUILT_IN_TOASCII:
389dd41b 10265 return fold_builtin_toascii (loc, arg0);
d49367d4 10266
df1cf42e 10267 case BUILT_IN_ISDIGIT:
389dd41b 10268 return fold_builtin_isdigit (loc, arg0);
467214fd 10269
4f35b1fc 10270 CASE_FLT_FN (BUILT_IN_FINITE):
c4503c0a 10271 case BUILT_IN_FINITED32:
10272 case BUILT_IN_FINITED64:
10273 case BUILT_IN_FINITED128:
cde061c1 10274 case BUILT_IN_ISFINITE:
a65c4d64 10275 {
10276 tree ret = fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISFINITE);
10277 if (ret)
10278 return ret;
10279 return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10280 }
726069ba 10281
4f35b1fc 10282 CASE_FLT_FN (BUILT_IN_ISINF):
c4503c0a 10283 case BUILT_IN_ISINFD32:
10284 case BUILT_IN_ISINFD64:
10285 case BUILT_IN_ISINFD128:
a65c4d64 10286 {
10287 tree ret = fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF);
10288 if (ret)
10289 return ret;
10290 return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10291 }
10292
10293 case BUILT_IN_ISNORMAL:
10294 return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
726069ba 10295
c319d56a 10296 case BUILT_IN_ISINF_SIGN:
389dd41b 10297 return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF_SIGN);
c319d56a 10298
4f35b1fc 10299 CASE_FLT_FN (BUILT_IN_ISNAN):
c4503c0a 10300 case BUILT_IN_ISNAND32:
10301 case BUILT_IN_ISNAND64:
10302 case BUILT_IN_ISNAND128:
389dd41b 10303 return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISNAN);
c2f47e15 10304
10305 case BUILT_IN_PRINTF:
10306 case BUILT_IN_PRINTF_UNLOCKED:
10307 case BUILT_IN_VPRINTF:
389dd41b 10308 return fold_builtin_printf (loc, fndecl, arg0, NULL_TREE, ignore, fcode);
c2f47e15 10309
10310 default:
10311 break;
10312 }
10313
10314 return NULL_TREE;
10315
10316}
10317
10318/* Fold a call to built-in function FNDECL with 2 arguments, ARG0 and ARG1.
10319 IGNORE is true if the result of the function call is ignored. This
10320 function returns NULL_TREE if no simplification was possible. */
10321
10322static tree
389dd41b 10323fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1, bool ignore)
c2f47e15 10324{
10325 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10326 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10327
10328 switch (fcode)
10329 {
65dd1378 10330 CASE_FLT_FN (BUILT_IN_JN):
10331 if (validate_arg (arg0, INTEGER_TYPE)
10332 && validate_arg (arg1, REAL_TYPE))
10333 return do_mpfr_bessel_n (arg0, arg1, type, mpfr_jn, NULL, 0);
10334 break;
6ff9eeff 10335
10336 CASE_FLT_FN (BUILT_IN_YN):
10337 if (validate_arg (arg0, INTEGER_TYPE)
10338 && validate_arg (arg1, REAL_TYPE))
10339 return do_mpfr_bessel_n (arg0, arg1, type, mpfr_yn,
10340 &dconst0, false);
10341 break;
e5407ca6 10342
10343 CASE_FLT_FN (BUILT_IN_DREM):
10344 CASE_FLT_FN (BUILT_IN_REMAINDER):
10345 if (validate_arg (arg0, REAL_TYPE)
10346 && validate_arg(arg1, REAL_TYPE))
10347 return do_mpfr_arg2 (arg0, arg1, type, mpfr_remainder);
10348 break;
e84da7c1 10349
10350 CASE_FLT_FN_REENT (BUILT_IN_GAMMA): /* GAMMA_R */
10351 CASE_FLT_FN_REENT (BUILT_IN_LGAMMA): /* LGAMMA_R */
10352 if (validate_arg (arg0, REAL_TYPE)
10353 && validate_arg(arg1, POINTER_TYPE))
10354 return do_mpfr_lgamma_r (arg0, arg1, type);
10355 break;
c2f47e15 10356
10357 CASE_FLT_FN (BUILT_IN_ATAN2):
10358 if (validate_arg (arg0, REAL_TYPE)
10359 && validate_arg(arg1, REAL_TYPE))
10360 return do_mpfr_arg2 (arg0, arg1, type, mpfr_atan2);
10361 break;
10362
10363 CASE_FLT_FN (BUILT_IN_FDIM):
10364 if (validate_arg (arg0, REAL_TYPE)
10365 && validate_arg(arg1, REAL_TYPE))
10366 return do_mpfr_arg2 (arg0, arg1, type, mpfr_dim);
10367 break;
10368
10369 CASE_FLT_FN (BUILT_IN_HYPOT):
389dd41b 10370 return fold_builtin_hypot (loc, fndecl, arg0, arg1, type);
c2f47e15 10371
c699fab8 10372#ifdef HAVE_mpc_pow
10373 CASE_FLT_FN (BUILT_IN_CPOW):
10374 if (validate_arg (arg0, COMPLEX_TYPE)
10375 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
10376 && validate_arg (arg1, COMPLEX_TYPE)
10377 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE)
652d9409 10378 return do_mpc_arg2 (arg0, arg1, type, /*do_nonfinite=*/ 0, mpc_pow);
c699fab8 10379 break;
10380#endif
10381
7587301b 10382 CASE_FLT_FN (BUILT_IN_LDEXP):
389dd41b 10383 return fold_builtin_load_exponent (loc, arg0, arg1, type, /*ldexp=*/true);
7587301b 10384 CASE_FLT_FN (BUILT_IN_SCALBN):
10385 CASE_FLT_FN (BUILT_IN_SCALBLN):
389dd41b 10386 return fold_builtin_load_exponent (loc, arg0, arg1,
10387 type, /*ldexp=*/false);
7587301b 10388
3838b9ae 10389 CASE_FLT_FN (BUILT_IN_FREXP):
389dd41b 10390 return fold_builtin_frexp (loc, arg0, arg1, type);
3838b9ae 10391
ebf8b4f5 10392 CASE_FLT_FN (BUILT_IN_MODF):
389dd41b 10393 return fold_builtin_modf (loc, arg0, arg1, type);
ebf8b4f5 10394
c2f47e15 10395 case BUILT_IN_BZERO:
389dd41b 10396 return fold_builtin_bzero (loc, arg0, arg1, ignore);
c2f47e15 10397
10398 case BUILT_IN_FPUTS:
389dd41b 10399 return fold_builtin_fputs (loc, arg0, arg1, ignore, false, NULL_TREE);
c2f47e15 10400
10401 case BUILT_IN_FPUTS_UNLOCKED:
389dd41b 10402 return fold_builtin_fputs (loc, arg0, arg1, ignore, true, NULL_TREE);
c2f47e15 10403
10404 case BUILT_IN_STRSTR:
389dd41b 10405 return fold_builtin_strstr (loc, arg0, arg1, type);
c2f47e15 10406
10407 case BUILT_IN_STRCAT:
389dd41b 10408 return fold_builtin_strcat (loc, arg0, arg1);
c2f47e15 10409
10410 case BUILT_IN_STRSPN:
389dd41b 10411 return fold_builtin_strspn (loc, arg0, arg1);
c2f47e15 10412
10413 case BUILT_IN_STRCSPN:
389dd41b 10414 return fold_builtin_strcspn (loc, arg0, arg1);
c2f47e15 10415
10416 case BUILT_IN_STRCHR:
10417 case BUILT_IN_INDEX:
389dd41b 10418 return fold_builtin_strchr (loc, arg0, arg1, type);
c2f47e15 10419
10420 case BUILT_IN_STRRCHR:
10421 case BUILT_IN_RINDEX:
389dd41b 10422 return fold_builtin_strrchr (loc, arg0, arg1, type);
c2f47e15 10423
10424 case BUILT_IN_STRCPY:
389dd41b 10425 return fold_builtin_strcpy (loc, fndecl, arg0, arg1, NULL_TREE);
c2f47e15 10426
c8b17b2e 10427 case BUILT_IN_STPCPY:
10428 if (ignore)
10429 {
10430 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10431 if (!fn)
10432 break;
10433
389dd41b 10434 return build_call_expr_loc (loc, fn, 2, arg0, arg1);
c8b17b2e 10435 }
a65c4d64 10436 else
10437 return fold_builtin_stpcpy (loc, fndecl, arg0, arg1);
c8b17b2e 10438 break;
10439
c2f47e15 10440 case BUILT_IN_STRCMP:
389dd41b 10441 return fold_builtin_strcmp (loc, arg0, arg1);
c2f47e15 10442
10443 case BUILT_IN_STRPBRK:
389dd41b 10444 return fold_builtin_strpbrk (loc, arg0, arg1, type);
c2f47e15 10445
10446 case BUILT_IN_EXPECT:
389dd41b 10447 return fold_builtin_expect (loc, arg0, arg1);
c2f47e15 10448
10449 CASE_FLT_FN (BUILT_IN_POW):
389dd41b 10450 return fold_builtin_pow (loc, fndecl, arg0, arg1, type);
c2f47e15 10451
10452 CASE_FLT_FN (BUILT_IN_POWI):
389dd41b 10453 return fold_builtin_powi (loc, fndecl, arg0, arg1, type);
c2f47e15 10454
10455 CASE_FLT_FN (BUILT_IN_COPYSIGN):
389dd41b 10456 return fold_builtin_copysign (loc, fndecl, arg0, arg1, type);
c2f47e15 10457
10458 CASE_FLT_FN (BUILT_IN_FMIN):
389dd41b 10459 return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/false);
c2f47e15 10460
10461 CASE_FLT_FN (BUILT_IN_FMAX):
389dd41b 10462 return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/true);
726069ba 10463
9bc9f15f 10464 case BUILT_IN_ISGREATER:
389dd41b 10465 return fold_builtin_unordered_cmp (loc, fndecl,
10466 arg0, arg1, UNLE_EXPR, LE_EXPR);
9bc9f15f 10467 case BUILT_IN_ISGREATEREQUAL:
389dd41b 10468 return fold_builtin_unordered_cmp (loc, fndecl,
10469 arg0, arg1, UNLT_EXPR, LT_EXPR);
9bc9f15f 10470 case BUILT_IN_ISLESS:
389dd41b 10471 return fold_builtin_unordered_cmp (loc, fndecl,
10472 arg0, arg1, UNGE_EXPR, GE_EXPR);
9bc9f15f 10473 case BUILT_IN_ISLESSEQUAL:
389dd41b 10474 return fold_builtin_unordered_cmp (loc, fndecl,
10475 arg0, arg1, UNGT_EXPR, GT_EXPR);
9bc9f15f 10476 case BUILT_IN_ISLESSGREATER:
389dd41b 10477 return fold_builtin_unordered_cmp (loc, fndecl,
10478 arg0, arg1, UNEQ_EXPR, EQ_EXPR);
9bc9f15f 10479 case BUILT_IN_ISUNORDERED:
389dd41b 10480 return fold_builtin_unordered_cmp (loc, fndecl,
10481 arg0, arg1, UNORDERED_EXPR,
d5019fe8 10482 NOP_EXPR);
9bc9f15f 10483
7c2f0500 10484 /* We do the folding for va_start in the expander. */
10485 case BUILT_IN_VA_START:
10486 break;
f0613857 10487
c2f47e15 10488 case BUILT_IN_SPRINTF:
389dd41b 10489 return fold_builtin_sprintf (loc, arg0, arg1, NULL_TREE, ignore);
c2f47e15 10490
0a39fd54 10491 case BUILT_IN_OBJECT_SIZE:
c2f47e15 10492 return fold_builtin_object_size (arg0, arg1);
0a39fd54 10493
10494 case BUILT_IN_PRINTF:
10495 case BUILT_IN_PRINTF_UNLOCKED:
10496 case BUILT_IN_VPRINTF:
389dd41b 10497 return fold_builtin_printf (loc, fndecl, arg0, arg1, ignore, fcode);
c2f47e15 10498
0a39fd54 10499 case BUILT_IN_PRINTF_CHK:
10500 case BUILT_IN_VPRINTF_CHK:
c2f47e15 10501 if (!validate_arg (arg0, INTEGER_TYPE)
10502 || TREE_SIDE_EFFECTS (arg0))
10503 return NULL_TREE;
10504 else
389dd41b 10505 return fold_builtin_printf (loc, fndecl,
10506 arg1, NULL_TREE, ignore, fcode);
c2f47e15 10507 break;
0a39fd54 10508
10509 case BUILT_IN_FPRINTF:
10510 case BUILT_IN_FPRINTF_UNLOCKED:
10511 case BUILT_IN_VFPRINTF:
389dd41b 10512 return fold_builtin_fprintf (loc, fndecl, arg0, arg1, NULL_TREE,
c2f47e15 10513 ignore, fcode);
10514
10515 default:
10516 break;
10517 }
10518 return NULL_TREE;
10519}
10520
10521/* Fold a call to built-in function FNDECL with 3 arguments, ARG0, ARG1,
10522 and ARG2. IGNORE is true if the result of the function call is ignored.
10523 This function returns NULL_TREE if no simplification was possible. */
10524
10525static tree
389dd41b 10526fold_builtin_3 (location_t loc, tree fndecl,
10527 tree arg0, tree arg1, tree arg2, bool ignore)
c2f47e15 10528{
10529 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10530 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10531 switch (fcode)
10532 {
10533
10534 CASE_FLT_FN (BUILT_IN_SINCOS):
389dd41b 10535 return fold_builtin_sincos (loc, arg0, arg1, arg2);
c2f47e15 10536
10537 CASE_FLT_FN (BUILT_IN_FMA):
10538 if (validate_arg (arg0, REAL_TYPE)
10539 && validate_arg(arg1, REAL_TYPE)
10540 && validate_arg(arg2, REAL_TYPE))
10541 return do_mpfr_arg3 (arg0, arg1, arg2, type, mpfr_fma);
10542 break;
10543
e5407ca6 10544 CASE_FLT_FN (BUILT_IN_REMQUO):
10545 if (validate_arg (arg0, REAL_TYPE)
10546 && validate_arg(arg1, REAL_TYPE)
10547 && validate_arg(arg2, POINTER_TYPE))
10548 return do_mpfr_remquo (arg0, arg1, arg2);
10549 break;
e5407ca6 10550
c2f47e15 10551 case BUILT_IN_MEMSET:
389dd41b 10552 return fold_builtin_memset (loc, arg0, arg1, arg2, type, ignore);
c2f47e15 10553
10554 case BUILT_IN_BCOPY:
389dd41b 10555 return fold_builtin_memory_op (loc, arg1, arg0, arg2,
10556 void_type_node, true, /*endp=*/3);
c2f47e15 10557
10558 case BUILT_IN_MEMCPY:
389dd41b 10559 return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10560 type, ignore, /*endp=*/0);
c2f47e15 10561
10562 case BUILT_IN_MEMPCPY:
389dd41b 10563 return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10564 type, ignore, /*endp=*/1);
c2f47e15 10565
10566 case BUILT_IN_MEMMOVE:
389dd41b 10567 return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10568 type, ignore, /*endp=*/3);
c2f47e15 10569
10570 case BUILT_IN_STRNCAT:
389dd41b 10571 return fold_builtin_strncat (loc, arg0, arg1, arg2);
c2f47e15 10572
10573 case BUILT_IN_STRNCPY:
389dd41b 10574 return fold_builtin_strncpy (loc, fndecl, arg0, arg1, arg2, NULL_TREE);
c2f47e15 10575
10576 case BUILT_IN_STRNCMP:
389dd41b 10577 return fold_builtin_strncmp (loc, arg0, arg1, arg2);
c2f47e15 10578
7959b13b 10579 case BUILT_IN_MEMCHR:
389dd41b 10580 return fold_builtin_memchr (loc, arg0, arg1, arg2, type);
7959b13b 10581
c2f47e15 10582 case BUILT_IN_BCMP:
10583 case BUILT_IN_MEMCMP:
389dd41b 10584 return fold_builtin_memcmp (loc, arg0, arg1, arg2);;
c2f47e15 10585
10586 case BUILT_IN_SPRINTF:
389dd41b 10587 return fold_builtin_sprintf (loc, arg0, arg1, arg2, ignore);
c2f47e15 10588
10589 case BUILT_IN_STRCPY_CHK:
10590 case BUILT_IN_STPCPY_CHK:
389dd41b 10591 return fold_builtin_stxcpy_chk (loc, fndecl, arg0, arg1, arg2, NULL_TREE,
c2f47e15 10592 ignore, fcode);
10593
10594 case BUILT_IN_STRCAT_CHK:
389dd41b 10595 return fold_builtin_strcat_chk (loc, fndecl, arg0, arg1, arg2);
c2f47e15 10596
10597 case BUILT_IN_PRINTF_CHK:
10598 case BUILT_IN_VPRINTF_CHK:
10599 if (!validate_arg (arg0, INTEGER_TYPE)
10600 || TREE_SIDE_EFFECTS (arg0))
10601 return NULL_TREE;
10602 else
389dd41b 10603 return fold_builtin_printf (loc, fndecl, arg1, arg2, ignore, fcode);
c2f47e15 10604 break;
10605
10606 case BUILT_IN_FPRINTF:
10607 case BUILT_IN_FPRINTF_UNLOCKED:
10608 case BUILT_IN_VFPRINTF:
389dd41b 10609 return fold_builtin_fprintf (loc, fndecl, arg0, arg1, arg2,
10610 ignore, fcode);
c2f47e15 10611
0a39fd54 10612 case BUILT_IN_FPRINTF_CHK:
10613 case BUILT_IN_VFPRINTF_CHK:
c2f47e15 10614 if (!validate_arg (arg1, INTEGER_TYPE)
10615 || TREE_SIDE_EFFECTS (arg1))
10616 return NULL_TREE;
10617 else
389dd41b 10618 return fold_builtin_fprintf (loc, fndecl, arg0, arg2, NULL_TREE,
c2f47e15 10619 ignore, fcode);
0a39fd54 10620
650e4c94 10621 default:
10622 break;
10623 }
c2f47e15 10624 return NULL_TREE;
10625}
650e4c94 10626
c2f47e15 10627/* Fold a call to built-in function FNDECL with 4 arguments, ARG0, ARG1,
10628 ARG2, and ARG3. IGNORE is true if the result of the function call is
10629 ignored. This function returns NULL_TREE if no simplification was
10630 possible. */
10631
10632static tree
389dd41b 10633fold_builtin_4 (location_t loc, tree fndecl,
10634 tree arg0, tree arg1, tree arg2, tree arg3, bool ignore)
c2f47e15 10635{
10636 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10637
10638 switch (fcode)
10639 {
10640 case BUILT_IN_MEMCPY_CHK:
10641 case BUILT_IN_MEMPCPY_CHK:
10642 case BUILT_IN_MEMMOVE_CHK:
10643 case BUILT_IN_MEMSET_CHK:
389dd41b 10644 return fold_builtin_memory_chk (loc, fndecl, arg0, arg1, arg2, arg3,
c2f47e15 10645 NULL_TREE, ignore,
10646 DECL_FUNCTION_CODE (fndecl));
10647
10648 case BUILT_IN_STRNCPY_CHK:
389dd41b 10649 return fold_builtin_strncpy_chk (loc, arg0, arg1, arg2, arg3, NULL_TREE);
c2f47e15 10650
10651 case BUILT_IN_STRNCAT_CHK:
389dd41b 10652 return fold_builtin_strncat_chk (loc, fndecl, arg0, arg1, arg2, arg3);
c2f47e15 10653
10654 case BUILT_IN_FPRINTF_CHK:
10655 case BUILT_IN_VFPRINTF_CHK:
10656 if (!validate_arg (arg1, INTEGER_TYPE)
10657 || TREE_SIDE_EFFECTS (arg1))
10658 return NULL_TREE;
10659 else
389dd41b 10660 return fold_builtin_fprintf (loc, fndecl, arg0, arg2, arg3,
c2f47e15 10661 ignore, fcode);
10662 break;
10663
10664 default:
10665 break;
10666 }
10667 return NULL_TREE;
10668}
10669
10670/* Fold a call to built-in function FNDECL. ARGS is an array of NARGS
10671 arguments, where NARGS <= 4. IGNORE is true if the result of the
10672 function call is ignored. This function returns NULL_TREE if no
10673 simplification was possible. Note that this only folds builtins with
10674 fixed argument patterns. Foldings that do varargs-to-varargs
10675 transformations, or that match calls with more than 4 arguments,
10676 need to be handled with fold_builtin_varargs instead. */
10677
10678#define MAX_ARGS_TO_FOLD_BUILTIN 4
10679
10680static tree
389dd41b 10681fold_builtin_n (location_t loc, tree fndecl, tree *args, int nargs, bool ignore)
c2f47e15 10682{
10683 tree ret = NULL_TREE;
a7f5bb2d 10684
c2f47e15 10685 switch (nargs)
10686 {
10687 case 0:
389dd41b 10688 ret = fold_builtin_0 (loc, fndecl, ignore);
c2f47e15 10689 break;
10690 case 1:
389dd41b 10691 ret = fold_builtin_1 (loc, fndecl, args[0], ignore);
c2f47e15 10692 break;
10693 case 2:
389dd41b 10694 ret = fold_builtin_2 (loc, fndecl, args[0], args[1], ignore);
c2f47e15 10695 break;
10696 case 3:
389dd41b 10697 ret = fold_builtin_3 (loc, fndecl, args[0], args[1], args[2], ignore);
c2f47e15 10698 break;
10699 case 4:
389dd41b 10700 ret = fold_builtin_4 (loc, fndecl, args[0], args[1], args[2], args[3],
c2f47e15 10701 ignore);
10702 break;
10703 default:
10704 break;
10705 }
10706 if (ret)
10707 {
75a70cf9 10708 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
389dd41b 10709 SET_EXPR_LOCATION (ret, loc);
c2f47e15 10710 TREE_NO_WARNING (ret) = 1;
10711 return ret;
10712 }
10713 return NULL_TREE;
10714}
10715
10716/* Builtins with folding operations that operate on "..." arguments
10717 need special handling; we need to store the arguments in a convenient
10718 data structure before attempting any folding. Fortunately there are
10719 only a few builtins that fall into this category. FNDECL is the
10720 function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
10721 result of the function call is ignored. */
10722
10723static tree
389dd41b 10724fold_builtin_varargs (location_t loc, tree fndecl, tree exp,
10725 bool ignore ATTRIBUTE_UNUSED)
c2f47e15 10726{
10727 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10728 tree ret = NULL_TREE;
10729
10730 switch (fcode)
10731 {
10732 case BUILT_IN_SPRINTF_CHK:
10733 case BUILT_IN_VSPRINTF_CHK:
389dd41b 10734 ret = fold_builtin_sprintf_chk (loc, exp, fcode);
c2f47e15 10735 break;
10736
10737 case BUILT_IN_SNPRINTF_CHK:
10738 case BUILT_IN_VSNPRINTF_CHK:
389dd41b 10739 ret = fold_builtin_snprintf_chk (loc, exp, NULL_TREE, fcode);
19fbe3a4 10740 break;
10741
10742 case BUILT_IN_FPCLASSIFY:
389dd41b 10743 ret = fold_builtin_fpclassify (loc, exp);
19fbe3a4 10744 break;
c2f47e15 10745
10746 default:
10747 break;
10748 }
10749 if (ret)
10750 {
10751 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
389dd41b 10752 SET_EXPR_LOCATION (ret, loc);
c2f47e15 10753 TREE_NO_WARNING (ret) = 1;
10754 return ret;
10755 }
10756 return NULL_TREE;
650e4c94 10757}
7e15618b 10758
198622c0 10759/* Return true if FNDECL shouldn't be folded right now.
10760 If a built-in function has an inline attribute always_inline
10761 wrapper, defer folding it after always_inline functions have
10762 been inlined, otherwise e.g. -D_FORTIFY_SOURCE checking
10763 might not be performed. */
10764
10765static bool
10766avoid_folding_inline_builtin (tree fndecl)
10767{
10768 return (DECL_DECLARED_INLINE_P (fndecl)
10769 && DECL_DISREGARD_INLINE_LIMITS (fndecl)
10770 && cfun
10771 && !cfun->always_inline_functions_inlined
10772 && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fndecl)));
10773}
10774
4ee9c684 10775/* A wrapper function for builtin folding that prevents warnings for
491e04ef 10776 "statement without effect" and the like, caused by removing the
4ee9c684 10777 call node earlier than the warning is generated. */
10778
10779tree
389dd41b 10780fold_call_expr (location_t loc, tree exp, bool ignore)
4ee9c684 10781{
c2f47e15 10782 tree ret = NULL_TREE;
10783 tree fndecl = get_callee_fndecl (exp);
10784 if (fndecl
10785 && TREE_CODE (fndecl) == FUNCTION_DECL
48dc2227 10786 && DECL_BUILT_IN (fndecl)
10787 /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized
10788 yet. Defer folding until we see all the arguments
10789 (after inlining). */
10790 && !CALL_EXPR_VA_ARG_PACK (exp))
10791 {
10792 int nargs = call_expr_nargs (exp);
10793
10794 /* Before gimplification CALL_EXPR_VA_ARG_PACK is not set, but
10795 instead last argument is __builtin_va_arg_pack (). Defer folding
10796 even in that case, until arguments are finalized. */
10797 if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR)
10798 {
10799 tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1));
10800 if (fndecl2
10801 && TREE_CODE (fndecl2) == FUNCTION_DECL
10802 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
10803 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
10804 return NULL_TREE;
10805 }
10806
198622c0 10807 if (avoid_folding_inline_builtin (fndecl))
10808 return NULL_TREE;
10809
c2f47e15 10810 /* FIXME: Don't use a list in this interface. */
10811 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
10812 return targetm.fold_builtin (fndecl, CALL_EXPR_ARGS (exp), ignore);
10813 else
10814 {
c2f47e15 10815 if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
10816 {
10817 tree *args = CALL_EXPR_ARGP (exp);
389dd41b 10818 ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
c2f47e15 10819 }
10820 if (!ret)
389dd41b 10821 ret = fold_builtin_varargs (loc, fndecl, exp, ignore);
c2f47e15 10822 if (ret)
389dd41b 10823 return ret;
c2f47e15 10824 }
4ee9c684 10825 }
c2f47e15 10826 return NULL_TREE;
10827}
10828
10829/* Conveniently construct a function call expression. FNDECL names the
10830 function to be called and ARGLIST is a TREE_LIST of arguments. */
10831
10832tree
389dd41b 10833build_function_call_expr (location_t loc, tree fndecl, tree arglist)
c2f47e15 10834{
10835 tree fntype = TREE_TYPE (fndecl);
10836 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
d01f58f9 10837 int n = list_length (arglist);
10838 tree *argarray = (tree *) alloca (n * sizeof (tree));
10839 int i;
389dd41b 10840
d01f58f9 10841 for (i = 0; i < n; i++, arglist = TREE_CHAIN (arglist))
10842 argarray[i] = TREE_VALUE (arglist);
389dd41b 10843 return fold_builtin_call_array (loc, TREE_TYPE (fntype), fn, n, argarray);
c2f47e15 10844}
10845
10846/* Conveniently construct a function call expression. FNDECL names the
10847 function to be called, N is the number of arguments, and the "..."
10848 parameters are the argument expressions. */
10849
10850tree
389dd41b 10851build_call_expr_loc (location_t loc, tree fndecl, int n, ...)
c2f47e15 10852{
10853 va_list ap;
c2f47e15 10854 tree fntype = TREE_TYPE (fndecl);
10855 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
d01f58f9 10856 tree *argarray = (tree *) alloca (n * sizeof (tree));
10857 int i;
c2f47e15 10858
10859 va_start (ap, n);
d01f58f9 10860 for (i = 0; i < n; i++)
10861 argarray[i] = va_arg (ap, tree);
c2f47e15 10862 va_end (ap);
389dd41b 10863 return fold_builtin_call_array (loc, TREE_TYPE (fntype), fn, n, argarray);
4ee9c684 10864}
10865
c2f47e15 10866/* Construct a CALL_EXPR with type TYPE with FN as the function expression.
d01f58f9 10867 N arguments are passed in the array ARGARRAY. */
805e22b2 10868
10869tree
389dd41b 10870fold_builtin_call_array (location_t loc, tree type,
d01f58f9 10871 tree fn,
10872 int n,
10873 tree *argarray)
7e15618b 10874{
c2f47e15 10875 tree ret = NULL_TREE;
10876 int i;
10877 tree exp;
10878
10879 if (TREE_CODE (fn) == ADDR_EXPR)
10880 {
10881 tree fndecl = TREE_OPERAND (fn, 0);
10882 if (TREE_CODE (fndecl) == FUNCTION_DECL
10883 && DECL_BUILT_IN (fndecl))
10884 {
48dc2227 10885 /* If last argument is __builtin_va_arg_pack (), arguments to this
10886 function are not finalized yet. Defer folding until they are. */
10887 if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
10888 {
10889 tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
10890 if (fndecl2
10891 && TREE_CODE (fndecl2) == FUNCTION_DECL
10892 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
10893 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
389dd41b 10894 return build_call_array_loc (loc, type, fn, n, argarray);
48dc2227 10895 }
198622c0 10896 if (avoid_folding_inline_builtin (fndecl))
389dd41b 10897 return build_call_array_loc (loc, type, fn, n, argarray);
c2f47e15 10898 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
10899 {
10900 tree arglist = NULL_TREE;
d01f58f9 10901 for (i = n - 1; i >= 0; i--)
10902 arglist = tree_cons (NULL_TREE, argarray[i], arglist);
c2f47e15 10903 ret = targetm.fold_builtin (fndecl, arglist, false);
10904 if (ret)
10905 return ret;
389dd41b 10906 return build_call_array_loc (loc, type, fn, n, argarray);
c2f47e15 10907 }
10908 else if (n <= MAX_ARGS_TO_FOLD_BUILTIN)
10909 {
10910 /* First try the transformations that don't require consing up
10911 an exp. */
389dd41b 10912 ret = fold_builtin_n (loc, fndecl, argarray, n, false);
c2f47e15 10913 if (ret)
10914 return ret;
10915 }
10916
10917 /* If we got this far, we need to build an exp. */
389dd41b 10918 exp = build_call_array_loc (loc, type, fn, n, argarray);
10919 ret = fold_builtin_varargs (loc, fndecl, exp, false);
c2f47e15 10920 return ret ? ret : exp;
10921 }
10922 }
10923
389dd41b 10924 return build_call_array_loc (loc, type, fn, n, argarray);
c2f47e15 10925}
10926
10927/* Construct a new CALL_EXPR using the tail of the argument list of EXP
10928 along with N new arguments specified as the "..." parameters. SKIP
10929 is the number of arguments in EXP to be omitted. This function is used
10930 to do varargs-to-varargs transformations. */
10931
10932static tree
389dd41b 10933rewrite_call_expr (location_t loc, tree exp, int skip, tree fndecl, int n, ...)
c2f47e15 10934{
10935 int oldnargs = call_expr_nargs (exp);
10936 int nargs = oldnargs - skip + n;
10937 tree fntype = TREE_TYPE (fndecl);
10938 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
10939 tree *buffer;
10940
10941 if (n > 0)
10942 {
10943 int i, j;
10944 va_list ap;
7e15618b 10945
364c0c59 10946 buffer = XALLOCAVEC (tree, nargs);
c2f47e15 10947 va_start (ap, n);
10948 for (i = 0; i < n; i++)
10949 buffer[i] = va_arg (ap, tree);
10950 va_end (ap);
10951 for (j = skip; j < oldnargs; j++, i++)
10952 buffer[i] = CALL_EXPR_ARG (exp, j);
10953 }
10954 else
10955 buffer = CALL_EXPR_ARGP (exp) + skip;
10956
389dd41b 10957 return fold (build_call_array_loc (loc, TREE_TYPE (exp), fn, nargs, buffer));
c2f47e15 10958}
10959
10960/* Validate a single argument ARG against a tree code CODE representing
10961 a type. */
10962
10963static bool
b7bf20db 10964validate_arg (const_tree arg, enum tree_code code)
c2f47e15 10965{
10966 if (!arg)
10967 return false;
10968 else if (code == POINTER_TYPE)
10969 return POINTER_TYPE_P (TREE_TYPE (arg));
c7f617c2 10970 else if (code == INTEGER_TYPE)
10971 return INTEGRAL_TYPE_P (TREE_TYPE (arg));
c2f47e15 10972 return code == TREE_CODE (TREE_TYPE (arg));
7e15618b 10973}
0eb671f7 10974
75a70cf9 10975/* This function validates the types of a function call argument list
10976 against a specified list of tree_codes. If the last specifier is a 0,
10977 that represents an ellipses, otherwise the last specifier must be a
10978 VOID_TYPE.
10979
10980 This is the GIMPLE version of validate_arglist. Eventually we want to
10981 completely convert builtins.c to work from GIMPLEs and the tree based
10982 validate_arglist will then be removed. */
10983
10984bool
10985validate_gimple_arglist (const_gimple call, ...)
10986{
10987 enum tree_code code;
10988 bool res = 0;
10989 va_list ap;
10990 const_tree arg;
10991 size_t i;
10992
10993 va_start (ap, call);
10994 i = 0;
10995
10996 do
10997 {
d62e827b 10998 code = (enum tree_code) va_arg (ap, int);
75a70cf9 10999 switch (code)
11000 {
11001 case 0:
11002 /* This signifies an ellipses, any further arguments are all ok. */
11003 res = true;
11004 goto end;
11005 case VOID_TYPE:
11006 /* This signifies an endlink, if no arguments remain, return
11007 true, otherwise return false. */
11008 res = (i == gimple_call_num_args (call));
11009 goto end;
11010 default:
11011 /* If no parameters remain or the parameter's code does not
11012 match the specified code, return false. Otherwise continue
11013 checking any remaining arguments. */
11014 arg = gimple_call_arg (call, i++);
11015 if (!validate_arg (arg, code))
11016 goto end;
11017 break;
11018 }
11019 }
11020 while (1);
11021
11022 /* We need gotos here since we can only have one VA_CLOSE in a
11023 function. */
11024 end: ;
11025 va_end (ap);
11026
11027 return res;
11028}
11029
0eb671f7 11030/* This function validates the types of a function call argument list
c2f47e15 11031 against a specified list of tree_codes. If the last specifier is a 0,
11032 that represents an ellipses, otherwise the last specifier must be a
11033 VOID_TYPE. */
27d0c333 11034
c2f47e15 11035bool
b7bf20db 11036validate_arglist (const_tree callexpr, ...)
0eb671f7 11037{
0eb671f7 11038 enum tree_code code;
c2f47e15 11039 bool res = 0;
ee582a61 11040 va_list ap;
b7bf20db 11041 const_call_expr_arg_iterator iter;
11042 const_tree arg;
aecda0d6 11043
c2f47e15 11044 va_start (ap, callexpr);
b7bf20db 11045 init_const_call_expr_arg_iterator (callexpr, &iter);
0eb671f7 11046
f0ce3b1f 11047 do
0eb671f7 11048 {
d62e827b 11049 code = (enum tree_code) va_arg (ap, int);
f0ce3b1f 11050 switch (code)
11051 {
11052 case 0:
11053 /* This signifies an ellipses, any further arguments are all ok. */
c2f47e15 11054 res = true;
f0ce3b1f 11055 goto end;
11056 case VOID_TYPE:
11057 /* This signifies an endlink, if no arguments remain, return
11058 true, otherwise return false. */
b7bf20db 11059 res = !more_const_call_expr_args_p (&iter);
f0ce3b1f 11060 goto end;
11061 default:
11062 /* If no parameters remain or the parameter's code does not
11063 match the specified code, return false. Otherwise continue
11064 checking any remaining arguments. */
b7bf20db 11065 arg = next_const_call_expr_arg (&iter);
c2f47e15 11066 if (!validate_arg (arg, code))
f0ce3b1f 11067 goto end;
11068 break;
11069 }
0eb671f7 11070 }
f0ce3b1f 11071 while (1);
0903457a 11072
11073 /* We need gotos here since we can only have one VA_CLOSE in a
11074 function. */
11075 end: ;
ee582a61 11076 va_end (ap);
0903457a 11077
11078 return res;
0eb671f7 11079}
fc2a2dcb 11080
fc2a2dcb 11081/* Default target-specific builtin expander that does nothing. */
11082
11083rtx
aecda0d6 11084default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
11085 rtx target ATTRIBUTE_UNUSED,
11086 rtx subtarget ATTRIBUTE_UNUSED,
11087 enum machine_mode mode ATTRIBUTE_UNUSED,
11088 int ignore ATTRIBUTE_UNUSED)
fc2a2dcb 11089{
11090 return NULL_RTX;
11091}
c7926a82 11092
01537105 11093/* Returns true is EXP represents data that would potentially reside
11094 in a readonly section. */
11095
11096static bool
11097readonly_data_expr (tree exp)
11098{
11099 STRIP_NOPS (exp);
11100
9ff0637e 11101 if (TREE_CODE (exp) != ADDR_EXPR)
11102 return false;
11103
11104 exp = get_base_address (TREE_OPERAND (exp, 0));
11105 if (!exp)
11106 return false;
11107
11108 /* Make sure we call decl_readonly_section only for trees it
11109 can handle (since it returns true for everything it doesn't
11110 understand). */
491e04ef 11111 if (TREE_CODE (exp) == STRING_CST
9ff0637e 11112 || TREE_CODE (exp) == CONSTRUCTOR
11113 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
11114 return decl_readonly_section (exp, 0);
01537105 11115 else
11116 return false;
11117}
4ee9c684 11118
c2f47e15 11119/* Simplify a call to the strstr builtin. S1 and S2 are the arguments
11120 to the call, and TYPE is its return type.
4ee9c684 11121
c2f47e15 11122 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11123 simplified form of the call as a tree.
11124
11125 The simplified form may be a constant or other expression which
11126 computes the same value, but in a more efficient manner (including
11127 calls to other builtin functions).
11128
11129 The call may contain arguments which need to be evaluated, but
11130 which are not useful to determine the result of the call. In
11131 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11132 COMPOUND_EXPR will be an argument which must be evaluated.
11133 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11134 COMPOUND_EXPR in the chain will contain the tree for the simplified
11135 form of the builtin function call. */
11136
11137static tree
389dd41b 11138fold_builtin_strstr (location_t loc, tree s1, tree s2, tree type)
4ee9c684 11139{
c2f47e15 11140 if (!validate_arg (s1, POINTER_TYPE)
11141 || !validate_arg (s2, POINTER_TYPE))
11142 return NULL_TREE;
4ee9c684 11143 else
11144 {
4ee9c684 11145 tree fn;
11146 const char *p1, *p2;
11147
11148 p2 = c_getstr (s2);
11149 if (p2 == NULL)
c2f47e15 11150 return NULL_TREE;
4ee9c684 11151
11152 p1 = c_getstr (s1);
11153 if (p1 != NULL)
11154 {
11155 const char *r = strstr (p1, p2);
daa1d5f5 11156 tree tem;
4ee9c684 11157
4ee9c684 11158 if (r == NULL)
779b4c41 11159 return build_int_cst (TREE_TYPE (s1), 0);
c0c67e38 11160
11161 /* Return an offset into the constant string argument. */
389dd41b 11162 tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (s1),
0de36bdb 11163 s1, size_int (r - p1));
389dd41b 11164 return fold_convert_loc (loc, type, tem);
4ee9c684 11165 }
11166
7efa231c 11167 /* The argument is const char *, and the result is char *, so we need
11168 a type conversion here to avoid a warning. */
4ee9c684 11169 if (p2[0] == '\0')
389dd41b 11170 return fold_convert_loc (loc, type, s1);
4ee9c684 11171
11172 if (p2[1] != '\0')
c2f47e15 11173 return NULL_TREE;
4ee9c684 11174
11175 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11176 if (!fn)
c2f47e15 11177 return NULL_TREE;
4ee9c684 11178
11179 /* New argument list transforming strstr(s1, s2) to
11180 strchr(s1, s2[0]). */
389dd41b 11181 return build_call_expr_loc (loc, fn, 2, s1, build_int_cst (NULL_TREE, p2[0]));
4ee9c684 11182 }
11183}
11184
c2f47e15 11185/* Simplify a call to the strchr builtin. S1 and S2 are the arguments to
11186 the call, and TYPE is its return type.
4ee9c684 11187
c2f47e15 11188 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11189 simplified form of the call as a tree.
11190
11191 The simplified form may be a constant or other expression which
11192 computes the same value, but in a more efficient manner (including
11193 calls to other builtin functions).
11194
11195 The call may contain arguments which need to be evaluated, but
11196 which are not useful to determine the result of the call. In
11197 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11198 COMPOUND_EXPR will be an argument which must be evaluated.
11199 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11200 COMPOUND_EXPR in the chain will contain the tree for the simplified
11201 form of the builtin function call. */
11202
11203static tree
389dd41b 11204fold_builtin_strchr (location_t loc, tree s1, tree s2, tree type)
4ee9c684 11205{
c2f47e15 11206 if (!validate_arg (s1, POINTER_TYPE)
11207 || !validate_arg (s2, INTEGER_TYPE))
11208 return NULL_TREE;
4ee9c684 11209 else
11210 {
4ee9c684 11211 const char *p1;
11212
11213 if (TREE_CODE (s2) != INTEGER_CST)
c2f47e15 11214 return NULL_TREE;
4ee9c684 11215
11216 p1 = c_getstr (s1);
11217 if (p1 != NULL)
11218 {
11219 char c;
11220 const char *r;
daa1d5f5 11221 tree tem;
4ee9c684 11222
11223 if (target_char_cast (s2, &c))
c2f47e15 11224 return NULL_TREE;
4ee9c684 11225
11226 r = strchr (p1, c);
11227
11228 if (r == NULL)
779b4c41 11229 return build_int_cst (TREE_TYPE (s1), 0);
4ee9c684 11230
11231 /* Return an offset into the constant string argument. */
389dd41b 11232 tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (s1),
0de36bdb 11233 s1, size_int (r - p1));
389dd41b 11234 return fold_convert_loc (loc, type, tem);
4ee9c684 11235 }
c2f47e15 11236 return NULL_TREE;
4ee9c684 11237 }
11238}
11239
c2f47e15 11240/* Simplify a call to the strrchr builtin. S1 and S2 are the arguments to
11241 the call, and TYPE is its return type.
4ee9c684 11242
c2f47e15 11243 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11244 simplified form of the call as a tree.
11245
11246 The simplified form may be a constant or other expression which
11247 computes the same value, but in a more efficient manner (including
11248 calls to other builtin functions).
11249
11250 The call may contain arguments which need to be evaluated, but
11251 which are not useful to determine the result of the call. In
11252 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11253 COMPOUND_EXPR will be an argument which must be evaluated.
11254 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11255 COMPOUND_EXPR in the chain will contain the tree for the simplified
11256 form of the builtin function call. */
11257
11258static tree
389dd41b 11259fold_builtin_strrchr (location_t loc, tree s1, tree s2, tree type)
4ee9c684 11260{
c2f47e15 11261 if (!validate_arg (s1, POINTER_TYPE)
11262 || !validate_arg (s2, INTEGER_TYPE))
11263 return NULL_TREE;
4ee9c684 11264 else
11265 {
4ee9c684 11266 tree fn;
11267 const char *p1;
11268
11269 if (TREE_CODE (s2) != INTEGER_CST)
c2f47e15 11270 return NULL_TREE;
4ee9c684 11271
11272 p1 = c_getstr (s1);
11273 if (p1 != NULL)
11274 {
11275 char c;
11276 const char *r;
daa1d5f5 11277 tree tem;
4ee9c684 11278
11279 if (target_char_cast (s2, &c))
c2f47e15 11280 return NULL_TREE;
4ee9c684 11281
11282 r = strrchr (p1, c);
11283
11284 if (r == NULL)
779b4c41 11285 return build_int_cst (TREE_TYPE (s1), 0);
4ee9c684 11286
11287 /* Return an offset into the constant string argument. */
389dd41b 11288 tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (s1),
0de36bdb 11289 s1, size_int (r - p1));
389dd41b 11290 return fold_convert_loc (loc, type, tem);
4ee9c684 11291 }
11292
11293 if (! integer_zerop (s2))
c2f47e15 11294 return NULL_TREE;
4ee9c684 11295
11296 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11297 if (!fn)
c2f47e15 11298 return NULL_TREE;
4ee9c684 11299
11300 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
389dd41b 11301 return build_call_expr_loc (loc, fn, 2, s1, s2);
4ee9c684 11302 }
11303}
11304
c2f47e15 11305/* Simplify a call to the strpbrk builtin. S1 and S2 are the arguments
11306 to the call, and TYPE is its return type.
4ee9c684 11307
c2f47e15 11308 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11309 simplified form of the call as a tree.
11310
11311 The simplified form may be a constant or other expression which
11312 computes the same value, but in a more efficient manner (including
11313 calls to other builtin functions).
11314
11315 The call may contain arguments which need to be evaluated, but
11316 which are not useful to determine the result of the call. In
11317 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11318 COMPOUND_EXPR will be an argument which must be evaluated.
11319 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11320 COMPOUND_EXPR in the chain will contain the tree for the simplified
11321 form of the builtin function call. */
11322
11323static tree
389dd41b 11324fold_builtin_strpbrk (location_t loc, tree s1, tree s2, tree type)
4ee9c684 11325{
c2f47e15 11326 if (!validate_arg (s1, POINTER_TYPE)
11327 || !validate_arg (s2, POINTER_TYPE))
11328 return NULL_TREE;
4ee9c684 11329 else
11330 {
4ee9c684 11331 tree fn;
11332 const char *p1, *p2;
11333
11334 p2 = c_getstr (s2);
11335 if (p2 == NULL)
c2f47e15 11336 return NULL_TREE;
4ee9c684 11337
11338 p1 = c_getstr (s1);
11339 if (p1 != NULL)
11340 {
11341 const char *r = strpbrk (p1, p2);
daa1d5f5 11342 tree tem;
4ee9c684 11343
11344 if (r == NULL)
779b4c41 11345 return build_int_cst (TREE_TYPE (s1), 0);
4ee9c684 11346
11347 /* Return an offset into the constant string argument. */
389dd41b 11348 tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (s1),
0de36bdb 11349 s1, size_int (r - p1));
389dd41b 11350 return fold_convert_loc (loc, type, tem);
4ee9c684 11351 }
11352
11353 if (p2[0] == '\0')
05abc81b 11354 /* strpbrk(x, "") == NULL.
11355 Evaluate and ignore s1 in case it had side-effects. */
389dd41b 11356 return omit_one_operand_loc (loc, TREE_TYPE (s1), integer_zero_node, s1);
4ee9c684 11357
11358 if (p2[1] != '\0')
c2f47e15 11359 return NULL_TREE; /* Really call strpbrk. */
4ee9c684 11360
11361 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11362 if (!fn)
c2f47e15 11363 return NULL_TREE;
4ee9c684 11364
11365 /* New argument list transforming strpbrk(s1, s2) to
11366 strchr(s1, s2[0]). */
389dd41b 11367 return build_call_expr_loc (loc, fn, 2, s1, build_int_cst (NULL_TREE, p2[0]));
4ee9c684 11368 }
11369}
11370
c2f47e15 11371/* Simplify a call to the strcat builtin. DST and SRC are the arguments
11372 to the call.
4ee9c684 11373
c2f47e15 11374 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11375 simplified form of the call as a tree.
11376
11377 The simplified form may be a constant or other expression which
11378 computes the same value, but in a more efficient manner (including
11379 calls to other builtin functions).
11380
11381 The call may contain arguments which need to be evaluated, but
11382 which are not useful to determine the result of the call. In
11383 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11384 COMPOUND_EXPR will be an argument which must be evaluated.
11385 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11386 COMPOUND_EXPR in the chain will contain the tree for the simplified
11387 form of the builtin function call. */
11388
11389static tree
389dd41b 11390fold_builtin_strcat (location_t loc ATTRIBUTE_UNUSED, tree dst, tree src)
4ee9c684 11391{
c2f47e15 11392 if (!validate_arg (dst, POINTER_TYPE)
11393 || !validate_arg (src, POINTER_TYPE))
11394 return NULL_TREE;
4ee9c684 11395 else
11396 {
4ee9c684 11397 const char *p = c_getstr (src);
11398
11399 /* If the string length is zero, return the dst parameter. */
11400 if (p && *p == '\0')
11401 return dst;
11402
a65c4d64 11403 if (optimize_insn_for_speed_p ())
11404 {
11405 /* See if we can store by pieces into (dst + strlen(dst)). */
11406 tree newdst, call;
11407 tree strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
11408 tree strcpy_fn = implicit_built_in_decls[BUILT_IN_STRCPY];
11409
11410 if (!strlen_fn || !strcpy_fn)
11411 return NULL_TREE;
11412
11413 /* If we don't have a movstr we don't want to emit an strcpy
11414 call. We have to do that if the length of the source string
11415 isn't computable (in that case we can use memcpy probably
11416 later expanding to a sequence of mov instructions). If we
11417 have movstr instructions we can emit strcpy calls. */
11418 if (!HAVE_movstr)
11419 {
11420 tree len = c_strlen (src, 1);
11421 if (! len || TREE_SIDE_EFFECTS (len))
11422 return NULL_TREE;
11423 }
11424
11425 /* Stabilize the argument list. */
11426 dst = builtin_save_expr (dst);
11427
11428 /* Create strlen (dst). */
11429 newdst = build_call_expr_loc (loc, strlen_fn, 1, dst);
11430 /* Create (dst p+ strlen (dst)). */
11431
11432 newdst = fold_build2_loc (loc, POINTER_PLUS_EXPR,
11433 TREE_TYPE (dst), dst, newdst);
11434 newdst = builtin_save_expr (newdst);
11435
11436 call = build_call_expr_loc (loc, strcpy_fn, 2, newdst, src);
11437 return build2 (COMPOUND_EXPR, TREE_TYPE (dst), call, dst);
11438 }
c2f47e15 11439 return NULL_TREE;
4ee9c684 11440 }
11441}
11442
c2f47e15 11443/* Simplify a call to the strncat builtin. DST, SRC, and LEN are the
11444 arguments to the call.
4ee9c684 11445
c2f47e15 11446 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11447 simplified form of the call as a tree.
11448
11449 The simplified form may be a constant or other expression which
11450 computes the same value, but in a more efficient manner (including
11451 calls to other builtin functions).
11452
11453 The call may contain arguments which need to be evaluated, but
11454 which are not useful to determine the result of the call. In
11455 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11456 COMPOUND_EXPR will be an argument which must be evaluated.
11457 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11458 COMPOUND_EXPR in the chain will contain the tree for the simplified
11459 form of the builtin function call. */
11460
11461static tree
389dd41b 11462fold_builtin_strncat (location_t loc, tree dst, tree src, tree len)
4ee9c684 11463{
c2f47e15 11464 if (!validate_arg (dst, POINTER_TYPE)
11465 || !validate_arg (src, POINTER_TYPE)
11466 || !validate_arg (len, INTEGER_TYPE))
11467 return NULL_TREE;
4ee9c684 11468 else
11469 {
4ee9c684 11470 const char *p = c_getstr (src);
11471
11472 /* If the requested length is zero, or the src parameter string
0a39fd54 11473 length is zero, return the dst parameter. */
4ee9c684 11474 if (integer_zerop (len) || (p && *p == '\0'))
389dd41b 11475 return omit_two_operands_loc (loc, TREE_TYPE (dst), dst, src, len);
4ee9c684 11476
11477 /* If the requested len is greater than or equal to the string
a0c938f0 11478 length, call strcat. */
4ee9c684 11479 if (TREE_CODE (len) == INTEGER_CST && p
11480 && compare_tree_int (len, strlen (p)) >= 0)
11481 {
4ee9c684 11482 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
11483
11484 /* If the replacement _DECL isn't initialized, don't do the
11485 transformation. */
11486 if (!fn)
c2f47e15 11487 return NULL_TREE;
4ee9c684 11488
389dd41b 11489 return build_call_expr_loc (loc, fn, 2, dst, src);
4ee9c684 11490 }
c2f47e15 11491 return NULL_TREE;
4ee9c684 11492 }
11493}
11494
c2f47e15 11495/* Simplify a call to the strspn builtin. S1 and S2 are the arguments
11496 to the call.
4ee9c684 11497
c2f47e15 11498 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11499 simplified form of the call as a tree.
11500
11501 The simplified form may be a constant or other expression which
11502 computes the same value, but in a more efficient manner (including
11503 calls to other builtin functions).
11504
11505 The call may contain arguments which need to be evaluated, but
11506 which are not useful to determine the result of the call. In
11507 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11508 COMPOUND_EXPR will be an argument which must be evaluated.
11509 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11510 COMPOUND_EXPR in the chain will contain the tree for the simplified
11511 form of the builtin function call. */
11512
11513static tree
389dd41b 11514fold_builtin_strspn (location_t loc, tree s1, tree s2)
4ee9c684 11515{
c2f47e15 11516 if (!validate_arg (s1, POINTER_TYPE)
11517 || !validate_arg (s2, POINTER_TYPE))
11518 return NULL_TREE;
4ee9c684 11519 else
11520 {
4ee9c684 11521 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11522
11523 /* If both arguments are constants, evaluate at compile-time. */
11524 if (p1 && p2)
11525 {
11526 const size_t r = strspn (p1, p2);
11527 return size_int (r);
11528 }
11529
c2f47e15 11530 /* If either argument is "", return NULL_TREE. */
4ee9c684 11531 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9bc9f15f 11532 /* Evaluate and ignore both arguments in case either one has
11533 side-effects. */
389dd41b 11534 return omit_two_operands_loc (loc, size_type_node, size_zero_node,
9bc9f15f 11535 s1, s2);
c2f47e15 11536 return NULL_TREE;
4ee9c684 11537 }
11538}
11539
c2f47e15 11540/* Simplify a call to the strcspn builtin. S1 and S2 are the arguments
11541 to the call.
4ee9c684 11542
c2f47e15 11543 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11544 simplified form of the call as a tree.
11545
11546 The simplified form may be a constant or other expression which
11547 computes the same value, but in a more efficient manner (including
11548 calls to other builtin functions).
11549
11550 The call may contain arguments which need to be evaluated, but
11551 which are not useful to determine the result of the call. In
11552 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11553 COMPOUND_EXPR will be an argument which must be evaluated.
11554 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11555 COMPOUND_EXPR in the chain will contain the tree for the simplified
11556 form of the builtin function call. */
11557
11558static tree
389dd41b 11559fold_builtin_strcspn (location_t loc, tree s1, tree s2)
4ee9c684 11560{
c2f47e15 11561 if (!validate_arg (s1, POINTER_TYPE)
11562 || !validate_arg (s2, POINTER_TYPE))
11563 return NULL_TREE;
4ee9c684 11564 else
11565 {
4ee9c684 11566 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11567
11568 /* If both arguments are constants, evaluate at compile-time. */
11569 if (p1 && p2)
11570 {
11571 const size_t r = strcspn (p1, p2);
11572 return size_int (r);
11573 }
11574
c2f47e15 11575 /* If the first argument is "", return NULL_TREE. */
4ee9c684 11576 if (p1 && *p1 == '\0')
11577 {
11578 /* Evaluate and ignore argument s2 in case it has
11579 side-effects. */
389dd41b 11580 return omit_one_operand_loc (loc, size_type_node,
39761420 11581 size_zero_node, s2);
4ee9c684 11582 }
11583
11584 /* If the second argument is "", return __builtin_strlen(s1). */
11585 if (p2 && *p2 == '\0')
11586 {
c2f47e15 11587 tree fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4ee9c684 11588
11589 /* If the replacement _DECL isn't initialized, don't do the
11590 transformation. */
11591 if (!fn)
c2f47e15 11592 return NULL_TREE;
4ee9c684 11593
389dd41b 11594 return build_call_expr_loc (loc, fn, 1, s1);
4ee9c684 11595 }
c2f47e15 11596 return NULL_TREE;
4ee9c684 11597 }
11598}
11599
c2f47e15 11600/* Fold a call to the fputs builtin. ARG0 and ARG1 are the arguments
11601 to the call. IGNORE is true if the value returned
f0613857 11602 by the builtin will be ignored. UNLOCKED is true is true if this
11603 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
11604 the known length of the string. Return NULL_TREE if no simplification
11605 was possible. */
4ee9c684 11606
11607tree
389dd41b 11608fold_builtin_fputs (location_t loc, tree arg0, tree arg1,
11609 bool ignore, bool unlocked, tree len)
4ee9c684 11610{
6d77ed92 11611 /* If we're using an unlocked function, assume the other unlocked
11612 functions exist explicitly. */
11613 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4ee9c684 11614 : implicit_built_in_decls[BUILT_IN_FPUTC];
6d77ed92 11615 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4ee9c684 11616 : implicit_built_in_decls[BUILT_IN_FWRITE];
11617
c403edd4 11618 /* If the return value is used, don't do the transformation. */
11619 if (!ignore)
c2f47e15 11620 return NULL_TREE;
4ee9c684 11621
11622 /* Verify the arguments in the original call. */
c2f47e15 11623 if (!validate_arg (arg0, POINTER_TYPE)
11624 || !validate_arg (arg1, POINTER_TYPE))
11625 return NULL_TREE;
4ee9c684 11626
f0613857 11627 if (! len)
c2f47e15 11628 len = c_strlen (arg0, 0);
4ee9c684 11629
11630 /* Get the length of the string passed to fputs. If the length
11631 can't be determined, punt. */
11632 if (!len
11633 || TREE_CODE (len) != INTEGER_CST)
c2f47e15 11634 return NULL_TREE;
4ee9c684 11635
11636 switch (compare_tree_int (len, 1))
11637 {
11638 case -1: /* length is 0, delete the call entirely . */
389dd41b 11639 return omit_one_operand_loc (loc, integer_type_node,
11640 integer_zero_node, arg1);;
05abc81b 11641
4ee9c684 11642 case 0: /* length is 1, call fputc. */
11643 {
c2f47e15 11644 const char *p = c_getstr (arg0);
4ee9c684 11645
11646 if (p != NULL)
11647 {
c2f47e15 11648 if (fn_fputc)
389dd41b 11649 return build_call_expr_loc (loc, fn_fputc, 2,
c2f47e15 11650 build_int_cst (NULL_TREE, p[0]), arg1);
11651 else
11652 return NULL_TREE;
4ee9c684 11653 }
11654 }
11655 /* FALLTHROUGH */
11656 case 1: /* length is greater than 1, call fwrite. */
11657 {
0bed3869 11658 /* If optimizing for size keep fputs. */
0bfd8d5c 11659 if (optimize_function_for_size_p (cfun))
c2f47e15 11660 return NULL_TREE;
4ee9c684 11661 /* New argument list transforming fputs(string, stream) to
11662 fwrite(string, 1, len, stream). */
c2f47e15 11663 if (fn_fwrite)
389dd41b 11664 return build_call_expr_loc (loc, fn_fwrite, 4, arg0,
11665 size_one_node, len, arg1);
c2f47e15 11666 else
11667 return NULL_TREE;
4ee9c684 11668 }
11669 default:
64db345d 11670 gcc_unreachable ();
4ee9c684 11671 }
c2f47e15 11672 return NULL_TREE;
4ee9c684 11673}
11674
c2f47e15 11675/* Fold the next_arg or va_start call EXP. Returns true if there was an error
743b0c6a 11676 produced. False otherwise. This is done so that we don't output the error
11677 or warning twice or three times. */
75a70cf9 11678
743b0c6a 11679bool
c2f47e15 11680fold_builtin_next_arg (tree exp, bool va_start_p)
4ee9c684 11681{
11682 tree fntype = TREE_TYPE (current_function_decl);
c2f47e15 11683 int nargs = call_expr_nargs (exp);
11684 tree arg;
4ee9c684 11685
11686 if (TYPE_ARG_TYPES (fntype) == 0
11687 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
11688 == void_type_node))
743b0c6a 11689 {
11690 error ("%<va_start%> used in function with fixed args");
11691 return true;
11692 }
c2f47e15 11693
11694 if (va_start_p)
79012a9d 11695 {
c2f47e15 11696 if (va_start_p && (nargs != 2))
11697 {
11698 error ("wrong number of arguments to function %<va_start%>");
11699 return true;
11700 }
11701 arg = CALL_EXPR_ARG (exp, 1);
79012a9d 11702 }
11703 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
11704 when we checked the arguments and if needed issued a warning. */
c2f47e15 11705 else
4ee9c684 11706 {
c2f47e15 11707 if (nargs == 0)
11708 {
11709 /* Evidently an out of date version of <stdarg.h>; can't validate
11710 va_start's second argument, but can still work as intended. */
11711 warning (0, "%<__builtin_next_arg%> called without an argument");
11712 return true;
11713 }
11714 else if (nargs > 1)
a0c938f0 11715 {
c2f47e15 11716 error ("wrong number of arguments to function %<__builtin_next_arg%>");
a0c938f0 11717 return true;
11718 }
c2f47e15 11719 arg = CALL_EXPR_ARG (exp, 0);
11720 }
11721
a8dd994c 11722 if (TREE_CODE (arg) == SSA_NAME)
11723 arg = SSA_NAME_VAR (arg);
11724
c2f47e15 11725 /* We destructively modify the call to be __builtin_va_start (ap, 0)
11726 or __builtin_next_arg (0) the first time we see it, after checking
11727 the arguments and if needed issuing a warning. */
11728 if (!integer_zerop (arg))
11729 {
11730 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
79012a9d 11731
4ee9c684 11732 /* Strip off all nops for the sake of the comparison. This
11733 is not quite the same as STRIP_NOPS. It does more.
11734 We must also strip off INDIRECT_EXPR for C++ reference
11735 parameters. */
72dd6141 11736 while (CONVERT_EXPR_P (arg)
4ee9c684 11737 || TREE_CODE (arg) == INDIRECT_REF)
11738 arg = TREE_OPERAND (arg, 0);
11739 if (arg != last_parm)
a0c938f0 11740 {
b08cf617 11741 /* FIXME: Sometimes with the tree optimizers we can get the
11742 not the last argument even though the user used the last
11743 argument. We just warn and set the arg to be the last
11744 argument so that we will get wrong-code because of
11745 it. */
c3ceba8e 11746 warning (0, "second parameter of %<va_start%> not last named argument");
743b0c6a 11747 }
24158ad7 11748
11749 /* Undefined by C99 7.15.1.4p4 (va_start):
11750 "If the parameter parmN is declared with the register storage
11751 class, with a function or array type, or with a type that is
11752 not compatible with the type that results after application of
11753 the default argument promotions, the behavior is undefined."
11754 */
11755 else if (DECL_REGISTER (arg))
11756 warning (0, "undefined behaviour when second parameter of "
11757 "%<va_start%> is declared with %<register%> storage");
11758
79012a9d 11759 /* We want to verify the second parameter just once before the tree
a0c938f0 11760 optimizers are run and then avoid keeping it in the tree,
11761 as otherwise we could warn even for correct code like:
11762 void foo (int i, ...)
11763 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
c2f47e15 11764 if (va_start_p)
11765 CALL_EXPR_ARG (exp, 1) = integer_zero_node;
11766 else
11767 CALL_EXPR_ARG (exp, 0) = integer_zero_node;
743b0c6a 11768 }
11769 return false;
4ee9c684 11770}
11771
11772
c2f47e15 11773/* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG.
11774 ORIG may be null if this is a 2-argument call. We don't attempt to
11775 simplify calls with more than 3 arguments.
4ee9c684 11776
c2f47e15 11777 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11778 simplified form of the call as a tree. If IGNORED is true, it means that
11779 the caller does not use the returned value of the function. */
11780
11781static tree
389dd41b 11782fold_builtin_sprintf (location_t loc, tree dest, tree fmt,
11783 tree orig, int ignored)
4ee9c684 11784{
c2f47e15 11785 tree call, retval;
4ee9c684 11786 const char *fmt_str = NULL;
11787
11788 /* Verify the required arguments in the original call. We deal with two
11789 types of sprintf() calls: 'sprintf (str, fmt)' and
11790 'sprintf (dest, "%s", orig)'. */
c2f47e15 11791 if (!validate_arg (dest, POINTER_TYPE)
11792 || !validate_arg (fmt, POINTER_TYPE))
11793 return NULL_TREE;
11794 if (orig && !validate_arg (orig, POINTER_TYPE))
4ee9c684 11795 return NULL_TREE;
4ee9c684 11796
11797 /* Check whether the format is a literal string constant. */
11798 fmt_str = c_getstr (fmt);
11799 if (fmt_str == NULL)
11800 return NULL_TREE;
11801
11802 call = NULL_TREE;
11803 retval = NULL_TREE;
11804
d4473c84 11805 if (!init_target_chars ())
c2f47e15 11806 return NULL_TREE;
99eabcc1 11807
4ee9c684 11808 /* If the format doesn't contain % args or %%, use strcpy. */
99eabcc1 11809 if (strchr (fmt_str, target_percent) == NULL)
4ee9c684 11810 {
11811 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
11812
11813 if (!fn)
11814 return NULL_TREE;
11815
72dfb3f2 11816 /* Don't optimize sprintf (buf, "abc", ptr++). */
c2f47e15 11817 if (orig)
72dfb3f2 11818 return NULL_TREE;
11819
4ee9c684 11820 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
11821 'format' is known to contain no % formats. */
389dd41b 11822 call = build_call_expr_loc (loc, fn, 2, dest, fmt);
4ee9c684 11823 if (!ignored)
7016c612 11824 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
4ee9c684 11825 }
11826
11827 /* If the format is "%s", use strcpy if the result isn't used. */
99eabcc1 11828 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
4ee9c684 11829 {
c2f47e15 11830 tree fn;
4ee9c684 11831 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
11832
11833 if (!fn)
11834 return NULL_TREE;
11835
72dfb3f2 11836 /* Don't crash on sprintf (str1, "%s"). */
c2f47e15 11837 if (!orig)
72dfb3f2 11838 return NULL_TREE;
11839
4ee9c684 11840 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
4ee9c684 11841 if (!ignored)
11842 {
11843 retval = c_strlen (orig, 1);
11844 if (!retval || TREE_CODE (retval) != INTEGER_CST)
11845 return NULL_TREE;
11846 }
389dd41b 11847 call = build_call_expr_loc (loc, fn, 2, dest, orig);
4ee9c684 11848 }
11849
11850 if (call && retval)
11851 {
389dd41b 11852 retval = fold_convert_loc
11853 (loc, TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
4ee9c684 11854 retval);
05abc81b 11855 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
4ee9c684 11856 }
11857 else
11858 return call;
11859}
0a39fd54 11860
c2f47e15 11861/* Expand a call EXP to __builtin_object_size. */
0a39fd54 11862
11863rtx
11864expand_builtin_object_size (tree exp)
11865{
11866 tree ost;
11867 int object_size_type;
11868 tree fndecl = get_callee_fndecl (exp);
0a39fd54 11869
c2f47e15 11870 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
0a39fd54 11871 {
b8c23db3 11872 error ("%Kfirst argument of %D must be a pointer, second integer constant",
11873 exp, fndecl);
0a39fd54 11874 expand_builtin_trap ();
11875 return const0_rtx;
11876 }
11877
c2f47e15 11878 ost = CALL_EXPR_ARG (exp, 1);
0a39fd54 11879 STRIP_NOPS (ost);
11880
11881 if (TREE_CODE (ost) != INTEGER_CST
11882 || tree_int_cst_sgn (ost) < 0
11883 || compare_tree_int (ost, 3) > 0)
11884 {
b8c23db3 11885 error ("%Klast argument of %D is not integer constant between 0 and 3",
11886 exp, fndecl);
0a39fd54 11887 expand_builtin_trap ();
11888 return const0_rtx;
11889 }
11890
11891 object_size_type = tree_low_cst (ost, 0);
11892
11893 return object_size_type < 2 ? constm1_rtx : const0_rtx;
11894}
11895
11896/* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
11897 FCODE is the BUILT_IN_* to use.
c2f47e15 11898 Return NULL_RTX if we failed; the caller should emit a normal call,
0a39fd54 11899 otherwise try to get the result in TARGET, if convenient (and in
11900 mode MODE if that's convenient). */
11901
11902static rtx
11903expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
11904 enum built_in_function fcode)
11905{
0a39fd54 11906 tree dest, src, len, size;
11907
c2f47e15 11908 if (!validate_arglist (exp,
0a39fd54 11909 POINTER_TYPE,
11910 fcode == BUILT_IN_MEMSET_CHK
11911 ? INTEGER_TYPE : POINTER_TYPE,
11912 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
c2f47e15 11913 return NULL_RTX;
0a39fd54 11914
c2f47e15 11915 dest = CALL_EXPR_ARG (exp, 0);
11916 src = CALL_EXPR_ARG (exp, 1);
11917 len = CALL_EXPR_ARG (exp, 2);
11918 size = CALL_EXPR_ARG (exp, 3);
0a39fd54 11919
11920 if (! host_integerp (size, 1))
c2f47e15 11921 return NULL_RTX;
0a39fd54 11922
11923 if (host_integerp (len, 1) || integer_all_onesp (size))
11924 {
11925 tree fn;
11926
11927 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
11928 {
b430e8d9 11929 warning_at (tree_nonartificial_location (exp),
11930 0, "%Kcall to %D will always overflow destination buffer",
11931 exp, get_callee_fndecl (exp));
c2f47e15 11932 return NULL_RTX;
0a39fd54 11933 }
11934
0a39fd54 11935 fn = NULL_TREE;
11936 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
11937 mem{cpy,pcpy,move,set} is available. */
11938 switch (fcode)
11939 {
11940 case BUILT_IN_MEMCPY_CHK:
11941 fn = built_in_decls[BUILT_IN_MEMCPY];
11942 break;
11943 case BUILT_IN_MEMPCPY_CHK:
11944 fn = built_in_decls[BUILT_IN_MEMPCPY];
11945 break;
11946 case BUILT_IN_MEMMOVE_CHK:
11947 fn = built_in_decls[BUILT_IN_MEMMOVE];
11948 break;
11949 case BUILT_IN_MEMSET_CHK:
11950 fn = built_in_decls[BUILT_IN_MEMSET];
11951 break;
11952 default:
11953 break;
11954 }
11955
11956 if (! fn)
c2f47e15 11957 return NULL_RTX;
0a39fd54 11958
a65c4d64 11959 fn = build_call_nofold (fn, 3, dest, src, len);
11960 gcc_assert (TREE_CODE (fn) == CALL_EXPR);
11961 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
0a39fd54 11962 return expand_expr (fn, target, mode, EXPAND_NORMAL);
11963 }
11964 else if (fcode == BUILT_IN_MEMSET_CHK)
c2f47e15 11965 return NULL_RTX;
0a39fd54 11966 else
11967 {
11968 unsigned int dest_align
11969 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
11970
11971 /* If DEST is not a pointer type, call the normal function. */
11972 if (dest_align == 0)
c2f47e15 11973 return NULL_RTX;
0a39fd54 11974
11975 /* If SRC and DEST are the same (and not volatile), do nothing. */
11976 if (operand_equal_p (src, dest, 0))
11977 {
11978 tree expr;
11979
11980 if (fcode != BUILT_IN_MEMPCPY_CHK)
11981 {
11982 /* Evaluate and ignore LEN in case it has side-effects. */
11983 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
11984 return expand_expr (dest, target, mode, EXPAND_NORMAL);
11985 }
11986
0de36bdb 11987 expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
0a39fd54 11988 return expand_expr (expr, target, mode, EXPAND_NORMAL);
11989 }
11990
11991 /* __memmove_chk special case. */
11992 if (fcode == BUILT_IN_MEMMOVE_CHK)
11993 {
11994 unsigned int src_align
11995 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
11996
11997 if (src_align == 0)
c2f47e15 11998 return NULL_RTX;
0a39fd54 11999
12000 /* If src is categorized for a readonly section we can use
12001 normal __memcpy_chk. */
12002 if (readonly_data_expr (src))
12003 {
12004 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12005 if (!fn)
c2f47e15 12006 return NULL_RTX;
a65c4d64 12007 fn = build_call_nofold (fn, 4, dest, src, len, size);
12008 gcc_assert (TREE_CODE (fn) == CALL_EXPR);
12009 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
0a39fd54 12010 return expand_expr (fn, target, mode, EXPAND_NORMAL);
12011 }
12012 }
c2f47e15 12013 return NULL_RTX;
0a39fd54 12014 }
12015}
12016
12017/* Emit warning if a buffer overflow is detected at compile time. */
12018
12019static void
12020maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
12021{
c2f47e15 12022 int is_strlen = 0;
0a39fd54 12023 tree len, size;
b430e8d9 12024 location_t loc = tree_nonartificial_location (exp);
0a39fd54 12025
12026 switch (fcode)
12027 {
12028 case BUILT_IN_STRCPY_CHK:
12029 case BUILT_IN_STPCPY_CHK:
12030 /* For __strcat_chk the warning will be emitted only if overflowing
12031 by at least strlen (dest) + 1 bytes. */
12032 case BUILT_IN_STRCAT_CHK:
c2f47e15 12033 len = CALL_EXPR_ARG (exp, 1);
12034 size = CALL_EXPR_ARG (exp, 2);
0a39fd54 12035 is_strlen = 1;
12036 break;
b356dfef 12037 case BUILT_IN_STRNCAT_CHK:
0a39fd54 12038 case BUILT_IN_STRNCPY_CHK:
c2f47e15 12039 len = CALL_EXPR_ARG (exp, 2);
12040 size = CALL_EXPR_ARG (exp, 3);
0a39fd54 12041 break;
12042 case BUILT_IN_SNPRINTF_CHK:
12043 case BUILT_IN_VSNPRINTF_CHK:
c2f47e15 12044 len = CALL_EXPR_ARG (exp, 1);
12045 size = CALL_EXPR_ARG (exp, 3);
0a39fd54 12046 break;
12047 default:
12048 gcc_unreachable ();
12049 }
12050
0a39fd54 12051 if (!len || !size)
12052 return;
12053
0a39fd54 12054 if (! host_integerp (size, 1) || integer_all_onesp (size))
12055 return;
12056
12057 if (is_strlen)
12058 {
12059 len = c_strlen (len, 1);
12060 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12061 return;
12062 }
b356dfef 12063 else if (fcode == BUILT_IN_STRNCAT_CHK)
12064 {
c2f47e15 12065 tree src = CALL_EXPR_ARG (exp, 1);
b356dfef 12066 if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12067 return;
12068 src = c_strlen (src, 1);
12069 if (! src || ! host_integerp (src, 1))
12070 {
b430e8d9 12071 warning_at (loc, 0, "%Kcall to %D might overflow destination buffer",
12072 exp, get_callee_fndecl (exp));
b356dfef 12073 return;
12074 }
12075 else if (tree_int_cst_lt (src, size))
12076 return;
12077 }
0a39fd54 12078 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
12079 return;
12080
b430e8d9 12081 warning_at (loc, 0, "%Kcall to %D will always overflow destination buffer",
12082 exp, get_callee_fndecl (exp));
0a39fd54 12083}
12084
12085/* Emit warning if a buffer overflow is detected at compile time
12086 in __sprintf_chk/__vsprintf_chk calls. */
12087
12088static void
12089maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
12090{
0a39fd54 12091 tree dest, size, len, fmt, flag;
12092 const char *fmt_str;
c2f47e15 12093 int nargs = call_expr_nargs (exp);
0a39fd54 12094
12095 /* Verify the required arguments in the original call. */
c2f47e15 12096
12097 if (nargs < 4)
0a39fd54 12098 return;
c2f47e15 12099 dest = CALL_EXPR_ARG (exp, 0);
12100 flag = CALL_EXPR_ARG (exp, 1);
12101 size = CALL_EXPR_ARG (exp, 2);
12102 fmt = CALL_EXPR_ARG (exp, 3);
0a39fd54 12103
12104 if (! host_integerp (size, 1) || integer_all_onesp (size))
12105 return;
12106
12107 /* Check whether the format is a literal string constant. */
12108 fmt_str = c_getstr (fmt);
12109 if (fmt_str == NULL)
12110 return;
12111
d4473c84 12112 if (!init_target_chars ())
99eabcc1 12113 return;
12114
0a39fd54 12115 /* If the format doesn't contain % args or %%, we know its size. */
99eabcc1 12116 if (strchr (fmt_str, target_percent) == 0)
0a39fd54 12117 len = build_int_cstu (size_type_node, strlen (fmt_str));
12118 /* If the format is "%s" and first ... argument is a string literal,
12119 we know it too. */
c2f47e15 12120 else if (fcode == BUILT_IN_SPRINTF_CHK
12121 && strcmp (fmt_str, target_percent_s) == 0)
0a39fd54 12122 {
12123 tree arg;
12124
c2f47e15 12125 if (nargs < 5)
0a39fd54 12126 return;
c2f47e15 12127 arg = CALL_EXPR_ARG (exp, 4);
0a39fd54 12128 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
12129 return;
12130
12131 len = c_strlen (arg, 1);
12132 if (!len || ! host_integerp (len, 1))
12133 return;
12134 }
12135 else
12136 return;
12137
12138 if (! tree_int_cst_lt (len, size))
b430e8d9 12139 warning_at (tree_nonartificial_location (exp),
12140 0, "%Kcall to %D will always overflow destination buffer",
12141 exp, get_callee_fndecl (exp));
0a39fd54 12142}
12143
2c281b15 12144/* Emit warning if a free is called with address of a variable. */
12145
12146static void
12147maybe_emit_free_warning (tree exp)
12148{
12149 tree arg = CALL_EXPR_ARG (exp, 0);
12150
12151 STRIP_NOPS (arg);
12152 if (TREE_CODE (arg) != ADDR_EXPR)
12153 return;
12154
12155 arg = get_base_address (TREE_OPERAND (arg, 0));
12156 if (arg == NULL || INDIRECT_REF_P (arg))
12157 return;
12158
12159 if (SSA_VAR_P (arg))
b430e8d9 12160 warning_at (tree_nonartificial_location (exp),
12161 0, "%Kattempt to free a non-heap object %qD", exp, arg);
2c281b15 12162 else
b430e8d9 12163 warning_at (tree_nonartificial_location (exp),
12164 0, "%Kattempt to free a non-heap object", exp);
2c281b15 12165}
12166
c2f47e15 12167/* Fold a call to __builtin_object_size with arguments PTR and OST,
12168 if possible. */
0a39fd54 12169
12170tree
c2f47e15 12171fold_builtin_object_size (tree ptr, tree ost)
0a39fd54 12172{
c2f47e15 12173 tree ret = NULL_TREE;
0a39fd54 12174 int object_size_type;
12175
c2f47e15 12176 if (!validate_arg (ptr, POINTER_TYPE)
12177 || !validate_arg (ost, INTEGER_TYPE))
12178 return NULL_TREE;
0a39fd54 12179
0a39fd54 12180 STRIP_NOPS (ost);
12181
12182 if (TREE_CODE (ost) != INTEGER_CST
12183 || tree_int_cst_sgn (ost) < 0
12184 || compare_tree_int (ost, 3) > 0)
c2f47e15 12185 return NULL_TREE;
0a39fd54 12186
12187 object_size_type = tree_low_cst (ost, 0);
12188
12189 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
12190 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
12191 and (size_t) 0 for types 2 and 3. */
12192 if (TREE_SIDE_EFFECTS (ptr))
697bbc3f 12193 return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0);
0a39fd54 12194
12195 if (TREE_CODE (ptr) == ADDR_EXPR)
12196 ret = build_int_cstu (size_type_node,
697bbc3f 12197 compute_builtin_object_size (ptr, object_size_type));
0a39fd54 12198
12199 else if (TREE_CODE (ptr) == SSA_NAME)
12200 {
12201 unsigned HOST_WIDE_INT bytes;
12202
12203 /* If object size is not known yet, delay folding until
12204 later. Maybe subsequent passes will help determining
12205 it. */
12206 bytes = compute_builtin_object_size (ptr, object_size_type);
12207 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
12208 ? -1 : 0))
12209 ret = build_int_cstu (size_type_node, bytes);
12210 }
12211
12212 if (ret)
12213 {
697bbc3f 12214 unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (ret);
12215 HOST_WIDE_INT high = TREE_INT_CST_HIGH (ret);
12216 if (fit_double_type (low, high, &low, &high, TREE_TYPE (ret)))
12217 ret = NULL_TREE;
0a39fd54 12218 }
12219
12220 return ret;
12221}
12222
12223/* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
c2f47e15 12224 DEST, SRC, LEN, and SIZE are the arguments to the call.
0a39fd54 12225 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
12226 code of the builtin. If MAXLEN is not NULL, it is maximum length
12227 passed as third argument. */
12228
12229tree
389dd41b 12230fold_builtin_memory_chk (location_t loc, tree fndecl,
c2f47e15 12231 tree dest, tree src, tree len, tree size,
12232 tree maxlen, bool ignore,
0a39fd54 12233 enum built_in_function fcode)
12234{
c2f47e15 12235 tree fn;
0a39fd54 12236
c2f47e15 12237 if (!validate_arg (dest, POINTER_TYPE)
12238 || !validate_arg (src,
12239 (fcode == BUILT_IN_MEMSET_CHK
12240 ? INTEGER_TYPE : POINTER_TYPE))
12241 || !validate_arg (len, INTEGER_TYPE)
12242 || !validate_arg (size, INTEGER_TYPE))
12243 return NULL_TREE;
0a39fd54 12244
12245 /* If SRC and DEST are the same (and not volatile), return DEST
12246 (resp. DEST+LEN for __mempcpy_chk). */
12247 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
12248 {
12249 if (fcode != BUILT_IN_MEMPCPY_CHK)
389dd41b 12250 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
12251 dest, len);
0a39fd54 12252 else
12253 {
389dd41b 12254 tree temp = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (dest),
12255 dest, len);
12256 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), temp);
0a39fd54 12257 }
12258 }
12259
12260 if (! host_integerp (size, 1))
c2f47e15 12261 return NULL_TREE;
0a39fd54 12262
12263 if (! integer_all_onesp (size))
12264 {
12265 if (! host_integerp (len, 1))
12266 {
12267 /* If LEN is not constant, try MAXLEN too.
12268 For MAXLEN only allow optimizing into non-_ocs function
12269 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12270 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12271 {
12272 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
12273 {
12274 /* (void) __mempcpy_chk () can be optimized into
12275 (void) __memcpy_chk (). */
12276 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12277 if (!fn)
c2f47e15 12278 return NULL_TREE;
0a39fd54 12279
389dd41b 12280 return build_call_expr_loc (loc, fn, 4, dest, src, len, size);
0a39fd54 12281 }
c2f47e15 12282 return NULL_TREE;
0a39fd54 12283 }
0a39fd54 12284 }
ad89623c 12285 else
12286 maxlen = len;
0a39fd54 12287
ad89623c 12288 if (tree_int_cst_lt (size, maxlen))
c2f47e15 12289 return NULL_TREE;
0a39fd54 12290 }
12291
0a39fd54 12292 fn = NULL_TREE;
12293 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12294 mem{cpy,pcpy,move,set} is available. */
12295 switch (fcode)
12296 {
12297 case BUILT_IN_MEMCPY_CHK:
12298 fn = built_in_decls[BUILT_IN_MEMCPY];
12299 break;
12300 case BUILT_IN_MEMPCPY_CHK:
12301 fn = built_in_decls[BUILT_IN_MEMPCPY];
12302 break;
12303 case BUILT_IN_MEMMOVE_CHK:
12304 fn = built_in_decls[BUILT_IN_MEMMOVE];
12305 break;
12306 case BUILT_IN_MEMSET_CHK:
12307 fn = built_in_decls[BUILT_IN_MEMSET];
12308 break;
12309 default:
12310 break;
12311 }
12312
12313 if (!fn)
c2f47e15 12314 return NULL_TREE;
0a39fd54 12315
389dd41b 12316 return build_call_expr_loc (loc, fn, 3, dest, src, len);
0a39fd54 12317}
12318
12319/* Fold a call to the __st[rp]cpy_chk builtin.
c2f47e15 12320 DEST, SRC, and SIZE are the arguments to the call.
12321 IGNORE is true if return value can be ignored. FCODE is the BUILT_IN_*
0a39fd54 12322 code of the builtin. If MAXLEN is not NULL, it is maximum length of
12323 strings passed as second argument. */
12324
12325tree
389dd41b 12326fold_builtin_stxcpy_chk (location_t loc, tree fndecl, tree dest,
12327 tree src, tree size,
c2f47e15 12328 tree maxlen, bool ignore,
0a39fd54 12329 enum built_in_function fcode)
12330{
c2f47e15 12331 tree len, fn;
0a39fd54 12332
c2f47e15 12333 if (!validate_arg (dest, POINTER_TYPE)
12334 || !validate_arg (src, POINTER_TYPE)
12335 || !validate_arg (size, INTEGER_TYPE))
12336 return NULL_TREE;
0a39fd54 12337
12338 /* If SRC and DEST are the same (and not volatile), return DEST. */
12339 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
389dd41b 12340 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest);
a0c938f0 12341
0a39fd54 12342 if (! host_integerp (size, 1))
c2f47e15 12343 return NULL_TREE;
0a39fd54 12344
12345 if (! integer_all_onesp (size))
12346 {
12347 len = c_strlen (src, 1);
12348 if (! len || ! host_integerp (len, 1))
12349 {
12350 /* If LEN is not constant, try MAXLEN too.
12351 For MAXLEN only allow optimizing into non-_ocs function
12352 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12353 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12354 {
12355 if (fcode == BUILT_IN_STPCPY_CHK)
12356 {
12357 if (! ignore)
c2f47e15 12358 return NULL_TREE;
0a39fd54 12359
12360 /* If return value of __stpcpy_chk is ignored,
12361 optimize into __strcpy_chk. */
12362 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
12363 if (!fn)
c2f47e15 12364 return NULL_TREE;
0a39fd54 12365
389dd41b 12366 return build_call_expr_loc (loc, fn, 3, dest, src, size);
0a39fd54 12367 }
12368
12369 if (! len || TREE_SIDE_EFFECTS (len))
c2f47e15 12370 return NULL_TREE;
0a39fd54 12371
12372 /* If c_strlen returned something, but not a constant,
12373 transform __strcpy_chk into __memcpy_chk. */
12374 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12375 if (!fn)
c2f47e15 12376 return NULL_TREE;
0a39fd54 12377
389dd41b 12378 len = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
12379 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
12380 build_call_expr_loc (loc, fn, 4,
12381 dest, src, len, size));
0a39fd54 12382 }
0a39fd54 12383 }
ad89623c 12384 else
12385 maxlen = len;
12386
12387 if (! tree_int_cst_lt (maxlen, size))
c2f47e15 12388 return NULL_TREE;
0a39fd54 12389 }
12390
0a39fd54 12391 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
12392 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
12393 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
12394 if (!fn)
c2f47e15 12395 return NULL_TREE;
0a39fd54 12396
389dd41b 12397 return build_call_expr_loc (loc, fn, 2, dest, src);
0a39fd54 12398}
12399
c2f47e15 12400/* Fold a call to the __strncpy_chk builtin. DEST, SRC, LEN, and SIZE
12401 are the arguments to the call. If MAXLEN is not NULL, it is maximum
12402 length passed as third argument. */
0a39fd54 12403
12404tree
389dd41b 12405fold_builtin_strncpy_chk (location_t loc, tree dest, tree src,
12406 tree len, tree size, tree maxlen)
0a39fd54 12407{
c2f47e15 12408 tree fn;
0a39fd54 12409
c2f47e15 12410 if (!validate_arg (dest, POINTER_TYPE)
12411 || !validate_arg (src, POINTER_TYPE)
12412 || !validate_arg (len, INTEGER_TYPE)
12413 || !validate_arg (size, INTEGER_TYPE))
12414 return NULL_TREE;
0a39fd54 12415
12416 if (! host_integerp (size, 1))
c2f47e15 12417 return NULL_TREE;
0a39fd54 12418
12419 if (! integer_all_onesp (size))
12420 {
12421 if (! host_integerp (len, 1))
12422 {
12423 /* If LEN is not constant, try MAXLEN too.
12424 For MAXLEN only allow optimizing into non-_ocs function
12425 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12426 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
c2f47e15 12427 return NULL_TREE;
0a39fd54 12428 }
ad89623c 12429 else
12430 maxlen = len;
0a39fd54 12431
ad89623c 12432 if (tree_int_cst_lt (size, maxlen))
c2f47e15 12433 return NULL_TREE;
0a39fd54 12434 }
12435
0a39fd54 12436 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
12437 fn = built_in_decls[BUILT_IN_STRNCPY];
12438 if (!fn)
c2f47e15 12439 return NULL_TREE;
0a39fd54 12440
389dd41b 12441 return build_call_expr_loc (loc, fn, 3, dest, src, len);
0a39fd54 12442}
12443
c2f47e15 12444/* Fold a call to the __strcat_chk builtin FNDECL. DEST, SRC, and SIZE
12445 are the arguments to the call. */
0a39fd54 12446
12447static tree
389dd41b 12448fold_builtin_strcat_chk (location_t loc, tree fndecl, tree dest,
12449 tree src, tree size)
0a39fd54 12450{
c2f47e15 12451 tree fn;
0a39fd54 12452 const char *p;
12453
c2f47e15 12454 if (!validate_arg (dest, POINTER_TYPE)
12455 || !validate_arg (src, POINTER_TYPE)
12456 || !validate_arg (size, INTEGER_TYPE))
12457 return NULL_TREE;
0a39fd54 12458
12459 p = c_getstr (src);
12460 /* If the SRC parameter is "", return DEST. */
12461 if (p && *p == '\0')
389dd41b 12462 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
0a39fd54 12463
12464 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
c2f47e15 12465 return NULL_TREE;
0a39fd54 12466
12467 /* If __builtin_strcat_chk is used, assume strcat is available. */
12468 fn = built_in_decls[BUILT_IN_STRCAT];
12469 if (!fn)
c2f47e15 12470 return NULL_TREE;
0a39fd54 12471
389dd41b 12472 return build_call_expr_loc (loc, fn, 2, dest, src);
0a39fd54 12473}
12474
c2f47e15 12475/* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
12476 LEN, and SIZE. */
0a39fd54 12477
12478static tree
389dd41b 12479fold_builtin_strncat_chk (location_t loc, tree fndecl,
c2f47e15 12480 tree dest, tree src, tree len, tree size)
0a39fd54 12481{
c2f47e15 12482 tree fn;
0a39fd54 12483 const char *p;
12484
c2f47e15 12485 if (!validate_arg (dest, POINTER_TYPE)
12486 || !validate_arg (src, POINTER_TYPE)
12487 || !validate_arg (size, INTEGER_TYPE)
12488 || !validate_arg (size, INTEGER_TYPE))
12489 return NULL_TREE;
0a39fd54 12490
12491 p = c_getstr (src);
12492 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
12493 if (p && *p == '\0')
389dd41b 12494 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
0a39fd54 12495 else if (integer_zerop (len))
389dd41b 12496 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
0a39fd54 12497
12498 if (! host_integerp (size, 1))
c2f47e15 12499 return NULL_TREE;
0a39fd54 12500
12501 if (! integer_all_onesp (size))
12502 {
12503 tree src_len = c_strlen (src, 1);
12504 if (src_len
12505 && host_integerp (src_len, 1)
12506 && host_integerp (len, 1)
12507 && ! tree_int_cst_lt (len, src_len))
12508 {
12509 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
12510 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
12511 if (!fn)
c2f47e15 12512 return NULL_TREE;
0a39fd54 12513
389dd41b 12514 return build_call_expr_loc (loc, fn, 3, dest, src, size);
0a39fd54 12515 }
c2f47e15 12516 return NULL_TREE;
0a39fd54 12517 }
12518
0a39fd54 12519 /* If __builtin_strncat_chk is used, assume strncat is available. */
12520 fn = built_in_decls[BUILT_IN_STRNCAT];
12521 if (!fn)
c2f47e15 12522 return NULL_TREE;
0a39fd54 12523
389dd41b 12524 return build_call_expr_loc (loc, fn, 3, dest, src, len);
0a39fd54 12525}
12526
c2f47e15 12527/* Fold a call EXP to __{,v}sprintf_chk. Return NULL_TREE if
0a39fd54 12528 a normal call should be emitted rather than expanding the function
12529 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
12530
12531static tree
389dd41b 12532fold_builtin_sprintf_chk (location_t loc, tree exp,
12533 enum built_in_function fcode)
0a39fd54 12534{
12535 tree dest, size, len, fn, fmt, flag;
12536 const char *fmt_str;
c2f47e15 12537 int nargs = call_expr_nargs (exp);
0a39fd54 12538
12539 /* Verify the required arguments in the original call. */
c2f47e15 12540 if (nargs < 4)
12541 return NULL_TREE;
12542 dest = CALL_EXPR_ARG (exp, 0);
12543 if (!validate_arg (dest, POINTER_TYPE))
12544 return NULL_TREE;
12545 flag = CALL_EXPR_ARG (exp, 1);
12546 if (!validate_arg (flag, INTEGER_TYPE))
12547 return NULL_TREE;
12548 size = CALL_EXPR_ARG (exp, 2);
12549 if (!validate_arg (size, INTEGER_TYPE))
12550 return NULL_TREE;
12551 fmt = CALL_EXPR_ARG (exp, 3);
12552 if (!validate_arg (fmt, POINTER_TYPE))
12553 return NULL_TREE;
0a39fd54 12554
12555 if (! host_integerp (size, 1))
c2f47e15 12556 return NULL_TREE;
0a39fd54 12557
12558 len = NULL_TREE;
12559
d4473c84 12560 if (!init_target_chars ())
c2f47e15 12561 return NULL_TREE;
99eabcc1 12562
0a39fd54 12563 /* Check whether the format is a literal string constant. */
12564 fmt_str = c_getstr (fmt);
12565 if (fmt_str != NULL)
12566 {
12567 /* If the format doesn't contain % args or %%, we know the size. */
99eabcc1 12568 if (strchr (fmt_str, target_percent) == 0)
0a39fd54 12569 {
c2f47e15 12570 if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
0a39fd54 12571 len = build_int_cstu (size_type_node, strlen (fmt_str));
12572 }
12573 /* If the format is "%s" and first ... argument is a string literal,
12574 we know the size too. */
c2f47e15 12575 else if (fcode == BUILT_IN_SPRINTF_CHK
12576 && strcmp (fmt_str, target_percent_s) == 0)
0a39fd54 12577 {
12578 tree arg;
12579
c2f47e15 12580 if (nargs == 5)
0a39fd54 12581 {
c2f47e15 12582 arg = CALL_EXPR_ARG (exp, 4);
12583 if (validate_arg (arg, POINTER_TYPE))
0a39fd54 12584 {
12585 len = c_strlen (arg, 1);
12586 if (! len || ! host_integerp (len, 1))
12587 len = NULL_TREE;
12588 }
12589 }
12590 }
12591 }
12592
12593 if (! integer_all_onesp (size))
12594 {
12595 if (! len || ! tree_int_cst_lt (len, size))
c2f47e15 12596 return NULL_TREE;
0a39fd54 12597 }
12598
12599 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
12600 or if format doesn't contain % chars or is "%s". */
12601 if (! integer_zerop (flag))
12602 {
12603 if (fmt_str == NULL)
c2f47e15 12604 return NULL_TREE;
12605 if (strchr (fmt_str, target_percent) != NULL
12606 && strcmp (fmt_str, target_percent_s))
12607 return NULL_TREE;
0a39fd54 12608 }
12609
0a39fd54 12610 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
12611 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
12612 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
12613 if (!fn)
c2f47e15 12614 return NULL_TREE;
0a39fd54 12615
389dd41b 12616 return rewrite_call_expr (loc, exp, 4, fn, 2, dest, fmt);
0a39fd54 12617}
12618
c2f47e15 12619/* Fold a call EXP to {,v}snprintf. Return NULL_TREE if
0a39fd54 12620 a normal call should be emitted rather than expanding the function
12621 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
12622 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
12623 passed as second argument. */
12624
12625tree
389dd41b 12626fold_builtin_snprintf_chk (location_t loc, tree exp, tree maxlen,
0a39fd54 12627 enum built_in_function fcode)
12628{
12629 tree dest, size, len, fn, fmt, flag;
12630 const char *fmt_str;
12631
12632 /* Verify the required arguments in the original call. */
c2f47e15 12633 if (call_expr_nargs (exp) < 5)
12634 return NULL_TREE;
12635 dest = CALL_EXPR_ARG (exp, 0);
12636 if (!validate_arg (dest, POINTER_TYPE))
12637 return NULL_TREE;
12638 len = CALL_EXPR_ARG (exp, 1);
12639 if (!validate_arg (len, INTEGER_TYPE))
12640 return NULL_TREE;
12641 flag = CALL_EXPR_ARG (exp, 2);
12642 if (!validate_arg (flag, INTEGER_TYPE))
12643 return NULL_TREE;
12644 size = CALL_EXPR_ARG (exp, 3);
12645 if (!validate_arg (size, INTEGER_TYPE))
12646 return NULL_TREE;
12647 fmt = CALL_EXPR_ARG (exp, 4);
12648 if (!validate_arg (fmt, POINTER_TYPE))
12649 return NULL_TREE;
0a39fd54 12650
12651 if (! host_integerp (size, 1))
c2f47e15 12652 return NULL_TREE;
0a39fd54 12653
12654 if (! integer_all_onesp (size))
12655 {
12656 if (! host_integerp (len, 1))
12657 {
12658 /* If LEN is not constant, try MAXLEN too.
12659 For MAXLEN only allow optimizing into non-_ocs function
12660 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12661 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
c2f47e15 12662 return NULL_TREE;
0a39fd54 12663 }
ad89623c 12664 else
12665 maxlen = len;
0a39fd54 12666
ad89623c 12667 if (tree_int_cst_lt (size, maxlen))
c2f47e15 12668 return NULL_TREE;
0a39fd54 12669 }
12670
d4473c84 12671 if (!init_target_chars ())
c2f47e15 12672 return NULL_TREE;
99eabcc1 12673
0a39fd54 12674 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
12675 or if format doesn't contain % chars or is "%s". */
12676 if (! integer_zerop (flag))
12677 {
12678 fmt_str = c_getstr (fmt);
12679 if (fmt_str == NULL)
c2f47e15 12680 return NULL_TREE;
12681 if (strchr (fmt_str, target_percent) != NULL
12682 && strcmp (fmt_str, target_percent_s))
12683 return NULL_TREE;
0a39fd54 12684 }
12685
0a39fd54 12686 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
12687 available. */
12688 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
12689 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
12690 if (!fn)
c2f47e15 12691 return NULL_TREE;
0a39fd54 12692
389dd41b 12693 return rewrite_call_expr (loc, exp, 5, fn, 3, dest, len, fmt);
0a39fd54 12694}
12695
12696/* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
c2f47e15 12697 FMT and ARG are the arguments to the call; we don't fold cases with
12698 more than 2 arguments, and ARG may be null if this is a 1-argument case.
0a39fd54 12699
c2f47e15 12700 Return NULL_TREE if no simplification was possible, otherwise return the
0a39fd54 12701 simplified form of the call as a tree. FCODE is the BUILT_IN_*
12702 code of the function to be simplified. */
12703
12704static tree
389dd41b 12705fold_builtin_printf (location_t loc, tree fndecl, tree fmt,
12706 tree arg, bool ignore,
0a39fd54 12707 enum built_in_function fcode)
12708{
c2f47e15 12709 tree fn_putchar, fn_puts, newarg, call = NULL_TREE;
0a39fd54 12710 const char *fmt_str = NULL;
12711
12712 /* If the return value is used, don't do the transformation. */
12713 if (! ignore)
c2f47e15 12714 return NULL_TREE;
0a39fd54 12715
12716 /* Verify the required arguments in the original call. */
c2f47e15 12717 if (!validate_arg (fmt, POINTER_TYPE))
12718 return NULL_TREE;
0a39fd54 12719
12720 /* Check whether the format is a literal string constant. */
12721 fmt_str = c_getstr (fmt);
12722 if (fmt_str == NULL)
12723 return NULL_TREE;
12724
12725 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
12726 {
6d77ed92 12727 /* If we're using an unlocked function, assume the other
12728 unlocked functions exist explicitly. */
12729 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
12730 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
0a39fd54 12731 }
12732 else
12733 {
12734 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
12735 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
12736 }
12737
d4473c84 12738 if (!init_target_chars ())
c2f47e15 12739 return NULL_TREE;
a0c938f0 12740
c2f47e15 12741 if (strcmp (fmt_str, target_percent_s) == 0
12742 || strchr (fmt_str, target_percent) == NULL)
0a39fd54 12743 {
12744 const char *str;
12745
99eabcc1 12746 if (strcmp (fmt_str, target_percent_s) == 0)
0a39fd54 12747 {
12748 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
c2f47e15 12749 return NULL_TREE;
0a39fd54 12750
c2f47e15 12751 if (!arg || !validate_arg (arg, POINTER_TYPE))
12752 return NULL_TREE;
0a39fd54 12753
c2f47e15 12754 str = c_getstr (arg);
0a39fd54 12755 if (str == NULL)
c2f47e15 12756 return NULL_TREE;
0a39fd54 12757 }
12758 else
12759 {
12760 /* The format specifier doesn't contain any '%' characters. */
12761 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
c2f47e15 12762 && arg)
12763 return NULL_TREE;
0a39fd54 12764 str = fmt_str;
12765 }
12766
12767 /* If the string was "", printf does nothing. */
12768 if (str[0] == '\0')
12769 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
12770
12771 /* If the string has length of 1, call putchar. */
12772 if (str[1] == '\0')
12773 {
12774 /* Given printf("c"), (where c is any one character,)
12775 convert "c"[0] to an int and pass that to the replacement
12776 function. */
c2f47e15 12777 newarg = build_int_cst (NULL_TREE, str[0]);
12778 if (fn_putchar)
389dd41b 12779 call = build_call_expr_loc (loc, fn_putchar, 1, newarg);
0a39fd54 12780 }
12781 else
12782 {
12783 /* If the string was "string\n", call puts("string"). */
12784 size_t len = strlen (str);
99eabcc1 12785 if ((unsigned char)str[len - 1] == target_newline)
0a39fd54 12786 {
12787 /* Create a NUL-terminated string that's one char shorter
12788 than the original, stripping off the trailing '\n'. */
364c0c59 12789 char *newstr = XALLOCAVEC (char, len);
0a39fd54 12790 memcpy (newstr, str, len - 1);
12791 newstr[len - 1] = 0;
12792
c2f47e15 12793 newarg = build_string_literal (len, newstr);
12794 if (fn_puts)
389dd41b 12795 call = build_call_expr_loc (loc, fn_puts, 1, newarg);
0a39fd54 12796 }
12797 else
12798 /* We'd like to arrange to call fputs(string,stdout) here,
12799 but we need stdout and don't have a way to get it yet. */
c2f47e15 12800 return NULL_TREE;
0a39fd54 12801 }
12802 }
12803
12804 /* The other optimizations can be done only on the non-va_list variants. */
12805 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
c2f47e15 12806 return NULL_TREE;
0a39fd54 12807
12808 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
99eabcc1 12809 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
0a39fd54 12810 {
c2f47e15 12811 if (!arg || !validate_arg (arg, POINTER_TYPE))
12812 return NULL_TREE;
12813 if (fn_puts)
389dd41b 12814 call = build_call_expr_loc (loc, fn_puts, 1, arg);
0a39fd54 12815 }
12816
12817 /* If the format specifier was "%c", call __builtin_putchar(arg). */
99eabcc1 12818 else if (strcmp (fmt_str, target_percent_c) == 0)
0a39fd54 12819 {
c2f47e15 12820 if (!arg || !validate_arg (arg, INTEGER_TYPE))
12821 return NULL_TREE;
12822 if (fn_putchar)
389dd41b 12823 call = build_call_expr_loc (loc, fn_putchar, 1, arg);
0a39fd54 12824 }
12825
c2f47e15 12826 if (!call)
12827 return NULL_TREE;
0a39fd54 12828
389dd41b 12829 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), call);
0a39fd54 12830}
12831
12832/* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
c2f47e15 12833 FP, FMT, and ARG are the arguments to the call. We don't fold calls with
12834 more than 3 arguments, and ARG may be null in the 2-argument case.
0a39fd54 12835
c2f47e15 12836 Return NULL_TREE if no simplification was possible, otherwise return the
0a39fd54 12837 simplified form of the call as a tree. FCODE is the BUILT_IN_*
12838 code of the function to be simplified. */
12839
12840static tree
389dd41b 12841fold_builtin_fprintf (location_t loc, tree fndecl, tree fp,
12842 tree fmt, tree arg, bool ignore,
0a39fd54 12843 enum built_in_function fcode)
12844{
c2f47e15 12845 tree fn_fputc, fn_fputs, call = NULL_TREE;
0a39fd54 12846 const char *fmt_str = NULL;
12847
12848 /* If the return value is used, don't do the transformation. */
12849 if (! ignore)
c2f47e15 12850 return NULL_TREE;
0a39fd54 12851
12852 /* Verify the required arguments in the original call. */
c2f47e15 12853 if (!validate_arg (fp, POINTER_TYPE))
12854 return NULL_TREE;
12855 if (!validate_arg (fmt, POINTER_TYPE))
12856 return NULL_TREE;
0a39fd54 12857
12858 /* Check whether the format is a literal string constant. */
12859 fmt_str = c_getstr (fmt);
12860 if (fmt_str == NULL)
12861 return NULL_TREE;
12862
12863 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
12864 {
6d77ed92 12865 /* If we're using an unlocked function, assume the other
12866 unlocked functions exist explicitly. */
12867 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
12868 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
0a39fd54 12869 }
12870 else
12871 {
12872 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
12873 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
12874 }
12875
d4473c84 12876 if (!init_target_chars ())
c2f47e15 12877 return NULL_TREE;
a0c938f0 12878
0a39fd54 12879 /* If the format doesn't contain % args or %%, use strcpy. */
99eabcc1 12880 if (strchr (fmt_str, target_percent) == NULL)
0a39fd54 12881 {
12882 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
c2f47e15 12883 && arg)
12884 return NULL_TREE;
0a39fd54 12885
12886 /* If the format specifier was "", fprintf does nothing. */
12887 if (fmt_str[0] == '\0')
12888 {
12889 /* If FP has side-effects, just wait until gimplification is
12890 done. */
12891 if (TREE_SIDE_EFFECTS (fp))
c2f47e15 12892 return NULL_TREE;
0a39fd54 12893
12894 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
12895 }
12896
12897 /* When "string" doesn't contain %, replace all cases of
12898 fprintf (fp, string) with fputs (string, fp). The fputs
12899 builtin will take care of special cases like length == 1. */
c2f47e15 12900 if (fn_fputs)
389dd41b 12901 call = build_call_expr_loc (loc, fn_fputs, 2, fmt, fp);
0a39fd54 12902 }
12903
12904 /* The other optimizations can be done only on the non-va_list variants. */
12905 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
c2f47e15 12906 return NULL_TREE;
0a39fd54 12907
12908 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
99eabcc1 12909 else if (strcmp (fmt_str, target_percent_s) == 0)
0a39fd54 12910 {
c2f47e15 12911 if (!arg || !validate_arg (arg, POINTER_TYPE))
12912 return NULL_TREE;
12913 if (fn_fputs)
389dd41b 12914 call = build_call_expr_loc (loc, fn_fputs, 2, arg, fp);
0a39fd54 12915 }
12916
12917 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
99eabcc1 12918 else if (strcmp (fmt_str, target_percent_c) == 0)
0a39fd54 12919 {
c2f47e15 12920 if (!arg || !validate_arg (arg, INTEGER_TYPE))
12921 return NULL_TREE;
12922 if (fn_fputc)
389dd41b 12923 call = build_call_expr_loc (loc, fn_fputc, 2, arg, fp);
0a39fd54 12924 }
12925
c2f47e15 12926 if (!call)
12927 return NULL_TREE;
389dd41b 12928 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), call);
0a39fd54 12929}
99eabcc1 12930
12931/* Initialize format string characters in the target charset. */
12932
12933static bool
12934init_target_chars (void)
12935{
12936 static bool init;
12937 if (!init)
12938 {
12939 target_newline = lang_hooks.to_target_charset ('\n');
12940 target_percent = lang_hooks.to_target_charset ('%');
12941 target_c = lang_hooks.to_target_charset ('c');
12942 target_s = lang_hooks.to_target_charset ('s');
12943 if (target_newline == 0 || target_percent == 0 || target_c == 0
12944 || target_s == 0)
12945 return false;
12946
12947 target_percent_c[0] = target_percent;
12948 target_percent_c[1] = target_c;
12949 target_percent_c[2] = '\0';
12950
12951 target_percent_s[0] = target_percent;
12952 target_percent_s[1] = target_s;
12953 target_percent_s[2] = '\0';
12954
12955 target_percent_s_newline[0] = target_percent;
12956 target_percent_s_newline[1] = target_s;
12957 target_percent_s_newline[2] = target_newline;
12958 target_percent_s_newline[3] = '\0';
a0c938f0 12959
99eabcc1 12960 init = true;
12961 }
12962 return true;
12963}
bffb7645 12964
f0c477f2 12965/* Helper function for do_mpfr_arg*(). Ensure M is a normal number
12966 and no overflow/underflow occurred. INEXACT is true if M was not
fa7637bd 12967 exactly calculated. TYPE is the tree type for the result. This
f0c477f2 12968 function assumes that you cleared the MPFR flags and then
12969 calculated M to see if anything subsequently set a flag prior to
12970 entering this function. Return NULL_TREE if any checks fail. */
12971
12972static tree
d4473c84 12973do_mpfr_ckconv (mpfr_srcptr m, tree type, int inexact)
f0c477f2 12974{
12975 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
12976 overflow/underflow occurred. If -frounding-math, proceed iff the
12977 result of calling FUNC was exact. */
d4473c84 12978 if (mpfr_number_p (m) && !mpfr_overflow_p () && !mpfr_underflow_p ()
f0c477f2 12979 && (!flag_rounding_math || !inexact))
12980 {
12981 REAL_VALUE_TYPE rr;
12982
66fa16e6 12983 real_from_mpfr (&rr, m, type, GMP_RNDN);
f0c477f2 12984 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
12985 check for overflow/underflow. If the REAL_VALUE_TYPE is zero
12986 but the mpft_t is not, then we underflowed in the
12987 conversion. */
776a7bab 12988 if (real_isfinite (&rr)
f0c477f2 12989 && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
12990 {
12991 REAL_VALUE_TYPE rmode;
12992
12993 real_convert (&rmode, TYPE_MODE (type), &rr);
12994 /* Proceed iff the specified mode can hold the value. */
12995 if (real_identical (&rmode, &rr))
12996 return build_real (type, rmode);
12997 }
12998 }
12999 return NULL_TREE;
13000}
13001
239d491a 13002#ifdef HAVE_mpc
13003/* Helper function for do_mpc_arg*(). Ensure M is a normal complex
13004 number and no overflow/underflow occurred. INEXACT is true if M
13005 was not exactly calculated. TYPE is the tree type for the result.
13006 This function assumes that you cleared the MPFR flags and then
13007 calculated M to see if anything subsequently set a flag prior to
652d9409 13008 entering this function. Return NULL_TREE if any checks fail, if
13009 FORCE_CONVERT is true, then bypass the checks. */
239d491a 13010
13011static tree
652d9409 13012do_mpc_ckconv (mpc_srcptr m, tree type, int inexact, int force_convert)
239d491a 13013{
13014 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13015 overflow/underflow occurred. If -frounding-math, proceed iff the
13016 result of calling FUNC was exact. */
652d9409 13017 if (force_convert
13018 || (mpfr_number_p (mpc_realref (m)) && mpfr_number_p (mpc_imagref (m))
13019 && !mpfr_overflow_p () && !mpfr_underflow_p ()
13020 && (!flag_rounding_math || !inexact)))
239d491a 13021 {
13022 REAL_VALUE_TYPE re, im;
13023
c3cfad90 13024 real_from_mpfr (&re, mpc_realref (m), type, GMP_RNDN);
13025 real_from_mpfr (&im, mpc_imagref (m), type, GMP_RNDN);
239d491a 13026 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR values,
13027 check for overflow/underflow. If the REAL_VALUE_TYPE is zero
13028 but the mpft_t is not, then we underflowed in the
13029 conversion. */
652d9409 13030 if (force_convert
13031 || (real_isfinite (&re) && real_isfinite (&im)
13032 && (re.cl == rvc_zero) == (mpfr_zero_p (mpc_realref (m)) != 0)
13033 && (im.cl == rvc_zero) == (mpfr_zero_p (mpc_imagref (m)) != 0)))
239d491a 13034 {
13035 REAL_VALUE_TYPE re_mode, im_mode;
13036
13037 real_convert (&re_mode, TYPE_MODE (TREE_TYPE (type)), &re);
13038 real_convert (&im_mode, TYPE_MODE (TREE_TYPE (type)), &im);
13039 /* Proceed iff the specified mode can hold the value. */
652d9409 13040 if (force_convert
13041 || (real_identical (&re_mode, &re)
13042 && real_identical (&im_mode, &im)))
239d491a 13043 return build_complex (type, build_real (TREE_TYPE (type), re_mode),
13044 build_real (TREE_TYPE (type), im_mode));
13045 }
13046 }
13047 return NULL_TREE;
13048}
13049#endif /* HAVE_mpc */
13050
bffb7645 13051/* If argument ARG is a REAL_CST, call the one-argument mpfr function
13052 FUNC on it and return the resulting value as a tree with type TYPE.
728bac60 13053 If MIN and/or MAX are not NULL, then the supplied ARG must be
13054 within those bounds. If INCLUSIVE is true, then MIN/MAX are
13055 acceptable values, otherwise they are not. The mpfr precision is
13056 set to the precision of TYPE. We assume that function FUNC returns
13057 zero if the result could be calculated exactly within the requested
13058 precision. */
bffb7645 13059
13060static tree
728bac60 13061do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
13062 const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
13063 bool inclusive)
bffb7645 13064{
13065 tree result = NULL_TREE;
13066
13067 STRIP_NOPS (arg);
13068
bd7d6fa4 13069 /* To proceed, MPFR must exactly represent the target floating point
13070 format, which only happens when the target base equals two. */
13071 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
f96bd2bf 13072 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
bffb7645 13073 {
f0c477f2 13074 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
bffb7645 13075
776a7bab 13076 if (real_isfinite (ra)
f0c477f2 13077 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
13078 && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
bffb7645 13079 {
e2eb2b7f 13080 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13081 const int prec = fmt->p;
13082 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
debf9994 13083 int inexact;
bffb7645 13084 mpfr_t m;
13085
13086 mpfr_init2 (m, prec);
66fa16e6 13087 mpfr_from_real (m, ra, GMP_RNDN);
d4473c84 13088 mpfr_clear_flags ();
e2eb2b7f 13089 inexact = func (m, m, rnd);
f0c477f2 13090 result = do_mpfr_ckconv (m, type, inexact);
bffb7645 13091 mpfr_clear (m);
13092 }
13093 }
13094
13095 return result;
13096}
f0c477f2 13097
13098/* If argument ARG is a REAL_CST, call the two-argument mpfr function
13099 FUNC on it and return the resulting value as a tree with type TYPE.
13100 The mpfr precision is set to the precision of TYPE. We assume that
13101 function FUNC returns zero if the result could be calculated
13102 exactly within the requested precision. */
13103
13104static tree
13105do_mpfr_arg2 (tree arg1, tree arg2, tree type,
13106 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13107{
13108 tree result = NULL_TREE;
13109
13110 STRIP_NOPS (arg1);
13111 STRIP_NOPS (arg2);
13112
bd7d6fa4 13113 /* To proceed, MPFR must exactly represent the target floating point
13114 format, which only happens when the target base equals two. */
13115 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
f96bd2bf 13116 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13117 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
f0c477f2 13118 {
13119 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13120 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13121
776a7bab 13122 if (real_isfinite (ra1) && real_isfinite (ra2))
f0c477f2 13123 {
e2eb2b7f 13124 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13125 const int prec = fmt->p;
13126 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
f0c477f2 13127 int inexact;
13128 mpfr_t m1, m2;
13129
13130 mpfr_inits2 (prec, m1, m2, NULL);
66fa16e6 13131 mpfr_from_real (m1, ra1, GMP_RNDN);
13132 mpfr_from_real (m2, ra2, GMP_RNDN);
d4473c84 13133 mpfr_clear_flags ();
e2eb2b7f 13134 inexact = func (m1, m1, m2, rnd);
f0c477f2 13135 result = do_mpfr_ckconv (m1, type, inexact);
13136 mpfr_clears (m1, m2, NULL);
13137 }
13138 }
13139
13140 return result;
13141}
d92f994c 13142
9917422b 13143/* If argument ARG is a REAL_CST, call the three-argument mpfr function
13144 FUNC on it and return the resulting value as a tree with type TYPE.
13145 The mpfr precision is set to the precision of TYPE. We assume that
13146 function FUNC returns zero if the result could be calculated
13147 exactly within the requested precision. */
13148
13149static tree
13150do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
13151 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13152{
13153 tree result = NULL_TREE;
13154
13155 STRIP_NOPS (arg1);
13156 STRIP_NOPS (arg2);
13157 STRIP_NOPS (arg3);
13158
bd7d6fa4 13159 /* To proceed, MPFR must exactly represent the target floating point
13160 format, which only happens when the target base equals two. */
13161 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
f96bd2bf 13162 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13163 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)
13164 && TREE_CODE (arg3) == REAL_CST && !TREE_OVERFLOW (arg3))
9917422b 13165 {
13166 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13167 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13168 const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
13169
776a7bab 13170 if (real_isfinite (ra1) && real_isfinite (ra2) && real_isfinite (ra3))
9917422b 13171 {
e2eb2b7f 13172 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13173 const int prec = fmt->p;
13174 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
9917422b 13175 int inexact;
13176 mpfr_t m1, m2, m3;
13177
13178 mpfr_inits2 (prec, m1, m2, m3, NULL);
66fa16e6 13179 mpfr_from_real (m1, ra1, GMP_RNDN);
13180 mpfr_from_real (m2, ra2, GMP_RNDN);
13181 mpfr_from_real (m3, ra3, GMP_RNDN);
d4473c84 13182 mpfr_clear_flags ();
e2eb2b7f 13183 inexact = func (m1, m1, m2, m3, rnd);
9917422b 13184 result = do_mpfr_ckconv (m1, type, inexact);
13185 mpfr_clears (m1, m2, m3, NULL);
13186 }
13187 }
13188
13189 return result;
13190}
13191
d92f994c 13192/* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
13193 the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
d735c391 13194 If ARG_SINP and ARG_COSP are NULL then the result is returned
13195 as a complex value.
d92f994c 13196 The type is taken from the type of ARG and is used for setting the
13197 precision of the calculation and results. */
13198
13199static tree
13200do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
13201{
bd7d6fa4 13202 tree const type = TREE_TYPE (arg);
d92f994c 13203 tree result = NULL_TREE;
13204
13205 STRIP_NOPS (arg);
13206
bd7d6fa4 13207 /* To proceed, MPFR must exactly represent the target floating point
13208 format, which only happens when the target base equals two. */
13209 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
f96bd2bf 13210 && TREE_CODE (arg) == REAL_CST
13211 && !TREE_OVERFLOW (arg))
d92f994c 13212 {
13213 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
13214
776a7bab 13215 if (real_isfinite (ra))
d92f994c 13216 {
e2eb2b7f 13217 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13218 const int prec = fmt->p;
13219 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
d92f994c 13220 tree result_s, result_c;
13221 int inexact;
13222 mpfr_t m, ms, mc;
13223
13224 mpfr_inits2 (prec, m, ms, mc, NULL);
66fa16e6 13225 mpfr_from_real (m, ra, GMP_RNDN);
d4473c84 13226 mpfr_clear_flags ();
e2eb2b7f 13227 inexact = mpfr_sin_cos (ms, mc, m, rnd);
d92f994c 13228 result_s = do_mpfr_ckconv (ms, type, inexact);
13229 result_c = do_mpfr_ckconv (mc, type, inexact);
13230 mpfr_clears (m, ms, mc, NULL);
13231 if (result_s && result_c)
13232 {
d735c391 13233 /* If we are to return in a complex value do so. */
13234 if (!arg_sinp && !arg_cosp)
13235 return build_complex (build_complex_type (type),
13236 result_c, result_s);
13237
d92f994c 13238 /* Dereference the sin/cos pointer arguments. */
13239 arg_sinp = build_fold_indirect_ref (arg_sinp);
13240 arg_cosp = build_fold_indirect_ref (arg_cosp);
13241 /* Proceed if valid pointer type were passed in. */
13242 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
13243 && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
13244 {
13245 /* Set the values. */
41076ef6 13246 result_s = fold_build2 (MODIFY_EXPR, type, arg_sinp,
35cc02b5 13247 result_s);
d92f994c 13248 TREE_SIDE_EFFECTS (result_s) = 1;
41076ef6 13249 result_c = fold_build2 (MODIFY_EXPR, type, arg_cosp,
35cc02b5 13250 result_c);
d92f994c 13251 TREE_SIDE_EFFECTS (result_c) = 1;
13252 /* Combine the assignments into a compound expr. */
13253 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13254 result_s, result_c));
13255 }
13256 }
13257 }
13258 }
13259 return result;
13260}
65dd1378 13261
65dd1378 13262/* If argument ARG1 is an INTEGER_CST and ARG2 is a REAL_CST, call the
13263 two-argument mpfr order N Bessel function FUNC on them and return
13264 the resulting value as a tree with type TYPE. The mpfr precision
13265 is set to the precision of TYPE. We assume that function FUNC
13266 returns zero if the result could be calculated exactly within the
13267 requested precision. */
13268static tree
13269do_mpfr_bessel_n (tree arg1, tree arg2, tree type,
13270 int (*func)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
13271 const REAL_VALUE_TYPE *min, bool inclusive)
13272{
13273 tree result = NULL_TREE;
13274
13275 STRIP_NOPS (arg1);
13276 STRIP_NOPS (arg2);
13277
13278 /* To proceed, MPFR must exactly represent the target floating point
13279 format, which only happens when the target base equals two. */
13280 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13281 && host_integerp (arg1, 0)
13282 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
13283 {
13284 const HOST_WIDE_INT n = tree_low_cst(arg1, 0);
13285 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg2);
13286
13287 if (n == (long)n
776a7bab 13288 && real_isfinite (ra)
65dd1378 13289 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min)))
13290 {
e2eb2b7f 13291 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13292 const int prec = fmt->p;
13293 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
65dd1378 13294 int inexact;
13295 mpfr_t m;
13296
13297 mpfr_init2 (m, prec);
13298 mpfr_from_real (m, ra, GMP_RNDN);
13299 mpfr_clear_flags ();
e2eb2b7f 13300 inexact = func (m, n, m, rnd);
65dd1378 13301 result = do_mpfr_ckconv (m, type, inexact);
13302 mpfr_clear (m);
13303 }
13304 }
13305
13306 return result;
13307}
e5407ca6 13308
13309/* If arguments ARG0 and ARG1 are REAL_CSTs, call mpfr_remquo() to set
13310 the pointer *(ARG_QUO) and return the result. The type is taken
13311 from the type of ARG0 and is used for setting the precision of the
13312 calculation and results. */
13313
13314static tree
13315do_mpfr_remquo (tree arg0, tree arg1, tree arg_quo)
13316{
13317 tree const type = TREE_TYPE (arg0);
13318 tree result = NULL_TREE;
13319
13320 STRIP_NOPS (arg0);
13321 STRIP_NOPS (arg1);
13322
13323 /* To proceed, MPFR must exactly represent the target floating point
13324 format, which only happens when the target base equals two. */
13325 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13326 && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
13327 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1))
13328 {
13329 const REAL_VALUE_TYPE *const ra0 = TREE_REAL_CST_PTR (arg0);
13330 const REAL_VALUE_TYPE *const ra1 = TREE_REAL_CST_PTR (arg1);
13331
776a7bab 13332 if (real_isfinite (ra0) && real_isfinite (ra1))
e5407ca6 13333 {
e2eb2b7f 13334 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13335 const int prec = fmt->p;
13336 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
e5407ca6 13337 tree result_rem;
13338 long integer_quo;
13339 mpfr_t m0, m1;
13340
13341 mpfr_inits2 (prec, m0, m1, NULL);
13342 mpfr_from_real (m0, ra0, GMP_RNDN);
13343 mpfr_from_real (m1, ra1, GMP_RNDN);
13344 mpfr_clear_flags ();
e2eb2b7f 13345 mpfr_remquo (m0, &integer_quo, m0, m1, rnd);
e5407ca6 13346 /* Remquo is independent of the rounding mode, so pass
13347 inexact=0 to do_mpfr_ckconv(). */
13348 result_rem = do_mpfr_ckconv (m0, type, /*inexact=*/ 0);
13349 mpfr_clears (m0, m1, NULL);
13350 if (result_rem)
13351 {
13352 /* MPFR calculates quo in the host's long so it may
13353 return more bits in quo than the target int can hold
13354 if sizeof(host long) > sizeof(target int). This can
13355 happen even for native compilers in LP64 mode. In
13356 these cases, modulo the quo value with the largest
13357 number that the target int can hold while leaving one
13358 bit for the sign. */
13359 if (sizeof (integer_quo) * CHAR_BIT > INT_TYPE_SIZE)
13360 integer_quo %= (long)(1UL << (INT_TYPE_SIZE - 1));
13361
13362 /* Dereference the quo pointer argument. */
13363 arg_quo = build_fold_indirect_ref (arg_quo);
13364 /* Proceed iff a valid pointer type was passed in. */
13365 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_quo)) == integer_type_node)
13366 {
13367 /* Set the value. */
13368 tree result_quo = fold_build2 (MODIFY_EXPR,
13369 TREE_TYPE (arg_quo), arg_quo,
13370 build_int_cst (NULL, integer_quo));
13371 TREE_SIDE_EFFECTS (result_quo) = 1;
13372 /* Combine the quo assignment with the rem. */
13373 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13374 result_quo, result_rem));
13375 }
13376 }
13377 }
13378 }
13379 return result;
13380}
e84da7c1 13381
13382/* If ARG is a REAL_CST, call mpfr_lgamma() on it and return the
13383 resulting value as a tree with type TYPE. The mpfr precision is
13384 set to the precision of TYPE. We assume that this mpfr function
13385 returns zero if the result could be calculated exactly within the
13386 requested precision. In addition, the integer pointer represented
13387 by ARG_SG will be dereferenced and set to the appropriate signgam
13388 (-1,1) value. */
13389
13390static tree
13391do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type)
13392{
13393 tree result = NULL_TREE;
13394
13395 STRIP_NOPS (arg);
13396
13397 /* To proceed, MPFR must exactly represent the target floating point
13398 format, which only happens when the target base equals two. Also
13399 verify ARG is a constant and that ARG_SG is an int pointer. */
13400 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13401 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)
13402 && TREE_CODE (TREE_TYPE (arg_sg)) == POINTER_TYPE
13403 && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg_sg))) == integer_type_node)
13404 {
13405 const REAL_VALUE_TYPE *const ra = TREE_REAL_CST_PTR (arg);
13406
13407 /* In addition to NaN and Inf, the argument cannot be zero or a
13408 negative integer. */
776a7bab 13409 if (real_isfinite (ra)
e84da7c1 13410 && ra->cl != rvc_zero
13411 && !(real_isneg(ra) && real_isinteger(ra, TYPE_MODE (type))))
13412 {
e2eb2b7f 13413 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13414 const int prec = fmt->p;
13415 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
e84da7c1 13416 int inexact, sg;
13417 mpfr_t m;
13418 tree result_lg;
13419
13420 mpfr_init2 (m, prec);
13421 mpfr_from_real (m, ra, GMP_RNDN);
13422 mpfr_clear_flags ();
e2eb2b7f 13423 inexact = mpfr_lgamma (m, &sg, m, rnd);
e84da7c1 13424 result_lg = do_mpfr_ckconv (m, type, inexact);
13425 mpfr_clear (m);
13426 if (result_lg)
13427 {
13428 tree result_sg;
13429
13430 /* Dereference the arg_sg pointer argument. */
13431 arg_sg = build_fold_indirect_ref (arg_sg);
13432 /* Assign the signgam value into *arg_sg. */
13433 result_sg = fold_build2 (MODIFY_EXPR,
13434 TREE_TYPE (arg_sg), arg_sg,
13435 build_int_cst (NULL, sg));
13436 TREE_SIDE_EFFECTS (result_sg) = 1;
13437 /* Combine the signgam assignment with the lgamma result. */
13438 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13439 result_sg, result_lg));
13440 }
13441 }
13442 }
13443
13444 return result;
13445}
75a70cf9 13446
239d491a 13447#ifdef HAVE_mpc
13448/* If argument ARG is a COMPLEX_CST, call the one-argument mpc
13449 function FUNC on it and return the resulting value as a tree with
13450 type TYPE. The mpfr precision is set to the precision of TYPE. We
13451 assume that function FUNC returns zero if the result could be
13452 calculated exactly within the requested precision. */
13453
13454static tree
13455do_mpc_arg1 (tree arg, tree type, int (*func)(mpc_ptr, mpc_srcptr, mpc_rnd_t))
13456{
13457 tree result = NULL_TREE;
13458
13459 STRIP_NOPS (arg);
13460
13461 /* To proceed, MPFR must exactly represent the target floating point
13462 format, which only happens when the target base equals two. */
13463 if (TREE_CODE (arg) == COMPLEX_CST && !TREE_OVERFLOW (arg)
13464 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE
13465 && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg))))->b == 2)
13466 {
13467 const REAL_VALUE_TYPE *const re = TREE_REAL_CST_PTR (TREE_REALPART (arg));
13468 const REAL_VALUE_TYPE *const im = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
13469
13470 if (real_isfinite (re) && real_isfinite (im))
13471 {
13472 const struct real_format *const fmt =
13473 REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
13474 const int prec = fmt->p;
13475 const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
44d89feb 13476 const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
239d491a 13477 int inexact;
13478 mpc_t m;
13479
13480 mpc_init2 (m, prec);
c3cfad90 13481 mpfr_from_real (mpc_realref(m), re, rnd);
13482 mpfr_from_real (mpc_imagref(m), im, rnd);
239d491a 13483 mpfr_clear_flags ();
44d89feb 13484 inexact = func (m, m, crnd);
652d9409 13485 result = do_mpc_ckconv (m, type, inexact, /*force_convert=*/ 0);
239d491a 13486 mpc_clear (m);
13487 }
13488 }
13489
13490 return result;
13491}
c699fab8 13492
13493/* If arguments ARG0 and ARG1 are a COMPLEX_CST, call the two-argument
13494 mpc function FUNC on it and return the resulting value as a tree
13495 with type TYPE. The mpfr precision is set to the precision of
13496 TYPE. We assume that function FUNC returns zero if the result
652d9409 13497 could be calculated exactly within the requested precision. If
13498 DO_NONFINITE is true, then fold expressions containing Inf or NaN
13499 in the arguments and/or results. */
c699fab8 13500
63e89698 13501#ifdef HAVE_mpc
13502tree
652d9409 13503do_mpc_arg2 (tree arg0, tree arg1, tree type, int do_nonfinite,
c699fab8 13504 int (*func)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t))
13505{
13506 tree result = NULL_TREE;
13507
13508 STRIP_NOPS (arg0);
13509 STRIP_NOPS (arg1);
13510
13511 /* To proceed, MPFR must exactly represent the target floating point
13512 format, which only happens when the target base equals two. */
13513 if (TREE_CODE (arg0) == COMPLEX_CST && !TREE_OVERFLOW (arg0)
13514 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
13515 && TREE_CODE (arg1) == COMPLEX_CST && !TREE_OVERFLOW (arg1)
13516 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE
13517 && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))))->b == 2)
13518 {
13519 const REAL_VALUE_TYPE *const re0 = TREE_REAL_CST_PTR (TREE_REALPART (arg0));
13520 const REAL_VALUE_TYPE *const im0 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg0));
13521 const REAL_VALUE_TYPE *const re1 = TREE_REAL_CST_PTR (TREE_REALPART (arg1));
13522 const REAL_VALUE_TYPE *const im1 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg1));
13523
652d9409 13524 if (do_nonfinite
13525 || (real_isfinite (re0) && real_isfinite (im0)
13526 && real_isfinite (re1) && real_isfinite (im1)))
c699fab8 13527 {
13528 const struct real_format *const fmt =
13529 REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
13530 const int prec = fmt->p;
13531 const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
13532 const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
13533 int inexact;
13534 mpc_t m0, m1;
13535
13536 mpc_init2 (m0, prec);
13537 mpc_init2 (m1, prec);
13538 mpfr_from_real (mpc_realref(m0), re0, rnd);
13539 mpfr_from_real (mpc_imagref(m0), im0, rnd);
13540 mpfr_from_real (mpc_realref(m1), re1, rnd);
13541 mpfr_from_real (mpc_imagref(m1), im1, rnd);
13542 mpfr_clear_flags ();
13543 inexact = func (m0, m0, m1, crnd);
652d9409 13544 result = do_mpc_ckconv (m0, type, inexact, do_nonfinite);
c699fab8 13545 mpc_clear (m0);
13546 mpc_clear (m1);
13547 }
13548 }
13549
13550 return result;
13551}
13552# endif
239d491a 13553#endif /* HAVE_mpc */
13554
75a70cf9 13555/* FIXME tuples.
13556 The functions below provide an alternate interface for folding
13557 builtin function calls presented as GIMPLE_CALL statements rather
13558 than as CALL_EXPRs. The folded result is still expressed as a
13559 tree. There is too much code duplication in the handling of
13560 varargs functions, and a more intrusive re-factoring would permit
13561 better sharing of code between the tree and statement-based
13562 versions of these functions. */
13563
13564/* Construct a new CALL_EXPR using the tail of the argument list of STMT
13565 along with N new arguments specified as the "..." parameters. SKIP
13566 is the number of arguments in STMT to be omitted. This function is used
13567 to do varargs-to-varargs transformations. */
13568
13569static tree
13570gimple_rewrite_call_expr (gimple stmt, int skip, tree fndecl, int n, ...)
13571{
13572 int oldnargs = gimple_call_num_args (stmt);
13573 int nargs = oldnargs - skip + n;
13574 tree fntype = TREE_TYPE (fndecl);
13575 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
13576 tree *buffer;
13577 int i, j;
13578 va_list ap;
389dd41b 13579 location_t loc = gimple_location (stmt);
75a70cf9 13580
13581 buffer = XALLOCAVEC (tree, nargs);
13582 va_start (ap, n);
13583 for (i = 0; i < n; i++)
13584 buffer[i] = va_arg (ap, tree);
13585 va_end (ap);
13586 for (j = skip; j < oldnargs; j++, i++)
13587 buffer[i] = gimple_call_arg (stmt, j);
13588
389dd41b 13589 return fold (build_call_array_loc (loc, TREE_TYPE (fntype), fn, nargs, buffer));
75a70cf9 13590}
13591
13592/* Fold a call STMT to __{,v}sprintf_chk. Return NULL_TREE if
13593 a normal call should be emitted rather than expanding the function
13594 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
13595
13596static tree
13597gimple_fold_builtin_sprintf_chk (gimple stmt, enum built_in_function fcode)
13598{
13599 tree dest, size, len, fn, fmt, flag;
13600 const char *fmt_str;
13601 int nargs = gimple_call_num_args (stmt);
13602
13603 /* Verify the required arguments in the original call. */
13604 if (nargs < 4)
13605 return NULL_TREE;
13606 dest = gimple_call_arg (stmt, 0);
13607 if (!validate_arg (dest, POINTER_TYPE))
13608 return NULL_TREE;
13609 flag = gimple_call_arg (stmt, 1);
13610 if (!validate_arg (flag, INTEGER_TYPE))
13611 return NULL_TREE;
13612 size = gimple_call_arg (stmt, 2);
13613 if (!validate_arg (size, INTEGER_TYPE))
13614 return NULL_TREE;
13615 fmt = gimple_call_arg (stmt, 3);
13616 if (!validate_arg (fmt, POINTER_TYPE))
13617 return NULL_TREE;
13618
13619 if (! host_integerp (size, 1))
13620 return NULL_TREE;
13621
13622 len = NULL_TREE;
13623
13624 if (!init_target_chars ())
13625 return NULL_TREE;
13626
13627 /* Check whether the format is a literal string constant. */
13628 fmt_str = c_getstr (fmt);
13629 if (fmt_str != NULL)
13630 {
13631 /* If the format doesn't contain % args or %%, we know the size. */
13632 if (strchr (fmt_str, target_percent) == 0)
13633 {
13634 if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
13635 len = build_int_cstu (size_type_node, strlen (fmt_str));
13636 }
13637 /* If the format is "%s" and first ... argument is a string literal,
13638 we know the size too. */
13639 else if (fcode == BUILT_IN_SPRINTF_CHK
13640 && strcmp (fmt_str, target_percent_s) == 0)
13641 {
13642 tree arg;
13643
13644 if (nargs == 5)
13645 {
13646 arg = gimple_call_arg (stmt, 4);
13647 if (validate_arg (arg, POINTER_TYPE))
13648 {
13649 len = c_strlen (arg, 1);
13650 if (! len || ! host_integerp (len, 1))
13651 len = NULL_TREE;
13652 }
13653 }
13654 }
13655 }
13656
13657 if (! integer_all_onesp (size))
13658 {
13659 if (! len || ! tree_int_cst_lt (len, size))
13660 return NULL_TREE;
13661 }
13662
13663 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
13664 or if format doesn't contain % chars or is "%s". */
13665 if (! integer_zerop (flag))
13666 {
13667 if (fmt_str == NULL)
13668 return NULL_TREE;
13669 if (strchr (fmt_str, target_percent) != NULL
13670 && strcmp (fmt_str, target_percent_s))
13671 return NULL_TREE;
13672 }
13673
13674 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
13675 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
13676 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
13677 if (!fn)
13678 return NULL_TREE;
13679
13680 return gimple_rewrite_call_expr (stmt, 4, fn, 2, dest, fmt);
13681}
13682
13683/* Fold a call STMT to {,v}snprintf. Return NULL_TREE if
13684 a normal call should be emitted rather than expanding the function
13685 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
13686 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
13687 passed as second argument. */
13688
13689tree
13690gimple_fold_builtin_snprintf_chk (gimple stmt, tree maxlen,
13691 enum built_in_function fcode)
13692{
13693 tree dest, size, len, fn, fmt, flag;
13694 const char *fmt_str;
13695
13696 /* Verify the required arguments in the original call. */
13697 if (gimple_call_num_args (stmt) < 5)
13698 return NULL_TREE;
13699 dest = gimple_call_arg (stmt, 0);
13700 if (!validate_arg (dest, POINTER_TYPE))
13701 return NULL_TREE;
13702 len = gimple_call_arg (stmt, 1);
13703 if (!validate_arg (len, INTEGER_TYPE))
13704 return NULL_TREE;
13705 flag = gimple_call_arg (stmt, 2);
13706 if (!validate_arg (flag, INTEGER_TYPE))
13707 return NULL_TREE;
13708 size = gimple_call_arg (stmt, 3);
13709 if (!validate_arg (size, INTEGER_TYPE))
13710 return NULL_TREE;
13711 fmt = gimple_call_arg (stmt, 4);
13712 if (!validate_arg (fmt, POINTER_TYPE))
13713 return NULL_TREE;
13714
13715 if (! host_integerp (size, 1))
13716 return NULL_TREE;
13717
13718 if (! integer_all_onesp (size))
13719 {
13720 if (! host_integerp (len, 1))
13721 {
13722 /* If LEN is not constant, try MAXLEN too.
13723 For MAXLEN only allow optimizing into non-_ocs function
13724 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
13725 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
13726 return NULL_TREE;
13727 }
13728 else
13729 maxlen = len;
13730
13731 if (tree_int_cst_lt (size, maxlen))
13732 return NULL_TREE;
13733 }
13734
13735 if (!init_target_chars ())
13736 return NULL_TREE;
13737
13738 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
13739 or if format doesn't contain % chars or is "%s". */
13740 if (! integer_zerop (flag))
13741 {
13742 fmt_str = c_getstr (fmt);
13743 if (fmt_str == NULL)
13744 return NULL_TREE;
13745 if (strchr (fmt_str, target_percent) != NULL
13746 && strcmp (fmt_str, target_percent_s))
13747 return NULL_TREE;
13748 }
13749
13750 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
13751 available. */
13752 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
13753 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
13754 if (!fn)
13755 return NULL_TREE;
13756
13757 return gimple_rewrite_call_expr (stmt, 5, fn, 3, dest, len, fmt);
13758}
13759
13760/* Builtins with folding operations that operate on "..." arguments
13761 need special handling; we need to store the arguments in a convenient
13762 data structure before attempting any folding. Fortunately there are
13763 only a few builtins that fall into this category. FNDECL is the
13764 function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
13765 result of the function call is ignored. */
13766
13767static tree
389dd41b 13768gimple_fold_builtin_varargs (tree fndecl, gimple stmt,
13769 bool ignore ATTRIBUTE_UNUSED)
75a70cf9 13770{
13771 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
13772 tree ret = NULL_TREE;
13773
13774 switch (fcode)
13775 {
13776 case BUILT_IN_SPRINTF_CHK:
13777 case BUILT_IN_VSPRINTF_CHK:
13778 ret = gimple_fold_builtin_sprintf_chk (stmt, fcode);
13779 break;
13780
13781 case BUILT_IN_SNPRINTF_CHK:
13782 case BUILT_IN_VSNPRINTF_CHK:
13783 ret = gimple_fold_builtin_snprintf_chk (stmt, NULL_TREE, fcode);
13784
13785 default:
13786 break;
13787 }
13788 if (ret)
13789 {
13790 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
13791 TREE_NO_WARNING (ret) = 1;
13792 return ret;
13793 }
13794 return NULL_TREE;
13795}
13796
13797/* A wrapper function for builtin folding that prevents warnings for
13798 "statement without effect" and the like, caused by removing the
13799 call node earlier than the warning is generated. */
13800
13801tree
13802fold_call_stmt (gimple stmt, bool ignore)
13803{
13804 tree ret = NULL_TREE;
13805 tree fndecl = gimple_call_fndecl (stmt);
389dd41b 13806 location_t loc = gimple_location (stmt);
75a70cf9 13807 if (fndecl
13808 && TREE_CODE (fndecl) == FUNCTION_DECL
13809 && DECL_BUILT_IN (fndecl)
13810 && !gimple_call_va_arg_pack_p (stmt))
13811 {
13812 int nargs = gimple_call_num_args (stmt);
13813
198622c0 13814 if (avoid_folding_inline_builtin (fndecl))
13815 return NULL_TREE;
75a70cf9 13816 /* FIXME: Don't use a list in this interface. */
13817 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
13818 {
13819 tree arglist = NULL_TREE;
13820 int i;
13821 for (i = nargs - 1; i >= 0; i--)
13822 arglist = tree_cons (NULL_TREE, gimple_call_arg (stmt, i), arglist);
13823 return targetm.fold_builtin (fndecl, arglist, ignore);
13824 }
13825 else
13826 {
13827 if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
13828 {
13829 tree args[MAX_ARGS_TO_FOLD_BUILTIN];
13830 int i;
13831 for (i = 0; i < nargs; i++)
13832 args[i] = gimple_call_arg (stmt, i);
389dd41b 13833 ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
75a70cf9 13834 }
13835 if (!ret)
13836 ret = gimple_fold_builtin_varargs (fndecl, stmt, ignore);
13837 if (ret)
13838 {
13839 /* Propagate location information from original call to
13840 expansion of builtin. Otherwise things like
13841 maybe_emit_chk_warning, that operate on the expansion
13842 of a builtin, will use the wrong location information. */
13843 if (gimple_has_location (stmt))
13844 {
13845 tree realret = ret;
13846 if (TREE_CODE (ret) == NOP_EXPR)
13847 realret = TREE_OPERAND (ret, 0);
13848 if (CAN_HAVE_LOCATION_P (realret)
13849 && !EXPR_HAS_LOCATION (realret))
389dd41b 13850 SET_EXPR_LOCATION (realret, loc);
75a70cf9 13851 return realret;
13852 }
13853 return ret;
13854 }
13855 }
13856 }
13857 return NULL_TREE;
13858}