]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/builtins.c
* config/m32r/m32r.c (m32r_is_insn): Return false for debugging
[thirdparty/gcc.git] / gcc / builtins.c
CommitLineData
53800dbe 1/* Expand builtin functions.
61f1dccc 2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
062b4460 3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
f96bd2bf 4 Free Software Foundation, Inc.
53800dbe 5
f12b58b3 6This file is part of GCC.
53800dbe 7
f12b58b3 8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
8c4c00c1 10Software Foundation; either version 3, or (at your option) any later
f12b58b3 11version.
53800dbe 12
f12b58b3 13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
53800dbe 17
18You should have received a copy of the GNU General Public License
8c4c00c1 19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
53800dbe 21
22#include "config.h"
23#include "system.h"
805e22b2 24#include "coretypes.h"
25#include "tm.h"
53800dbe 26#include "machmode.h"
ef258422 27#include "real.h"
53800dbe 28#include "rtl.h"
29#include "tree.h"
75a70cf9 30#include "gimple.h"
53800dbe 31#include "flags.h"
32#include "regs.h"
33#include "hard-reg-set.h"
34#include "except.h"
35#include "function.h"
53800dbe 36#include "insn-config.h"
37#include "expr.h"
d8fc4d0b 38#include "optabs.h"
39#include "libfuncs.h"
53800dbe 40#include "recog.h"
41#include "output.h"
42#include "typeclass.h"
53800dbe 43#include "toplev.h"
689df48e 44#include "predict.h"
1dd6c958 45#include "tm_p.h"
fc2a2dcb 46#include "target.h"
63c62881 47#include "langhooks.h"
0ec80471 48#include "basic-block.h"
fd62c19a 49#include "tree-mudflap.h"
5a84fdd6 50#include "tree-flow.h"
162719b3 51#include "value-prof.h"
07311427 52#include "diagnostic.h"
53800dbe 53
5383fb56 54#ifndef SLOW_UNALIGNED_ACCESS
55#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) STRICT_ALIGNMENT
56#endif
57
726e2588 58#ifndef PAD_VARARGS_DOWN
59#define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
60#endif
239d491a 61#ifdef HAVE_mpc
62static tree do_mpc_arg1 (tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_rnd_t));
63#endif
726e2588 64
ab7943b9 65/* Define the names of the builtin function types and codes. */
8934cb0c 66const char *const built_in_class_names[4]
ab7943b9 67 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
68
9cfddb70 69#define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
0dfc45b5 70const char * built_in_names[(int) END_BUILTINS] =
4e9d90c7 71{
72#include "builtins.def"
73};
74#undef DEF_BUILTIN
ab7943b9 75
df94cd3b 76/* Setup an array of _DECL trees, make sure each element is
77 initialized to NULL_TREE. */
d2d4bdde 78tree built_in_decls[(int) END_BUILTINS];
0a68165a 79/* Declarations used when constructing the builtin implicitly in the compiler.
80 It may be NULL_TREE when this is invalid (for instance runtime is not
4ee9c684 81 required to implement the function call in all cases). */
0a68165a 82tree implicit_built_in_decls[(int) END_BUILTINS];
df94cd3b 83
aecda0d6 84static const char *c_getstr (tree);
85static rtx c_readstr (const char *, enum machine_mode);
86static int target_char_cast (tree, char *);
d8ae1baa 87static rtx get_memory_rtx (tree, tree);
aecda0d6 88static int apply_args_size (void);
89static int apply_result_size (void);
d8c9779c 90#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
aecda0d6 91static rtx result_vector (int, rtx);
d8c9779c 92#endif
843d08a9 93static void expand_builtin_update_setjmp_buf (rtx);
aecda0d6 94static void expand_builtin_prefetch (tree);
95static rtx expand_builtin_apply_args (void);
96static rtx expand_builtin_apply_args_1 (void);
97static rtx expand_builtin_apply (rtx, rtx, rtx);
98static void expand_builtin_return (rtx);
99static enum type_class type_to_class (tree);
100static rtx expand_builtin_classify_type (tree);
101static void expand_errno_check (tree, rtx);
102static rtx expand_builtin_mathfn (tree, rtx, rtx);
103static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
6b43bae4 104static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
a67a90e5 105static rtx expand_builtin_interclass_mathfn (tree, rtx, rtx);
c3147c1a 106static rtx expand_builtin_sincos (tree);
d735c391 107static rtx expand_builtin_cexpi (tree, rtx, rtx);
ff1b14e4 108static rtx expand_builtin_int_roundingfn (tree, rtx);
109static rtx expand_builtin_int_roundingfn_2 (tree, rtx);
aecda0d6 110static rtx expand_builtin_args_info (tree);
79012a9d 111static rtx expand_builtin_next_arg (void);
aecda0d6 112static rtx expand_builtin_va_start (tree);
113static rtx expand_builtin_va_end (tree);
114static rtx expand_builtin_va_copy (tree);
7959b13b 115static rtx expand_builtin_memchr (tree, rtx, enum machine_mode);
c2f47e15 116static rtx expand_builtin_memcmp (tree, rtx, enum machine_mode);
aecda0d6 117static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
118static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
119static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
7da1412b 120static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
aecda0d6 121static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
122static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
123static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
124static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
c2f47e15 125static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode);
126static rtx expand_builtin_mempcpy_args (tree, tree, tree, tree, rtx,
127 enum machine_mode, int);
128static rtx expand_builtin_memmove (tree, rtx, enum machine_mode, int);
129static rtx expand_builtin_memmove_args (tree, tree, tree, tree, rtx,
130 enum machine_mode, int);
131static rtx expand_builtin_bcopy (tree, int);
1d89860b 132static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
c2f47e15 133static rtx expand_builtin_strcpy_args (tree, tree, tree, rtx, enum machine_mode);
aecda0d6 134static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
aecda0d6 135static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
aecda0d6 136static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
c2f47e15 137static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
138static rtx expand_builtin_memset_args (tree, tree, tree, rtx, enum machine_mode, tree);
aecda0d6 139static rtx expand_builtin_bzero (tree);
140static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
c2f47e15 141static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
142static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
143static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
144static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
aecda0d6 145static rtx expand_builtin_alloca (tree, rtx);
146static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
147static rtx expand_builtin_frame_address (tree, tree);
19bf118a 148static rtx expand_builtin_fputs (tree, rtx, bool);
149static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
150static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
6411575e 151static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
389dd41b 152static tree stabilize_va_list_loc (location_t, tree, int);
aecda0d6 153static rtx expand_builtin_expect (tree, rtx);
154static tree fold_builtin_constant_p (tree);
389dd41b 155static tree fold_builtin_expect (location_t, tree, tree);
aecda0d6 156static tree fold_builtin_classify_type (tree);
389dd41b 157static tree fold_builtin_strlen (location_t, tree);
158static tree fold_builtin_inf (location_t, tree, int);
aecda0d6 159static tree fold_builtin_nan (tree, tree, int);
389dd41b 160static tree rewrite_call_expr (location_t, tree, int, tree, int, ...);
b7bf20db 161static bool validate_arg (const_tree, enum tree_code code);
277f8dd2 162static bool integer_valued_real_p (tree);
389dd41b 163static tree fold_trunc_transparent_mathfn (location_t, tree, tree);
aecda0d6 164static bool readonly_data_expr (tree);
165static rtx expand_builtin_fabs (tree, rtx, rtx);
27f261ef 166static rtx expand_builtin_signbit (tree, rtx);
389dd41b 167static tree fold_builtin_sqrt (location_t, tree, tree);
168static tree fold_builtin_cbrt (location_t, tree, tree);
169static tree fold_builtin_pow (location_t, tree, tree, tree, tree);
170static tree fold_builtin_powi (location_t, tree, tree, tree, tree);
171static tree fold_builtin_cos (location_t, tree, tree, tree);
172static tree fold_builtin_cosh (location_t, tree, tree, tree);
bffb7645 173static tree fold_builtin_tan (tree, tree);
389dd41b 174static tree fold_builtin_trunc (location_t, tree, tree);
175static tree fold_builtin_floor (location_t, tree, tree);
176static tree fold_builtin_ceil (location_t, tree, tree);
177static tree fold_builtin_round (location_t, tree, tree);
178static tree fold_builtin_int_roundingfn (location_t, tree, tree);
10b9666f 179static tree fold_builtin_bitop (tree, tree);
389dd41b 180static tree fold_builtin_memory_op (location_t, tree, tree, tree, tree, bool, int);
181static tree fold_builtin_strchr (location_t, tree, tree, tree);
182static tree fold_builtin_memchr (location_t, tree, tree, tree, tree);
183static tree fold_builtin_memcmp (location_t, tree, tree, tree);
184static tree fold_builtin_strcmp (location_t, tree, tree);
185static tree fold_builtin_strncmp (location_t, tree, tree, tree);
186static tree fold_builtin_signbit (location_t, tree, tree);
187static tree fold_builtin_copysign (location_t, tree, tree, tree, tree);
188static tree fold_builtin_isascii (location_t, tree);
189static tree fold_builtin_toascii (location_t, tree);
190static tree fold_builtin_isdigit (location_t, tree);
191static tree fold_builtin_fabs (location_t, tree, tree);
192static tree fold_builtin_abs (location_t, tree, tree);
193static tree fold_builtin_unordered_cmp (location_t, tree, tree, tree, enum tree_code,
d5019fe8 194 enum tree_code);
389dd41b 195static tree fold_builtin_n (location_t, tree, tree *, int, bool);
196static tree fold_builtin_0 (location_t, tree, bool);
197static tree fold_builtin_1 (location_t, tree, tree, bool);
198static tree fold_builtin_2 (location_t, tree, tree, tree, bool);
199static tree fold_builtin_3 (location_t, tree, tree, tree, tree, bool);
200static tree fold_builtin_4 (location_t, tree, tree, tree, tree, tree, bool);
201static tree fold_builtin_varargs (location_t, tree, tree, bool);
202
203static tree fold_builtin_strpbrk (location_t, tree, tree, tree);
204static tree fold_builtin_strstr (location_t, tree, tree, tree);
205static tree fold_builtin_strrchr (location_t, tree, tree, tree);
206static tree fold_builtin_strcat (location_t, tree, tree);
207static tree fold_builtin_strncat (location_t, tree, tree, tree);
208static tree fold_builtin_strspn (location_t, tree, tree);
209static tree fold_builtin_strcspn (location_t, tree, tree);
210static tree fold_builtin_sprintf (location_t, tree, tree, tree, int);
4ee9c684 211
0a39fd54 212static rtx expand_builtin_object_size (tree);
213static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
214 enum built_in_function);
215static void maybe_emit_chk_warning (tree, enum built_in_function);
216static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
2c281b15 217static void maybe_emit_free_warning (tree);
c2f47e15 218static tree fold_builtin_object_size (tree, tree);
389dd41b 219static tree fold_builtin_strcat_chk (location_t, tree, tree, tree, tree);
220static tree fold_builtin_strncat_chk (location_t, tree, tree, tree, tree, tree);
221static tree fold_builtin_sprintf_chk (location_t, tree, enum built_in_function);
222static tree fold_builtin_printf (location_t, tree, tree, tree, bool, enum built_in_function);
223static tree fold_builtin_fprintf (location_t, tree, tree, tree, tree, bool,
c2f47e15 224 enum built_in_function);
99eabcc1 225static bool init_target_chars (void);
226
227static unsigned HOST_WIDE_INT target_newline;
228static unsigned HOST_WIDE_INT target_percent;
229static unsigned HOST_WIDE_INT target_c;
230static unsigned HOST_WIDE_INT target_s;
231static char target_percent_c[3];
232static char target_percent_s[3];
233static char target_percent_s_newline[4];
728bac60 234static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
235 const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool);
f0c477f2 236static tree do_mpfr_arg2 (tree, tree, tree,
237 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
9917422b 238static tree do_mpfr_arg3 (tree, tree, tree, tree,
239 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
d92f994c 240static tree do_mpfr_sincos (tree, tree, tree);
65dd1378 241static tree do_mpfr_bessel_n (tree, tree, tree,
242 int (*)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
243 const REAL_VALUE_TYPE *, bool);
e5407ca6 244static tree do_mpfr_remquo (tree, tree, tree);
e84da7c1 245static tree do_mpfr_lgamma_r (tree, tree, tree);
0a39fd54 246
1c47b3e8 247bool
248is_builtin_name (const char *name)
b6a5fc45 249{
b6a5fc45 250 if (strncmp (name, "__builtin_", 10) == 0)
251 return true;
252 if (strncmp (name, "__sync_", 7) == 0)
253 return true;
254 return false;
255}
4ee9c684 256
1c47b3e8 257/* Return true if NODE should be considered for inline expansion regardless
258 of the optimization level. This means whenever a function is invoked with
259 its "internal" name, which normally contains the prefix "__builtin". */
260
261static bool
262called_as_built_in (tree node)
263{
264 /* Note that we must use DECL_NAME, not DECL_ASSEMBLER_NAME_SET_P since
265 we want the name used to call the function, not the name it
266 will have. */
267 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
268 return is_builtin_name (name);
269}
270
698537d1 271/* Return the alignment in bits of EXP, an object.
272 Don't return more than MAX_ALIGN no matter what, ALIGN is the inital
273 guessed alignment e.g. from type alignment. */
274
275int
276get_object_alignment (tree exp, unsigned int align, unsigned int max_align)
277{
278 unsigned int inner;
279
280 inner = max_align;
281 if (handled_component_p (exp))
282 {
283 HOST_WIDE_INT bitsize, bitpos;
284 tree offset;
285 enum machine_mode mode;
286 int unsignedp, volatilep;
287
288 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
289 &mode, &unsignedp, &volatilep, true);
290 if (bitpos)
291 inner = MIN (inner, (unsigned) (bitpos & -bitpos));
292 while (offset)
293 {
294 tree next_offset;
295
296 if (TREE_CODE (offset) == PLUS_EXPR)
297 {
298 next_offset = TREE_OPERAND (offset, 0);
299 offset = TREE_OPERAND (offset, 1);
300 }
301 else
302 next_offset = NULL;
303 if (host_integerp (offset, 1))
304 {
305 /* Any overflow in calculating offset_bits won't change
306 the alignment. */
307 unsigned offset_bits
308 = ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT);
309
310 if (offset_bits)
311 inner = MIN (inner, (offset_bits & -offset_bits));
312 }
313 else if (TREE_CODE (offset) == MULT_EXPR
314 && host_integerp (TREE_OPERAND (offset, 1), 1))
315 {
316 /* Any overflow in calculating offset_factor won't change
317 the alignment. */
318 unsigned offset_factor
319 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
320 * BITS_PER_UNIT);
321
322 if (offset_factor)
323 inner = MIN (inner, (offset_factor & -offset_factor));
324 }
325 else
326 {
327 inner = MIN (inner, BITS_PER_UNIT);
328 break;
329 }
330 offset = next_offset;
331 }
332 }
333 if (DECL_P (exp))
334 align = MIN (inner, DECL_ALIGN (exp));
335#ifdef CONSTANT_ALIGNMENT
336 else if (CONSTANT_CLASS_P (exp))
337 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
338#endif
339 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
340 || TREE_CODE (exp) == INDIRECT_REF)
341 align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
342 else
343 align = MIN (align, inner);
344 return MIN (align, max_align);
345}
346
7abca321 347/* Returns true iff we can trust that alignment information has been
348 calculated properly. */
349
350bool
351can_trust_pointer_alignment (void)
352{
353 /* We rely on TER to compute accurate alignment information. */
354 return (optimize && flag_tree_ter);
355}
356
53800dbe 357/* Return the alignment in bits of EXP, a pointer valued expression.
358 But don't return more than MAX_ALIGN no matter what.
359 The alignment returned is, by default, the alignment of the thing that
27d0c333 360 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
53800dbe 361
362 Otherwise, look at the expression to see if we can do better, i.e., if the
363 expression is actually pointing at an object whose alignment is tighter. */
364
f656b751 365int
aecda0d6 366get_pointer_alignment (tree exp, unsigned int max_align)
53800dbe 367{
27d0c333 368 unsigned int align, inner;
53800dbe 369
7abca321 370 if (!can_trust_pointer_alignment ())
189575ff 371 return 0;
372
535e2026 373 if (!POINTER_TYPE_P (TREE_TYPE (exp)))
374 return 0;
375
53800dbe 376 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
377 align = MIN (align, max_align);
378
379 while (1)
380 {
381 switch (TREE_CODE (exp))
382 {
72dd6141 383 CASE_CONVERT:
53800dbe 384 exp = TREE_OPERAND (exp, 0);
552752f7 385 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
53800dbe 386 return align;
325d1c45 387
53800dbe 388 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
389 align = MIN (inner, max_align);
390 break;
391
0de36bdb 392 case POINTER_PLUS_EXPR:
53800dbe 393 /* If sum of pointer + int, restrict our maximum alignment to that
394 imposed by the integer. If not, we can't do any better than
395 ALIGN. */
325d1c45 396 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
53800dbe 397 return align;
398
0994d2ed 399 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
400 & (max_align / BITS_PER_UNIT - 1))
53800dbe 401 != 0)
402 max_align >>= 1;
403
404 exp = TREE_OPERAND (exp, 0);
405 break;
406
407 case ADDR_EXPR:
408 /* See what we are pointing at and look at its alignment. */
698537d1 409 return get_object_alignment (TREE_OPERAND (exp, 0), align, max_align);
53800dbe 410
411 default:
412 return align;
413 }
414 }
415}
416
417/* Compute the length of a C string. TREE_STRING_LENGTH is not the right
418 way, because it could contain a zero byte in the middle.
419 TREE_STRING_LENGTH is the size of the character array, not the string.
420
4172d65e 421 ONLY_VALUE should be nonzero if the result is not going to be emitted
c09841f6 422 into the instruction stream and zero if it is going to be expanded.
4172d65e 423 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
681fab1e 424 is returned, otherwise NULL, since
425 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
426 evaluate the side-effects.
427
902de8ed 428 The value returned is of type `ssizetype'.
429
53800dbe 430 Unfortunately, string_constant can't access the values of const char
431 arrays with initializers, so neither can we do so here. */
432
4ee9c684 433tree
681fab1e 434c_strlen (tree src, int only_value)
53800dbe 435{
436 tree offset_node;
27d0c333 437 HOST_WIDE_INT offset;
438 int max;
44acf429 439 const char *ptr;
53800dbe 440
681fab1e 441 STRIP_NOPS (src);
442 if (TREE_CODE (src) == COND_EXPR
443 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
444 {
445 tree len1, len2;
446
447 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
448 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
0862b7e9 449 if (tree_int_cst_equal (len1, len2))
681fab1e 450 return len1;
451 }
452
453 if (TREE_CODE (src) == COMPOUND_EXPR
454 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
455 return c_strlen (TREE_OPERAND (src, 1), only_value);
456
53800dbe 457 src = string_constant (src, &offset_node);
458 if (src == 0)
c2f47e15 459 return NULL_TREE;
902de8ed 460
83d79705 461 max = TREE_STRING_LENGTH (src) - 1;
53800dbe 462 ptr = TREE_STRING_POINTER (src);
902de8ed 463
53800dbe 464 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
465 {
466 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
467 compute the offset to the following null if we don't know where to
468 start searching for it. */
469 int i;
902de8ed 470
53800dbe 471 for (i = 0; i < max; i++)
472 if (ptr[i] == 0)
c2f47e15 473 return NULL_TREE;
902de8ed 474
53800dbe 475 /* We don't know the starting offset, but we do know that the string
476 has no internal zero bytes. We can assume that the offset falls
477 within the bounds of the string; otherwise, the programmer deserves
478 what he gets. Subtract the offset from the length of the string,
902de8ed 479 and return that. This would perhaps not be valid if we were dealing
480 with named arrays in addition to literal string constants. */
481
389dd41b 482 return size_diffop_loc (input_location, size_int (max), offset_node);
53800dbe 483 }
484
485 /* We have a known offset into the string. Start searching there for
27d0c333 486 a null character if we can represent it as a single HOST_WIDE_INT. */
dabc4084 487 if (offset_node == 0)
53800dbe 488 offset = 0;
dabc4084 489 else if (! host_integerp (offset_node, 0))
490 offset = -1;
53800dbe 491 else
27d0c333 492 offset = tree_low_cst (offset_node, 0);
902de8ed 493
1f63a7d6 494 /* If the offset is known to be out of bounds, warn, and call strlen at
495 runtime. */
53800dbe 496 if (offset < 0 || offset > max)
497 {
1f63a7d6 498 /* Suppress multiple warnings for propagated constant strings. */
499 if (! TREE_NO_WARNING (src))
500 {
501 warning (0, "offset outside bounds of constant string");
502 TREE_NO_WARNING (src) = 1;
503 }
c2f47e15 504 return NULL_TREE;
53800dbe 505 }
902de8ed 506
53800dbe 507 /* Use strlen to search for the first zero byte. Since any strings
508 constructed with build_string will have nulls appended, we win even
509 if we get handed something like (char[4])"abcd".
510
511 Since OFFSET is our starting index into the string, no further
512 calculation is needed. */
902de8ed 513 return ssize_int (strlen (ptr + offset));
53800dbe 514}
515
83d79705 516/* Return a char pointer for a C string if it is a string constant
517 or sum of string constant and integer constant. */
518
519static const char *
aecda0d6 520c_getstr (tree src)
83d79705 521{
522 tree offset_node;
83d79705 523
524 src = string_constant (src, &offset_node);
525 if (src == 0)
526 return 0;
527
8c85fcb7 528 if (offset_node == 0)
529 return TREE_STRING_POINTER (src);
530 else if (!host_integerp (offset_node, 1)
531 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
83d79705 532 return 0;
83d79705 533
8c85fcb7 534 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
83d79705 535}
536
8c85fcb7 537/* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
538 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
ecc318ff 539
6840589f 540static rtx
aecda0d6 541c_readstr (const char *str, enum machine_mode mode)
6840589f 542{
543 HOST_WIDE_INT c[2];
544 HOST_WIDE_INT ch;
545 unsigned int i, j;
546
64db345d 547 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
7d3f6cc7 548
6840589f 549 c[0] = 0;
550 c[1] = 0;
551 ch = 1;
552 for (i = 0; i < GET_MODE_SIZE (mode); i++)
553 {
554 j = i;
555 if (WORDS_BIG_ENDIAN)
556 j = GET_MODE_SIZE (mode) - i - 1;
557 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
558 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
559 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
560 j *= BITS_PER_UNIT;
64db345d 561 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
7d3f6cc7 562
6840589f 563 if (ch)
564 ch = (unsigned char) str[i];
565 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
566 }
567 return immed_double_const (c[0], c[1], mode);
568}
569
ecc318ff 570/* Cast a target constant CST to target CHAR and if that value fits into
5206b159 571 host char type, return zero and put that value into variable pointed to by
ecc318ff 572 P. */
573
574static int
aecda0d6 575target_char_cast (tree cst, char *p)
ecc318ff 576{
577 unsigned HOST_WIDE_INT val, hostval;
578
27d0c333 579 if (!host_integerp (cst, 1)
ecc318ff 580 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
581 return 1;
582
27d0c333 583 val = tree_low_cst (cst, 1);
ecc318ff 584 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
585 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
586
587 hostval = val;
588 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
589 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
590
591 if (val != hostval)
592 return 1;
593
594 *p = hostval;
595 return 0;
596}
597
4ee9c684 598/* Similar to save_expr, but assumes that arbitrary code is not executed
599 in between the multiple evaluations. In particular, we assume that a
600 non-addressable local variable will not be modified. */
601
602static tree
603builtin_save_expr (tree exp)
604{
605 if (TREE_ADDRESSABLE (exp) == 0
606 && (TREE_CODE (exp) == PARM_DECL
607 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
608 return exp;
609
610 return save_expr (exp);
611}
612
53800dbe 613/* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
614 times to get the address of either a higher stack frame, or a return
615 address located within it (depending on FNDECL_CODE). */
902de8ed 616
c626df3d 617static rtx
869d0ef0 618expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
53800dbe 619{
620 int i;
621
869d0ef0 622#ifdef INITIAL_FRAME_ADDRESS_RTX
623 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
624#else
e3e15c50 625 rtx tem;
626
1b74fde7 627 /* For a zero count with __builtin_return_address, we don't care what
628 frame address we return, because target-specific definitions will
629 override us. Therefore frame pointer elimination is OK, and using
630 the soft frame pointer is OK.
631
fa7637bd 632 For a nonzero count, or a zero count with __builtin_frame_address,
1b74fde7 633 we require a stable offset from the current frame pointer to the
634 previous one, so we must use the hard frame pointer, and
e3e15c50 635 we must disable frame pointer elimination. */
1b74fde7 636 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
e3e15c50 637 tem = frame_pointer_rtx;
a0c938f0 638 else
e3e15c50 639 {
640 tem = hard_frame_pointer_rtx;
641
642 /* Tell reload not to eliminate the frame pointer. */
18d50ae6 643 crtl->accesses_prior_frames = 1;
e3e15c50 644 }
869d0ef0 645#endif
646
53800dbe 647 /* Some machines need special handling before we can access
3a69c60c 648 arbitrary frames. For example, on the SPARC, we must first flush
53800dbe 649 all register windows to the stack. */
650#ifdef SETUP_FRAME_ADDRESSES
651 if (count > 0)
652 SETUP_FRAME_ADDRESSES ();
653#endif
654
3a69c60c 655 /* On the SPARC, the return address is not in the frame, it is in a
53800dbe 656 register. There is no way to access it off of the current frame
657 pointer, but it can be accessed off the previous frame pointer by
658 reading the value from the register window save area. */
659#ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
660 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
661 count--;
662#endif
663
664 /* Scan back COUNT frames to the specified frame. */
665 for (i = 0; i < count; i++)
666 {
667 /* Assume the dynamic chain pointer is in the word that the
668 frame address points to, unless otherwise specified. */
669#ifdef DYNAMIC_CHAIN_ADDRESS
670 tem = DYNAMIC_CHAIN_ADDRESS (tem);
671#endif
672 tem = memory_address (Pmode, tem);
00060fc2 673 tem = gen_frame_mem (Pmode, tem);
83fc1478 674 tem = copy_to_reg (tem);
53800dbe 675 }
676
3a69c60c 677 /* For __builtin_frame_address, return what we've got. But, on
678 the SPARC for example, we may have to add a bias. */
53800dbe 679 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
3a69c60c 680#ifdef FRAME_ADDR_RTX
681 return FRAME_ADDR_RTX (tem);
682#else
53800dbe 683 return tem;
3a69c60c 684#endif
53800dbe 685
3a69c60c 686 /* For __builtin_return_address, get the return address from that frame. */
53800dbe 687#ifdef RETURN_ADDR_RTX
688 tem = RETURN_ADDR_RTX (count, tem);
689#else
690 tem = memory_address (Pmode,
691 plus_constant (tem, GET_MODE_SIZE (Pmode)));
00060fc2 692 tem = gen_frame_mem (Pmode, tem);
53800dbe 693#endif
694 return tem;
695}
696
f7c44134 697/* Alias set used for setjmp buffer. */
32c2fdea 698static alias_set_type setjmp_alias_set = -1;
f7c44134 699
6b7f6858 700/* Construct the leading half of a __builtin_setjmp call. Control will
2c8a1497 701 return to RECEIVER_LABEL. This is also called directly by the SJLJ
702 exception handling code. */
53800dbe 703
6b7f6858 704void
aecda0d6 705expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
53800dbe 706{
53800dbe 707 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
53800dbe 708 rtx stack_save;
f7c44134 709 rtx mem;
53800dbe 710
f7c44134 711 if (setjmp_alias_set == -1)
712 setjmp_alias_set = new_alias_set ();
713
85d654dd 714 buf_addr = convert_memory_address (Pmode, buf_addr);
53800dbe 715
37ae8504 716 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
53800dbe 717
6b7f6858 718 /* We store the frame pointer and the address of receiver_label in
719 the buffer and use the rest of it for the stack save area, which
720 is machine-dependent. */
53800dbe 721
f7c44134 722 mem = gen_rtx_MEM (Pmode, buf_addr);
ab6ab77e 723 set_mem_alias_set (mem, setjmp_alias_set);
e3e026e8 724 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
f7c44134 725
726 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
ab6ab77e 727 set_mem_alias_set (mem, setjmp_alias_set);
f7c44134 728
729 emit_move_insn (validize_mem (mem),
6b7f6858 730 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
53800dbe 731
732 stack_save = gen_rtx_MEM (sa_mode,
733 plus_constant (buf_addr,
734 2 * GET_MODE_SIZE (Pmode)));
ab6ab77e 735 set_mem_alias_set (stack_save, setjmp_alias_set);
53800dbe 736 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
737
738 /* If there is further processing to do, do it. */
739#ifdef HAVE_builtin_setjmp_setup
740 if (HAVE_builtin_setjmp_setup)
741 emit_insn (gen_builtin_setjmp_setup (buf_addr));
742#endif
743
6b7f6858 744 /* Tell optimize_save_area_alloca that extra work is going to
745 need to go on during alloca. */
18d50ae6 746 cfun->calls_setjmp = 1;
80ab81b9 747
29f09705 748 /* We have a nonlocal label. */
18d50ae6 749 cfun->has_nonlocal_label = 1;
6b7f6858 750}
53800dbe 751
2c8a1497 752/* Construct the trailing part of a __builtin_setjmp call. This is
753 also called directly by the SJLJ exception handling code. */
6b7f6858 754
755void
aecda0d6 756expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
6b7f6858 757{
82c7907c 758 rtx chain;
759
53800dbe 760 /* Clobber the FP when we get here, so we have to make sure it's
761 marked as used by this function. */
18b42941 762 emit_use (hard_frame_pointer_rtx);
53800dbe 763
764 /* Mark the static chain as clobbered here so life information
765 doesn't get messed up for it. */
82c7907c 766 chain = targetm.calls.static_chain (current_function_decl, true);
767 if (chain && REG_P (chain))
768 emit_clobber (chain);
53800dbe 769
770 /* Now put in the code to restore the frame pointer, and argument
491e04ef 771 pointer, if needed. */
53800dbe 772#ifdef HAVE_nonlocal_goto
773 if (! HAVE_nonlocal_goto)
774#endif
5a1c3f40 775 {
776 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
777 /* This might change the hard frame pointer in ways that aren't
778 apparent to early optimization passes, so force a clobber. */
18b42941 779 emit_clobber (hard_frame_pointer_rtx);
5a1c3f40 780 }
53800dbe 781
782#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
783 if (fixed_regs[ARG_POINTER_REGNUM])
784 {
785#ifdef ELIMINABLE_REGS
786 size_t i;
e99c3a1d 787 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
53800dbe 788
3098b2d3 789 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
53800dbe 790 if (elim_regs[i].from == ARG_POINTER_REGNUM
791 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
792 break;
793
3098b2d3 794 if (i == ARRAY_SIZE (elim_regs))
53800dbe 795#endif
796 {
797 /* Now restore our arg pointer from the address at which it
05927e40 798 was saved in our stack frame. */
27a7a23a 799 emit_move_insn (crtl->args.internal_arg_pointer,
b079a207 800 copy_to_reg (get_arg_pointer_save_area ()));
53800dbe 801 }
802 }
803#endif
804
805#ifdef HAVE_builtin_setjmp_receiver
806 if (HAVE_builtin_setjmp_receiver)
6b7f6858 807 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
53800dbe 808 else
809#endif
810#ifdef HAVE_nonlocal_goto_receiver
811 if (HAVE_nonlocal_goto_receiver)
812 emit_insn (gen_nonlocal_goto_receiver ());
813 else
814#endif
6b7f6858 815 { /* Nothing */ }
57f6bb94 816
3072d30e 817 /* We must not allow the code we just generated to be reordered by
818 scheduling. Specifically, the update of the frame pointer must
819 happen immediately, not later. */
820 emit_insn (gen_blockage ());
6b7f6858 821}
53800dbe 822
53800dbe 823/* __builtin_longjmp is passed a pointer to an array of five words (not
824 all will be used on all machines). It operates similarly to the C
825 library function of the same name, but is more efficient. Much of
2c8a1497 826 the code below is copied from the handling of non-local gotos. */
53800dbe 827
c626df3d 828static void
aecda0d6 829expand_builtin_longjmp (rtx buf_addr, rtx value)
53800dbe 830{
4712c7d6 831 rtx fp, lab, stack, insn, last;
53800dbe 832 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
833
27a7a23a 834 /* DRAP is needed for stack realign if longjmp is expanded to current
835 function */
836 if (SUPPORTS_STACK_ALIGNMENT)
837 crtl->need_drap = true;
838
f7c44134 839 if (setjmp_alias_set == -1)
840 setjmp_alias_set = new_alias_set ();
841
85d654dd 842 buf_addr = convert_memory_address (Pmode, buf_addr);
479e4d5e 843
53800dbe 844 buf_addr = force_reg (Pmode, buf_addr);
845
82c7907c 846 /* We require that the user must pass a second argument of 1, because
847 that is what builtin_setjmp will return. */
64db345d 848 gcc_assert (value == const1_rtx);
53800dbe 849
4712c7d6 850 last = get_last_insn ();
53800dbe 851#ifdef HAVE_builtin_longjmp
852 if (HAVE_builtin_longjmp)
853 emit_insn (gen_builtin_longjmp (buf_addr));
854 else
855#endif
856 {
857 fp = gen_rtx_MEM (Pmode, buf_addr);
858 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
859 GET_MODE_SIZE (Pmode)));
860
861 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
862 2 * GET_MODE_SIZE (Pmode)));
ab6ab77e 863 set_mem_alias_set (fp, setjmp_alias_set);
864 set_mem_alias_set (lab, setjmp_alias_set);
865 set_mem_alias_set (stack, setjmp_alias_set);
53800dbe 866
867 /* Pick up FP, label, and SP from the block and jump. This code is
868 from expand_goto in stmt.c; see there for detailed comments. */
03fd9d2c 869#ifdef HAVE_nonlocal_goto
53800dbe 870 if (HAVE_nonlocal_goto)
871 /* We have to pass a value to the nonlocal_goto pattern that will
872 get copied into the static_chain pointer, but it does not matter
873 what that value is, because builtin_setjmp does not use it. */
28d202a8 874 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
53800dbe 875 else
876#endif
877 {
878 lab = copy_to_reg (lab);
879
18b42941 880 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
881 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
2a871ad1 882
53800dbe 883 emit_move_insn (hard_frame_pointer_rtx, fp);
884 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
885
18b42941 886 emit_use (hard_frame_pointer_rtx);
887 emit_use (stack_pointer_rtx);
53800dbe 888 emit_indirect_jump (lab);
889 }
890 }
615166bb 891
892 /* Search backwards and mark the jump insn as a non-local goto.
893 Note that this precludes the use of __builtin_longjmp to a
894 __builtin_setjmp target in the same function. However, we've
895 already cautioned the user that these functions are for
896 internal exception handling use only. */
449c0509 897 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
898 {
64db345d 899 gcc_assert (insn != last);
7d3f6cc7 900
6d7dc5b9 901 if (JUMP_P (insn))
449c0509 902 {
a1ddb869 903 add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
449c0509 904 break;
905 }
6d7dc5b9 906 else if (CALL_P (insn))
9342ee68 907 break;
449c0509 908 }
53800dbe 909}
910
4ee9c684 911/* Expand a call to __builtin_nonlocal_goto. We're passed the target label
912 and the address of the save area. */
913
914static rtx
c2f47e15 915expand_builtin_nonlocal_goto (tree exp)
4ee9c684 916{
917 tree t_label, t_save_area;
918 rtx r_label, r_save_area, r_fp, r_sp, insn;
919
c2f47e15 920 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4ee9c684 921 return NULL_RTX;
922
c2f47e15 923 t_label = CALL_EXPR_ARG (exp, 0);
924 t_save_area = CALL_EXPR_ARG (exp, 1);
4ee9c684 925
8ec3c5c2 926 r_label = expand_normal (t_label);
3dce56cc 927 r_label = convert_memory_address (Pmode, r_label);
8ec3c5c2 928 r_save_area = expand_normal (t_save_area);
3dce56cc 929 r_save_area = convert_memory_address (Pmode, r_save_area);
51adbc8a 930 /* Copy the address of the save location to a register just in case it was based
931 on the frame pointer. */
932 r_save_area = copy_to_reg (r_save_area);
4ee9c684 933 r_fp = gen_rtx_MEM (Pmode, r_save_area);
934 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
935 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
936
18d50ae6 937 crtl->has_nonlocal_goto = 1;
4ee9c684 938
03fd9d2c 939#ifdef HAVE_nonlocal_goto
4ee9c684 940 /* ??? We no longer need to pass the static chain value, afaik. */
941 if (HAVE_nonlocal_goto)
942 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
943 else
944#endif
945 {
946 r_label = copy_to_reg (r_label);
947
18b42941 948 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
949 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
491e04ef 950
4ee9c684 951 /* Restore frame pointer for containing function.
952 This sets the actual hard register used for the frame pointer
953 to the location of the function's incoming static chain info.
954 The non-local goto handler will then adjust it to contain the
955 proper value and reload the argument pointer, if needed. */
956 emit_move_insn (hard_frame_pointer_rtx, r_fp);
957 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
491e04ef 958
4ee9c684 959 /* USE of hard_frame_pointer_rtx added for consistency;
960 not clear if really needed. */
18b42941 961 emit_use (hard_frame_pointer_rtx);
962 emit_use (stack_pointer_rtx);
ad0d0af8 963
964 /* If the architecture is using a GP register, we must
965 conservatively assume that the target function makes use of it.
966 The prologue of functions with nonlocal gotos must therefore
967 initialize the GP register to the appropriate value, and we
968 must then make sure that this value is live at the point
969 of the jump. (Note that this doesn't necessarily apply
970 to targets with a nonlocal_goto pattern; they are free
971 to implement it in their own way. Note also that this is
972 a no-op if the GP register is a global invariant.) */
973 if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
974 && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
18b42941 975 emit_use (pic_offset_table_rtx);
ad0d0af8 976
4ee9c684 977 emit_indirect_jump (r_label);
978 }
491e04ef 979
4ee9c684 980 /* Search backwards to the jump insn and mark it as a
981 non-local goto. */
982 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
983 {
6d7dc5b9 984 if (JUMP_P (insn))
4ee9c684 985 {
a1ddb869 986 add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
4ee9c684 987 break;
988 }
6d7dc5b9 989 else if (CALL_P (insn))
4ee9c684 990 break;
991 }
992
993 return const0_rtx;
994}
995
843d08a9 996/* __builtin_update_setjmp_buf is passed a pointer to an array of five words
997 (not all will be used on all machines) that was passed to __builtin_setjmp.
998 It updates the stack pointer in that block to correspond to the current
999 stack pointer. */
1000
1001static void
1002expand_builtin_update_setjmp_buf (rtx buf_addr)
1003{
1004 enum machine_mode sa_mode = Pmode;
1005 rtx stack_save;
1006
1007
1008#ifdef HAVE_save_stack_nonlocal
1009 if (HAVE_save_stack_nonlocal)
1010 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
1011#endif
1012#ifdef STACK_SAVEAREA_MODE
1013 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
1014#endif
1015
1016 stack_save
1017 = gen_rtx_MEM (sa_mode,
1018 memory_address
1019 (sa_mode,
1020 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
1021
1022#ifdef HAVE_setjmp
1023 if (HAVE_setjmp)
1024 emit_insn (gen_setjmp ());
1025#endif
1026
1027 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
1028}
1029
5e3608d8 1030/* Expand a call to __builtin_prefetch. For a target that does not support
1031 data prefetch, evaluate the memory address argument in case it has side
1032 effects. */
1033
1034static void
c2f47e15 1035expand_builtin_prefetch (tree exp)
5e3608d8 1036{
1037 tree arg0, arg1, arg2;
c2f47e15 1038 int nargs;
5e3608d8 1039 rtx op0, op1, op2;
1040
c2f47e15 1041 if (!validate_arglist (exp, POINTER_TYPE, 0))
26a5cadb 1042 return;
1043
c2f47e15 1044 arg0 = CALL_EXPR_ARG (exp, 0);
1045
26a5cadb 1046 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
1047 zero (read) and argument 2 (locality) defaults to 3 (high degree of
1048 locality). */
c2f47e15 1049 nargs = call_expr_nargs (exp);
1050 if (nargs > 1)
1051 arg1 = CALL_EXPR_ARG (exp, 1);
26a5cadb 1052 else
c2f47e15 1053 arg1 = integer_zero_node;
1054 if (nargs > 2)
1055 arg2 = CALL_EXPR_ARG (exp, 2);
1056 else
1057 arg2 = build_int_cst (NULL_TREE, 3);
5e3608d8 1058
1059 /* Argument 0 is an address. */
1060 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
1061
1062 /* Argument 1 (read/write flag) must be a compile-time constant int. */
1063 if (TREE_CODE (arg1) != INTEGER_CST)
1064 {
07e3a3d2 1065 error ("second argument to %<__builtin_prefetch%> must be a constant");
9342ee68 1066 arg1 = integer_zero_node;
5e3608d8 1067 }
8ec3c5c2 1068 op1 = expand_normal (arg1);
5e3608d8 1069 /* Argument 1 must be either zero or one. */
1070 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
1071 {
c3ceba8e 1072 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
07e3a3d2 1073 " using zero");
5e3608d8 1074 op1 = const0_rtx;
1075 }
1076
1077 /* Argument 2 (locality) must be a compile-time constant int. */
1078 if (TREE_CODE (arg2) != INTEGER_CST)
1079 {
07e3a3d2 1080 error ("third argument to %<__builtin_prefetch%> must be a constant");
5e3608d8 1081 arg2 = integer_zero_node;
1082 }
8ec3c5c2 1083 op2 = expand_normal (arg2);
5e3608d8 1084 /* Argument 2 must be 0, 1, 2, or 3. */
1085 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1086 {
c3ceba8e 1087 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
5e3608d8 1088 op2 = const0_rtx;
1089 }
1090
1091#ifdef HAVE_prefetch
1092 if (HAVE_prefetch)
1093 {
f0ce3b1f 1094 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
4cd21437 1095 (op0,
f0ce3b1f 1096 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
19bf118a 1097 || (GET_MODE (op0) != Pmode))
9342ee68 1098 {
85d654dd 1099 op0 = convert_memory_address (Pmode, op0);
9342ee68 1100 op0 = force_reg (Pmode, op0);
1101 }
5e3608d8 1102 emit_insn (gen_prefetch (op0, op1, op2));
1103 }
5e3608d8 1104#endif
0a534ba7 1105
f0ce3b1f 1106 /* Don't do anything with direct references to volatile memory, but
1107 generate code to handle other side effects. */
e16ceb8e 1108 if (!MEM_P (op0) && side_effects_p (op0))
f0ce3b1f 1109 emit_insn (op0);
5e3608d8 1110}
1111
f7c44134 1112/* Get a MEM rtx for expression EXP which is the address of an operand
d8ae1baa 1113 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1114 the maximum length of the block of memory that might be accessed or
1115 NULL if unknown. */
f7c44134 1116
53800dbe 1117static rtx
d8ae1baa 1118get_memory_rtx (tree exp, tree len)
53800dbe 1119{
ad0a178f 1120 tree orig_exp = exp;
1121 rtx addr, mem;
1122 HOST_WIDE_INT off;
1123
1124 /* When EXP is not resolved SAVE_EXPR, MEM_ATTRS can be still derived
1125 from its expression, for expr->a.b only <variable>.a.b is recorded. */
1126 if (TREE_CODE (exp) == SAVE_EXPR && !SAVE_EXPR_RESOLVED_P (exp))
1127 exp = TREE_OPERAND (exp, 0);
1128
1129 addr = expand_expr (orig_exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1130 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
2a631e19 1131
f7c44134 1132 /* Get an expression we can use to find the attributes to assign to MEM.
1133 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1134 we can. First remove any nops. */
72dd6141 1135 while (CONVERT_EXPR_P (exp)
f7c44134 1136 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1137 exp = TREE_OPERAND (exp, 0);
1138
ad0a178f 1139 off = 0;
1140 if (TREE_CODE (exp) == POINTER_PLUS_EXPR
1141 && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
1142 && host_integerp (TREE_OPERAND (exp, 1), 0)
1143 && (off = tree_low_cst (TREE_OPERAND (exp, 1), 0)) > 0)
1144 exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1145 else if (TREE_CODE (exp) == ADDR_EXPR)
a1a25d19 1146 exp = TREE_OPERAND (exp, 0);
f7c44134 1147 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
a1a25d19 1148 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1149 else
1150 exp = NULL;
1151
1152 /* Honor attributes derived from exp, except for the alias set
1153 (as builtin stringops may alias with anything) and the size
1154 (as stringops may access multiple array elements). */
1155 if (exp)
eec8e941 1156 {
a1a25d19 1157 set_mem_attributes (mem, exp, 0);
d8ae1baa 1158
ad0a178f 1159 if (off)
1160 mem = adjust_automodify_address_nv (mem, BLKmode, NULL, off);
1161
d8ae1baa 1162 /* Allow the string and memory builtins to overflow from one
1163 field into another, see http://gcc.gnu.org/PR23561.
1164 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1165 memory accessed by the string or memory builtin will fit
1166 within the field. */
1167 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1168 {
1169 tree mem_expr = MEM_EXPR (mem);
1170 HOST_WIDE_INT offset = -1, length = -1;
1171 tree inner = exp;
1172
1173 while (TREE_CODE (inner) == ARRAY_REF
72dd6141 1174 || CONVERT_EXPR_P (inner)
d8ae1baa 1175 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1176 || TREE_CODE (inner) == SAVE_EXPR)
1177 inner = TREE_OPERAND (inner, 0);
1178
1179 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1180
1181 if (MEM_OFFSET (mem)
971ba038 1182 && CONST_INT_P (MEM_OFFSET (mem)))
d8ae1baa 1183 offset = INTVAL (MEM_OFFSET (mem));
1184
1185 if (offset >= 0 && len && host_integerp (len, 0))
1186 length = tree_low_cst (len, 0);
1187
1188 while (TREE_CODE (inner) == COMPONENT_REF)
1189 {
1190 tree field = TREE_OPERAND (inner, 1);
d8ae1baa 1191 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1192 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1193
6933ebec 1194 /* Bitfields are generally not byte-addressable. */
1195 gcc_assert (!DECL_BIT_FIELD (field)
1196 || ((tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1197 % BITS_PER_UNIT) == 0
1198 && host_integerp (DECL_SIZE (field), 0)
1199 && (TREE_INT_CST_LOW (DECL_SIZE (field))
1200 % BITS_PER_UNIT) == 0));
1201
b2f0b2a3 1202 /* If we can prove that the memory starting at XEXP (mem, 0) and
1203 ending at XEXP (mem, 0) + LENGTH will fit into this field, we
1204 can keep the COMPONENT_REF in MEM_EXPR. But be careful with
1205 fields without DECL_SIZE_UNIT like flexible array members. */
d8ae1baa 1206 if (length >= 0
b2f0b2a3 1207 && DECL_SIZE_UNIT (field)
6933ebec 1208 && host_integerp (DECL_SIZE_UNIT (field), 0))
d8ae1baa 1209 {
1210 HOST_WIDE_INT size
6933ebec 1211 = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field));
d8ae1baa 1212 if (offset <= size
1213 && length <= size
1214 && offset + length <= size)
1215 break;
1216 }
1217
1218 if (offset >= 0
1219 && host_integerp (DECL_FIELD_OFFSET (field), 0))
6933ebec 1220 offset += TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field))
d8ae1baa 1221 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1222 / BITS_PER_UNIT;
1223 else
1224 {
1225 offset = -1;
1226 length = -1;
1227 }
1228
1229 mem_expr = TREE_OPERAND (mem_expr, 0);
1230 inner = TREE_OPERAND (inner, 0);
d8ae1baa 1231 }
1232
1233 if (mem_expr == NULL)
1234 offset = -1;
1235 if (mem_expr != MEM_EXPR (mem))
1236 {
1237 set_mem_expr (mem, mem_expr);
1238 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1239 }
1240 }
eec8e941 1241 set_mem_alias_set (mem, 0);
a1a25d19 1242 set_mem_size (mem, NULL_RTX);
eec8e941 1243 }
53800dbe 1244
53800dbe 1245 return mem;
1246}
1247\f
1248/* Built-in functions to perform an untyped call and return. */
1249
1250/* For each register that may be used for calling a function, this
1251 gives a mode used to copy the register's value. VOIDmode indicates
1252 the register is not used for calling a function. If the machine
1253 has register windows, this gives only the outbound registers.
1254 INCOMING_REGNO gives the corresponding inbound register. */
1255static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1256
1257/* For each register that may be used for returning values, this gives
1258 a mode used to copy the register's value. VOIDmode indicates the
1259 register is not used for returning values. If the machine has
1260 register windows, this gives only the outbound registers.
1261 INCOMING_REGNO gives the corresponding inbound register. */
1262static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1263
1264/* For each register that may be used for calling a function, this
1265 gives the offset of that register into the block returned by
1266 __builtin_apply_args. 0 indicates that the register is not
1267 used for calling a function. */
1268static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1269
53800dbe 1270/* Return the size required for the block returned by __builtin_apply_args,
1271 and initialize apply_args_mode. */
1272
1273static int
aecda0d6 1274apply_args_size (void)
53800dbe 1275{
1276 static int size = -1;
58e9ce8f 1277 int align;
1278 unsigned int regno;
53800dbe 1279 enum machine_mode mode;
1280
1281 /* The values computed by this function never change. */
1282 if (size < 0)
1283 {
1284 /* The first value is the incoming arg-pointer. */
1285 size = GET_MODE_SIZE (Pmode);
1286
1287 /* The second value is the structure value address unless this is
1288 passed as an "invisible" first argument. */
6812c89e 1289 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
53800dbe 1290 size += GET_MODE_SIZE (Pmode);
1291
1292 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1293 if (FUNCTION_ARG_REGNO_P (regno))
1294 {
0862b7e9 1295 mode = reg_raw_mode[regno];
1296
64db345d 1297 gcc_assert (mode != VOIDmode);
53800dbe 1298
1299 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1300 if (size % align != 0)
1301 size = CEIL (size, align) * align;
1302 apply_args_reg_offset[regno] = size;
1303 size += GET_MODE_SIZE (mode);
1304 apply_args_mode[regno] = mode;
1305 }
1306 else
1307 {
1308 apply_args_mode[regno] = VOIDmode;
1309 apply_args_reg_offset[regno] = 0;
1310 }
1311 }
1312 return size;
1313}
1314
1315/* Return the size required for the block returned by __builtin_apply,
1316 and initialize apply_result_mode. */
1317
1318static int
aecda0d6 1319apply_result_size (void)
53800dbe 1320{
1321 static int size = -1;
1322 int align, regno;
1323 enum machine_mode mode;
1324
1325 /* The values computed by this function never change. */
1326 if (size < 0)
1327 {
1328 size = 0;
1329
1330 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1331 if (FUNCTION_VALUE_REGNO_P (regno))
1332 {
0862b7e9 1333 mode = reg_raw_mode[regno];
1334
64db345d 1335 gcc_assert (mode != VOIDmode);
53800dbe 1336
1337 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1338 if (size % align != 0)
1339 size = CEIL (size, align) * align;
1340 size += GET_MODE_SIZE (mode);
1341 apply_result_mode[regno] = mode;
1342 }
1343 else
1344 apply_result_mode[regno] = VOIDmode;
1345
1346 /* Allow targets that use untyped_call and untyped_return to override
1347 the size so that machine-specific information can be stored here. */
1348#ifdef APPLY_RESULT_SIZE
1349 size = APPLY_RESULT_SIZE;
1350#endif
1351 }
1352 return size;
1353}
1354
1355#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1356/* Create a vector describing the result block RESULT. If SAVEP is true,
1357 the result block is used to save the values; otherwise it is used to
1358 restore the values. */
1359
1360static rtx
aecda0d6 1361result_vector (int savep, rtx result)
53800dbe 1362{
1363 int regno, size, align, nelts;
1364 enum machine_mode mode;
1365 rtx reg, mem;
364c0c59 1366 rtx *savevec = XALLOCAVEC (rtx, FIRST_PSEUDO_REGISTER);
bf8e3599 1367
53800dbe 1368 size = nelts = 0;
1369 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1370 if ((mode = apply_result_mode[regno]) != VOIDmode)
1371 {
1372 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1373 if (size % align != 0)
1374 size = CEIL (size, align) * align;
1375 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
e513d163 1376 mem = adjust_address (result, mode, size);
53800dbe 1377 savevec[nelts++] = (savep
1378 ? gen_rtx_SET (VOIDmode, mem, reg)
1379 : gen_rtx_SET (VOIDmode, reg, mem));
1380 size += GET_MODE_SIZE (mode);
1381 }
1382 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1383}
1384#endif /* HAVE_untyped_call or HAVE_untyped_return */
1385
1386/* Save the state required to perform an untyped call with the same
1387 arguments as were passed to the current function. */
1388
1389static rtx
aecda0d6 1390expand_builtin_apply_args_1 (void)
53800dbe 1391{
1c7e61a7 1392 rtx registers, tem;
53800dbe 1393 int size, align, regno;
1394 enum machine_mode mode;
6812c89e 1395 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
53800dbe 1396
1397 /* Create a block where the arg-pointer, structure value address,
1398 and argument registers can be saved. */
1399 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1400
1401 /* Walk past the arg-pointer and structure value address. */
1402 size = GET_MODE_SIZE (Pmode);
6812c89e 1403 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
53800dbe 1404 size += GET_MODE_SIZE (Pmode);
1405
1406 /* Save each register used in calling a function to the block. */
1407 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1408 if ((mode = apply_args_mode[regno]) != VOIDmode)
1409 {
53800dbe 1410 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1411 if (size % align != 0)
1412 size = CEIL (size, align) * align;
1413
1414 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1415
e513d163 1416 emit_move_insn (adjust_address (registers, mode, size), tem);
53800dbe 1417 size += GET_MODE_SIZE (mode);
1418 }
1419
1420 /* Save the arg pointer to the block. */
27a7a23a 1421 tem = copy_to_reg (crtl->args.internal_arg_pointer);
f083a92b 1422#ifdef STACK_GROWS_DOWNWARD
1c7e61a7 1423 /* We need the pointer as the caller actually passed them to us, not
9d4b544c 1424 as we might have pretended they were passed. Make sure it's a valid
1425 operand, as emit_move_insn isn't expected to handle a PLUS. */
1426 tem
abe32cce 1427 = force_operand (plus_constant (tem, crtl->args.pretend_args_size),
9d4b544c 1428 NULL_RTX);
1c7e61a7 1429#endif
1430 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
0862b7e9 1431
53800dbe 1432 size = GET_MODE_SIZE (Pmode);
1433
1434 /* Save the structure value address unless this is passed as an
1435 "invisible" first argument. */
45550790 1436 if (struct_incoming_value)
53800dbe 1437 {
e513d163 1438 emit_move_insn (adjust_address (registers, Pmode, size),
45550790 1439 copy_to_reg (struct_incoming_value));
53800dbe 1440 size += GET_MODE_SIZE (Pmode);
1441 }
1442
1443 /* Return the address of the block. */
1444 return copy_addr_to_reg (XEXP (registers, 0));
1445}
1446
1447/* __builtin_apply_args returns block of memory allocated on
1448 the stack into which is stored the arg pointer, structure
1449 value address, static chain, and all the registers that might
1450 possibly be used in performing a function call. The code is
1451 moved to the start of the function so the incoming values are
1452 saved. */
27d0c333 1453
53800dbe 1454static rtx
aecda0d6 1455expand_builtin_apply_args (void)
53800dbe 1456{
1457 /* Don't do __builtin_apply_args more than once in a function.
1458 Save the result of the first call and reuse it. */
1459 if (apply_args_value != 0)
1460 return apply_args_value;
1461 {
1462 /* When this function is called, it means that registers must be
1463 saved on entry to this function. So we migrate the
1464 call to the first insn of this function. */
1465 rtx temp;
1466 rtx seq;
1467
1468 start_sequence ();
1469 temp = expand_builtin_apply_args_1 ();
1470 seq = get_insns ();
1471 end_sequence ();
1472
1473 apply_args_value = temp;
1474
31d3e01c 1475 /* Put the insns after the NOTE that starts the function.
1476 If this is inside a start_sequence, make the outer-level insn
53800dbe 1477 chain current, so the code is placed at the start of the
0ef1a651 1478 function. If internal_arg_pointer is a non-virtual pseudo,
1479 it needs to be placed after the function that initializes
1480 that pseudo. */
53800dbe 1481 push_topmost_sequence ();
0ef1a651 1482 if (REG_P (crtl->args.internal_arg_pointer)
1483 && REGNO (crtl->args.internal_arg_pointer) > LAST_VIRTUAL_REGISTER)
1484 emit_insn_before (seq, parm_birth_insn);
1485 else
1486 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
53800dbe 1487 pop_topmost_sequence ();
1488 return temp;
1489 }
1490}
1491
1492/* Perform an untyped call and save the state required to perform an
1493 untyped return of whatever value was returned by the given function. */
1494
1495static rtx
aecda0d6 1496expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
53800dbe 1497{
1498 int size, align, regno;
1499 enum machine_mode mode;
2a631e19 1500 rtx incoming_args, result, reg, dest, src, call_insn;
53800dbe 1501 rtx old_stack_level = 0;
1502 rtx call_fusage = 0;
6812c89e 1503 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
53800dbe 1504
85d654dd 1505 arguments = convert_memory_address (Pmode, arguments);
726ec87c 1506
53800dbe 1507 /* Create a block where the return registers can be saved. */
1508 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1509
53800dbe 1510 /* Fetch the arg pointer from the ARGUMENTS block. */
1511 incoming_args = gen_reg_rtx (Pmode);
726ec87c 1512 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
53800dbe 1513#ifndef STACK_GROWS_DOWNWARD
ad99e708 1514 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1515 incoming_args, 0, OPTAB_LIB_WIDEN);
53800dbe 1516#endif
1517
04a46d40 1518 /* Push a new argument block and copy the arguments. Do not allow
1519 the (potential) memcpy call below to interfere with our stack
1520 manipulations. */
53800dbe 1521 do_pending_stack_adjust ();
04a46d40 1522 NO_DEFER_POP;
53800dbe 1523
2358393e 1524 /* Save the stack with nonlocal if available. */
53800dbe 1525#ifdef HAVE_save_stack_nonlocal
1526 if (HAVE_save_stack_nonlocal)
1527 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1528 else
1529#endif
1530 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1531
59647703 1532 /* Allocate a block of memory onto the stack and copy the memory
1533 arguments to the outgoing arguments address. */
1534 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
27a7a23a 1535
1536 /* Set DRAP flag to true, even though allocate_dynamic_stack_space
1537 may have already set current_function_calls_alloca to true.
1538 current_function_calls_alloca won't be set if argsize is zero,
1539 so we have to guarantee need_drap is true here. */
1540 if (SUPPORTS_STACK_ALIGNMENT)
1541 crtl->need_drap = true;
1542
59647703 1543 dest = virtual_outgoing_args_rtx;
1544#ifndef STACK_GROWS_DOWNWARD
971ba038 1545 if (CONST_INT_P (argsize))
59647703 1546 dest = plus_constant (dest, -INTVAL (argsize));
1547 else
1548 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1549#endif
2a631e19 1550 dest = gen_rtx_MEM (BLKmode, dest);
1551 set_mem_align (dest, PARM_BOUNDARY);
1552 src = gen_rtx_MEM (BLKmode, incoming_args);
1553 set_mem_align (src, PARM_BOUNDARY);
0378dbdc 1554 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
53800dbe 1555
1556 /* Refer to the argument block. */
1557 apply_args_size ();
1558 arguments = gen_rtx_MEM (BLKmode, arguments);
2a631e19 1559 set_mem_align (arguments, PARM_BOUNDARY);
53800dbe 1560
1561 /* Walk past the arg-pointer and structure value address. */
1562 size = GET_MODE_SIZE (Pmode);
45550790 1563 if (struct_value)
53800dbe 1564 size += GET_MODE_SIZE (Pmode);
1565
1566 /* Restore each of the registers previously saved. Make USE insns
1567 for each of these registers for use in making the call. */
1568 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1569 if ((mode = apply_args_mode[regno]) != VOIDmode)
1570 {
1571 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1572 if (size % align != 0)
1573 size = CEIL (size, align) * align;
1574 reg = gen_rtx_REG (mode, regno);
e513d163 1575 emit_move_insn (reg, adjust_address (arguments, mode, size));
53800dbe 1576 use_reg (&call_fusage, reg);
1577 size += GET_MODE_SIZE (mode);
1578 }
1579
1580 /* Restore the structure value address unless this is passed as an
1581 "invisible" first argument. */
1582 size = GET_MODE_SIZE (Pmode);
45550790 1583 if (struct_value)
53800dbe 1584 {
1585 rtx value = gen_reg_rtx (Pmode);
e513d163 1586 emit_move_insn (value, adjust_address (arguments, Pmode, size));
45550790 1587 emit_move_insn (struct_value, value);
8ad4c111 1588 if (REG_P (struct_value))
45550790 1589 use_reg (&call_fusage, struct_value);
53800dbe 1590 size += GET_MODE_SIZE (Pmode);
1591 }
1592
1593 /* All arguments and registers used for the call are set up by now! */
82c7907c 1594 function = prepare_call_address (NULL, function, NULL, &call_fusage, 0, 0);
53800dbe 1595
1596 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1597 and we don't want to load it into a register as an optimization,
1598 because prepare_call_address already did it if it should be done. */
1599 if (GET_CODE (function) != SYMBOL_REF)
1600 function = memory_address (FUNCTION_MODE, function);
1601
1602 /* Generate the actual call instruction and save the return value. */
1603#ifdef HAVE_untyped_call
1604 if (HAVE_untyped_call)
1605 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1606 result, result_vector (1, result)));
1607 else
1608#endif
1609#ifdef HAVE_call_value
1610 if (HAVE_call_value)
1611 {
1612 rtx valreg = 0;
1613
1614 /* Locate the unique return register. It is not possible to
1615 express a call that sets more than one return register using
1616 call_value; use untyped_call for that. In fact, untyped_call
1617 only needs to save the return registers in the given block. */
1618 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1619 if ((mode = apply_result_mode[regno]) != VOIDmode)
1620 {
64db345d 1621 gcc_assert (!valreg); /* HAVE_untyped_call required. */
7d3f6cc7 1622
53800dbe 1623 valreg = gen_rtx_REG (mode, regno);
1624 }
1625
2ed6c343 1626 emit_call_insn (GEN_CALL_VALUE (valreg,
53800dbe 1627 gen_rtx_MEM (FUNCTION_MODE, function),
1628 const0_rtx, NULL_RTX, const0_rtx));
1629
e513d163 1630 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
53800dbe 1631 }
1632 else
1633#endif
64db345d 1634 gcc_unreachable ();
53800dbe 1635
d5f9786f 1636 /* Find the CALL insn we just emitted, and attach the register usage
1637 information. */
1638 call_insn = last_call_insn ();
1639 add_function_usage_to (call_insn, call_fusage);
53800dbe 1640
1641 /* Restore the stack. */
1642#ifdef HAVE_save_stack_nonlocal
1643 if (HAVE_save_stack_nonlocal)
1644 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1645 else
1646#endif
1647 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1648
04a46d40 1649 OK_DEFER_POP;
1650
53800dbe 1651 /* Return the address of the result block. */
85d654dd 1652 result = copy_addr_to_reg (XEXP (result, 0));
1653 return convert_memory_address (ptr_mode, result);
53800dbe 1654}
1655
1656/* Perform an untyped return. */
1657
1658static void
aecda0d6 1659expand_builtin_return (rtx result)
53800dbe 1660{
1661 int size, align, regno;
1662 enum machine_mode mode;
1663 rtx reg;
1664 rtx call_fusage = 0;
1665
85d654dd 1666 result = convert_memory_address (Pmode, result);
726ec87c 1667
53800dbe 1668 apply_result_size ();
1669 result = gen_rtx_MEM (BLKmode, result);
1670
1671#ifdef HAVE_untyped_return
1672 if (HAVE_untyped_return)
1673 {
1674 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1675 emit_barrier ();
1676 return;
1677 }
1678#endif
1679
1680 /* Restore the return value and note that each value is used. */
1681 size = 0;
1682 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1683 if ((mode = apply_result_mode[regno]) != VOIDmode)
1684 {
1685 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1686 if (size % align != 0)
1687 size = CEIL (size, align) * align;
1688 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
e513d163 1689 emit_move_insn (reg, adjust_address (result, mode, size));
53800dbe 1690
1691 push_to_sequence (call_fusage);
18b42941 1692 emit_use (reg);
53800dbe 1693 call_fusage = get_insns ();
1694 end_sequence ();
1695 size += GET_MODE_SIZE (mode);
1696 }
1697
1698 /* Put the USE insns before the return. */
31d3e01c 1699 emit_insn (call_fusage);
53800dbe 1700
1701 /* Return whatever values was restored by jumping directly to the end
1702 of the function. */
62380d2d 1703 expand_naked_return ();
53800dbe 1704}
1705
539a3a92 1706/* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
27d0c333 1707
539a3a92 1708static enum type_class
aecda0d6 1709type_to_class (tree type)
539a3a92 1710{
1711 switch (TREE_CODE (type))
1712 {
1713 case VOID_TYPE: return void_type_class;
1714 case INTEGER_TYPE: return integer_type_class;
539a3a92 1715 case ENUMERAL_TYPE: return enumeral_type_class;
1716 case BOOLEAN_TYPE: return boolean_type_class;
1717 case POINTER_TYPE: return pointer_type_class;
1718 case REFERENCE_TYPE: return reference_type_class;
1719 case OFFSET_TYPE: return offset_type_class;
1720 case REAL_TYPE: return real_type_class;
1721 case COMPLEX_TYPE: return complex_type_class;
1722 case FUNCTION_TYPE: return function_type_class;
1723 case METHOD_TYPE: return method_type_class;
1724 case RECORD_TYPE: return record_type_class;
1725 case UNION_TYPE:
1726 case QUAL_UNION_TYPE: return union_type_class;
1727 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1728 ? string_type_class : array_type_class);
539a3a92 1729 case LANG_TYPE: return lang_type_class;
1730 default: return no_type_class;
1731 }
1732}
bf8e3599 1733
c2f47e15 1734/* Expand a call EXP to __builtin_classify_type. */
27d0c333 1735
53800dbe 1736static rtx
c2f47e15 1737expand_builtin_classify_type (tree exp)
53800dbe 1738{
c2f47e15 1739 if (call_expr_nargs (exp))
1740 return GEN_INT (type_to_class (TREE_TYPE (CALL_EXPR_ARG (exp, 0))));
53800dbe 1741 return GEN_INT (no_type_class);
1742}
1743
07976da7 1744/* This helper macro, meant to be used in mathfn_built_in below,
1745 determines which among a set of three builtin math functions is
1746 appropriate for a given type mode. The `F' and `L' cases are
1747 automatically generated from the `double' case. */
1748#define CASE_MATHFN(BUILT_IN_MATHFN) \
1749 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1750 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1751 fcodel = BUILT_IN_MATHFN##L ; break;
cd2656b0 1752/* Similar to above, but appends _R after any F/L suffix. */
1753#define CASE_MATHFN_REENT(BUILT_IN_MATHFN) \
1754 case BUILT_IN_MATHFN##_R: case BUILT_IN_MATHFN##F_R: case BUILT_IN_MATHFN##L_R: \
1755 fcode = BUILT_IN_MATHFN##_R; fcodef = BUILT_IN_MATHFN##F_R ; \
1756 fcodel = BUILT_IN_MATHFN##L_R ; break;
07976da7 1757
1758/* Return mathematic function equivalent to FN but operating directly
c319d56a 1759 on TYPE, if available. If IMPLICIT is true find the function in
1760 implicit_built_in_decls[], otherwise use built_in_decls[]. If we
1761 can't do the conversion, return zero. */
1762
1763static tree
1764mathfn_built_in_1 (tree type, enum built_in_function fn, bool implicit)
0a68165a 1765{
c319d56a 1766 tree const *const fn_arr
1767 = implicit ? implicit_built_in_decls : built_in_decls;
07976da7 1768 enum built_in_function fcode, fcodef, fcodel;
1769
1770 switch (fn)
1771 {
746114e8 1772 CASE_MATHFN (BUILT_IN_ACOS)
1773 CASE_MATHFN (BUILT_IN_ACOSH)
1774 CASE_MATHFN (BUILT_IN_ASIN)
1775 CASE_MATHFN (BUILT_IN_ASINH)
07976da7 1776 CASE_MATHFN (BUILT_IN_ATAN)
746114e8 1777 CASE_MATHFN (BUILT_IN_ATAN2)
1778 CASE_MATHFN (BUILT_IN_ATANH)
1779 CASE_MATHFN (BUILT_IN_CBRT)
07976da7 1780 CASE_MATHFN (BUILT_IN_CEIL)
d735c391 1781 CASE_MATHFN (BUILT_IN_CEXPI)
746114e8 1782 CASE_MATHFN (BUILT_IN_COPYSIGN)
07976da7 1783 CASE_MATHFN (BUILT_IN_COS)
746114e8 1784 CASE_MATHFN (BUILT_IN_COSH)
1785 CASE_MATHFN (BUILT_IN_DREM)
1786 CASE_MATHFN (BUILT_IN_ERF)
1787 CASE_MATHFN (BUILT_IN_ERFC)
07976da7 1788 CASE_MATHFN (BUILT_IN_EXP)
746114e8 1789 CASE_MATHFN (BUILT_IN_EXP10)
1790 CASE_MATHFN (BUILT_IN_EXP2)
1791 CASE_MATHFN (BUILT_IN_EXPM1)
1792 CASE_MATHFN (BUILT_IN_FABS)
1793 CASE_MATHFN (BUILT_IN_FDIM)
07976da7 1794 CASE_MATHFN (BUILT_IN_FLOOR)
746114e8 1795 CASE_MATHFN (BUILT_IN_FMA)
1796 CASE_MATHFN (BUILT_IN_FMAX)
1797 CASE_MATHFN (BUILT_IN_FMIN)
1798 CASE_MATHFN (BUILT_IN_FMOD)
1799 CASE_MATHFN (BUILT_IN_FREXP)
1800 CASE_MATHFN (BUILT_IN_GAMMA)
cd2656b0 1801 CASE_MATHFN_REENT (BUILT_IN_GAMMA) /* GAMMA_R */
746114e8 1802 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1803 CASE_MATHFN (BUILT_IN_HYPOT)
1804 CASE_MATHFN (BUILT_IN_ILOGB)
1805 CASE_MATHFN (BUILT_IN_INF)
69b779ea 1806 CASE_MATHFN (BUILT_IN_ISINF)
746114e8 1807 CASE_MATHFN (BUILT_IN_J0)
1808 CASE_MATHFN (BUILT_IN_J1)
1809 CASE_MATHFN (BUILT_IN_JN)
ac148751 1810 CASE_MATHFN (BUILT_IN_LCEIL)
746114e8 1811 CASE_MATHFN (BUILT_IN_LDEXP)
ad52b9b7 1812 CASE_MATHFN (BUILT_IN_LFLOOR)
746114e8 1813 CASE_MATHFN (BUILT_IN_LGAMMA)
cd2656b0 1814 CASE_MATHFN_REENT (BUILT_IN_LGAMMA) /* LGAMMA_R */
ac148751 1815 CASE_MATHFN (BUILT_IN_LLCEIL)
ad52b9b7 1816 CASE_MATHFN (BUILT_IN_LLFLOOR)
746114e8 1817 CASE_MATHFN (BUILT_IN_LLRINT)
1818 CASE_MATHFN (BUILT_IN_LLROUND)
07976da7 1819 CASE_MATHFN (BUILT_IN_LOG)
746114e8 1820 CASE_MATHFN (BUILT_IN_LOG10)
1821 CASE_MATHFN (BUILT_IN_LOG1P)
1822 CASE_MATHFN (BUILT_IN_LOG2)
1823 CASE_MATHFN (BUILT_IN_LOGB)
1824 CASE_MATHFN (BUILT_IN_LRINT)
1825 CASE_MATHFN (BUILT_IN_LROUND)
1826 CASE_MATHFN (BUILT_IN_MODF)
1827 CASE_MATHFN (BUILT_IN_NAN)
1828 CASE_MATHFN (BUILT_IN_NANS)
07976da7 1829 CASE_MATHFN (BUILT_IN_NEARBYINT)
746114e8 1830 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1831 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1832 CASE_MATHFN (BUILT_IN_POW)
757c219d 1833 CASE_MATHFN (BUILT_IN_POWI)
746114e8 1834 CASE_MATHFN (BUILT_IN_POW10)
1835 CASE_MATHFN (BUILT_IN_REMAINDER)
1836 CASE_MATHFN (BUILT_IN_REMQUO)
1837 CASE_MATHFN (BUILT_IN_RINT)
07976da7 1838 CASE_MATHFN (BUILT_IN_ROUND)
746114e8 1839 CASE_MATHFN (BUILT_IN_SCALB)
1840 CASE_MATHFN (BUILT_IN_SCALBLN)
1841 CASE_MATHFN (BUILT_IN_SCALBN)
c319d56a 1842 CASE_MATHFN (BUILT_IN_SIGNBIT)
746114e8 1843 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
07976da7 1844 CASE_MATHFN (BUILT_IN_SIN)
746114e8 1845 CASE_MATHFN (BUILT_IN_SINCOS)
1846 CASE_MATHFN (BUILT_IN_SINH)
07976da7 1847 CASE_MATHFN (BUILT_IN_SQRT)
1848 CASE_MATHFN (BUILT_IN_TAN)
746114e8 1849 CASE_MATHFN (BUILT_IN_TANH)
1850 CASE_MATHFN (BUILT_IN_TGAMMA)
07976da7 1851 CASE_MATHFN (BUILT_IN_TRUNC)
746114e8 1852 CASE_MATHFN (BUILT_IN_Y0)
1853 CASE_MATHFN (BUILT_IN_Y1)
1854 CASE_MATHFN (BUILT_IN_YN)
07976da7 1855
0a68165a 1856 default:
c2f47e15 1857 return NULL_TREE;
0a68165a 1858 }
07976da7 1859
96b9f485 1860 if (TYPE_MAIN_VARIANT (type) == double_type_node)
c319d56a 1861 return fn_arr[fcode];
96b9f485 1862 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
c319d56a 1863 return fn_arr[fcodef];
96b9f485 1864 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
c319d56a 1865 return fn_arr[fcodel];
07976da7 1866 else
c2f47e15 1867 return NULL_TREE;
0a68165a 1868}
1869
c319d56a 1870/* Like mathfn_built_in_1(), but always use the implicit array. */
1871
1872tree
1873mathfn_built_in (tree type, enum built_in_function fn)
1874{
1875 return mathfn_built_in_1 (type, fn, /*implicit=*/ 1);
1876}
1877
0fd605a5 1878/* If errno must be maintained, expand the RTL to check if the result,
1879 TARGET, of a built-in function call, EXP, is NaN, and if so set
1880 errno to EDOM. */
1881
1882static void
aecda0d6 1883expand_errno_check (tree exp, rtx target)
0fd605a5 1884{
7f05340e 1885 rtx lab = gen_label_rtx ();
0fd605a5 1886
7f05340e 1887 /* Test the result; if it is NaN, set errno=EDOM because
1888 the argument was not in the domain. */
3fcf767f 1889 do_compare_rtx_and_jump (target, target, EQ, 0, GET_MODE (target),
1890 NULL_RTX, NULL_RTX, lab);
0fd605a5 1891
1892#ifdef TARGET_EDOM
7f05340e 1893 /* If this built-in doesn't throw an exception, set errno directly. */
c2f47e15 1894 if (TREE_NOTHROW (TREE_OPERAND (CALL_EXPR_FN (exp), 0)))
7f05340e 1895 {
0fd605a5 1896#ifdef GEN_ERRNO_RTX
7f05340e 1897 rtx errno_rtx = GEN_ERRNO_RTX;
0fd605a5 1898#else
7f05340e 1899 rtx errno_rtx
0fd605a5 1900 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1901#endif
7f05340e 1902 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
0fd605a5 1903 emit_label (lab);
7f05340e 1904 return;
0fd605a5 1905 }
7f05340e 1906#endif
1907
08491912 1908 /* Make sure the library call isn't expanded as a tail call. */
1909 CALL_EXPR_TAILCALL (exp) = 0;
1910
7f05340e 1911 /* We can't set errno=EDOM directly; let the library call do it.
1912 Pop the arguments right away in case the call gets deleted. */
1913 NO_DEFER_POP;
1914 expand_call (exp, target, 0);
1915 OK_DEFER_POP;
1916 emit_label (lab);
0fd605a5 1917}
1918
6b43bae4 1919/* Expand a call to one of the builtin math functions (sqrt, exp, or log).
c2f47e15 1920 Return NULL_RTX if a normal call should be emitted rather than expanding
1921 the function in-line. EXP is the expression that is a call to the builtin
53800dbe 1922 function; if convenient, the result should be placed in TARGET.
1923 SUBTARGET may be used as the target for computing one of EXP's operands. */
27d0c333 1924
53800dbe 1925static rtx
aecda0d6 1926expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
53800dbe 1927{
bf8e3599 1928 optab builtin_optab;
bd421108 1929 rtx op0, insns, before_call;
c6e6ecb1 1930 tree fndecl = get_callee_fndecl (exp);
7f05340e 1931 enum machine_mode mode;
528ee710 1932 bool errno_set = false;
abfea505 1933 tree arg;
53800dbe 1934
c2f47e15 1935 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
1936 return NULL_RTX;
53800dbe 1937
c2f47e15 1938 arg = CALL_EXPR_ARG (exp, 0);
53800dbe 1939
1940 switch (DECL_FUNCTION_CODE (fndecl))
1941 {
4f35b1fc 1942 CASE_FLT_FN (BUILT_IN_SQRT):
7f05340e 1943 errno_set = ! tree_expr_nonnegative_p (arg);
1944 builtin_optab = sqrt_optab;
1945 break;
4f35b1fc 1946 CASE_FLT_FN (BUILT_IN_EXP):
528ee710 1947 errno_set = true; builtin_optab = exp_optab; break;
4f35b1fc 1948 CASE_FLT_FN (BUILT_IN_EXP10):
1949 CASE_FLT_FN (BUILT_IN_POW10):
750ef9f5 1950 errno_set = true; builtin_optab = exp10_optab; break;
4f35b1fc 1951 CASE_FLT_FN (BUILT_IN_EXP2):
750ef9f5 1952 errno_set = true; builtin_optab = exp2_optab; break;
4f35b1fc 1953 CASE_FLT_FN (BUILT_IN_EXPM1):
a6b4eed2 1954 errno_set = true; builtin_optab = expm1_optab; break;
4f35b1fc 1955 CASE_FLT_FN (BUILT_IN_LOGB):
4efbc641 1956 errno_set = true; builtin_optab = logb_optab; break;
4f35b1fc 1957 CASE_FLT_FN (BUILT_IN_LOG):
528ee710 1958 errno_set = true; builtin_optab = log_optab; break;
4f35b1fc 1959 CASE_FLT_FN (BUILT_IN_LOG10):
d3cd9bde 1960 errno_set = true; builtin_optab = log10_optab; break;
4f35b1fc 1961 CASE_FLT_FN (BUILT_IN_LOG2):
d3cd9bde 1962 errno_set = true; builtin_optab = log2_optab; break;
4f35b1fc 1963 CASE_FLT_FN (BUILT_IN_LOG1P):
f474cd93 1964 errno_set = true; builtin_optab = log1p_optab; break;
4f35b1fc 1965 CASE_FLT_FN (BUILT_IN_ASIN):
8de2f465 1966 builtin_optab = asin_optab; break;
4f35b1fc 1967 CASE_FLT_FN (BUILT_IN_ACOS):
8de2f465 1968 builtin_optab = acos_optab; break;
4f35b1fc 1969 CASE_FLT_FN (BUILT_IN_TAN):
528ee710 1970 builtin_optab = tan_optab; break;
4f35b1fc 1971 CASE_FLT_FN (BUILT_IN_ATAN):
528ee710 1972 builtin_optab = atan_optab; break;
4f35b1fc 1973 CASE_FLT_FN (BUILT_IN_FLOOR):
528ee710 1974 builtin_optab = floor_optab; break;
4f35b1fc 1975 CASE_FLT_FN (BUILT_IN_CEIL):
528ee710 1976 builtin_optab = ceil_optab; break;
4f35b1fc 1977 CASE_FLT_FN (BUILT_IN_TRUNC):
a7cc195f 1978 builtin_optab = btrunc_optab; break;
4f35b1fc 1979 CASE_FLT_FN (BUILT_IN_ROUND):
528ee710 1980 builtin_optab = round_optab; break;
4f35b1fc 1981 CASE_FLT_FN (BUILT_IN_NEARBYINT):
0ddf4ad9 1982 builtin_optab = nearbyint_optab;
1983 if (flag_trapping_math)
1984 break;
1985 /* Else fallthrough and expand as rint. */
4f35b1fc 1986 CASE_FLT_FN (BUILT_IN_RINT):
aef94a0f 1987 builtin_optab = rint_optab; break;
b3154a1f 1988 CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
1989 builtin_optab = significand_optab; break;
42721db0 1990 default:
64db345d 1991 gcc_unreachable ();
53800dbe 1992 }
1993
7f05340e 1994 /* Make a suitable register to place result in. */
1995 mode = TYPE_MODE (TREE_TYPE (exp));
fc4eef90 1996
7f05340e 1997 if (! flag_errno_math || ! HONOR_NANS (mode))
1998 errno_set = false;
1999
bd421108 2000 /* Before working hard, check whether the instruction is available. */
99bdde56 2001 if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing)
68e6cb9d 2002 {
bd421108 2003 target = gen_reg_rtx (mode);
7f05340e 2004
bd421108 2005 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2006 need to expand the argument again. This way, we will not perform
2007 side-effects more the once. */
abfea505 2008 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
7f05340e 2009
1db6d067 2010 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
7f05340e 2011
bd421108 2012 start_sequence ();
53800dbe 2013
bd421108 2014 /* Compute into TARGET.
2015 Set TARGET to wherever the result comes back. */
2016 target = expand_unop (mode, builtin_optab, op0, target, 0);
2017
2018 if (target != 0)
2019 {
2020 if (errno_set)
2021 expand_errno_check (exp, target);
2022
2023 /* Output the entire sequence. */
2024 insns = get_insns ();
2025 end_sequence ();
2026 emit_insn (insns);
2027 return target;
2028 }
2029
2030 /* If we were unable to expand via the builtin, stop the sequence
2031 (without outputting the insns) and call to the library function
2032 with the stabilized argument list. */
53800dbe 2033 end_sequence ();
53800dbe 2034 }
2035
bd421108 2036 before_call = get_last_insn ();
2037
1e5b92fa 2038 return expand_call (exp, target, target == const0_rtx);
0fd605a5 2039}
2040
2041/* Expand a call to the builtin binary math functions (pow and atan2).
c2f47e15 2042 Return NULL_RTX if a normal call should be emitted rather than expanding the
0fd605a5 2043 function in-line. EXP is the expression that is a call to the builtin
2044 function; if convenient, the result should be placed in TARGET.
2045 SUBTARGET may be used as the target for computing one of EXP's
2046 operands. */
2047
2048static rtx
aecda0d6 2049expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
0fd605a5 2050{
2051 optab builtin_optab;
2052 rtx op0, op1, insns;
4737caf2 2053 int op1_type = REAL_TYPE;
c6e6ecb1 2054 tree fndecl = get_callee_fndecl (exp);
abfea505 2055 tree arg0, arg1;
7f05340e 2056 enum machine_mode mode;
0fd605a5 2057 bool errno_set = true;
0fd605a5 2058
73a954a1 2059 switch (DECL_FUNCTION_CODE (fndecl))
2060 {
2061 CASE_FLT_FN (BUILT_IN_SCALBN):
2062 CASE_FLT_FN (BUILT_IN_SCALBLN):
2063 CASE_FLT_FN (BUILT_IN_LDEXP):
2064 op1_type = INTEGER_TYPE;
2065 default:
2066 break;
2067 }
4737caf2 2068
c2f47e15 2069 if (!validate_arglist (exp, REAL_TYPE, op1_type, VOID_TYPE))
2070 return NULL_RTX;
0fd605a5 2071
c2f47e15 2072 arg0 = CALL_EXPR_ARG (exp, 0);
2073 arg1 = CALL_EXPR_ARG (exp, 1);
0fd605a5 2074
0fd605a5 2075 switch (DECL_FUNCTION_CODE (fndecl))
2076 {
4f35b1fc 2077 CASE_FLT_FN (BUILT_IN_POW):
0fd605a5 2078 builtin_optab = pow_optab; break;
4f35b1fc 2079 CASE_FLT_FN (BUILT_IN_ATAN2):
0fd605a5 2080 builtin_optab = atan2_optab; break;
73a954a1 2081 CASE_FLT_FN (BUILT_IN_SCALB):
2082 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2083 return 0;
2084 builtin_optab = scalb_optab; break;
2085 CASE_FLT_FN (BUILT_IN_SCALBN):
2086 CASE_FLT_FN (BUILT_IN_SCALBLN):
2087 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2088 return 0;
2089 /* Fall through... */
4f35b1fc 2090 CASE_FLT_FN (BUILT_IN_LDEXP):
4737caf2 2091 builtin_optab = ldexp_optab; break;
4f35b1fc 2092 CASE_FLT_FN (BUILT_IN_FMOD):
80ed5c06 2093 builtin_optab = fmod_optab; break;
ef722005 2094 CASE_FLT_FN (BUILT_IN_REMAINDER):
4f35b1fc 2095 CASE_FLT_FN (BUILT_IN_DREM):
ef722005 2096 builtin_optab = remainder_optab; break;
0fd605a5 2097 default:
64db345d 2098 gcc_unreachable ();
0fd605a5 2099 }
2100
7f05340e 2101 /* Make a suitable register to place result in. */
2102 mode = TYPE_MODE (TREE_TYPE (exp));
fc4eef90 2103
2104 /* Before working hard, check whether the instruction is available. */
99bdde56 2105 if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing)
c2f47e15 2106 return NULL_RTX;
fc4eef90 2107
7f05340e 2108 target = gen_reg_rtx (mode);
2109
2110 if (! flag_errno_math || ! HONOR_NANS (mode))
2111 errno_set = false;
2112
4ee9c684 2113 /* Always stabilize the argument list. */
abfea505 2114 CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
2115 CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1);
7f05340e 2116
8ec3c5c2 2117 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2118 op1 = expand_normal (arg1);
7f05340e 2119
7f05340e 2120 start_sequence ();
2121
0fd605a5 2122 /* Compute into TARGET.
2123 Set TARGET to wherever the result comes back. */
7f05340e 2124 target = expand_binop (mode, builtin_optab, op0, op1,
0fd605a5 2125 target, 0, OPTAB_DIRECT);
53800dbe 2126
68e6cb9d 2127 /* If we were unable to expand via the builtin, stop the sequence
2128 (without outputting the insns) and call to the library function
2129 with the stabilized argument list. */
0fd605a5 2130 if (target == 0)
2131 {
2132 end_sequence ();
68e6cb9d 2133 return expand_call (exp, target, target == const0_rtx);
53800dbe 2134 }
2135
a4356fb9 2136 if (errno_set)
2137 expand_errno_check (exp, target);
0fd605a5 2138
53800dbe 2139 /* Output the entire sequence. */
2140 insns = get_insns ();
2141 end_sequence ();
31d3e01c 2142 emit_insn (insns);
bf8e3599 2143
53800dbe 2144 return target;
2145}
2146
6b43bae4 2147/* Expand a call to the builtin sin and cos math functions.
c2f47e15 2148 Return NULL_RTX if a normal call should be emitted rather than expanding the
6b43bae4 2149 function in-line. EXP is the expression that is a call to the builtin
2150 function; if convenient, the result should be placed in TARGET.
2151 SUBTARGET may be used as the target for computing one of EXP's
2152 operands. */
2153
2154static rtx
2155expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2156{
2157 optab builtin_optab;
7511b819 2158 rtx op0, insns;
6b43bae4 2159 tree fndecl = get_callee_fndecl (exp);
6b43bae4 2160 enum machine_mode mode;
abfea505 2161 tree arg;
6b43bae4 2162
c2f47e15 2163 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2164 return NULL_RTX;
6b43bae4 2165
c2f47e15 2166 arg = CALL_EXPR_ARG (exp, 0);
6b43bae4 2167
2168 switch (DECL_FUNCTION_CODE (fndecl))
2169 {
4f35b1fc 2170 CASE_FLT_FN (BUILT_IN_SIN):
2171 CASE_FLT_FN (BUILT_IN_COS):
6b43bae4 2172 builtin_optab = sincos_optab; break;
2173 default:
64db345d 2174 gcc_unreachable ();
6b43bae4 2175 }
2176
2177 /* Make a suitable register to place result in. */
2178 mode = TYPE_MODE (TREE_TYPE (exp));
2179
6b43bae4 2180 /* Check if sincos insn is available, otherwise fallback
0bed3869 2181 to sin or cos insn. */
99bdde56 2182 if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing)
6b43bae4 2183 switch (DECL_FUNCTION_CODE (fndecl))
2184 {
4f35b1fc 2185 CASE_FLT_FN (BUILT_IN_SIN):
6b43bae4 2186 builtin_optab = sin_optab; break;
4f35b1fc 2187 CASE_FLT_FN (BUILT_IN_COS):
6b43bae4 2188 builtin_optab = cos_optab; break;
2189 default:
64db345d 2190 gcc_unreachable ();
6b43bae4 2191 }
6b43bae4 2192
2193 /* Before working hard, check whether the instruction is available. */
99bdde56 2194 if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing)
6b43bae4 2195 {
2196 target = gen_reg_rtx (mode);
2197
2198 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2199 need to expand the argument again. This way, we will not perform
2200 side-effects more the once. */
abfea505 2201 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
6b43bae4 2202
1db6d067 2203 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
6b43bae4 2204
6b43bae4 2205 start_sequence ();
2206
2207 /* Compute into TARGET.
2208 Set TARGET to wherever the result comes back. */
2209 if (builtin_optab == sincos_optab)
2210 {
64db345d 2211 int result;
7d3f6cc7 2212
6b43bae4 2213 switch (DECL_FUNCTION_CODE (fndecl))
2214 {
4f35b1fc 2215 CASE_FLT_FN (BUILT_IN_SIN):
64db345d 2216 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
6b43bae4 2217 break;
4f35b1fc 2218 CASE_FLT_FN (BUILT_IN_COS):
64db345d 2219 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
6b43bae4 2220 break;
2221 default:
64db345d 2222 gcc_unreachable ();
6b43bae4 2223 }
64db345d 2224 gcc_assert (result);
6b43bae4 2225 }
2226 else
2227 {
2228 target = expand_unop (mode, builtin_optab, op0, target, 0);
2229 }
2230
2231 if (target != 0)
2232 {
6b43bae4 2233 /* Output the entire sequence. */
2234 insns = get_insns ();
2235 end_sequence ();
2236 emit_insn (insns);
2237 return target;
2238 }
2239
2240 /* If we were unable to expand via the builtin, stop the sequence
2241 (without outputting the insns) and call to the library function
2242 with the stabilized argument list. */
2243 end_sequence ();
2244 }
2245
6b43bae4 2246 target = expand_call (exp, target, target == const0_rtx);
2247
2248 return target;
2249}
2250
a67a90e5 2251/* Expand a call to one of the builtin math functions that operate on
2252 floating point argument and output an integer result (ilogb, isinf,
2253 isnan, etc).
2254 Return 0 if a normal call should be emitted rather than expanding the
2255 function in-line. EXP is the expression that is a call to the builtin
2256 function; if convenient, the result should be placed in TARGET.
2257 SUBTARGET may be used as the target for computing one of EXP's operands. */
2258
2259static rtx
2260expand_builtin_interclass_mathfn (tree exp, rtx target, rtx subtarget)
2261{
cde061c1 2262 optab builtin_optab = 0;
2263 enum insn_code icode = CODE_FOR_nothing;
a67a90e5 2264 rtx op0;
2265 tree fndecl = get_callee_fndecl (exp);
a67a90e5 2266 enum machine_mode mode;
2267 bool errno_set = false;
abfea505 2268 tree arg;
389dd41b 2269 location_t loc = EXPR_LOCATION (exp);
a67a90e5 2270
c2f47e15 2271 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2272 return NULL_RTX;
a67a90e5 2273
c2f47e15 2274 arg = CALL_EXPR_ARG (exp, 0);
a67a90e5 2275
2276 switch (DECL_FUNCTION_CODE (fndecl))
2277 {
2278 CASE_FLT_FN (BUILT_IN_ILOGB):
2279 errno_set = true; builtin_optab = ilogb_optab; break;
69b779ea 2280 CASE_FLT_FN (BUILT_IN_ISINF):
2281 builtin_optab = isinf_optab; break;
8a1a9cb7 2282 case BUILT_IN_ISNORMAL:
cde061c1 2283 case BUILT_IN_ISFINITE:
2284 CASE_FLT_FN (BUILT_IN_FINITE):
2285 /* These builtins have no optabs (yet). */
2286 break;
a67a90e5 2287 default:
2288 gcc_unreachable ();
2289 }
2290
2291 /* There's no easy way to detect the case we need to set EDOM. */
2292 if (flag_errno_math && errno_set)
2293 return NULL_RTX;
2294
2295 /* Optab mode depends on the mode of the input argument. */
2296 mode = TYPE_MODE (TREE_TYPE (arg));
2297
cde061c1 2298 if (builtin_optab)
99bdde56 2299 icode = optab_handler (builtin_optab, mode)->insn_code;
a67a90e5 2300
2301 /* Before working hard, check whether the instruction is available. */
2302 if (icode != CODE_FOR_nothing)
2303 {
2304 /* Make a suitable register to place result in. */
2305 if (!target
2306 || GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
2307 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
2308
2309 gcc_assert (insn_data[icode].operand[0].predicate
2310 (target, GET_MODE (target)));
2311
2312 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2313 need to expand the argument again. This way, we will not perform
2314 side-effects more the once. */
abfea505 2315 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
a67a90e5 2316
1db6d067 2317 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
a67a90e5 2318
2319 if (mode != GET_MODE (op0))
2320 op0 = convert_to_mode (mode, op0, 0);
2321
2322 /* Compute into TARGET.
2323 Set TARGET to wherever the result comes back. */
2324 emit_unop_insn (icode, target, op0, UNKNOWN);
2325 return target;
2326 }
2327
06f7a99d 2328 /* If there is no optab, try generic code. */
2329 switch (DECL_FUNCTION_CODE (fndecl))
2330 {
2331 tree result;
2332
2333 CASE_FLT_FN (BUILT_IN_ISINF):
2334 {
2335 /* isinf(x) -> isgreater(fabs(x),DBL_MAX). */
2336 tree const isgr_fn = built_in_decls[BUILT_IN_ISGREATER];
2337 tree const type = TREE_TYPE (arg);
2338 REAL_VALUE_TYPE r;
2339 char buf[128];
2340
2341 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2342 real_from_string (&r, buf);
2343 result = build_call_expr (isgr_fn, 2,
389dd41b 2344 fold_build1_loc (loc, ABS_EXPR, type, arg),
06f7a99d 2345 build_real (type, r));
2346 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2347 }
cde061c1 2348 CASE_FLT_FN (BUILT_IN_FINITE):
2349 case BUILT_IN_ISFINITE:
2350 {
2351 /* isfinite(x) -> islessequal(fabs(x),DBL_MAX). */
2352 tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
2353 tree const type = TREE_TYPE (arg);
2354 REAL_VALUE_TYPE r;
2355 char buf[128];
2356
2357 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2358 real_from_string (&r, buf);
2359 result = build_call_expr (isle_fn, 2,
389dd41b 2360 fold_build1_loc (loc, ABS_EXPR, type, arg),
cde061c1 2361 build_real (type, r));
2362 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2363 }
8a1a9cb7 2364 case BUILT_IN_ISNORMAL:
2365 {
2366 /* isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) &
2367 islessequal(fabs(x),DBL_MAX). */
2368 tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
2369 tree const isge_fn = built_in_decls[BUILT_IN_ISGREATEREQUAL];
2370 tree const type = TREE_TYPE (arg);
2371 REAL_VALUE_TYPE rmax, rmin;
2372 char buf[128];
2373
2374 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2375 real_from_string (&rmax, buf);
2376 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
2377 real_from_string (&rmin, buf);
389dd41b 2378 arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg));
8a1a9cb7 2379 result = build_call_expr (isle_fn, 2, arg,
2380 build_real (type, rmax));
2381 result = fold_build2 (BIT_AND_EXPR, integer_type_node, result,
2382 build_call_expr (isge_fn, 2, arg,
2383 build_real (type, rmin)));
2384 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2385 }
06f7a99d 2386 default:
2387 break;
2388 }
2389
a67a90e5 2390 target = expand_call (exp, target, target == const0_rtx);
2391
2392 return target;
2393}
2394
c3147c1a 2395/* Expand a call to the builtin sincos math function.
c2f47e15 2396 Return NULL_RTX if a normal call should be emitted rather than expanding the
c3147c1a 2397 function in-line. EXP is the expression that is a call to the builtin
2398 function. */
2399
2400static rtx
2401expand_builtin_sincos (tree exp)
2402{
2403 rtx op0, op1, op2, target1, target2;
c3147c1a 2404 enum machine_mode mode;
2405 tree arg, sinp, cosp;
2406 int result;
389dd41b 2407 location_t loc = EXPR_LOCATION (exp);
c3147c1a 2408
c2f47e15 2409 if (!validate_arglist (exp, REAL_TYPE,
2410 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2411 return NULL_RTX;
c3147c1a 2412
c2f47e15 2413 arg = CALL_EXPR_ARG (exp, 0);
2414 sinp = CALL_EXPR_ARG (exp, 1);
2415 cosp = CALL_EXPR_ARG (exp, 2);
c3147c1a 2416
2417 /* Make a suitable register to place result in. */
2418 mode = TYPE_MODE (TREE_TYPE (arg));
2419
2420 /* Check if sincos insn is available, otherwise emit the call. */
99bdde56 2421 if (optab_handler (sincos_optab, mode)->insn_code == CODE_FOR_nothing)
c3147c1a 2422 return NULL_RTX;
2423
2424 target1 = gen_reg_rtx (mode);
2425 target2 = gen_reg_rtx (mode);
2426
8ec3c5c2 2427 op0 = expand_normal (arg);
389dd41b 2428 op1 = expand_normal (build_fold_indirect_ref_loc (loc, sinp));
2429 op2 = expand_normal (build_fold_indirect_ref_loc (loc, cosp));
c3147c1a 2430
2431 /* Compute into target1 and target2.
2432 Set TARGET to wherever the result comes back. */
2433 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2434 gcc_assert (result);
2435
2436 /* Move target1 and target2 to the memory locations indicated
2437 by op1 and op2. */
2438 emit_move_insn (op1, target1);
2439 emit_move_insn (op2, target2);
2440
2441 return const0_rtx;
2442}
2443
d735c391 2444/* Expand a call to the internal cexpi builtin to the sincos math function.
2445 EXP is the expression that is a call to the builtin function; if convenient,
2446 the result should be placed in TARGET. SUBTARGET may be used as the target
2447 for computing one of EXP's operands. */
2448
2449static rtx
2450expand_builtin_cexpi (tree exp, rtx target, rtx subtarget)
2451{
2452 tree fndecl = get_callee_fndecl (exp);
d735c391 2453 tree arg, type;
c2f47e15 2454 enum machine_mode mode;
d735c391 2455 rtx op0, op1, op2;
389dd41b 2456 location_t loc = EXPR_LOCATION (exp);
d735c391 2457
c2f47e15 2458 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2459 return NULL_RTX;
d735c391 2460
c2f47e15 2461 arg = CALL_EXPR_ARG (exp, 0);
d735c391 2462 type = TREE_TYPE (arg);
2463 mode = TYPE_MODE (TREE_TYPE (arg));
2464
2465 /* Try expanding via a sincos optab, fall back to emitting a libcall
18b8d8ae 2466 to sincos or cexp. We are sure we have sincos or cexp because cexpi
2467 is only generated from sincos, cexp or if we have either of them. */
99bdde56 2468 if (optab_handler (sincos_optab, mode)->insn_code != CODE_FOR_nothing)
d735c391 2469 {
2470 op1 = gen_reg_rtx (mode);
2471 op2 = gen_reg_rtx (mode);
2472
1db6d067 2473 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
d735c391 2474
2475 /* Compute into op1 and op2. */
2476 expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
2477 }
18b8d8ae 2478 else if (TARGET_HAS_SINCOS)
d735c391 2479 {
c2f47e15 2480 tree call, fn = NULL_TREE;
d735c391 2481 tree top1, top2;
2482 rtx op1a, op2a;
2483
2484 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2485 fn = built_in_decls[BUILT_IN_SINCOSF];
2486 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2487 fn = built_in_decls[BUILT_IN_SINCOS];
2488 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2489 fn = built_in_decls[BUILT_IN_SINCOSL];
c2f47e15 2490 else
2491 gcc_unreachable ();
d735c391 2492
2493 op1 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2494 op2 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2495 op1a = copy_to_mode_reg (Pmode, XEXP (op1, 0));
2496 op2a = copy_to_mode_reg (Pmode, XEXP (op2, 0));
2497 top1 = make_tree (build_pointer_type (TREE_TYPE (arg)), op1a);
2498 top2 = make_tree (build_pointer_type (TREE_TYPE (arg)), op2a);
2499
d735c391 2500 /* Make sure not to fold the sincos call again. */
2501 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
c2f47e15 2502 expand_normal (build_call_nary (TREE_TYPE (TREE_TYPE (fn)),
2503 call, 3, arg, top1, top2));
d735c391 2504 }
18b8d8ae 2505 else
2506 {
0ecbc158 2507 tree call, fn = NULL_TREE, narg;
18b8d8ae 2508 tree ctype = build_complex_type (type);
2509
0ecbc158 2510 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2511 fn = built_in_decls[BUILT_IN_CEXPF];
2512 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2513 fn = built_in_decls[BUILT_IN_CEXP];
2514 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2515 fn = built_in_decls[BUILT_IN_CEXPL];
c2f47e15 2516 else
2517 gcc_unreachable ();
fc0dfa6e 2518
2519 /* If we don't have a decl for cexp create one. This is the
2520 friendliest fallback if the user calls __builtin_cexpi
2521 without full target C99 function support. */
2522 if (fn == NULL_TREE)
2523 {
2524 tree fntype;
2525 const char *name = NULL;
2526
2527 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2528 name = "cexpf";
2529 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2530 name = "cexp";
2531 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2532 name = "cexpl";
2533
2534 fntype = build_function_type_list (ctype, ctype, NULL_TREE);
2535 fn = build_fn_decl (name, fntype);
2536 }
2537
389dd41b 2538 narg = fold_build2_loc (loc, COMPLEX_EXPR, ctype,
18b8d8ae 2539 build_real (type, dconst0), arg);
2540
2541 /* Make sure not to fold the cexp call again. */
2542 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
3737e769 2543 return expand_expr (build_call_nary (ctype, call, 1, narg),
1db6d067 2544 target, VOIDmode, EXPAND_NORMAL);
18b8d8ae 2545 }
d735c391 2546
2547 /* Now build the proper return type. */
2548 return expand_expr (build2 (COMPLEX_EXPR, build_complex_type (type),
2549 make_tree (TREE_TYPE (arg), op2),
2550 make_tree (TREE_TYPE (arg), op1)),
1db6d067 2551 target, VOIDmode, EXPAND_NORMAL);
d735c391 2552}
2553
7d3afc77 2554/* Expand a call to one of the builtin rounding functions gcc defines
2555 as an extension (lfloor and lceil). As these are gcc extensions we
2556 do not need to worry about setting errno to EDOM.
ad52b9b7 2557 If expanding via optab fails, lower expression to (int)(floor(x)).
2558 EXP is the expression that is a call to the builtin function;
ff1b14e4 2559 if convenient, the result should be placed in TARGET. */
ad52b9b7 2560
2561static rtx
ff1b14e4 2562expand_builtin_int_roundingfn (tree exp, rtx target)
ad52b9b7 2563{
9c42dd28 2564 convert_optab builtin_optab;
ad52b9b7 2565 rtx op0, insns, tmp;
2566 tree fndecl = get_callee_fndecl (exp);
ad52b9b7 2567 enum built_in_function fallback_fn;
2568 tree fallback_fndecl;
2569 enum machine_mode mode;
4de0924f 2570 tree arg;
ad52b9b7 2571
c2f47e15 2572 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
ad52b9b7 2573 gcc_unreachable ();
2574
c2f47e15 2575 arg = CALL_EXPR_ARG (exp, 0);
ad52b9b7 2576
2577 switch (DECL_FUNCTION_CODE (fndecl))
2578 {
4f35b1fc 2579 CASE_FLT_FN (BUILT_IN_LCEIL):
2580 CASE_FLT_FN (BUILT_IN_LLCEIL):
ac148751 2581 builtin_optab = lceil_optab;
2582 fallback_fn = BUILT_IN_CEIL;
2583 break;
2584
4f35b1fc 2585 CASE_FLT_FN (BUILT_IN_LFLOOR):
2586 CASE_FLT_FN (BUILT_IN_LLFLOOR):
ad52b9b7 2587 builtin_optab = lfloor_optab;
2588 fallback_fn = BUILT_IN_FLOOR;
2589 break;
2590
2591 default:
2592 gcc_unreachable ();
2593 }
2594
2595 /* Make a suitable register to place result in. */
2596 mode = TYPE_MODE (TREE_TYPE (exp));
2597
9c42dd28 2598 target = gen_reg_rtx (mode);
ad52b9b7 2599
9c42dd28 2600 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2601 need to expand the argument again. This way, we will not perform
2602 side-effects more the once. */
abfea505 2603 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
ad52b9b7 2604
ff1b14e4 2605 op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
ad52b9b7 2606
9c42dd28 2607 start_sequence ();
ad52b9b7 2608
9c42dd28 2609 /* Compute into TARGET. */
2610 if (expand_sfix_optab (target, op0, builtin_optab))
2611 {
2612 /* Output the entire sequence. */
2613 insns = get_insns ();
ad52b9b7 2614 end_sequence ();
9c42dd28 2615 emit_insn (insns);
2616 return target;
ad52b9b7 2617 }
2618
9c42dd28 2619 /* If we were unable to expand via the builtin, stop the sequence
2620 (without outputting the insns). */
2621 end_sequence ();
2622
ad52b9b7 2623 /* Fall back to floating point rounding optab. */
2624 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
fc0dfa6e 2625
2626 /* For non-C99 targets we may end up without a fallback fndecl here
2627 if the user called __builtin_lfloor directly. In this case emit
2628 a call to the floor/ceil variants nevertheless. This should result
2629 in the best user experience for not full C99 targets. */
2630 if (fallback_fndecl == NULL_TREE)
2631 {
2632 tree fntype;
2633 const char *name = NULL;
2634
2635 switch (DECL_FUNCTION_CODE (fndecl))
2636 {
2637 case BUILT_IN_LCEIL:
2638 case BUILT_IN_LLCEIL:
2639 name = "ceil";
2640 break;
2641 case BUILT_IN_LCEILF:
2642 case BUILT_IN_LLCEILF:
2643 name = "ceilf";
2644 break;
2645 case BUILT_IN_LCEILL:
2646 case BUILT_IN_LLCEILL:
2647 name = "ceill";
2648 break;
2649 case BUILT_IN_LFLOOR:
2650 case BUILT_IN_LLFLOOR:
2651 name = "floor";
2652 break;
2653 case BUILT_IN_LFLOORF:
2654 case BUILT_IN_LLFLOORF:
2655 name = "floorf";
2656 break;
2657 case BUILT_IN_LFLOORL:
2658 case BUILT_IN_LLFLOORL:
2659 name = "floorl";
2660 break;
2661 default:
2662 gcc_unreachable ();
2663 }
2664
2665 fntype = build_function_type_list (TREE_TYPE (arg),
2666 TREE_TYPE (arg), NULL_TREE);
2667 fallback_fndecl = build_fn_decl (name, fntype);
2668 }
2669
c2f47e15 2670 exp = build_call_expr (fallback_fndecl, 1, arg);
ad52b9b7 2671
d4c690af 2672 tmp = expand_normal (exp);
ad52b9b7 2673
2674 /* Truncate the result of floating point optab to integer
2675 via expand_fix (). */
2676 target = gen_reg_rtx (mode);
2677 expand_fix (target, tmp, 0);
2678
2679 return target;
2680}
2681
7d3afc77 2682/* Expand a call to one of the builtin math functions doing integer
2683 conversion (lrint).
2684 Return 0 if a normal call should be emitted rather than expanding the
2685 function in-line. EXP is the expression that is a call to the builtin
ff1b14e4 2686 function; if convenient, the result should be placed in TARGET. */
7d3afc77 2687
2688static rtx
ff1b14e4 2689expand_builtin_int_roundingfn_2 (tree exp, rtx target)
7d3afc77 2690{
5f51ee59 2691 convert_optab builtin_optab;
7d3afc77 2692 rtx op0, insns;
2693 tree fndecl = get_callee_fndecl (exp);
4de0924f 2694 tree arg;
c2f47e15 2695 enum machine_mode mode;
7d3afc77 2696
2697 /* There's no easy way to detect the case we need to set EDOM. */
2698 if (flag_errno_math)
2699 return NULL_RTX;
2700
c2f47e15 2701 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2702 gcc_unreachable ();
2703
2704 arg = CALL_EXPR_ARG (exp, 0);
7d3afc77 2705
2706 switch (DECL_FUNCTION_CODE (fndecl))
2707 {
2708 CASE_FLT_FN (BUILT_IN_LRINT):
2709 CASE_FLT_FN (BUILT_IN_LLRINT):
2710 builtin_optab = lrint_optab; break;
ef2f1a10 2711 CASE_FLT_FN (BUILT_IN_LROUND):
2712 CASE_FLT_FN (BUILT_IN_LLROUND):
2713 builtin_optab = lround_optab; break;
7d3afc77 2714 default:
2715 gcc_unreachable ();
2716 }
2717
2718 /* Make a suitable register to place result in. */
2719 mode = TYPE_MODE (TREE_TYPE (exp));
2720
5f51ee59 2721 target = gen_reg_rtx (mode);
7d3afc77 2722
5f51ee59 2723 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2724 need to expand the argument again. This way, we will not perform
2725 side-effects more the once. */
abfea505 2726 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
7d3afc77 2727
ff1b14e4 2728 op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
7d3afc77 2729
5f51ee59 2730 start_sequence ();
7d3afc77 2731
5f51ee59 2732 if (expand_sfix_optab (target, op0, builtin_optab))
2733 {
2734 /* Output the entire sequence. */
2735 insns = get_insns ();
7d3afc77 2736 end_sequence ();
5f51ee59 2737 emit_insn (insns);
2738 return target;
7d3afc77 2739 }
2740
5f51ee59 2741 /* If we were unable to expand via the builtin, stop the sequence
2742 (without outputting the insns) and call to the library function
2743 with the stabilized argument list. */
2744 end_sequence ();
2745
7d3afc77 2746 target = expand_call (exp, target, target == const0_rtx);
2747
2748 return target;
2749}
2750
f1b844c6 2751/* To evaluate powi(x,n), the floating point value x raised to the
2752 constant integer exponent n, we use a hybrid algorithm that
2753 combines the "window method" with look-up tables. For an
2754 introduction to exponentiation algorithms and "addition chains",
2755 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2756 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2757 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2758 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2759
2760/* Provide a default value for POWI_MAX_MULTS, the maximum number of
2761 multiplications to inline before calling the system library's pow
2762 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2763 so this default never requires calling pow, powf or powl. */
0862b7e9 2764
f1b844c6 2765#ifndef POWI_MAX_MULTS
2766#define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2767#endif
2768
2769/* The size of the "optimal power tree" lookup table. All
2770 exponents less than this value are simply looked up in the
2771 powi_table below. This threshold is also used to size the
2772 cache of pseudo registers that hold intermediate results. */
2773#define POWI_TABLE_SIZE 256
2774
2775/* The size, in bits of the window, used in the "window method"
2776 exponentiation algorithm. This is equivalent to a radix of
2777 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2778#define POWI_WINDOW_SIZE 3
2779
2780/* The following table is an efficient representation of an
2781 "optimal power tree". For each value, i, the corresponding
2782 value, j, in the table states than an optimal evaluation
2783 sequence for calculating pow(x,i) can be found by evaluating
2784 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2785 100 integers is given in Knuth's "Seminumerical algorithms". */
2786
2787static const unsigned char powi_table[POWI_TABLE_SIZE] =
2788 {
2789 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2790 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2791 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2792 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2793 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2794 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2795 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2796 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2797 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2798 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2799 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2800 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2801 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2802 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2803 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2804 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2805 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2806 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2807 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2808 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2809 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2810 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2811 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2812 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2813 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2814 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2815 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2816 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2817 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2818 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2819 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2820 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2821 };
2822
2823
2824/* Return the number of multiplications required to calculate
2825 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2826 subroutine of powi_cost. CACHE is an array indicating
2827 which exponents have already been calculated. */
2828
2829static int
2830powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2831{
2832 /* If we've already calculated this exponent, then this evaluation
2833 doesn't require any additional multiplications. */
2834 if (cache[n])
2835 return 0;
2836
2837 cache[n] = true;
2838 return powi_lookup_cost (n - powi_table[n], cache)
2839 + powi_lookup_cost (powi_table[n], cache) + 1;
2840}
2841
2842/* Return the number of multiplications required to calculate
2843 powi(x,n) for an arbitrary x, given the exponent N. This
2844 function needs to be kept in sync with expand_powi below. */
2845
2846static int
2847powi_cost (HOST_WIDE_INT n)
2848{
2849 bool cache[POWI_TABLE_SIZE];
2850 unsigned HOST_WIDE_INT digit;
2851 unsigned HOST_WIDE_INT val;
2852 int result;
2853
2854 if (n == 0)
2855 return 0;
2856
2857 /* Ignore the reciprocal when calculating the cost. */
2858 val = (n < 0) ? -n : n;
2859
2860 /* Initialize the exponent cache. */
2861 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2862 cache[1] = true;
2863
2864 result = 0;
2865
2866 while (val >= POWI_TABLE_SIZE)
2867 {
2868 if (val & 1)
2869 {
2870 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2871 result += powi_lookup_cost (digit, cache)
2872 + POWI_WINDOW_SIZE + 1;
2873 val >>= POWI_WINDOW_SIZE;
2874 }
2875 else
2876 {
2877 val >>= 1;
2878 result++;
2879 }
2880 }
0862b7e9 2881
6881dbab 2882 return result + powi_lookup_cost (val, cache);
f1b844c6 2883}
2884
2885/* Recursive subroutine of expand_powi. This function takes the array,
2886 CACHE, of already calculated exponents and an exponent N and returns
2887 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2888
2889static rtx
2890expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2891{
2892 unsigned HOST_WIDE_INT digit;
2893 rtx target, result;
2894 rtx op0, op1;
2895
2896 if (n < POWI_TABLE_SIZE)
2897 {
2898 if (cache[n])
a0c938f0 2899 return cache[n];
f1b844c6 2900
2901 target = gen_reg_rtx (mode);
2902 cache[n] = target;
2903
2904 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2905 op1 = expand_powi_1 (mode, powi_table[n], cache);
2906 }
2907 else if (n & 1)
2908 {
2909 target = gen_reg_rtx (mode);
2910 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2911 op0 = expand_powi_1 (mode, n - digit, cache);
2912 op1 = expand_powi_1 (mode, digit, cache);
2913 }
2914 else
2915 {
2916 target = gen_reg_rtx (mode);
2917 op0 = expand_powi_1 (mode, n >> 1, cache);
2918 op1 = op0;
2919 }
2920
2921 result = expand_mult (mode, op0, op1, target, 0);
2922 if (result != target)
2923 emit_move_insn (target, result);
2924 return target;
2925}
2926
2927/* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2928 floating point operand in mode MODE, and N is the exponent. This
2929 function needs to be kept in sync with powi_cost above. */
0862b7e9 2930
f1b844c6 2931static rtx
2932expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2933{
2934 unsigned HOST_WIDE_INT val;
2935 rtx cache[POWI_TABLE_SIZE];
2936 rtx result;
2937
2938 if (n == 0)
2939 return CONST1_RTX (mode);
2940
2941 val = (n < 0) ? -n : n;
2942
19bf118a 2943 memset (cache, 0, sizeof (cache));
f1b844c6 2944 cache[1] = x;
2945
2946 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2947
2948 /* If the original exponent was negative, reciprocate the result. */
2949 if (n < 0)
2950 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2951 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2952
2953 return result;
2954}
2955
c2f47e15 2956/* Expand a call to the pow built-in mathematical function. Return NULL_RTX if
f1b844c6 2957 a normal call should be emitted rather than expanding the function
2958 in-line. EXP is the expression that is a call to the builtin
2959 function; if convenient, the result should be placed in TARGET. */
2960
2961static rtx
2962expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2963{
c2f47e15 2964 tree arg0, arg1;
2965 tree fn, narg0;
1c4709b4 2966 tree type = TREE_TYPE (exp);
2967 REAL_VALUE_TYPE cint, c, c2;
2968 HOST_WIDE_INT n;
2969 rtx op, op2;
2970 enum machine_mode mode = TYPE_MODE (type);
f1b844c6 2971
c2f47e15 2972 if (! validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2973 return NULL_RTX;
f1b844c6 2974
c2f47e15 2975 arg0 = CALL_EXPR_ARG (exp, 0);
2976 arg1 = CALL_EXPR_ARG (exp, 1);
f1b844c6 2977
1c4709b4 2978 if (TREE_CODE (arg1) != REAL_CST
f96bd2bf 2979 || TREE_OVERFLOW (arg1))
1c4709b4 2980 return expand_builtin_mathfn_2 (exp, target, subtarget);
2981
2982 /* Handle constant exponents. */
2983
2984 /* For integer valued exponents we can expand to an optimal multiplication
2985 sequence using expand_powi. */
2986 c = TREE_REAL_CST (arg1);
2987 n = real_to_integer (&c);
2988 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2989 if (real_identical (&c, &cint)
2990 && ((n >= -1 && n <= 2)
2991 || (flag_unsafe_math_optimizations
a0d18cec 2992 && optimize_insn_for_speed_p ()
1c4709b4 2993 && powi_cost (n) <= POWI_MAX_MULTS)))
f1b844c6 2994 {
1db6d067 2995 op = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
1c4709b4 2996 if (n != 1)
2997 {
2998 op = force_reg (mode, op);
2999 op = expand_powi (op, mode, n);
3000 }
3001 return op;
3002 }
3003
3004 narg0 = builtin_save_expr (arg0);
f1b844c6 3005
1c4709b4 3006 /* If the exponent is not integer valued, check if it is half of an integer.
3007 In this case we can expand to sqrt (x) * x**(n/2). */
3008 fn = mathfn_built_in (type, BUILT_IN_SQRT);
3009 if (fn != NULL_TREE)
3010 {
3011 real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
3012 n = real_to_integer (&c2);
f1b844c6 3013 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
1c4709b4 3014 if (real_identical (&c2, &cint)
3015 && ((flag_unsafe_math_optimizations
a0d18cec 3016 && optimize_insn_for_speed_p ()
1c4709b4 3017 && powi_cost (n/2) <= POWI_MAX_MULTS)
3018 || n == 1))
f1b844c6 3019 {
c2f47e15 3020 tree call_expr = build_call_expr (fn, 1, narg0);
8697cf4d 3021 /* Use expand_expr in case the newly built call expression
3022 was folded to a non-call. */
3023 op = expand_expr (call_expr, subtarget, mode, EXPAND_NORMAL);
1c4709b4 3024 if (n != 1)
8c5cac78 3025 {
1db6d067 3026 op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL);
1c4709b4 3027 op2 = force_reg (mode, op2);
3028 op2 = expand_powi (op2, mode, abs (n / 2));
3029 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
3030 0, OPTAB_LIB_WIDEN);
3031 /* If the original exponent was negative, reciprocate the
3032 result. */
3033 if (n < 0)
3034 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
3035 op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
8c5cac78 3036 }
1c4709b4 3037 return op;
f1b844c6 3038 }
3039 }
b613c2a6 3040
1c4709b4 3041 /* Try if the exponent is a third of an integer. In this case
5a84ba55 3042 we can expand to x**(n/3) * cbrt(x)**(n%3). As cbrt (x) is
3043 different from pow (x, 1./3.) due to rounding and behavior
3044 with negative x we need to constrain this transformation to
3045 unsafe math and positive x or finite math. */
1c4709b4 3046 fn = mathfn_built_in (type, BUILT_IN_CBRT);
5a84ba55 3047 if (fn != NULL_TREE
3048 && flag_unsafe_math_optimizations
3049 && (tree_expr_nonnegative_p (arg0)
3050 || !HONOR_NANS (mode)))
1c4709b4 3051 {
3fa759a9 3052 REAL_VALUE_TYPE dconst3;
3053 real_from_integer (&dconst3, VOIDmode, 3, 0, 0);
1c4709b4 3054 real_arithmetic (&c2, MULT_EXPR, &c, &dconst3);
3055 real_round (&c2, mode, &c2);
3056 n = real_to_integer (&c2);
3057 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
3058 real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
3059 real_convert (&c2, mode, &c2);
3060 if (real_identical (&c2, &c)
a0d18cec 3061 && ((optimize_insn_for_speed_p ()
1c4709b4 3062 && powi_cost (n/3) <= POWI_MAX_MULTS)
3063 || n == 1))
3064 {
c2f47e15 3065 tree call_expr = build_call_expr (fn, 1,narg0);
1c4709b4 3066 op = expand_builtin (call_expr, NULL_RTX, subtarget, mode, 0);
3067 if (abs (n) % 3 == 2)
3068 op = expand_simple_binop (mode, MULT, op, op, op,
3069 0, OPTAB_LIB_WIDEN);
3070 if (n != 1)
3071 {
1db6d067 3072 op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL);
1c4709b4 3073 op2 = force_reg (mode, op2);
3074 op2 = expand_powi (op2, mode, abs (n / 3));
3075 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
3076 0, OPTAB_LIB_WIDEN);
3077 /* If the original exponent was negative, reciprocate the
3078 result. */
3079 if (n < 0)
3080 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
3081 op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
3082 }
3083 return op;
3084 }
3085 }
3086
3087 /* Fall back to optab expansion. */
b613c2a6 3088 return expand_builtin_mathfn_2 (exp, target, subtarget);
f1b844c6 3089}
3090
c2f47e15 3091/* Expand a call to the powi built-in mathematical function. Return NULL_RTX if
757c219d 3092 a normal call should be emitted rather than expanding the function
3093 in-line. EXP is the expression that is a call to the builtin
3094 function; if convenient, the result should be placed in TARGET. */
3095
3096static rtx
3097expand_builtin_powi (tree exp, rtx target, rtx subtarget)
3098{
757c219d 3099 tree arg0, arg1;
3100 rtx op0, op1;
3101 enum machine_mode mode;
d0405f40 3102 enum machine_mode mode2;
757c219d 3103
c2f47e15 3104 if (! validate_arglist (exp, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
3105 return NULL_RTX;
757c219d 3106
c2f47e15 3107 arg0 = CALL_EXPR_ARG (exp, 0);
3108 arg1 = CALL_EXPR_ARG (exp, 1);
757c219d 3109 mode = TYPE_MODE (TREE_TYPE (exp));
3110
3111 /* Handle constant power. */
3112
3113 if (TREE_CODE (arg1) == INTEGER_CST
f96bd2bf 3114 && !TREE_OVERFLOW (arg1))
757c219d 3115 {
3116 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
3117
3118 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
3119 Otherwise, check the number of multiplications required. */
3120 if ((TREE_INT_CST_HIGH (arg1) == 0
3121 || TREE_INT_CST_HIGH (arg1) == -1)
3122 && ((n >= -1 && n <= 2)
a0d18cec 3123 || (optimize_insn_for_speed_p ()
757c219d 3124 && powi_cost (n) <= POWI_MAX_MULTS)))
3125 {
1db6d067 3126 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
757c219d 3127 op0 = force_reg (mode, op0);
3128 return expand_powi (op0, mode, n);
3129 }
3130 }
3131
3132 /* Emit a libcall to libgcc. */
3133
c2f47e15 3134 /* Mode of the 2nd argument must match that of an int. */
d0405f40 3135 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
3136
757c219d 3137 if (target == NULL_RTX)
3138 target = gen_reg_rtx (mode);
3139
1db6d067 3140 op0 = expand_expr (arg0, subtarget, mode, EXPAND_NORMAL);
757c219d 3141 if (GET_MODE (op0) != mode)
3142 op0 = convert_to_mode (mode, op0, 0);
1db6d067 3143 op1 = expand_expr (arg1, NULL_RTX, mode2, EXPAND_NORMAL);
d0405f40 3144 if (GET_MODE (op1) != mode2)
3145 op1 = convert_to_mode (mode2, op1, 0);
757c219d 3146
f36b9f69 3147 target = emit_library_call_value (optab_libfunc (powi_optab, mode),
2dd6f9ed 3148 target, LCT_CONST, mode, 2,
d0405f40 3149 op0, mode, op1, mode2);
757c219d 3150
3151 return target;
3152}
3153
c2f47e15 3154/* Expand expression EXP which is a call to the strlen builtin. Return
3155 NULL_RTX if we failed the caller should emit a normal call, otherwise
aed0bd19 3156 try to get the result in TARGET, if convenient. */
f7c44134 3157
53800dbe 3158static rtx
c2f47e15 3159expand_builtin_strlen (tree exp, rtx target,
aecda0d6 3160 enum machine_mode target_mode)
53800dbe 3161{
c2f47e15 3162 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
3163 return NULL_RTX;
53800dbe 3164 else
3165 {
911c0150 3166 rtx pat;
c2f47e15 3167 tree len;
3168 tree src = CALL_EXPR_ARG (exp, 0);
911c0150 3169 rtx result, src_reg, char_rtx, before_strlen;
80cd7a5e 3170 enum machine_mode insn_mode = target_mode, char_mode;
ef2c4a29 3171 enum insn_code icode = CODE_FOR_nothing;
6248e345 3172 int align;
3173
3174 /* If the length can be computed at compile-time, return it. */
681fab1e 3175 len = c_strlen (src, 0);
6248e345 3176 if (len)
80cd7a5e 3177 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
6248e345 3178
681fab1e 3179 /* If the length can be computed at compile-time and is constant
3180 integer, but there are side-effects in src, evaluate
3181 src for side-effects, then return len.
3182 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
3183 can be optimized into: i++; x = 3; */
3184 len = c_strlen (src, 1);
3185 if (len && TREE_CODE (len) == INTEGER_CST)
3186 {
3187 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3188 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
3189 }
3190
6248e345 3191 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
53800dbe 3192
53800dbe 3193 /* If SRC is not a pointer type, don't do this operation inline. */
3194 if (align == 0)
c2f47e15 3195 return NULL_RTX;
53800dbe 3196
911c0150 3197 /* Bail out if we can't compute strlen in the right mode. */
53800dbe 3198 while (insn_mode != VOIDmode)
3199 {
99bdde56 3200 icode = optab_handler (strlen_optab, insn_mode)->insn_code;
53800dbe 3201 if (icode != CODE_FOR_nothing)
c28ae87f 3202 break;
53800dbe 3203
3204 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
3205 }
3206 if (insn_mode == VOIDmode)
c2f47e15 3207 return NULL_RTX;
53800dbe 3208
3209 /* Make a place to write the result of the instruction. */
3210 result = target;
3211 if (! (result != 0
8ad4c111 3212 && REG_P (result)
53800dbe 3213 && GET_MODE (result) == insn_mode
3214 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3215 result = gen_reg_rtx (insn_mode);
3216
911c0150 3217 /* Make a place to hold the source address. We will not expand
3218 the actual source until we are sure that the expansion will
3219 not fail -- there are trees that cannot be expanded twice. */
3220 src_reg = gen_reg_rtx (Pmode);
53800dbe 3221
911c0150 3222 /* Mark the beginning of the strlen sequence so we can emit the
3223 source operand later. */
f0ce3b1f 3224 before_strlen = get_last_insn ();
53800dbe 3225
53800dbe 3226 char_rtx = const0_rtx;
f7c44134 3227 char_mode = insn_data[(int) icode].operand[2].mode;
3228 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
3229 char_mode))
53800dbe 3230 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
3231
911c0150 3232 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
3233 char_rtx, GEN_INT (align));
3234 if (! pat)
c2f47e15 3235 return NULL_RTX;
911c0150 3236 emit_insn (pat);
3237
3238 /* Now that we are assured of success, expand the source. */
3239 start_sequence ();
c5aba89c 3240 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
911c0150 3241 if (pat != src_reg)
3242 emit_move_insn (src_reg, pat);
31d3e01c 3243 pat = get_insns ();
911c0150 3244 end_sequence ();
bceb0d1f 3245
3246 if (before_strlen)
3247 emit_insn_after (pat, before_strlen);
3248 else
3249 emit_insn_before (pat, get_insns ());
53800dbe 3250
3251 /* Return the value in the proper mode for this function. */
80cd7a5e 3252 if (GET_MODE (result) == target_mode)
911c0150 3253 target = result;
53800dbe 3254 else if (target != 0)
911c0150 3255 convert_move (target, result, 0);
53800dbe 3256 else
80cd7a5e 3257 target = convert_to_mode (target_mode, result, 0);
911c0150 3258
3259 return target;
53800dbe 3260 }
3261}
3262
c2f47e15 3263/* Expand a call to the strstr builtin. Return NULL_RTX if we failed the
17f5ea87 3264 caller should emit a normal call, otherwise try to get the result
3265 in TARGET, if convenient (and in mode MODE if that's convenient). */
3266
3267static rtx
c2f47e15 3268expand_builtin_strstr (tree exp, rtx target, enum machine_mode mode)
17f5ea87 3269{
c2f47e15 3270 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
17f5ea87 3271 {
c2f47e15 3272 tree type = TREE_TYPE (exp);
389dd41b 3273 tree result = fold_builtin_strstr (EXPR_LOCATION (exp),
3274 CALL_EXPR_ARG (exp, 0),
c2f47e15 3275 CALL_EXPR_ARG (exp, 1), type);
2c84ee37 3276 if (result)
3277 return expand_expr (result, target, mode, EXPAND_NORMAL);
17f5ea87 3278 }
c2f47e15 3279 return NULL_RTX;
17f5ea87 3280}
3281
c2f47e15 3282/* Expand a call to the strchr builtin. Return NULL_RTX if we failed the
46f3a74a 3283 caller should emit a normal call, otherwise try to get the result
3284 in TARGET, if convenient (and in mode MODE if that's convenient). */
3285
3286static rtx
c2f47e15 3287expand_builtin_strchr (tree exp, rtx target, enum machine_mode mode)
46f3a74a 3288{
c2f47e15 3289 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
46f3a74a 3290 {
c2f47e15 3291 tree type = TREE_TYPE (exp);
389dd41b 3292 tree result = fold_builtin_strchr (EXPR_LOCATION (exp),
3293 CALL_EXPR_ARG (exp, 0),
c2f47e15 3294 CALL_EXPR_ARG (exp, 1), type);
2c84ee37 3295 if (result)
3296 return expand_expr (result, target, mode, EXPAND_NORMAL);
83d79705 3297
2c84ee37 3298 /* FIXME: Should use strchrM optab so that ports can optimize this. */
83d79705 3299 }
c2f47e15 3300 return NULL_RTX;
83d79705 3301}
3302
c2f47e15 3303/* Expand a call to the strrchr builtin. Return NULL_RTX if we failed the
83d79705 3304 caller should emit a normal call, otherwise try to get the result
3305 in TARGET, if convenient (and in mode MODE if that's convenient). */
3306
3307static rtx
c2f47e15 3308expand_builtin_strrchr (tree exp, rtx target, enum machine_mode mode)
83d79705 3309{
c2f47e15 3310 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
83d79705 3311 {
c2f47e15 3312 tree type = TREE_TYPE (exp);
389dd41b 3313 tree result = fold_builtin_strrchr (EXPR_LOCATION (exp),
3314 CALL_EXPR_ARG (exp, 0),
c2f47e15 3315 CALL_EXPR_ARG (exp, 1), type);
2c84ee37 3316 if (result)
3317 return expand_expr (result, target, mode, EXPAND_NORMAL);
83d79705 3318 }
c2f47e15 3319 return NULL_RTX;
83d79705 3320}
3321
c2f47e15 3322/* Expand a call to the strpbrk builtin. Return NULL_RTX if we failed the
83d79705 3323 caller should emit a normal call, otherwise try to get the result
3324 in TARGET, if convenient (and in mode MODE if that's convenient). */
3325
3326static rtx
c2f47e15 3327expand_builtin_strpbrk (tree exp, rtx target, enum machine_mode mode)
83d79705 3328{
c2f47e15 3329 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
83d79705 3330 {
c2f47e15 3331 tree type = TREE_TYPE (exp);
389dd41b 3332 tree result = fold_builtin_strpbrk (EXPR_LOCATION (exp),
3333 CALL_EXPR_ARG (exp, 0),
c2f47e15 3334 CALL_EXPR_ARG (exp, 1), type);
2c84ee37 3335 if (result)
3336 return expand_expr (result, target, mode, EXPAND_NORMAL);
46f3a74a 3337 }
c2f47e15 3338 return NULL_RTX;
46f3a74a 3339}
3340
6840589f 3341/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3342 bytes from constant string DATA + OFFSET and return it as target
3343 constant. */
3344
3345static rtx
aecda0d6 3346builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
3347 enum machine_mode mode)
6840589f 3348{
3349 const char *str = (const char *) data;
3350
64db345d 3351 gcc_assert (offset >= 0
3352 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
3353 <= strlen (str) + 1));
6840589f 3354
3355 return c_readstr (str + offset, mode);
3356}
3357
c2f47e15 3358/* Expand a call EXP to the memcpy builtin.
3359 Return NULL_RTX if we failed, the caller should emit a normal call,
3b824fa6 3360 otherwise try to get the result in TARGET, if convenient (and in
9fe0e1b8 3361 mode MODE if that's convenient). */
c2f47e15 3362
53800dbe 3363static rtx
5a0de151 3364expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
53800dbe 3365{
8e76ec06 3366 tree fndecl = get_callee_fndecl (exp);
c2f47e15 3367
3368 if (!validate_arglist (exp,
3369 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3370 return NULL_RTX;
53800dbe 3371 else
3372 {
c2f47e15 3373 tree dest = CALL_EXPR_ARG (exp, 0);
3374 tree src = CALL_EXPR_ARG (exp, 1);
3375 tree len = CALL_EXPR_ARG (exp, 2);
6840589f 3376 const char *src_str;
27d0c333 3377 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3378 unsigned int dest_align
3379 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
53800dbe 3380 rtx dest_mem, src_mem, dest_addr, len_rtx;
389dd41b 3381 tree result = fold_builtin_memory_op (EXPR_LOCATION (exp),
3382 dest, src, len,
c2f47e15 3383 TREE_TYPE (TREE_TYPE (fndecl)),
4f46f2b9 3384 false, /*endp=*/0);
162719b3 3385 HOST_WIDE_INT expected_size = -1;
3386 unsigned int expected_align = 0;
75a70cf9 3387 tree_ann_common_t ann;
5a0de151 3388
3389 if (result)
4f46f2b9 3390 {
3391 while (TREE_CODE (result) == COMPOUND_EXPR)
3392 {
3393 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3394 EXPAND_NORMAL);
3395 result = TREE_OPERAND (result, 1);
3396 }
3397 return expand_expr (result, target, mode, EXPAND_NORMAL);
3398 }
53800dbe 3399
6f428e8b 3400 /* If DEST is not a pointer type, call the normal function. */
3401 if (dest_align == 0)
c2f47e15 3402 return NULL_RTX;
6f428e8b 3403
6f428e8b 3404 /* If either SRC is not a pointer type, don't do this
a0c938f0 3405 operation in-line. */
6f428e8b 3406 if (src_align == 0)
c2f47e15 3407 return NULL_RTX;
162719b3 3408
75a70cf9 3409 ann = tree_common_ann (exp);
3410 if (ann)
3411 stringop_block_profile (ann->stmt, &expected_align, &expected_size);
3412
162719b3 3413 if (expected_align < dest_align)
3414 expected_align = dest_align;
d8ae1baa 3415 dest_mem = get_memory_rtx (dest, len);
2a631e19 3416 set_mem_align (dest_mem, dest_align);
8ec3c5c2 3417 len_rtx = expand_normal (len);
6840589f 3418 src_str = c_getstr (src);
3419
3420 /* If SRC is a string constant and block move would be done
3421 by pieces, we can avoid loading the string from memory
3422 and only stored the computed constants. */
3423 if (src_str
971ba038 3424 && CONST_INT_P (len_rtx)
6840589f 3425 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3426 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
364c0c59 3427 CONST_CAST (char *, src_str),
3428 dest_align, false))
6840589f 3429 {
9fe0e1b8 3430 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3431 builtin_memcpy_read_str,
364c0c59 3432 CONST_CAST (char *, src_str),
3433 dest_align, false, 0);
e5716f7e 3434 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3435 dest_mem = convert_memory_address (ptr_mode, dest_mem);
9fe0e1b8 3436 return dest_mem;
6840589f 3437 }
3438
d8ae1baa 3439 src_mem = get_memory_rtx (src, len);
2a631e19 3440 set_mem_align (src_mem, src_align);
53800dbe 3441
53800dbe 3442 /* Copy word part most expediently. */
162719b3 3443 dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx,
3444 CALL_EXPR_TAILCALL (exp)
3445 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3446 expected_align, expected_size);
53800dbe 3447
3448 if (dest_addr == 0)
e5716f7e 3449 {
3450 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3451 dest_addr = convert_memory_address (ptr_mode, dest_addr);
e5716f7e 3452 }
9fe0e1b8 3453 return dest_addr;
53800dbe 3454 }
3455}
3456
c2f47e15 3457/* Expand a call EXP to the mempcpy builtin.
3458 Return NULL_RTX if we failed; the caller should emit a normal call,
647661c6 3459 otherwise try to get the result in TARGET, if convenient (and in
9fe0e1b8 3460 mode MODE if that's convenient). If ENDP is 0 return the
3461 destination pointer, if ENDP is 1 return the end pointer ala
3462 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3463 stpcpy. */
647661c6 3464
3465static rtx
c8b17b2e 3466expand_builtin_mempcpy (tree exp, rtx target, enum machine_mode mode)
647661c6 3467{
c2f47e15 3468 if (!validate_arglist (exp,
3469 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3470 return NULL_RTX;
3471 else
3472 {
3473 tree dest = CALL_EXPR_ARG (exp, 0);
3474 tree src = CALL_EXPR_ARG (exp, 1);
3475 tree len = CALL_EXPR_ARG (exp, 2);
3476 return expand_builtin_mempcpy_args (dest, src, len,
3477 TREE_TYPE (exp),
3478 target, mode, /*endp=*/ 1);
3479 }
3480}
3481
3482/* Helper function to do the actual work for expand_builtin_mempcpy. The
3483 arguments to the builtin_mempcpy call DEST, SRC, and LEN are broken out
3484 so that this can also be called without constructing an actual CALL_EXPR.
3485 TYPE is the return type of the call. The other arguments and return value
3486 are the same as for expand_builtin_mempcpy. */
3487
3488static rtx
3489expand_builtin_mempcpy_args (tree dest, tree src, tree len, tree type,
3490 rtx target, enum machine_mode mode, int endp)
3491{
3492 /* If return value is ignored, transform mempcpy into memcpy. */
c8b17b2e 3493 if (target == const0_rtx && implicit_built_in_decls[BUILT_IN_MEMCPY])
9fe0e1b8 3494 {
3495 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
c8b17b2e 3496 tree result = build_call_expr (fn, 3, dest, src, len);
9fe0e1b8 3497
c8b17b2e 3498 while (TREE_CODE (result) == COMPOUND_EXPR)
3499 {
3500 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3501 EXPAND_NORMAL);
3502 result = TREE_OPERAND (result, 1);
3503 }
3504 return expand_expr (result, target, mode, EXPAND_NORMAL);
9fe0e1b8 3505 }
647661c6 3506 else
3507 {
9fe0e1b8 3508 const char *src_str;
3509 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3510 unsigned int dest_align
3511 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3512 rtx dest_mem, src_mem, len_rtx;
389dd41b 3513 tree result = fold_builtin_memory_op (UNKNOWN_LOCATION,
3514 dest, src, len, type, false, endp);
9fe0e1b8 3515
7da1412b 3516 if (result)
4f46f2b9 3517 {
3518 while (TREE_CODE (result) == COMPOUND_EXPR)
3519 {
3520 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3521 EXPAND_NORMAL);
3522 result = TREE_OPERAND (result, 1);
3523 }
3524 return expand_expr (result, target, mode, EXPAND_NORMAL);
3525 }
a0c938f0 3526
7da1412b 3527 /* If either SRC or DEST is not a pointer type, don't do this
a0c938f0 3528 operation in-line. */
7da1412b 3529 if (dest_align == 0 || src_align == 0)
c2f47e15 3530 return NULL_RTX;
9fe0e1b8 3531
6217c238 3532 /* If LEN is not constant, call the normal function. */
3533 if (! host_integerp (len, 1))
c2f47e15 3534 return NULL_RTX;
0862b7e9 3535
8ec3c5c2 3536 len_rtx = expand_normal (len);
9fe0e1b8 3537 src_str = c_getstr (src);
647661c6 3538
9fe0e1b8 3539 /* If SRC is a string constant and block move would be done
3540 by pieces, we can avoid loading the string from memory
3541 and only stored the computed constants. */
3542 if (src_str
971ba038 3543 && CONST_INT_P (len_rtx)
9fe0e1b8 3544 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3545 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
364c0c59 3546 CONST_CAST (char *, src_str),
3547 dest_align, false))
9fe0e1b8 3548 {
d8ae1baa 3549 dest_mem = get_memory_rtx (dest, len);
9fe0e1b8 3550 set_mem_align (dest_mem, dest_align);
3551 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3552 builtin_memcpy_read_str,
364c0c59 3553 CONST_CAST (char *, src_str),
3554 dest_align, false, endp);
9fe0e1b8 3555 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3556 dest_mem = convert_memory_address (ptr_mode, dest_mem);
9fe0e1b8 3557 return dest_mem;
647661c6 3558 }
3559
971ba038 3560 if (CONST_INT_P (len_rtx)
9fe0e1b8 3561 && can_move_by_pieces (INTVAL (len_rtx),
3562 MIN (dest_align, src_align)))
3563 {
d8ae1baa 3564 dest_mem = get_memory_rtx (dest, len);
9fe0e1b8 3565 set_mem_align (dest_mem, dest_align);
d8ae1baa 3566 src_mem = get_memory_rtx (src, len);
9fe0e1b8 3567 set_mem_align (src_mem, src_align);
3568 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3569 MIN (dest_align, src_align), endp);
3570 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3571 dest_mem = convert_memory_address (ptr_mode, dest_mem);
9fe0e1b8 3572 return dest_mem;
3573 }
3574
c2f47e15 3575 return NULL_RTX;
647661c6 3576 }
3577}
3578
c2f47e15 3579/* Expand expression EXP, which is a call to the memmove builtin. Return
3580 NULL_RTX if we failed; the caller should emit a normal call. */
c4950093 3581
3582static rtx
c2f47e15 3583expand_builtin_memmove (tree exp, rtx target, enum machine_mode mode, int ignore)
c4950093 3584{
c2f47e15 3585 if (!validate_arglist (exp,
3586 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3587 return NULL_RTX;
c4950093 3588 else
3589 {
c2f47e15 3590 tree dest = CALL_EXPR_ARG (exp, 0);
3591 tree src = CALL_EXPR_ARG (exp, 1);
3592 tree len = CALL_EXPR_ARG (exp, 2);
3593 return expand_builtin_memmove_args (dest, src, len, TREE_TYPE (exp),
3594 target, mode, ignore);
3595 }
3596}
7e72af53 3597
c2f47e15 3598/* Helper function to do the actual work for expand_builtin_memmove. The
3599 arguments to the builtin_memmove call DEST, SRC, and LEN are broken out
3600 so that this can also be called without constructing an actual CALL_EXPR.
3601 TYPE is the return type of the call. The other arguments and return value
3602 are the same as for expand_builtin_memmove. */
3603
3604static rtx
3605expand_builtin_memmove_args (tree dest, tree src, tree len,
3606 tree type, rtx target, enum machine_mode mode,
3607 int ignore)
3608{
389dd41b 3609 tree result = fold_builtin_memory_op (UNKNOWN_LOCATION,
3610 dest, src, len, type, ignore, /*endp=*/3);
c2f47e15 3611
3612 if (result)
3613 {
05be68f3 3614 STRIP_TYPE_NOPS (result);
c2f47e15 3615 while (TREE_CODE (result) == COMPOUND_EXPR)
4f46f2b9 3616 {
c2f47e15 3617 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3618 EXPAND_NORMAL);
3619 result = TREE_OPERAND (result, 1);
4f46f2b9 3620 }
c2f47e15 3621 return expand_expr (result, target, mode, EXPAND_NORMAL);
3622 }
3623
3624 /* Otherwise, call the normal function. */
3625 return NULL_RTX;
c4950093 3626}
3627
c2f47e15 3628/* Expand expression EXP, which is a call to the bcopy builtin. Return
3629 NULL_RTX if we failed the caller should emit a normal call. */
c4950093 3630
3631static rtx
c2f47e15 3632expand_builtin_bcopy (tree exp, int ignore)
c4950093 3633{
0b25db21 3634 tree type = TREE_TYPE (exp);
c2f47e15 3635 tree src, dest, size;
389dd41b 3636 location_t loc = EXPR_LOCATION (exp);
c4950093 3637
c2f47e15 3638 if (!validate_arglist (exp,
3639 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
c4950093 3640 return NULL_RTX;
3641
c2f47e15 3642 src = CALL_EXPR_ARG (exp, 0);
3643 dest = CALL_EXPR_ARG (exp, 1);
3644 size = CALL_EXPR_ARG (exp, 2);
c4950093 3645
c2f47e15 3646 /* Transform bcopy(ptr x, ptr y, int z) to memmove(ptr y, ptr x, size_t z).
3647 This is done this way so that if it isn't expanded inline, we fall
3648 back to calling bcopy instead of memmove. */
3649 return expand_builtin_memmove_args (dest, src,
389dd41b 3650 fold_convert_loc (loc, sizetype, size),
c2f47e15 3651 type, const0_rtx, VOIDmode,
3652 ignore);
c4950093 3653}
3654
727c62dd 3655#ifndef HAVE_movstr
3656# define HAVE_movstr 0
3657# define CODE_FOR_movstr CODE_FOR_nothing
3658#endif
3659
c2f47e15 3660/* Expand into a movstr instruction, if one is available. Return NULL_RTX if
727c62dd 3661 we failed, the caller should emit a normal call, otherwise try to
3662 get the result in TARGET, if convenient. If ENDP is 0 return the
3663 destination pointer, if ENDP is 1 return the end pointer ala
3664 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3665 stpcpy. */
3666
3667static rtx
3668expand_movstr (tree dest, tree src, rtx target, int endp)
3669{
3670 rtx end;
3671 rtx dest_mem;
3672 rtx src_mem;
3673 rtx insn;
3674 const struct insn_data * data;
3675
3676 if (!HAVE_movstr)
c2f47e15 3677 return NULL_RTX;
727c62dd 3678
d8ae1baa 3679 dest_mem = get_memory_rtx (dest, NULL);
3680 src_mem = get_memory_rtx (src, NULL);
727c62dd 3681 if (!endp)
3682 {
3683 target = force_reg (Pmode, XEXP (dest_mem, 0));
3684 dest_mem = replace_equiv_address (dest_mem, target);
3685 end = gen_reg_rtx (Pmode);
3686 }
3687 else
3688 {
3689 if (target == 0 || target == const0_rtx)
3690 {
3691 end = gen_reg_rtx (Pmode);
3692 if (target == 0)
3693 target = end;
3694 }
3695 else
3696 end = target;
3697 }
3698
3699 data = insn_data + CODE_FOR_movstr;
3700
3701 if (data->operand[0].mode != VOIDmode)
3702 end = gen_lowpart (data->operand[0].mode, end);
3703
3704 insn = data->genfun (end, dest_mem, src_mem);
3705
64db345d 3706 gcc_assert (insn);
727c62dd 3707
3708 emit_insn (insn);
3709
3710 /* movstr is supposed to set end to the address of the NUL
3711 terminator. If the caller requested a mempcpy-like return value,
3712 adjust it. */
3713 if (endp == 1 && target != const0_rtx)
c5aba89c 3714 {
3715 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3716 emit_move_insn (target, force_operand (tem, NULL_RTX));
3717 }
727c62dd 3718
3719 return target;
3720}
3721
c2f47e15 3722/* Expand expression EXP, which is a call to the strcpy builtin. Return
3723 NULL_RTX if we failed the caller should emit a normal call, otherwise
3724 try to get the result in TARGET, if convenient (and in mode MODE if that's
6f428e8b 3725 convenient). */
902de8ed 3726
53800dbe 3727static rtx
c2f47e15 3728expand_builtin_strcpy (tree fndecl, tree exp, rtx target, enum machine_mode mode)
53800dbe 3729{
c2f47e15 3730 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3731 {
3732 tree dest = CALL_EXPR_ARG (exp, 0);
3733 tree src = CALL_EXPR_ARG (exp, 1);
3734 return expand_builtin_strcpy_args (fndecl, dest, src, target, mode);
3735 }
3736 return NULL_RTX;
3737}
3738
3739/* Helper function to do the actual work for expand_builtin_strcpy. The
3740 arguments to the builtin_strcpy call DEST and SRC are broken out
3741 so that this can also be called without constructing an actual CALL_EXPR.
3742 The other arguments and return value are the same as for
3743 expand_builtin_strcpy. */
3744
3745static rtx
3746expand_builtin_strcpy_args (tree fndecl, tree dest, tree src,
3747 rtx target, enum machine_mode mode)
3748{
389dd41b 3749 tree result = fold_builtin_strcpy (UNKNOWN_LOCATION,
3750 fndecl, dest, src, 0);
c2f47e15 3751 if (result)
3752 return expand_expr (result, target, mode, EXPAND_NORMAL);
3753 return expand_movstr (dest, src, target, /*endp=*/0);
902de8ed 3754
53800dbe 3755}
3756
c2f47e15 3757/* Expand a call EXP to the stpcpy builtin.
3758 Return NULL_RTX if we failed the caller should emit a normal call,
3b824fa6 3759 otherwise try to get the result in TARGET, if convenient (and in
3760 mode MODE if that's convenient). */
3761
3762static rtx
dc369150 3763expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3b824fa6 3764{
c2f47e15 3765 tree dst, src;
389dd41b 3766 location_t loc = EXPR_LOCATION (exp);
c2f47e15 3767
3768 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3769 return NULL_RTX;
3770
3771 dst = CALL_EXPR_ARG (exp, 0);
3772 src = CALL_EXPR_ARG (exp, 1);
3773
727c62dd 3774 /* If return value is ignored, transform stpcpy into strcpy. */
c8b17b2e 3775 if (target == const0_rtx && implicit_built_in_decls[BUILT_IN_STRCPY])
978836e5 3776 {
3777 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
c8b17b2e 3778 tree result = build_call_expr (fn, 2, dst, src);
978836e5 3779
c8b17b2e 3780 STRIP_NOPS (result);
3781 while (TREE_CODE (result) == COMPOUND_EXPR)
3782 {
3783 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3784 EXPAND_NORMAL);
3785 result = TREE_OPERAND (result, 1);
3786 }
3787 return expand_expr (result, target, mode, EXPAND_NORMAL);
978836e5 3788 }
3b824fa6 3789 else
3790 {
c2f47e15 3791 tree len, lenp1;
727c62dd 3792 rtx ret;
647661c6 3793
9fe0e1b8 3794 /* Ensure we get an actual string whose length can be evaluated at
a0c938f0 3795 compile-time, not an expression containing a string. This is
3796 because the latter will potentially produce pessimized code
3797 when used to produce the return value. */
681fab1e 3798 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
c2f47e15 3799 return expand_movstr (dst, src, target, /*endp=*/2);
3b824fa6 3800
389dd41b 3801 lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
c2f47e15 3802 ret = expand_builtin_mempcpy_args (dst, src, lenp1, TREE_TYPE (exp),
3803 target, mode, /*endp=*/2);
727c62dd 3804
3805 if (ret)
3806 return ret;
3807
3808 if (TREE_CODE (len) == INTEGER_CST)
3809 {
8ec3c5c2 3810 rtx len_rtx = expand_normal (len);
727c62dd 3811
971ba038 3812 if (CONST_INT_P (len_rtx))
727c62dd 3813 {
c2f47e15 3814 ret = expand_builtin_strcpy_args (get_callee_fndecl (exp),
3815 dst, src, target, mode);
727c62dd 3816
3817 if (ret)
3818 {
3819 if (! target)
7ac87324 3820 {
3821 if (mode != VOIDmode)
3822 target = gen_reg_rtx (mode);
3823 else
3824 target = gen_reg_rtx (GET_MODE (ret));
3825 }
727c62dd 3826 if (GET_MODE (target) != GET_MODE (ret))
3827 ret = gen_lowpart (GET_MODE (target), ret);
3828
c5aba89c 3829 ret = plus_constant (ret, INTVAL (len_rtx));
3830 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
64db345d 3831 gcc_assert (ret);
727c62dd 3832
3833 return target;
3834 }
3835 }
3836 }
3837
c2f47e15 3838 return expand_movstr (dst, src, target, /*endp=*/2);
3b824fa6 3839 }
3840}
3841
6840589f 3842/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3843 bytes from constant string DATA + OFFSET and return it as target
3844 constant. */
3845
09879952 3846rtx
aecda0d6 3847builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3848 enum machine_mode mode)
6840589f 3849{
3850 const char *str = (const char *) data;
3851
3852 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3853 return const0_rtx;
3854
3855 return c_readstr (str + offset, mode);
3856}
3857
c2f47e15 3858/* Expand expression EXP, which is a call to the strncpy builtin. Return
3859 NULL_RTX if we failed the caller should emit a normal call. */
ed09096d 3860
3861static rtx
8ff6a5cd 3862expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
ed09096d 3863{
ea726109 3864 tree fndecl = get_callee_fndecl (exp);
389dd41b 3865 location_t loc = EXPR_LOCATION (exp);
c2f47e15 3866
3867 if (validate_arglist (exp,
3868 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
ed09096d 3869 {
c2f47e15 3870 tree dest = CALL_EXPR_ARG (exp, 0);
3871 tree src = CALL_EXPR_ARG (exp, 1);
3872 tree len = CALL_EXPR_ARG (exp, 2);
3873 tree slen = c_strlen (src, 1);
389dd41b 3874 tree result = fold_builtin_strncpy (EXPR_LOCATION (exp),
3875 fndecl, dest, src, len, slen);
a0c938f0 3876
8ff6a5cd 3877 if (result)
4f46f2b9 3878 {
3879 while (TREE_CODE (result) == COMPOUND_EXPR)
3880 {
3881 expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3882 EXPAND_NORMAL);
3883 result = TREE_OPERAND (result, 1);
3884 }
3885 return expand_expr (result, target, mode, EXPAND_NORMAL);
3886 }
6840589f 3887
8ff6a5cd 3888 /* We must be passed a constant len and src parameter. */
3889 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
c2f47e15 3890 return NULL_RTX;
ed09096d 3891
389dd41b 3892 slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
ed09096d 3893
3894 /* We're required to pad with trailing zeros if the requested
a0c938f0 3895 len is greater than strlen(s2)+1. In that case try to
6840589f 3896 use store_by_pieces, if it fails, punt. */
ed09096d 3897 if (tree_int_cst_lt (slen, len))
6840589f 3898 {
27d0c333 3899 unsigned int dest_align
3900 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
c2f47e15 3901 const char *p = c_getstr (src);
6840589f 3902 rtx dest_mem;
3903
27d0c333 3904 if (!p || dest_align == 0 || !host_integerp (len, 1)
3905 || !can_store_by_pieces (tree_low_cst (len, 1),
6840589f 3906 builtin_strncpy_read_str,
364c0c59 3907 CONST_CAST (char *, p),
3908 dest_align, false))
c2f47e15 3909 return NULL_RTX;
6840589f 3910
d8ae1baa 3911 dest_mem = get_memory_rtx (dest, len);
27d0c333 3912 store_by_pieces (dest_mem, tree_low_cst (len, 1),
6840589f 3913 builtin_strncpy_read_str,
364c0c59 3914 CONST_CAST (char *, p), dest_align, false, 0);
e5716f7e 3915 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
85d654dd 3916 dest_mem = convert_memory_address (ptr_mode, dest_mem);
e5716f7e 3917 return dest_mem;
6840589f 3918 }
ed09096d 3919 }
c2f47e15 3920 return NULL_RTX;
ed09096d 3921}
3922
ecc318ff 3923/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3924 bytes from constant string DATA + OFFSET and return it as target
3925 constant. */
3926
f656b751 3927rtx
aecda0d6 3928builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3929 enum machine_mode mode)
ecc318ff 3930{
3931 const char *c = (const char *) data;
364c0c59 3932 char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
ecc318ff 3933
3934 memset (p, *c, GET_MODE_SIZE (mode));
3935
3936 return c_readstr (p, mode);
3937}
3938
a7ec6974 3939/* Callback routine for store_by_pieces. Return the RTL of a register
3940 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3941 char value given in the RTL register data. For example, if mode is
3942 4 bytes wide, return the RTL for 0x01010101*data. */
3943
3944static rtx
aecda0d6 3945builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3946 enum machine_mode mode)
a7ec6974 3947{
3948 rtx target, coeff;
3949 size_t size;
3950 char *p;
3951
3952 size = GET_MODE_SIZE (mode);
f0ce3b1f 3953 if (size == 1)
3954 return (rtx) data;
a7ec6974 3955
364c0c59 3956 p = XALLOCAVEC (char, size);
a7ec6974 3957 memset (p, 1, size);
3958 coeff = c_readstr (p, mode);
3959
f0ce3b1f 3960 target = convert_to_mode (mode, (rtx) data, 1);
a7ec6974 3961 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3962 return force_reg (mode, target);
3963}
3964
c2f47e15 3965/* Expand expression EXP, which is a call to the memset builtin. Return
3966 NULL_RTX if we failed the caller should emit a normal call, otherwise
3967 try to get the result in TARGET, if convenient (and in mode MODE if that's
6f428e8b 3968 convenient). */
902de8ed 3969
53800dbe 3970static rtx
c2f47e15 3971expand_builtin_memset (tree exp, rtx target, enum machine_mode mode)
53800dbe 3972{
c2f47e15 3973 if (!validate_arglist (exp,
3974 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3975 return NULL_RTX;
53800dbe 3976 else
3977 {
c2f47e15 3978 tree dest = CALL_EXPR_ARG (exp, 0);
3979 tree val = CALL_EXPR_ARG (exp, 1);
3980 tree len = CALL_EXPR_ARG (exp, 2);
3981 return expand_builtin_memset_args (dest, val, len, target, mode, exp);
3982 }
3983}
53800dbe 3984
c2f47e15 3985/* Helper function to do the actual work for expand_builtin_memset. The
3986 arguments to the builtin_memset call DEST, VAL, and LEN are broken out
3987 so that this can also be called without constructing an actual CALL_EXPR.
3988 The other arguments and return value are the same as for
3989 expand_builtin_memset. */
6b961939 3990
c2f47e15 3991static rtx
3992expand_builtin_memset_args (tree dest, tree val, tree len,
3993 rtx target, enum machine_mode mode, tree orig_exp)
3994{
3995 tree fndecl, fn;
3996 enum built_in_function fcode;
3997 char c;
3998 unsigned int dest_align;
3999 rtx dest_mem, dest_addr, len_rtx;
4000 HOST_WIDE_INT expected_size = -1;
4001 unsigned int expected_align = 0;
75a70cf9 4002 tree_ann_common_t ann;
53800dbe 4003
c2f47e15 4004 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
162719b3 4005
c2f47e15 4006 /* If DEST is not a pointer type, don't do this operation in-line. */
4007 if (dest_align == 0)
4008 return NULL_RTX;
6f428e8b 4009
75a70cf9 4010 ann = tree_common_ann (orig_exp);
4011 if (ann)
4012 stringop_block_profile (ann->stmt, &expected_align, &expected_size);
4013
c2f47e15 4014 if (expected_align < dest_align)
4015 expected_align = dest_align;
6b961939 4016
c2f47e15 4017 /* If the LEN parameter is zero, return DEST. */
4018 if (integer_zerop (len))
4019 {
4020 /* Evaluate and ignore VAL in case it has side-effects. */
4021 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
4022 return expand_expr (dest, target, mode, EXPAND_NORMAL);
4023 }
7a3e5564 4024
c2f47e15 4025 /* Stabilize the arguments in case we fail. */
4026 dest = builtin_save_expr (dest);
4027 val = builtin_save_expr (val);
4028 len = builtin_save_expr (len);
a7ec6974 4029
c2f47e15 4030 len_rtx = expand_normal (len);
4031 dest_mem = get_memory_rtx (dest, len);
a7ec6974 4032
c2f47e15 4033 if (TREE_CODE (val) != INTEGER_CST)
4034 {
4035 rtx val_rtx;
a7ec6974 4036
c2f47e15 4037 val_rtx = expand_normal (val);
4038 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
4039 val_rtx, 0);
53800dbe 4040
c2f47e15 4041 /* Assume that we can memset by pieces if we can store
4042 * the coefficients by pieces (in the required modes).
4043 * We can't pass builtin_memset_gen_str as that emits RTL. */
4044 c = 1;
4045 if (host_integerp (len, 1)
c2f47e15 4046 && can_store_by_pieces (tree_low_cst (len, 1),
4b297e2e 4047 builtin_memset_read_str, &c, dest_align,
4048 true))
c2f47e15 4049 {
4050 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
4051 val_rtx);
4052 store_by_pieces (dest_mem, tree_low_cst (len, 1),
4b297e2e 4053 builtin_memset_gen_str, val_rtx, dest_align,
4054 true, 0);
c2f47e15 4055 }
4056 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
4057 dest_align, expected_align,
4058 expected_size))
6b961939 4059 goto do_libcall;
c2f47e15 4060
4061 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
4062 dest_mem = convert_memory_address (ptr_mode, dest_mem);
4063 return dest_mem;
4064 }
53800dbe 4065
c2f47e15 4066 if (target_char_cast (val, &c))
4067 goto do_libcall;
ecc318ff 4068
c2f47e15 4069 if (c)
4070 {
4071 if (host_integerp (len, 1)
c2f47e15 4072 && can_store_by_pieces (tree_low_cst (len, 1),
4b297e2e 4073 builtin_memset_read_str, &c, dest_align,
4074 true))
c2f47e15 4075 store_by_pieces (dest_mem, tree_low_cst (len, 1),
4b297e2e 4076 builtin_memset_read_str, &c, dest_align, true, 0);
c2f47e15 4077 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
4078 dest_align, expected_align,
4079 expected_size))
4080 goto do_libcall;
4081
4082 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
4083 dest_mem = convert_memory_address (ptr_mode, dest_mem);
4084 return dest_mem;
4085 }
ecc318ff 4086
c2f47e15 4087 set_mem_align (dest_mem, dest_align);
4088 dest_addr = clear_storage_hints (dest_mem, len_rtx,
4089 CALL_EXPR_TAILCALL (orig_exp)
4090 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
4091 expected_align, expected_size);
53800dbe 4092
c2f47e15 4093 if (dest_addr == 0)
4094 {
4095 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
4096 dest_addr = convert_memory_address (ptr_mode, dest_addr);
4097 }
53800dbe 4098
c2f47e15 4099 return dest_addr;
6b961939 4100
c2f47e15 4101 do_libcall:
4102 fndecl = get_callee_fndecl (orig_exp);
4103 fcode = DECL_FUNCTION_CODE (fndecl);
4104 if (fcode == BUILT_IN_MEMSET)
4105 fn = build_call_expr (fndecl, 3, dest, val, len);
4106 else if (fcode == BUILT_IN_BZERO)
4107 fn = build_call_expr (fndecl, 2, dest, len);
4108 else
4109 gcc_unreachable ();
4110 if (TREE_CODE (fn) == CALL_EXPR)
4111 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
4112 return expand_call (fn, target, target == const0_rtx);
53800dbe 4113}
4114
c2f47e15 4115/* Expand expression EXP, which is a call to the bzero builtin. Return
4116 NULL_RTX if we failed the caller should emit a normal call. */
27d0c333 4117
ffc83088 4118static rtx
0b25db21 4119expand_builtin_bzero (tree exp)
ffc83088 4120{
c2f47e15 4121 tree dest, size;
389dd41b 4122 location_t loc = EXPR_LOCATION (exp);
ffc83088 4123
c2f47e15 4124 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7369e7ba 4125 return NULL_RTX;
ffc83088 4126
c2f47e15 4127 dest = CALL_EXPR_ARG (exp, 0);
4128 size = CALL_EXPR_ARG (exp, 1);
bf8e3599 4129
7369e7ba 4130 /* New argument list transforming bzero(ptr x, int y) to
6f428e8b 4131 memset(ptr x, int 0, size_t y). This is done this way
4132 so that if it isn't expanded inline, we fallback to
4133 calling bzero instead of memset. */
bf8e3599 4134
c2f47e15 4135 return expand_builtin_memset_args (dest, integer_zero_node,
389dd41b 4136 fold_convert_loc (loc, sizetype, size),
c2f47e15 4137 const0_rtx, VOIDmode, exp);
ffc83088 4138}
4139
7959b13b 4140/* Expand a call to the memchr builtin. Return NULL_RTX if we failed the
4141 caller should emit a normal call, otherwise try to get the result
4142 in TARGET, if convenient (and in mode MODE if that's convenient). */
4143
4144static rtx
4145expand_builtin_memchr (tree exp, rtx target, enum machine_mode mode)
4146{
4147 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE,
4148 INTEGER_TYPE, VOID_TYPE))
4149 {
4150 tree type = TREE_TYPE (exp);
389dd41b 4151 tree result = fold_builtin_memchr (EXPR_LOCATION (exp),
4152 CALL_EXPR_ARG (exp, 0),
7959b13b 4153 CALL_EXPR_ARG (exp, 1),
4154 CALL_EXPR_ARG (exp, 2), type);
4155 if (result)
4156 return expand_expr (result, target, mode, EXPAND_NORMAL);
4157 }
4158 return NULL_RTX;
4159}
4160
7a3f89b5 4161/* Expand expression EXP, which is a call to the memcmp built-in function.
c2f47e15 4162 Return NULL_RTX if we failed and the
53800dbe 4163 caller should emit a normal call, otherwise try to get the result in
6f428e8b 4164 TARGET, if convenient (and in mode MODE, if that's convenient). */
27d0c333 4165
53800dbe 4166static rtx
c2f47e15 4167expand_builtin_memcmp (tree exp, rtx target, enum machine_mode mode)
53800dbe 4168{
389dd41b 4169 location_t loc = EXPR_LOCATION (exp);
4170
c2f47e15 4171 if (!validate_arglist (exp,
4172 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4173 return NULL_RTX;
218bc19e 4174 else
6f428e8b 4175 {
04700344 4176 tree result = fold_builtin_memcmp (loc,
389dd41b 4177 CALL_EXPR_ARG (exp, 0),
c2f47e15 4178 CALL_EXPR_ARG (exp, 1),
4179 CALL_EXPR_ARG (exp, 2));
218bc19e 4180 if (result)
4181 return expand_expr (result, target, mode, EXPAND_NORMAL);
6f428e8b 4182 }
4183
6ac5504b 4184#if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
53800dbe 4185 {
0cd832f0 4186 rtx arg1_rtx, arg2_rtx, arg3_rtx;
53800dbe 4187 rtx result;
0cd832f0 4188 rtx insn;
c2f47e15 4189 tree arg1 = CALL_EXPR_ARG (exp, 0);
4190 tree arg2 = CALL_EXPR_ARG (exp, 1);
4191 tree len = CALL_EXPR_ARG (exp, 2);
53800dbe 4192
4193 int arg1_align
4194 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4195 int arg2_align
4196 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
b428c0a5 4197 enum machine_mode insn_mode;
4198
4199#ifdef HAVE_cmpmemsi
4200 if (HAVE_cmpmemsi)
4201 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
4202 else
4203#endif
6ac5504b 4204#ifdef HAVE_cmpstrnsi
4205 if (HAVE_cmpstrnsi)
4206 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
b428c0a5 4207 else
4208#endif
c2f47e15 4209 return NULL_RTX;
53800dbe 4210
4211 /* If we don't have POINTER_TYPE, call the function. */
4212 if (arg1_align == 0 || arg2_align == 0)
c2f47e15 4213 return NULL_RTX;
53800dbe 4214
4215 /* Make a place to write the result of the instruction. */
4216 result = target;
4217 if (! (result != 0
8ad4c111 4218 && REG_P (result) && GET_MODE (result) == insn_mode
53800dbe 4219 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4220 result = gen_reg_rtx (insn_mode);
4221
d8ae1baa 4222 arg1_rtx = get_memory_rtx (arg1, len);
4223 arg2_rtx = get_memory_rtx (arg2, len);
389dd41b 4224 arg3_rtx = expand_normal (fold_convert_loc (loc, sizetype, len));
83f88f8e 4225
4226 /* Set MEM_SIZE as appropriate. */
971ba038 4227 if (CONST_INT_P (arg3_rtx))
83f88f8e 4228 {
4229 set_mem_size (arg1_rtx, arg3_rtx);
4230 set_mem_size (arg2_rtx, arg3_rtx);
4231 }
4232
b428c0a5 4233#ifdef HAVE_cmpmemsi
4234 if (HAVE_cmpmemsi)
4235 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4236 GEN_INT (MIN (arg1_align, arg2_align)));
0cd832f0 4237 else
b428c0a5 4238#endif
6ac5504b 4239#ifdef HAVE_cmpstrnsi
4240 if (HAVE_cmpstrnsi)
4241 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4242 GEN_INT (MIN (arg1_align, arg2_align)));
b428c0a5 4243 else
4244#endif
64db345d 4245 gcc_unreachable ();
0cd832f0 4246
4247 if (insn)
4248 emit_insn (insn);
4249 else
2dd6f9ed 4250 emit_library_call_value (memcmp_libfunc, result, LCT_PURE,
0cd832f0 4251 TYPE_MODE (integer_type_node), 3,
4252 XEXP (arg1_rtx, 0), Pmode,
4253 XEXP (arg2_rtx, 0), Pmode,
4254 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
78a8ed03 4255 TYPE_UNSIGNED (sizetype)),
0cd832f0 4256 TYPE_MODE (sizetype));
53800dbe 4257
4258 /* Return the value in the proper mode for this function. */
4259 mode = TYPE_MODE (TREE_TYPE (exp));
4260 if (GET_MODE (result) == mode)
4261 return result;
4262 else if (target != 0)
4263 {
4264 convert_move (target, result, 0);
4265 return target;
4266 }
4267 else
4268 return convert_to_mode (mode, result, 0);
4269 }
83d79705 4270#endif
53800dbe 4271
c2f47e15 4272 return NULL_RTX;
6f428e8b 4273}
4274
c2f47e15 4275/* Expand expression EXP, which is a call to the strcmp builtin. Return NULL_RTX
53800dbe 4276 if we failed the caller should emit a normal call, otherwise try to get
4277 the result in TARGET, if convenient. */
902de8ed 4278
53800dbe 4279static rtx
aecda0d6 4280expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
53800dbe 4281{
389dd41b 4282 location_t loc = EXPR_LOCATION (exp);
4283
c2f47e15 4284 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4285 return NULL_RTX;
218bc19e 4286 else
ef6c187e 4287 {
389dd41b 4288 tree result = fold_builtin_strcmp (loc,
4289 CALL_EXPR_ARG (exp, 0),
c2f47e15 4290 CALL_EXPR_ARG (exp, 1));
218bc19e 4291 if (result)
4292 return expand_expr (result, target, mode, EXPAND_NORMAL);
ef6c187e 4293 }
bf8e3599 4294
6ac5504b 4295#if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
4296 if (cmpstr_optab[SImode] != CODE_FOR_nothing
4297 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
4298 {
4299 rtx arg1_rtx, arg2_rtx;
4300 rtx result, insn = NULL_RTX;
4301 tree fndecl, fn;
c2f47e15 4302 tree arg1 = CALL_EXPR_ARG (exp, 0);
4303 tree arg2 = CALL_EXPR_ARG (exp, 1);
a0c938f0 4304
6ac5504b 4305 int arg1_align
4306 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4307 int arg2_align
4308 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4309
4310 /* If we don't have POINTER_TYPE, call the function. */
4311 if (arg1_align == 0 || arg2_align == 0)
c2f47e15 4312 return NULL_RTX;
7a3f89b5 4313
6ac5504b 4314 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
4315 arg1 = builtin_save_expr (arg1);
4316 arg2 = builtin_save_expr (arg2);
7a3f89b5 4317
d8ae1baa 4318 arg1_rtx = get_memory_rtx (arg1, NULL);
4319 arg2_rtx = get_memory_rtx (arg2, NULL);
53800dbe 4320
6ac5504b 4321#ifdef HAVE_cmpstrsi
4322 /* Try to call cmpstrsi. */
4323 if (HAVE_cmpstrsi)
4324 {
a0c938f0 4325 enum machine_mode insn_mode
6ac5504b 4326 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
4327
4328 /* Make a place to write the result of the instruction. */
4329 result = target;
4330 if (! (result != 0
4331 && REG_P (result) && GET_MODE (result) == insn_mode
4332 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4333 result = gen_reg_rtx (insn_mode);
4334
4335 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
4336 GEN_INT (MIN (arg1_align, arg2_align)));
4337 }
4338#endif
03fd9d2c 4339#ifdef HAVE_cmpstrnsi
6ac5504b 4340 /* Try to determine at least one length and call cmpstrnsi. */
a0c938f0 4341 if (!insn && HAVE_cmpstrnsi)
6ac5504b 4342 {
4343 tree len;
4344 rtx arg3_rtx;
4345
a0c938f0 4346 enum machine_mode insn_mode
6ac5504b 4347 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
4348 tree len1 = c_strlen (arg1, 1);
4349 tree len2 = c_strlen (arg2, 1);
4350
4351 if (len1)
4352 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
4353 if (len2)
4354 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
4355
4356 /* If we don't have a constant length for the first, use the length
4357 of the second, if we know it. We don't require a constant for
4358 this case; some cost analysis could be done if both are available
4359 but neither is constant. For now, assume they're equally cheap,
4360 unless one has side effects. If both strings have constant lengths,
4361 use the smaller. */
4362
4363 if (!len1)
4364 len = len2;
4365 else if (!len2)
4366 len = len1;
4367 else if (TREE_SIDE_EFFECTS (len1))
4368 len = len2;
4369 else if (TREE_SIDE_EFFECTS (len2))
4370 len = len1;
4371 else if (TREE_CODE (len1) != INTEGER_CST)
4372 len = len2;
4373 else if (TREE_CODE (len2) != INTEGER_CST)
4374 len = len1;
4375 else if (tree_int_cst_lt (len1, len2))
4376 len = len1;
4377 else
4378 len = len2;
4379
4380 /* If both arguments have side effects, we cannot optimize. */
4381 if (!len || TREE_SIDE_EFFECTS (len))
6b961939 4382 goto do_libcall;
53800dbe 4383
8ec3c5c2 4384 arg3_rtx = expand_normal (len);
902de8ed 4385
6ac5504b 4386 /* Make a place to write the result of the instruction. */
4387 result = target;
4388 if (! (result != 0
4389 && REG_P (result) && GET_MODE (result) == insn_mode
4390 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4391 result = gen_reg_rtx (insn_mode);
53800dbe 4392
6ac5504b 4393 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4394 GEN_INT (MIN (arg1_align, arg2_align)));
4395 }
4396#endif
3f8aefe2 4397
6ac5504b 4398 if (insn)
4399 {
4400 emit_insn (insn);
3f8aefe2 4401
6ac5504b 4402 /* Return the value in the proper mode for this function. */
4403 mode = TYPE_MODE (TREE_TYPE (exp));
4404 if (GET_MODE (result) == mode)
4405 return result;
4406 if (target == 0)
4407 return convert_to_mode (mode, result, 0);
4408 convert_move (target, result, 0);
4409 return target;
4410 }
902de8ed 4411
6ac5504b 4412 /* Expand the library call ourselves using a stabilized argument
4413 list to avoid re-evaluating the function's arguments twice. */
2694880e 4414#ifdef HAVE_cmpstrnsi
6b961939 4415 do_libcall:
2694880e 4416#endif
6ac5504b 4417 fndecl = get_callee_fndecl (exp);
c2f47e15 4418 fn = build_call_expr (fndecl, 2, arg1, arg2);
6ac5504b 4419 if (TREE_CODE (fn) == CALL_EXPR)
4420 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4421 return expand_call (fn, target, target == const0_rtx);
4422 }
7a3f89b5 4423#endif
c2f47e15 4424 return NULL_RTX;
83d79705 4425}
53800dbe 4426
c2f47e15 4427/* Expand expression EXP, which is a call to the strncmp builtin. Return
4428 NULL_RTX if we failed the caller should emit a normal call, otherwise try to get
ed09096d 4429 the result in TARGET, if convenient. */
27d0c333 4430
ed09096d 4431static rtx
aecda0d6 4432expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
ed09096d 4433{
389dd41b 4434 location_t loc = EXPR_LOCATION (exp);
4435
c2f47e15 4436 if (!validate_arglist (exp,
4437 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4438 return NULL_RTX;
218bc19e 4439 else
ef6c187e 4440 {
04700344 4441 tree result = fold_builtin_strncmp (loc,
389dd41b 4442 CALL_EXPR_ARG (exp, 0),
c2f47e15 4443 CALL_EXPR_ARG (exp, 1),
4444 CALL_EXPR_ARG (exp, 2));
218bc19e 4445 if (result)
4446 return expand_expr (result, target, mode, EXPAND_NORMAL);
ef6c187e 4447 }
ed09096d 4448
6e34e617 4449 /* If c_strlen can determine an expression for one of the string
6ac5504b 4450 lengths, and it doesn't have side effects, then emit cmpstrnsi
7a3f89b5 4451 using length MIN(strlen(string)+1, arg3). */
6ac5504b 4452#ifdef HAVE_cmpstrnsi
4453 if (HAVE_cmpstrnsi)
7a3f89b5 4454 {
4455 tree len, len1, len2;
4456 rtx arg1_rtx, arg2_rtx, arg3_rtx;
4457 rtx result, insn;
0b25db21 4458 tree fndecl, fn;
c2f47e15 4459 tree arg1 = CALL_EXPR_ARG (exp, 0);
4460 tree arg2 = CALL_EXPR_ARG (exp, 1);
4461 tree arg3 = CALL_EXPR_ARG (exp, 2);
6f428e8b 4462
7a3f89b5 4463 int arg1_align
4464 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4465 int arg2_align
4466 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4467 enum machine_mode insn_mode
6ac5504b 4468 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
bf8e3599 4469
681fab1e 4470 len1 = c_strlen (arg1, 1);
4471 len2 = c_strlen (arg2, 1);
7a3f89b5 4472
4473 if (len1)
389dd41b 4474 len1 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len1);
7a3f89b5 4475 if (len2)
389dd41b 4476 len2 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len2);
7a3f89b5 4477
4478 /* If we don't have a constant length for the first, use the length
4479 of the second, if we know it. We don't require a constant for
4480 this case; some cost analysis could be done if both are available
4481 but neither is constant. For now, assume they're equally cheap,
4482 unless one has side effects. If both strings have constant lengths,
4483 use the smaller. */
4484
4485 if (!len1)
4486 len = len2;
4487 else if (!len2)
4488 len = len1;
4489 else if (TREE_SIDE_EFFECTS (len1))
4490 len = len2;
4491 else if (TREE_SIDE_EFFECTS (len2))
4492 len = len1;
4493 else if (TREE_CODE (len1) != INTEGER_CST)
4494 len = len2;
4495 else if (TREE_CODE (len2) != INTEGER_CST)
4496 len = len1;
4497 else if (tree_int_cst_lt (len1, len2))
4498 len = len1;
4499 else
4500 len = len2;
6e34e617 4501
7a3f89b5 4502 /* If both arguments have side effects, we cannot optimize. */
4503 if (!len || TREE_SIDE_EFFECTS (len))
c2f47e15 4504 return NULL_RTX;
bf8e3599 4505
7a3f89b5 4506 /* The actual new length parameter is MIN(len,arg3). */
389dd41b 4507 len = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (len), len,
4508 fold_convert_loc (loc, TREE_TYPE (len), arg3));
7a3f89b5 4509
4510 /* If we don't have POINTER_TYPE, call the function. */
4511 if (arg1_align == 0 || arg2_align == 0)
c2f47e15 4512 return NULL_RTX;
7a3f89b5 4513
4514 /* Make a place to write the result of the instruction. */
4515 result = target;
4516 if (! (result != 0
8ad4c111 4517 && REG_P (result) && GET_MODE (result) == insn_mode
7a3f89b5 4518 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4519 result = gen_reg_rtx (insn_mode);
4520
6ac5504b 4521 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
4ee9c684 4522 arg1 = builtin_save_expr (arg1);
4523 arg2 = builtin_save_expr (arg2);
4524 len = builtin_save_expr (len);
3f8aefe2 4525
d8ae1baa 4526 arg1_rtx = get_memory_rtx (arg1, len);
4527 arg2_rtx = get_memory_rtx (arg2, len);
8ec3c5c2 4528 arg3_rtx = expand_normal (len);
6ac5504b 4529 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4530 GEN_INT (MIN (arg1_align, arg2_align)));
3f8aefe2 4531 if (insn)
4532 {
4533 emit_insn (insn);
4534
4535 /* Return the value in the proper mode for this function. */
4536 mode = TYPE_MODE (TREE_TYPE (exp));
4537 if (GET_MODE (result) == mode)
4538 return result;
4539 if (target == 0)
4540 return convert_to_mode (mode, result, 0);
4541 convert_move (target, result, 0);
4542 return target;
4543 }
7a3f89b5 4544
3f8aefe2 4545 /* Expand the library call ourselves using a stabilized argument
4546 list to avoid re-evaluating the function's arguments twice. */
3f8aefe2 4547 fndecl = get_callee_fndecl (exp);
c2f47e15 4548 fn = build_call_expr (fndecl, 3, arg1, arg2, len);
0b25db21 4549 if (TREE_CODE (fn) == CALL_EXPR)
4550 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4551 return expand_call (fn, target, target == const0_rtx);
7a3f89b5 4552 }
4553#endif
c2f47e15 4554 return NULL_RTX;
ed09096d 4555}
4556
49f0327b 4557/* Expand expression EXP, which is a call to the strcat builtin.
c2f47e15 4558 Return NULL_RTX if we failed the caller should emit a normal call,
49f0327b 4559 otherwise try to get the result in TARGET, if convenient. */
27d0c333 4560
49f0327b 4561static rtx
c2f47e15 4562expand_builtin_strcat (tree fndecl, tree exp, rtx target, enum machine_mode mode)
49f0327b 4563{
389dd41b 4564 location_t loc = EXPR_LOCATION (exp);
4565
c2f47e15 4566 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4567 return NULL_RTX;
49f0327b 4568 else
4569 {
c2f47e15 4570 tree dst = CALL_EXPR_ARG (exp, 0);
4571 tree src = CALL_EXPR_ARG (exp, 1);
49f0327b 4572 const char *p = c_getstr (src);
4573
1d89860b 4574 /* If the string length is zero, return the dst parameter. */
a0c938f0 4575 if (p && *p == '\0')
1d89860b 4576 return expand_expr (dst, target, mode, EXPAND_NORMAL);
a0c938f0 4577
a0d18cec 4578 if (optimize_insn_for_speed_p ())
ca71f89b 4579 {
1d89860b 4580 /* See if we can store by pieces into (dst + strlen(dst)). */
4581 tree newsrc, newdst,
4582 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4583 rtx insns;
4584
4585 /* Stabilize the argument list. */
4586 newsrc = builtin_save_expr (src);
1d89860b 4587 dst = builtin_save_expr (dst);
4588
4589 start_sequence ();
4590
4591 /* Create strlen (dst). */
c2f47e15 4592 newdst = build_call_expr (strlen_fn, 1, dst);
0de36bdb 4593 /* Create (dst p+ strlen (dst)). */
1d89860b 4594
389dd41b 4595 newdst = fold_build2_loc (loc, POINTER_PLUS_EXPR,
4596 TREE_TYPE (dst), dst, newdst);
1d89860b 4597 newdst = builtin_save_expr (newdst);
1d89860b 4598
c2f47e15 4599 if (!expand_builtin_strcpy_args (fndecl, newdst, newsrc, target, mode))
ca71f89b 4600 {
1d89860b 4601 end_sequence (); /* Stop sequence. */
c2f47e15 4602 return NULL_RTX;
ca71f89b 4603 }
a0c938f0 4604
1d89860b 4605 /* Output the entire sequence. */
4606 insns = get_insns ();
4607 end_sequence ();
4608 emit_insn (insns);
a0c938f0 4609
1d89860b 4610 return expand_expr (dst, target, mode, EXPAND_NORMAL);
ca71f89b 4611 }
49f0327b 4612
c2f47e15 4613 return NULL_RTX;
49f0327b 4614 }
4615}
4616
4617/* Expand expression EXP, which is a call to the strncat builtin.
c2f47e15 4618 Return NULL_RTX if we failed the caller should emit a normal call,
49f0327b 4619 otherwise try to get the result in TARGET, if convenient. */
27d0c333 4620
49f0327b 4621static rtx
c2f47e15 4622expand_builtin_strncat (tree exp, rtx target, enum machine_mode mode)
49f0327b 4623{
c2f47e15 4624 if (validate_arglist (exp,
4625 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
49f0327b 4626 {
389dd41b 4627 tree result = fold_builtin_strncat (EXPR_LOCATION (exp),
4628 CALL_EXPR_ARG (exp, 0),
c2f47e15 4629 CALL_EXPR_ARG (exp, 1),
4630 CALL_EXPR_ARG (exp, 2));
2c84ee37 4631 if (result)
4632 return expand_expr (result, target, mode, EXPAND_NORMAL);
49f0327b 4633 }
c2f47e15 4634 return NULL_RTX;
49f0327b 4635}
4636
4637/* Expand expression EXP, which is a call to the strspn builtin.
c2f47e15 4638 Return NULL_RTX if we failed the caller should emit a normal call,
49f0327b 4639 otherwise try to get the result in TARGET, if convenient. */
27d0c333 4640
49f0327b 4641static rtx
c2f47e15 4642expand_builtin_strspn (tree exp, rtx target, enum machine_mode mode)
49f0327b 4643{
c2f47e15 4644 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
49f0327b 4645 {
389dd41b 4646 tree result = fold_builtin_strspn (EXPR_LOCATION (exp),
4647 CALL_EXPR_ARG (exp, 0),
c2f47e15 4648 CALL_EXPR_ARG (exp, 1));
2c84ee37 4649 if (result)
4650 return expand_expr (result, target, mode, EXPAND_NORMAL);
49f0327b 4651 }
c2f47e15 4652 return NULL_RTX;
49f0327b 4653}
4654
4655/* Expand expression EXP, which is a call to the strcspn builtin.
c2f47e15 4656 Return NULL_RTX if we failed the caller should emit a normal call,
49f0327b 4657 otherwise try to get the result in TARGET, if convenient. */
27d0c333 4658
49f0327b 4659static rtx
c2f47e15 4660expand_builtin_strcspn (tree exp, rtx target, enum machine_mode mode)
49f0327b 4661{
c2f47e15 4662 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
49f0327b 4663 {
389dd41b 4664 tree result = fold_builtin_strcspn (EXPR_LOCATION (exp),
4665 CALL_EXPR_ARG (exp, 0),
c2f47e15 4666 CALL_EXPR_ARG (exp, 1));
2c84ee37 4667 if (result)
4668 return expand_expr (result, target, mode, EXPAND_NORMAL);
49f0327b 4669 }
c2f47e15 4670 return NULL_RTX;
49f0327b 4671}
4672
a66c9326 4673/* Expand a call to __builtin_saveregs, generating the result in TARGET,
4674 if that's convenient. */
902de8ed 4675
a66c9326 4676rtx
aecda0d6 4677expand_builtin_saveregs (void)
53800dbe 4678{
a66c9326 4679 rtx val, seq;
53800dbe 4680
4681 /* Don't do __builtin_saveregs more than once in a function.
4682 Save the result of the first call and reuse it. */
4683 if (saveregs_value != 0)
4684 return saveregs_value;
53800dbe 4685
a66c9326 4686 /* When this function is called, it means that registers must be
4687 saved on entry to this function. So we migrate the call to the
4688 first insn of this function. */
4689
4690 start_sequence ();
53800dbe 4691
a66c9326 4692 /* Do whatever the machine needs done in this case. */
45550790 4693 val = targetm.calls.expand_builtin_saveregs ();
53800dbe 4694
a66c9326 4695 seq = get_insns ();
4696 end_sequence ();
53800dbe 4697
a66c9326 4698 saveregs_value = val;
53800dbe 4699
31d3e01c 4700 /* Put the insns after the NOTE that starts the function. If this
4701 is inside a start_sequence, make the outer-level insn chain current, so
a66c9326 4702 the code is placed at the start of the function. */
4703 push_topmost_sequence ();
0ec80471 4704 emit_insn_after (seq, entry_of_function ());
a66c9326 4705 pop_topmost_sequence ();
4706
4707 return val;
53800dbe 4708}
4709
4710/* __builtin_args_info (N) returns word N of the arg space info
4711 for the current function. The number and meanings of words
4712 is controlled by the definition of CUMULATIVE_ARGS. */
f7c44134 4713
53800dbe 4714static rtx
c2f47e15 4715expand_builtin_args_info (tree exp)
53800dbe 4716{
53800dbe 4717 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
abe32cce 4718 int *word_ptr = (int *) &crtl->args.info;
53800dbe 4719
64db345d 4720 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
53800dbe 4721
c2f47e15 4722 if (call_expr_nargs (exp) != 0)
53800dbe 4723 {
c2f47e15 4724 if (!host_integerp (CALL_EXPR_ARG (exp, 0), 0))
eb586f2c 4725 error ("argument of %<__builtin_args_info%> must be constant");
53800dbe 4726 else
4727 {
c2f47e15 4728 HOST_WIDE_INT wordnum = tree_low_cst (CALL_EXPR_ARG (exp, 0), 0);
53800dbe 4729
27d0c333 4730 if (wordnum < 0 || wordnum >= nwords)
eb586f2c 4731 error ("argument of %<__builtin_args_info%> out of range");
53800dbe 4732 else
4733 return GEN_INT (word_ptr[wordnum]);
4734 }
4735 }
4736 else
eb586f2c 4737 error ("missing argument in %<__builtin_args_info%>");
53800dbe 4738
4739 return const0_rtx;
53800dbe 4740}
4741
79012a9d 4742/* Expand a call to __builtin_next_arg. */
27d0c333 4743
53800dbe 4744static rtx
79012a9d 4745expand_builtin_next_arg (void)
53800dbe 4746{
79012a9d 4747 /* Checking arguments is already done in fold_builtin_next_arg
4748 that must be called before this function. */
940ddc5c 4749 return expand_binop (ptr_mode, add_optab,
abe32cce 4750 crtl->args.internal_arg_pointer,
4751 crtl->args.arg_offset_rtx,
53800dbe 4752 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4753}
4754
a66c9326 4755/* Make it easier for the backends by protecting the valist argument
4756 from multiple evaluations. */
4757
4758static tree
389dd41b 4759stabilize_va_list_loc (location_t loc, tree valist, int needs_lvalue)
a66c9326 4760{
5f57a8b1 4761 tree vatype = targetm.canonical_va_list_type (TREE_TYPE (valist));
4762
4763 gcc_assert (vatype != NULL_TREE);
4764
4765 if (TREE_CODE (vatype) == ARRAY_TYPE)
a66c9326 4766 {
2d47cc32 4767 if (TREE_SIDE_EFFECTS (valist))
4768 valist = save_expr (valist);
11a61dea 4769
2d47cc32 4770 /* For this case, the backends will be expecting a pointer to
5f57a8b1 4771 vatype, but it's possible we've actually been given an array
4772 (an actual TARGET_CANONICAL_VA_LIST_TYPE (valist)).
2d47cc32 4773 So fix it. */
4774 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
8a15c04a 4775 {
5f57a8b1 4776 tree p1 = build_pointer_type (TREE_TYPE (vatype));
389dd41b 4777 valist = build_fold_addr_expr_with_type_loc (loc, valist, p1);
8a15c04a 4778 }
a66c9326 4779 }
11a61dea 4780 else
a66c9326 4781 {
2d47cc32 4782 tree pt;
11a61dea 4783
2d47cc32 4784 if (! needs_lvalue)
4785 {
11a61dea 4786 if (! TREE_SIDE_EFFECTS (valist))
4787 return valist;
bf8e3599 4788
5f57a8b1 4789 pt = build_pointer_type (vatype);
389dd41b 4790 valist = fold_build1_loc (loc, ADDR_EXPR, pt, valist);
a66c9326 4791 TREE_SIDE_EFFECTS (valist) = 1;
a66c9326 4792 }
2d47cc32 4793
11a61dea 4794 if (TREE_SIDE_EFFECTS (valist))
2d47cc32 4795 valist = save_expr (valist);
389dd41b 4796 valist = build_fold_indirect_ref_loc (loc, valist);
a66c9326 4797 }
4798
4799 return valist;
4800}
4801
2e15d750 4802/* The "standard" definition of va_list is void*. */
4803
4804tree
4805std_build_builtin_va_list (void)
4806{
4807 return ptr_type_node;
4808}
4809
5f57a8b1 4810/* The "standard" abi va_list is va_list_type_node. */
4811
4812tree
4813std_fn_abi_va_list (tree fndecl ATTRIBUTE_UNUSED)
4814{
4815 return va_list_type_node;
4816}
4817
4818/* The "standard" type of va_list is va_list_type_node. */
4819
4820tree
4821std_canonical_va_list_type (tree type)
4822{
4823 tree wtype, htype;
4824
4825 if (INDIRECT_REF_P (type))
4826 type = TREE_TYPE (type);
4827 else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE(type)))
4828 type = TREE_TYPE (type);
5f57a8b1 4829 wtype = va_list_type_node;
4830 htype = type;
7b36f9ab 4831 /* Treat structure va_list types. */
4832 if (TREE_CODE (wtype) == RECORD_TYPE && POINTER_TYPE_P (htype))
4833 htype = TREE_TYPE (htype);
4834 else if (TREE_CODE (wtype) == ARRAY_TYPE)
5f57a8b1 4835 {
4836 /* If va_list is an array type, the argument may have decayed
4837 to a pointer type, e.g. by being passed to another function.
4838 In that case, unwrap both types so that we can compare the
4839 underlying records. */
4840 if (TREE_CODE (htype) == ARRAY_TYPE
4841 || POINTER_TYPE_P (htype))
4842 {
4843 wtype = TREE_TYPE (wtype);
4844 htype = TREE_TYPE (htype);
4845 }
4846 }
4847 if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
4848 return va_list_type_node;
4849
4850 return NULL_TREE;
4851}
4852
a66c9326 4853/* The "standard" implementation of va_start: just assign `nextarg' to
4854 the variable. */
27d0c333 4855
a66c9326 4856void
aecda0d6 4857std_expand_builtin_va_start (tree valist, rtx nextarg)
a66c9326 4858{
f03c17bc 4859 rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
4860 convert_move (va_r, nextarg, 0);
a66c9326 4861}
4862
c2f47e15 4863/* Expand EXP, a call to __builtin_va_start. */
27d0c333 4864
a66c9326 4865static rtx
c2f47e15 4866expand_builtin_va_start (tree exp)
a66c9326 4867{
4868 rtx nextarg;
c2f47e15 4869 tree valist;
389dd41b 4870 location_t loc = EXPR_LOCATION (exp);
a66c9326 4871
c2f47e15 4872 if (call_expr_nargs (exp) < 2)
cb166087 4873 {
389dd41b 4874 error_at (loc, "too few arguments to function %<va_start%>");
cb166087 4875 return const0_rtx;
4876 }
a66c9326 4877
c2f47e15 4878 if (fold_builtin_next_arg (exp, true))
79012a9d 4879 return const0_rtx;
7c2f0500 4880
79012a9d 4881 nextarg = expand_builtin_next_arg ();
389dd41b 4882 valist = stabilize_va_list_loc (loc, CALL_EXPR_ARG (exp, 0), 1);
a66c9326 4883
8a58ed0a 4884 if (targetm.expand_builtin_va_start)
4885 targetm.expand_builtin_va_start (valist, nextarg);
4886 else
4887 std_expand_builtin_va_start (valist, nextarg);
a66c9326 4888
4889 return const0_rtx;
4890}
4891
a66c9326 4892/* The "standard" implementation of va_arg: read the value from the
4893 current (padded) address and increment by the (padded) size. */
f7c44134 4894
e0eca1fa 4895tree
75a70cf9 4896std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
4897 gimple_seq *post_p)
fcdd3ab3 4898{
52cc2eeb 4899 tree addr, t, type_size, rounded_size, valist_tmp;
b8e8e485 4900 unsigned HOST_WIDE_INT align, boundary;
bef380a4 4901 bool indirect;
52cc2eeb 4902
4903#ifdef ARGS_GROW_DOWNWARD
4904 /* All of the alignment and movement below is for args-grow-up machines.
4905 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4906 implement their own specialized gimplify_va_arg_expr routines. */
64db345d 4907 gcc_unreachable ();
52cc2eeb 4908#endif
fcdd3ab3 4909
bef380a4 4910 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4911 if (indirect)
4912 type = build_pointer_type (type);
4913
52cc2eeb 4914 align = PARM_BOUNDARY / BITS_PER_UNIT;
c8b779eb 4915 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
4916
4917 /* When we align parameter on stack for caller, if the parameter
befa808c 4918 alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
4919 aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
c8b779eb 4920 here with caller. */
befa808c 4921 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
4922 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
c8b779eb 4923
4924 boundary /= BITS_PER_UNIT;
fcdd3ab3 4925
52cc2eeb 4926 /* Hoist the valist value into a temporary for the moment. */
ecdeeb37 4927 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4928
fcdd3ab3 4929 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4930 requires greater alignment, we must perform dynamic alignment. */
85c1f587 4931 if (boundary > align
4932 && !integer_zerop (TYPE_SIZE (type)))
fcdd3ab3 4933 {
41076ef6 4934 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
389dd41b 4935 fold_build2 (POINTER_PLUS_EXPR,
4936 TREE_TYPE (valist),
0de36bdb 4937 valist_tmp, size_int (boundary - 1)));
52cc2eeb 4938 gimplify_and_add (t, pre_p);
4939
0de36bdb 4940 t = fold_convert (sizetype, valist_tmp);
41076ef6 4941 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
0de36bdb 4942 fold_convert (TREE_TYPE (valist),
4943 fold_build2 (BIT_AND_EXPR, sizetype, t,
4944 size_int (-boundary))));
ecdeeb37 4945 gimplify_and_add (t, pre_p);
fcdd3ab3 4946 }
c5dc0c32 4947 else
4948 boundary = align;
4949
4950 /* If the actual alignment is less than the alignment of the type,
4951 adjust the type accordingly so that we don't assume strict alignment
f0b5f617 4952 when dereferencing the pointer. */
c5dc0c32 4953 boundary *= BITS_PER_UNIT;
4954 if (boundary < TYPE_ALIGN (type))
4955 {
4956 type = build_variant_type_copy (type);
4957 TYPE_ALIGN (type) = boundary;
4958 }
fcdd3ab3 4959
bcff3604 4960 /* Compute the rounded size of the type. */
52cc2eeb 4961 type_size = size_in_bytes (type);
4962 rounded_size = round_up (type_size, align);
4963
fcdd3ab3 4964 /* Reduce rounded_size so it's sharable with the postqueue. */
4965 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4966
4967 /* Get AP. */
ecdeeb37 4968 addr = valist_tmp;
52cc2eeb 4969 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
fcdd3ab3 4970 {
4971 /* Small args are padded downward. */
389dd41b 4972 t = fold_build2_loc (input_location, GT_EXPR, sizetype,
4973 rounded_size, size_int (align));
49d00087 4974 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4975 size_binop (MINUS_EXPR, rounded_size, type_size));
389dd41b 4976 addr = fold_build2 (POINTER_PLUS_EXPR,
4977 TREE_TYPE (addr), addr, t);
fcdd3ab3 4978 }
4979
fcdd3ab3 4980 /* Compute new value for AP. */
0de36bdb 4981 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (valist), valist_tmp, rounded_size);
41076ef6 4982 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
ecdeeb37 4983 gimplify_and_add (t, pre_p);
e0eca1fa 4984
4985 addr = fold_convert (build_pointer_type (type), addr);
fcdd3ab3 4986
bef380a4 4987 if (indirect)
f2462d6c 4988 addr = build_va_arg_indirect_ref (addr);
4989
4990 return build_va_arg_indirect_ref (addr);
4991}
a0930a69 4992
f2462d6c 4993/* Build an indirect-ref expression over the given TREE, which represents a
4994 piece of a va_arg() expansion. */
4995tree
4996build_va_arg_indirect_ref (tree addr)
4997{
389dd41b 4998 addr = build_fold_indirect_ref_loc (EXPR_LOCATION (addr), addr);
f2462d6c 4999
a0930a69 5000 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
5001 mf_mark (addr);
bef380a4 5002
a0930a69 5003 return addr;
433006a9 5004}
5005
fcdd3ab3 5006/* Return a dummy expression of type TYPE in order to keep going after an
5007 error. */
5008
5009static tree
5010dummy_object (tree type)
5011{
535664e3 5012 tree t = build_int_cst (build_pointer_type (type), 0);
fcdd3ab3 5013 return build1 (INDIRECT_REF, type, t);
5014}
5015
2799a2b7 5016/* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
5017 builtin function, but a very special sort of operator. */
fcdd3ab3 5018
5019enum gimplify_status
75a70cf9 5020gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
fcdd3ab3 5021{
5f57a8b1 5022 tree promoted_type, have_va_type;
fcdd3ab3 5023 tree valist = TREE_OPERAND (*expr_p, 0);
5024 tree type = TREE_TYPE (*expr_p);
5025 tree t;
389dd41b 5026 location_t loc = EXPR_LOCATION (*expr_p);
fcdd3ab3 5027
5028 /* Verify that valist is of the proper type. */
fcdd3ab3 5029 have_va_type = TREE_TYPE (valist);
f43dda35 5030 if (have_va_type == error_mark_node)
5031 return GS_ERROR;
5f57a8b1 5032 have_va_type = targetm.canonical_va_list_type (have_va_type);
f43dda35 5033
5f57a8b1 5034 if (have_va_type == NULL_TREE)
fcdd3ab3 5035 {
e60a6f7b 5036 error_at (loc, "first argument to %<va_arg%> not of type %<va_list%>");
e0eca1fa 5037 return GS_ERROR;
fcdd3ab3 5038 }
5039
5040 /* Generate a diagnostic for requesting data of a type that cannot
5041 be passed through `...' due to type promotion at the call site. */
5f57a8b1 5042 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
fcdd3ab3 5043 != type)
5044 {
5045 static bool gave_help;
a52d5726 5046 bool warned;
fcdd3ab3 5047
5048 /* Unfortunately, this is merely undefined, rather than a constraint
5049 violation, so we cannot make this an error. If this call is never
5050 executed, the program is still strictly conforming. */
e60a6f7b 5051 warned = warning_at (loc, 0,
5052 "%qT is promoted to %qT when passed through %<...%>",
5053 type, promoted_type);
a52d5726 5054 if (!gave_help && warned)
fcdd3ab3 5055 {
5056 gave_help = true;
e60a6f7b 5057 inform (loc, "(so you should pass %qT not %qT to %<va_arg%>)",
5058 promoted_type, type);
fcdd3ab3 5059 }
5060
5061 /* We can, however, treat "undefined" any way we please.
5062 Call abort to encourage the user to fix the program. */
a52d5726 5063 if (warned)
e60a6f7b 5064 inform (loc, "if this code is reached, the program will abort");
ad0e7a06 5065 /* Before the abort, allow the evaluation of the va_list
5066 expression to exit or longjmp. */
5067 gimplify_and_add (valist, pre_p);
389dd41b 5068 t = build_call_expr_loc (loc,
5069 implicit_built_in_decls[BUILT_IN_TRAP], 0);
75a70cf9 5070 gimplify_and_add (t, pre_p);
fcdd3ab3 5071
5072 /* This is dead code, but go ahead and finish so that the
5073 mode of the result comes out right. */
5074 *expr_p = dummy_object (type);
5075 return GS_ALL_DONE;
5076 }
5077 else
5078 {
5079 /* Make it easier for the backends by protecting the valist argument
a0c938f0 5080 from multiple evaluations. */
5f57a8b1 5081 if (TREE_CODE (have_va_type) == ARRAY_TYPE)
e0eca1fa 5082 {
5083 /* For this case, the backends will be expecting a pointer to
5f57a8b1 5084 TREE_TYPE (abi), but it's possible we've
5085 actually been given an array (an actual TARGET_FN_ABI_VA_LIST).
e0eca1fa 5086 So fix it. */
5087 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
5088 {
5f57a8b1 5089 tree p1 = build_pointer_type (TREE_TYPE (have_va_type));
389dd41b 5090 valist = fold_convert_loc (loc, p1,
5091 build_fold_addr_expr_loc (loc, valist));
e0eca1fa 5092 }
75a70cf9 5093
e0eca1fa 5094 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
5095 }
5096 else
5097 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
fcdd3ab3 5098
17a6380d 5099 if (!targetm.gimplify_va_arg_expr)
75a70cf9 5100 /* FIXME: Once most targets are converted we should merely
89f18f73 5101 assert this is non-null. */
fcdd3ab3 5102 return GS_ALL_DONE;
5103
17a6380d 5104 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
fcdd3ab3 5105 return GS_OK;
5106 }
5107}
5108
c2f47e15 5109/* Expand EXP, a call to __builtin_va_end. */
f7c44134 5110
a66c9326 5111static rtx
c2f47e15 5112expand_builtin_va_end (tree exp)
a66c9326 5113{
c2f47e15 5114 tree valist = CALL_EXPR_ARG (exp, 0);
8a15c04a 5115
8a15c04a 5116 /* Evaluate for side effects, if needed. I hate macros that don't
5117 do that. */
5118 if (TREE_SIDE_EFFECTS (valist))
5119 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
a66c9326 5120
5121 return const0_rtx;
5122}
5123
c2f47e15 5124/* Expand EXP, a call to __builtin_va_copy. We do this as a
a66c9326 5125 builtin rather than just as an assignment in stdarg.h because of the
5126 nastiness of array-type va_list types. */
f7c44134 5127
a66c9326 5128static rtx
c2f47e15 5129expand_builtin_va_copy (tree exp)
a66c9326 5130{
5131 tree dst, src, t;
389dd41b 5132 location_t loc = EXPR_LOCATION (exp);
a66c9326 5133
c2f47e15 5134 dst = CALL_EXPR_ARG (exp, 0);
5135 src = CALL_EXPR_ARG (exp, 1);
a66c9326 5136
389dd41b 5137 dst = stabilize_va_list_loc (loc, dst, 1);
5138 src = stabilize_va_list_loc (loc, src, 0);
a66c9326 5139
5f57a8b1 5140 gcc_assert (cfun != NULL && cfun->decl != NULL_TREE);
5141
5142 if (TREE_CODE (targetm.fn_abi_va_list (cfun->decl)) != ARRAY_TYPE)
a66c9326 5143 {
5f57a8b1 5144 t = build2 (MODIFY_EXPR, targetm.fn_abi_va_list (cfun->decl), dst, src);
a66c9326 5145 TREE_SIDE_EFFECTS (t) = 1;
5146 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5147 }
5148 else
5149 {
11a61dea 5150 rtx dstb, srcb, size;
5151
5152 /* Evaluate to pointers. */
5153 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
5154 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
5f57a8b1 5155 size = expand_expr (TYPE_SIZE_UNIT (targetm.fn_abi_va_list (cfun->decl)),
5156 NULL_RTX, VOIDmode, EXPAND_NORMAL);
11a61dea 5157
85d654dd 5158 dstb = convert_memory_address (Pmode, dstb);
5159 srcb = convert_memory_address (Pmode, srcb);
726ec87c 5160
11a61dea 5161 /* "Dereference" to BLKmode memories. */
5162 dstb = gen_rtx_MEM (BLKmode, dstb);
ab6ab77e 5163 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
5f57a8b1 5164 set_mem_align (dstb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
11a61dea 5165 srcb = gen_rtx_MEM (BLKmode, srcb);
ab6ab77e 5166 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
5f57a8b1 5167 set_mem_align (srcb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
11a61dea 5168
5169 /* Copy. */
0378dbdc 5170 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
a66c9326 5171 }
5172
5173 return const0_rtx;
5174}
5175
53800dbe 5176/* Expand a call to one of the builtin functions __builtin_frame_address or
5177 __builtin_return_address. */
27d0c333 5178
53800dbe 5179static rtx
c2f47e15 5180expand_builtin_frame_address (tree fndecl, tree exp)
53800dbe 5181{
53800dbe 5182 /* The argument must be a nonnegative integer constant.
5183 It counts the number of frames to scan up the stack.
5184 The value is the return address saved in that frame. */
c2f47e15 5185 if (call_expr_nargs (exp) == 0)
53800dbe 5186 /* Warning about missing arg was already issued. */
5187 return const0_rtx;
c2f47e15 5188 else if (! host_integerp (CALL_EXPR_ARG (exp, 0), 1))
53800dbe 5189 {
5190 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
07e3a3d2 5191 error ("invalid argument to %<__builtin_frame_address%>");
53800dbe 5192 else
07e3a3d2 5193 error ("invalid argument to %<__builtin_return_address%>");
53800dbe 5194 return const0_rtx;
5195 }
5196 else
5197 {
27d0c333 5198 rtx tem
5199 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
c2f47e15 5200 tree_low_cst (CALL_EXPR_ARG (exp, 0), 1));
53800dbe 5201
5202 /* Some ports cannot access arbitrary stack frames. */
5203 if (tem == NULL)
5204 {
5205 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
c3ceba8e 5206 warning (0, "unsupported argument to %<__builtin_frame_address%>");
53800dbe 5207 else
c3ceba8e 5208 warning (0, "unsupported argument to %<__builtin_return_address%>");
53800dbe 5209 return const0_rtx;
5210 }
5211
5212 /* For __builtin_frame_address, return what we've got. */
5213 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
5214 return tem;
5215
8ad4c111 5216 if (!REG_P (tem)
53800dbe 5217 && ! CONSTANT_P (tem))
5218 tem = copy_to_mode_reg (Pmode, tem);
5219 return tem;
5220 }
5221}
5222
c2f47e15 5223/* Expand EXP, a call to the alloca builtin. Return NULL_RTX if
53800dbe 5224 we failed and the caller should emit a normal call, otherwise try to get
5225 the result in TARGET, if convenient. */
15c6cf6b 5226
53800dbe 5227static rtx
c2f47e15 5228expand_builtin_alloca (tree exp, rtx target)
53800dbe 5229{
5230 rtx op0;
15c6cf6b 5231 rtx result;
53800dbe 5232
f9fa0459 5233 /* Emit normal call if marked not-inlineable. */
5234 if (CALL_CANNOT_INLINE_P (exp))
c2f47e15 5235 return NULL_RTX;
4ee9c684 5236
c2f47e15 5237 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5238 return NULL_RTX;
53800dbe 5239
5240 /* Compute the argument. */
c2f47e15 5241 op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
53800dbe 5242
5243 /* Allocate the desired space. */
15c6cf6b 5244 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
85d654dd 5245 result = convert_memory_address (ptr_mode, result);
15c6cf6b 5246
5247 return result;
53800dbe 5248}
5249
c2f47e15 5250/* Expand a call to a bswap builtin with argument ARG0. MODE
42791117 5251 is the mode to expand with. */
5252
5253static rtx
c2f47e15 5254expand_builtin_bswap (tree exp, rtx target, rtx subtarget)
42791117 5255{
5256 enum machine_mode mode;
5257 tree arg;
5258 rtx op0;
5259
c2f47e15 5260 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5261 return NULL_RTX;
42791117 5262
c2f47e15 5263 arg = CALL_EXPR_ARG (exp, 0);
42791117 5264 mode = TYPE_MODE (TREE_TYPE (arg));
1db6d067 5265 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
42791117 5266
5267 target = expand_unop (mode, bswap_optab, op0, target, 1);
5268
5269 gcc_assert (target);
5270
5271 return convert_to_mode (mode, target, 0);
5272}
5273
c2f47e15 5274/* Expand a call to a unary builtin in EXP.
5275 Return NULL_RTX if a normal call should be emitted rather than expanding the
53800dbe 5276 function in-line. If convenient, the result should be placed in TARGET.
5277 SUBTARGET may be used as the target for computing one of EXP's operands. */
15c6cf6b 5278
53800dbe 5279static rtx
c2f47e15 5280expand_builtin_unop (enum machine_mode target_mode, tree exp, rtx target,
aecda0d6 5281 rtx subtarget, optab op_optab)
53800dbe 5282{
5283 rtx op0;
c2f47e15 5284
5285 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5286 return NULL_RTX;
53800dbe 5287
5288 /* Compute the argument. */
1db6d067 5289 op0 = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
5290 VOIDmode, EXPAND_NORMAL);
6a08d0ab 5291 /* Compute op, into TARGET if possible.
53800dbe 5292 Set TARGET to wherever the result comes back. */
c2f47e15 5293 target = expand_unop (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0))),
6a08d0ab 5294 op_optab, op0, target, 1);
64db345d 5295 gcc_assert (target);
7d3f6cc7 5296
efb070c8 5297 return convert_to_mode (target_mode, target, 0);
53800dbe 5298}
89cfe6e5 5299
df94cd3b 5300/* If the string passed to fputs is a constant and is one character
2c0e001b 5301 long, we attempt to transform this call into __builtin_fputc(). */
15c6cf6b 5302
df94cd3b 5303static rtx
c2f47e15 5304expand_builtin_fputs (tree exp, rtx target, bool unlocked)
df94cd3b 5305{
2c0e001b 5306 /* Verify the arguments in the original call. */
c2f47e15 5307 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
ce1b14f4 5308 {
389dd41b 5309 tree result = fold_builtin_fputs (EXPR_LOCATION (exp),
5310 CALL_EXPR_ARG (exp, 0),
c2f47e15 5311 CALL_EXPR_ARG (exp, 1),
5312 (target == const0_rtx),
2c84ee37 5313 unlocked, NULL_TREE);
5314 if (result)
5315 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
ce1b14f4 5316 }
c2f47e15 5317 return NULL_RTX;
3311f67b 5318}
5319
5a74f77e 5320/* Expand a call to __builtin_expect. We just return our argument
5321 as the builtin_expect semantic should've been already executed by
5322 tree branch prediction pass. */
89cfe6e5 5323
5324static rtx
c2f47e15 5325expand_builtin_expect (tree exp, rtx target)
89cfe6e5 5326{
c2f47e15 5327 tree arg, c;
89cfe6e5 5328
c2f47e15 5329 if (call_expr_nargs (exp) < 2)
89cfe6e5 5330 return const0_rtx;
c2f47e15 5331 arg = CALL_EXPR_ARG (exp, 0);
5332 c = CALL_EXPR_ARG (exp, 1);
89cfe6e5 5333
c2f47e15 5334 target = expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5a74f77e 5335 /* When guessing was done, the hints should be already stripped away. */
07311427 5336 gcc_assert (!flag_guess_branch_prob
5337 || optimize == 0 || errorcount || sorrycount);
89cfe6e5 5338 return target;
5339}
689df48e 5340
c22de3f0 5341void
aecda0d6 5342expand_builtin_trap (void)
a0ef1725 5343{
5344#ifdef HAVE_trap
5345 if (HAVE_trap)
5346 emit_insn (gen_trap ());
5347 else
5348#endif
5349 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
5350 emit_barrier ();
5351}
78a74442 5352
d2b48f0c 5353/* Expand a call to __builtin_unreachable. We do nothing except emit
5354 a barrier saying that control flow will not pass here.
5355
5356 It is the responsibility of the program being compiled to ensure
5357 that control flow does never reach __builtin_unreachable. */
5358static void
5359expand_builtin_unreachable (void)
5360{
5361 emit_barrier ();
5362}
5363
c2f47e15 5364/* Expand EXP, a call to fabs, fabsf or fabsl.
5365 Return NULL_RTX if a normal call should be emitted rather than expanding
78a74442 5366 the function inline. If convenient, the result should be placed
5367 in TARGET. SUBTARGET may be used as the target for computing
5368 the operand. */
5369
5370static rtx
c2f47e15 5371expand_builtin_fabs (tree exp, rtx target, rtx subtarget)
78a74442 5372{
5373 enum machine_mode mode;
5374 tree arg;
5375 rtx op0;
5376
c2f47e15 5377 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
5378 return NULL_RTX;
78a74442 5379
c2f47e15 5380 arg = CALL_EXPR_ARG (exp, 0);
c7f617c2 5381 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
78a74442 5382 mode = TYPE_MODE (TREE_TYPE (arg));
1db6d067 5383 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
78a74442 5384 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
5385}
5386
c2f47e15 5387/* Expand EXP, a call to copysign, copysignf, or copysignl.
270436f3 5388 Return NULL is a normal call should be emitted rather than expanding the
5389 function inline. If convenient, the result should be placed in TARGET.
5390 SUBTARGET may be used as the target for computing the operand. */
5391
5392static rtx
c2f47e15 5393expand_builtin_copysign (tree exp, rtx target, rtx subtarget)
270436f3 5394{
5395 rtx op0, op1;
5396 tree arg;
5397
c2f47e15 5398 if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
5399 return NULL_RTX;
270436f3 5400
c2f47e15 5401 arg = CALL_EXPR_ARG (exp, 0);
8ec3c5c2 5402 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
270436f3 5403
c2f47e15 5404 arg = CALL_EXPR_ARG (exp, 1);
8ec3c5c2 5405 op1 = expand_normal (arg);
270436f3 5406
5407 return expand_copysign (op0, op1, target);
5408}
5409
19bf118a 5410/* Create a new constant string literal and return a char* pointer to it.
5411 The STRING_CST value is the LEN characters at STR. */
1e8e9920 5412tree
19bf118a 5413build_string_literal (int len, const char *str)
5414{
5415 tree t, elem, index, type;
5416
5417 t = build_string (len, str);
5418 elem = build_type_variant (char_type_node, 1, 0);
40238f64 5419 index = build_index_type (size_int (len - 1));
19bf118a 5420 type = build_array_type (elem, index);
5421 TREE_TYPE (t) = type;
5422 TREE_CONSTANT (t) = 1;
5423 TREE_READONLY (t) = 1;
5424 TREE_STATIC (t) = 1;
5425
19bf118a 5426 type = build_pointer_type (elem);
40238f64 5427 t = build1 (ADDR_EXPR, type,
5428 build4 (ARRAY_REF, elem,
5429 t, integer_zero_node, NULL_TREE, NULL_TREE));
19bf118a 5430 return t;
5431}
5432
0b25db21 5433/* Expand EXP, a call to printf or printf_unlocked.
c2f47e15 5434 Return NULL_RTX if a normal call should be emitted rather than transforming
19bf118a 5435 the function inline. If convenient, the result should be placed in
0862b7e9 5436 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
19bf118a 5437 call. */
5438static rtx
0b25db21 5439expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
19bf118a 5440 bool unlocked)
5441{
6d77ed92 5442 /* If we're using an unlocked function, assume the other unlocked
5443 functions exist explicitly. */
5444 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
5445 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
5446 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
5447 : implicit_built_in_decls[BUILT_IN_PUTS];
19bf118a 5448 const char *fmt_str;
c2f47e15 5449 tree fn = 0;
5450 tree fmt, arg;
5451 int nargs = call_expr_nargs (exp);
19bf118a 5452
5453 /* If the return value is used, don't do the transformation. */
5454 if (target != const0_rtx)
c2f47e15 5455 return NULL_RTX;
19bf118a 5456
5457 /* Verify the required arguments in the original call. */
c2f47e15 5458 if (nargs == 0)
5459 return NULL_RTX;
5460 fmt = CALL_EXPR_ARG (exp, 0);
552752f7 5461 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
c2f47e15 5462 return NULL_RTX;
19bf118a 5463
5464 /* Check whether the format is a literal string constant. */
5465 fmt_str = c_getstr (fmt);
5466 if (fmt_str == NULL)
c2f47e15 5467 return NULL_RTX;
19bf118a 5468
d4473c84 5469 if (!init_target_chars ())
c2f47e15 5470 return NULL_RTX;
a0c938f0 5471
19bf118a 5472 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
99eabcc1 5473 if (strcmp (fmt_str, target_percent_s_newline) == 0)
19bf118a 5474 {
c2f47e15 5475 if ((nargs != 2)
5476 || ! POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (exp, 1))))
5477 return NULL_RTX;
5478 if (fn_puts)
5479 fn = build_call_expr (fn_puts, 1, CALL_EXPR_ARG (exp, 1));
19bf118a 5480 }
5481 /* If the format specifier was "%c", call __builtin_putchar(arg). */
99eabcc1 5482 else if (strcmp (fmt_str, target_percent_c) == 0)
19bf118a 5483 {
c2f47e15 5484 if ((nargs != 2)
5485 || TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1))) != INTEGER_TYPE)
5486 return NULL_RTX;
5487 if (fn_putchar)
5488 fn = build_call_expr (fn_putchar, 1, CALL_EXPR_ARG (exp, 1));
19bf118a 5489 }
5490 else
5491 {
5492 /* We can't handle anything else with % args or %% ... yet. */
99eabcc1 5493 if (strchr (fmt_str, target_percent))
c2f47e15 5494 return NULL_RTX;
19bf118a 5495
c2f47e15 5496 if (nargs > 1)
5497 return NULL_RTX;
19bf118a 5498
5499 /* If the format specifier was "", printf does nothing. */
5500 if (fmt_str[0] == '\0')
5501 return const0_rtx;
5502 /* If the format specifier has length of 1, call putchar. */
5503 if (fmt_str[1] == '\0')
5504 {
5505 /* Given printf("c"), (where c is any one character,)
5506 convert "c"[0] to an int and pass that to the replacement
5507 function. */
7016c612 5508 arg = build_int_cst (NULL_TREE, fmt_str[0]);
c2f47e15 5509 if (fn_putchar)
5510 fn = build_call_expr (fn_putchar, 1, arg);
19bf118a 5511 }
5512 else
5513 {
5514 /* If the format specifier was "string\n", call puts("string"). */
5515 size_t len = strlen (fmt_str);
99eabcc1 5516 if ((unsigned char)fmt_str[len - 1] == target_newline)
19bf118a 5517 {
91c82c20 5518 /* Create a NUL-terminated string that's one char shorter
19bf118a 5519 than the original, stripping off the trailing '\n'. */
364c0c59 5520 char *newstr = XALLOCAVEC (char, len);
19bf118a 5521 memcpy (newstr, fmt_str, len - 1);
5522 newstr[len - 1] = 0;
19bf118a 5523 arg = build_string_literal (len, newstr);
c2f47e15 5524 if (fn_puts)
5525 fn = build_call_expr (fn_puts, 1, arg);
19bf118a 5526 }
5527 else
5528 /* We'd like to arrange to call fputs(string,stdout) here,
5529 but we need stdout and don't have a way to get it yet. */
c2f47e15 5530 return NULL_RTX;
19bf118a 5531 }
5532 }
5533
5534 if (!fn)
c2f47e15 5535 return NULL_RTX;
0b25db21 5536 if (TREE_CODE (fn) == CALL_EXPR)
5537 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5538 return expand_expr (fn, target, mode, EXPAND_NORMAL);
19bf118a 5539}
5540
0b25db21 5541/* Expand EXP, a call to fprintf or fprintf_unlocked.
c2f47e15 5542 Return NULL_RTX if a normal call should be emitted rather than transforming
19bf118a 5543 the function inline. If convenient, the result should be placed in
0862b7e9 5544 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
19bf118a 5545 call. */
5546static rtx
0b25db21 5547expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
a0c938f0 5548 bool unlocked)
19bf118a 5549{
6d77ed92 5550 /* If we're using an unlocked function, assume the other unlocked
5551 functions exist explicitly. */
5552 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5553 : implicit_built_in_decls[BUILT_IN_FPUTC];
5554 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5555 : implicit_built_in_decls[BUILT_IN_FPUTS];
19bf118a 5556 const char *fmt_str;
c2f47e15 5557 tree fn = 0;
5558 tree fmt, fp, arg;
5559 int nargs = call_expr_nargs (exp);
19bf118a 5560
5561 /* If the return value is used, don't do the transformation. */
5562 if (target != const0_rtx)
c2f47e15 5563 return NULL_RTX;
19bf118a 5564
5565 /* Verify the required arguments in the original call. */
c2f47e15 5566 if (nargs < 2)
5567 return NULL_RTX;
5568 fp = CALL_EXPR_ARG (exp, 0);
552752f7 5569 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
c2f47e15 5570 return NULL_RTX;
5571 fmt = CALL_EXPR_ARG (exp, 1);
552752f7 5572 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
c2f47e15 5573 return NULL_RTX;
19bf118a 5574
5575 /* Check whether the format is a literal string constant. */
5576 fmt_str = c_getstr (fmt);
5577 if (fmt_str == NULL)
c2f47e15 5578 return NULL_RTX;
19bf118a 5579
d4473c84 5580 if (!init_target_chars ())
c2f47e15 5581 return NULL_RTX;
a0c938f0 5582
19bf118a 5583 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
99eabcc1 5584 if (strcmp (fmt_str, target_percent_s) == 0)
19bf118a 5585 {
c2f47e15 5586 if ((nargs != 3)
5587 || ! POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (exp, 2))))
5588 return NULL_RTX;
5589 arg = CALL_EXPR_ARG (exp, 2);
5590 if (fn_fputs)
5591 fn = build_call_expr (fn_fputs, 2, arg, fp);
19bf118a 5592 }
5593 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
99eabcc1 5594 else if (strcmp (fmt_str, target_percent_c) == 0)
19bf118a 5595 {
c2f47e15 5596 if ((nargs != 3)
5597 || TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2))) != INTEGER_TYPE)
5598 return NULL_RTX;
5599 arg = CALL_EXPR_ARG (exp, 2);
5600 if (fn_fputc)
5601 fn = build_call_expr (fn_fputc, 2, arg, fp);
19bf118a 5602 }
5603 else
5604 {
5605 /* We can't handle anything else with % args or %% ... yet. */
99eabcc1 5606 if (strchr (fmt_str, target_percent))
c2f47e15 5607 return NULL_RTX;
19bf118a 5608
c2f47e15 5609 if (nargs > 2)
5610 return NULL_RTX;
19bf118a 5611
5612 /* If the format specifier was "", fprintf does nothing. */
5613 if (fmt_str[0] == '\0')
5614 {
5615 /* Evaluate and ignore FILE* argument for side-effects. */
5616 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5617 return const0_rtx;
5618 }
5619
5620 /* When "string" doesn't contain %, replace all cases of
5621 fprintf(stream,string) with fputs(string,stream). The fputs
5622 builtin will take care of special cases like length == 1. */
c2f47e15 5623 if (fn_fputs)
5624 fn = build_call_expr (fn_fputs, 2, fmt, fp);
19bf118a 5625 }
5626
5627 if (!fn)
c2f47e15 5628 return NULL_RTX;
0b25db21 5629 if (TREE_CODE (fn) == CALL_EXPR)
5630 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5631 return expand_expr (fn, target, mode, EXPAND_NORMAL);
19bf118a 5632}
5633
c2f47e15 5634/* Expand a call EXP to sprintf. Return NULL_RTX if
6411575e 5635 a normal call should be emitted rather than expanding the function
5636 inline. If convenient, the result should be placed in TARGET with
5637 mode MODE. */
5638
5639static rtx
c2f47e15 5640expand_builtin_sprintf (tree exp, rtx target, enum machine_mode mode)
6411575e 5641{
c2f47e15 5642 tree dest, fmt;
a7a723f0 5643 const char *fmt_str;
c2f47e15 5644 int nargs = call_expr_nargs (exp);
6411575e 5645
5646 /* Verify the required arguments in the original call. */
c2f47e15 5647 if (nargs < 2)
5648 return NULL_RTX;
5649 dest = CALL_EXPR_ARG (exp, 0);
552752f7 5650 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
c2f47e15 5651 return NULL_RTX;
5652 fmt = CALL_EXPR_ARG (exp, 0);
552752f7 5653 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
c2f47e15 5654 return NULL_RTX;
6411575e 5655
5656 /* Check whether the format is a literal string constant. */
a7a723f0 5657 fmt_str = c_getstr (fmt);
5658 if (fmt_str == NULL)
c2f47e15 5659 return NULL_RTX;
6411575e 5660
d4473c84 5661 if (!init_target_chars ())
c2f47e15 5662 return NULL_RTX;
99eabcc1 5663
6411575e 5664 /* If the format doesn't contain % args or %%, use strcpy. */
99eabcc1 5665 if (strchr (fmt_str, target_percent) == 0)
6411575e 5666 {
5667 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5668 tree exp;
5669
c2f47e15 5670 if ((nargs > 2) || ! fn)
5671 return NULL_RTX;
5672 expand_expr (build_call_expr (fn, 2, dest, fmt),
6411575e 5673 const0_rtx, VOIDmode, EXPAND_NORMAL);
5674 if (target == const0_rtx)
5675 return const0_rtx;
7016c612 5676 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
6411575e 5677 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5678 }
a7a723f0 5679 /* If the format is "%s", use strcpy if the result isn't used. */
99eabcc1 5680 else if (strcmp (fmt_str, target_percent_s) == 0)
6411575e 5681 {
a7a723f0 5682 tree fn, arg, len;
5683 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
6411575e 5684
a7a723f0 5685 if (! fn)
c2f47e15 5686 return NULL_RTX;
5687 if (nargs != 3)
5688 return NULL_RTX;
5689 arg = CALL_EXPR_ARG (exp, 2);
552752f7 5690 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
c2f47e15 5691 return NULL_RTX;
6411575e 5692
5693 if (target != const0_rtx)
5694 {
681fab1e 5695 len = c_strlen (arg, 1);
a7a723f0 5696 if (! len || TREE_CODE (len) != INTEGER_CST)
c2f47e15 5697 return NULL_RTX;
6411575e 5698 }
5699 else
a7a723f0 5700 len = NULL_TREE;
6411575e 5701
c2f47e15 5702 expand_expr (build_call_expr (fn, 2, dest, arg),
6411575e 5703 const0_rtx, VOIDmode, EXPAND_NORMAL);
5704
5705 if (target == const0_rtx)
5706 return const0_rtx;
a7a723f0 5707 return expand_expr (len, target, mode, EXPAND_NORMAL);
6411575e 5708 }
5709
c2f47e15 5710 return NULL_RTX;
6411575e 5711}
27f261ef 5712
4ee9c684 5713/* Expand a call to either the entry or exit function profiler. */
5714
5715static rtx
5716expand_builtin_profile_func (bool exitp)
5717{
f4e36c33 5718 rtx this_rtx, which;
4ee9c684 5719
f4e36c33 5720 this_rtx = DECL_RTL (current_function_decl);
5721 gcc_assert (MEM_P (this_rtx));
5722 this_rtx = XEXP (this_rtx, 0);
4ee9c684 5723
5724 if (exitp)
5725 which = profile_function_exit_libfunc;
5726 else
5727 which = profile_function_entry_libfunc;
5728
f4e36c33 5729 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this_rtx, Pmode,
4ee9c684 5730 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
869d0ef0 5731 0),
4ee9c684 5732 Pmode);
5733
5734 return const0_rtx;
5735}
5736
ac8fb6db 5737/* Expand a call to __builtin___clear_cache. */
5738
5739static rtx
5740expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED)
5741{
5742#ifndef HAVE_clear_cache
5743#ifdef CLEAR_INSN_CACHE
5744 /* There is no "clear_cache" insn, and __clear_cache() in libgcc
5745 does something. Just do the default expansion to a call to
5746 __clear_cache(). */
5747 return NULL_RTX;
5748#else
5749 /* There is no "clear_cache" insn, and __clear_cache() in libgcc
5750 does nothing. There is no need to call it. Do nothing. */
5751 return const0_rtx;
5752#endif /* CLEAR_INSN_CACHE */
5753#else
5754 /* We have a "clear_cache" insn, and it will handle everything. */
5755 tree begin, end;
5756 rtx begin_rtx, end_rtx;
5757 enum insn_code icode;
5758
5759 /* We must not expand to a library call. If we did, any
5760 fallback library function in libgcc that might contain a call to
5761 __builtin___clear_cache() would recurse infinitely. */
5762 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
5763 {
5764 error ("both arguments to %<__builtin___clear_cache%> must be pointers");
5765 return const0_rtx;
5766 }
5767
5768 if (HAVE_clear_cache)
5769 {
5770 icode = CODE_FOR_clear_cache;
5771
5772 begin = CALL_EXPR_ARG (exp, 0);
5773 begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL);
5774 begin_rtx = convert_memory_address (Pmode, begin_rtx);
5775 if (!insn_data[icode].operand[0].predicate (begin_rtx, Pmode))
5776 begin_rtx = copy_to_mode_reg (Pmode, begin_rtx);
5777
5778 end = CALL_EXPR_ARG (exp, 1);
5779 end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL);
5780 end_rtx = convert_memory_address (Pmode, end_rtx);
5781 if (!insn_data[icode].operand[1].predicate (end_rtx, Pmode))
5782 end_rtx = copy_to_mode_reg (Pmode, end_rtx);
5783
5784 emit_insn (gen_clear_cache (begin_rtx, end_rtx));
5785 }
5786 return const0_rtx;
5787#endif /* HAVE_clear_cache */
5788}
5789
4ee9c684 5790/* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5791
5792static rtx
5793round_trampoline_addr (rtx tramp)
5794{
5795 rtx temp, addend, mask;
5796
5797 /* If we don't need too much alignment, we'll have been guaranteed
5798 proper alignment by get_trampoline_type. */
5799 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5800 return tramp;
5801
5802 /* Round address up to desired boundary. */
5803 temp = gen_reg_rtx (Pmode);
5804 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5805 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5806
5807 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5808 temp, 0, OPTAB_LIB_WIDEN);
5809 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5810 temp, 0, OPTAB_LIB_WIDEN);
5811
5812 return tramp;
5813}
5814
5815static rtx
c2f47e15 5816expand_builtin_init_trampoline (tree exp)
4ee9c684 5817{
5818 tree t_tramp, t_func, t_chain;
82c7907c 5819 rtx m_tramp, r_tramp, r_chain, tmp;
4ee9c684 5820
c2f47e15 5821 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE,
4ee9c684 5822 POINTER_TYPE, VOID_TYPE))
5823 return NULL_RTX;
5824
c2f47e15 5825 t_tramp = CALL_EXPR_ARG (exp, 0);
5826 t_func = CALL_EXPR_ARG (exp, 1);
5827 t_chain = CALL_EXPR_ARG (exp, 2);
4ee9c684 5828
8ec3c5c2 5829 r_tramp = expand_normal (t_tramp);
82c7907c 5830 m_tramp = gen_rtx_MEM (BLKmode, r_tramp);
5831 MEM_NOTRAP_P (m_tramp) = 1;
5832
5833 /* The TRAMP argument should be the address of a field within the
5834 local function's FRAME decl. Let's see if we can fill in the
5835 to fill in the MEM_ATTRs for this memory. */
5836 if (TREE_CODE (t_tramp) == ADDR_EXPR)
5837 set_mem_attributes_minus_bitpos (m_tramp, TREE_OPERAND (t_tramp, 0),
5838 true, 0);
5839
5840 tmp = round_trampoline_addr (r_tramp);
5841 if (tmp != r_tramp)
5842 {
5843 m_tramp = change_address (m_tramp, BLKmode, tmp);
5844 set_mem_align (m_tramp, TRAMPOLINE_ALIGNMENT);
5845 set_mem_size (m_tramp, GEN_INT (TRAMPOLINE_SIZE));
5846 }
5847
5848 /* The FUNC argument should be the address of the nested function.
5849 Extract the actual function decl to pass to the hook. */
5850 gcc_assert (TREE_CODE (t_func) == ADDR_EXPR);
5851 t_func = TREE_OPERAND (t_func, 0);
5852 gcc_assert (TREE_CODE (t_func) == FUNCTION_DECL);
5853
8ec3c5c2 5854 r_chain = expand_normal (t_chain);
4ee9c684 5855
5856 /* Generate insns to initialize the trampoline. */
82c7907c 5857 targetm.calls.trampoline_init (m_tramp, t_func, r_chain);
4ee9c684 5858
82c7907c 5859 trampolines_created = 1;
4ee9c684 5860 return const0_rtx;
5861}
5862
5863static rtx
c2f47e15 5864expand_builtin_adjust_trampoline (tree exp)
4ee9c684 5865{
5866 rtx tramp;
5867
c2f47e15 5868 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
4ee9c684 5869 return NULL_RTX;
5870
c2f47e15 5871 tramp = expand_normal (CALL_EXPR_ARG (exp, 0));
4ee9c684 5872 tramp = round_trampoline_addr (tramp);
82c7907c 5873 if (targetm.calls.trampoline_adjust_address)
5874 tramp = targetm.calls.trampoline_adjust_address (tramp);
4ee9c684 5875
5876 return tramp;
5877}
5878
93f564d6 5879/* Expand the call EXP to the built-in signbit, signbitf or signbitl
5880 function. The function first checks whether the back end provides
5881 an insn to implement signbit for the respective mode. If not, it
5882 checks whether the floating point format of the value is such that
5883 the sign bit can be extracted. If that is not the case, the
5884 function returns NULL_RTX to indicate that a normal call should be
5885 emitted rather than expanding the function in-line. EXP is the
5886 expression that is a call to the builtin function; if convenient,
5887 the result should be placed in TARGET. */
27f261ef 5888static rtx
5889expand_builtin_signbit (tree exp, rtx target)
5890{
5891 const struct real_format *fmt;
5892 enum machine_mode fmode, imode, rmode;
5893 HOST_WIDE_INT hi, lo;
c2f47e15 5894 tree arg;
ca4f1f5b 5895 int word, bitpos;
27eda240 5896 enum insn_code icode;
27f261ef 5897 rtx temp;
389dd41b 5898 location_t loc = EXPR_LOCATION (exp);
27f261ef 5899
c2f47e15 5900 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
5901 return NULL_RTX;
27f261ef 5902
c2f47e15 5903 arg = CALL_EXPR_ARG (exp, 0);
27f261ef 5904 fmode = TYPE_MODE (TREE_TYPE (arg));
5905 rmode = TYPE_MODE (TREE_TYPE (exp));
5906 fmt = REAL_MODE_FORMAT (fmode);
5907
93f564d6 5908 arg = builtin_save_expr (arg);
5909
5910 /* Expand the argument yielding a RTX expression. */
5911 temp = expand_normal (arg);
5912
5913 /* Check if the back end provides an insn that handles signbit for the
5914 argument's mode. */
27eda240 5915 icode = signbit_optab->handlers [(int) fmode].insn_code;
5916 if (icode != CODE_FOR_nothing)
93f564d6 5917 {
5918 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
27eda240 5919 emit_unop_insn (icode, target, temp, UNKNOWN);
93f564d6 5920 return target;
5921 }
5922
27f261ef 5923 /* For floating point formats without a sign bit, implement signbit
5924 as "ARG < 0.0". */
8d564692 5925 bitpos = fmt->signbit_ro;
ca4f1f5b 5926 if (bitpos < 0)
27f261ef 5927 {
5928 /* But we can't do this if the format supports signed zero. */
5929 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
c2f47e15 5930 return NULL_RTX;
27f261ef 5931
389dd41b 5932 arg = fold_build2_loc (loc, LT_EXPR, TREE_TYPE (exp), arg,
49d00087 5933 build_real (TREE_TYPE (arg), dconst0));
27f261ef 5934 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5935 }
5936
ca4f1f5b 5937 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
27f261ef 5938 {
ca4f1f5b 5939 imode = int_mode_for_mode (fmode);
5940 if (imode == BLKmode)
c2f47e15 5941 return NULL_RTX;
ca4f1f5b 5942 temp = gen_lowpart (imode, temp);
24fd4260 5943 }
5944 else
5945 {
ca4f1f5b 5946 imode = word_mode;
5947 /* Handle targets with different FP word orders. */
5948 if (FLOAT_WORDS_BIG_ENDIAN)
a0c938f0 5949 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
ca4f1f5b 5950 else
a0c938f0 5951 word = bitpos / BITS_PER_WORD;
ca4f1f5b 5952 temp = operand_subword_force (temp, word, fmode);
5953 bitpos = bitpos % BITS_PER_WORD;
5954 }
5955
44b0f1d0 5956 /* Force the intermediate word_mode (or narrower) result into a
5957 register. This avoids attempting to create paradoxical SUBREGs
5958 of floating point modes below. */
5959 temp = force_reg (imode, temp);
5960
ca4f1f5b 5961 /* If the bitpos is within the "result mode" lowpart, the operation
5962 can be implement with a single bitwise AND. Otherwise, we need
5963 a right shift and an AND. */
5964
5965 if (bitpos < GET_MODE_BITSIZE (rmode))
5966 {
24fd4260 5967 if (bitpos < HOST_BITS_PER_WIDE_INT)
27f261ef 5968 {
24fd4260 5969 hi = 0;
5970 lo = (HOST_WIDE_INT) 1 << bitpos;
27f261ef 5971 }
5972 else
24fd4260 5973 {
5974 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5975 lo = 0;
5976 }
27f261ef 5977
4a46f016 5978 if (GET_MODE_SIZE (imode) > GET_MODE_SIZE (rmode))
ca4f1f5b 5979 temp = gen_lowpart (rmode, temp);
24fd4260 5980 temp = expand_binop (rmode, and_optab, temp,
5981 immed_double_const (lo, hi, rmode),
ca4f1f5b 5982 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27f261ef 5983 }
ca4f1f5b 5984 else
5985 {
5986 /* Perform a logical right shift to place the signbit in the least
a0c938f0 5987 significant bit, then truncate the result to the desired mode
ca4f1f5b 5988 and mask just this bit. */
5989 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5990 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5991 temp = gen_lowpart (rmode, temp);
5992 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5993 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5994 }
5995
27f261ef 5996 return temp;
5997}
73673831 5998
5999/* Expand fork or exec calls. TARGET is the desired target of the
c2f47e15 6000 call. EXP is the call. FN is the
73673831 6001 identificator of the actual function. IGNORE is nonzero if the
6002 value is to be ignored. */
6003
6004static rtx
c2f47e15 6005expand_builtin_fork_or_exec (tree fn, tree exp, rtx target, int ignore)
73673831 6006{
6007 tree id, decl;
6008 tree call;
6009
6010 /* If we are not profiling, just call the function. */
6011 if (!profile_arc_flag)
6012 return NULL_RTX;
6013
6014 /* Otherwise call the wrapper. This should be equivalent for the rest of
6015 compiler, so the code does not diverge, and the wrapper may run the
9c9bad97 6016 code necessary for keeping the profiling sane. */
73673831 6017
6018 switch (DECL_FUNCTION_CODE (fn))
6019 {
6020 case BUILT_IN_FORK:
6021 id = get_identifier ("__gcov_fork");
6022 break;
6023
6024 case BUILT_IN_EXECL:
6025 id = get_identifier ("__gcov_execl");
6026 break;
6027
6028 case BUILT_IN_EXECV:
6029 id = get_identifier ("__gcov_execv");
6030 break;
6031
6032 case BUILT_IN_EXECLP:
6033 id = get_identifier ("__gcov_execlp");
6034 break;
6035
6036 case BUILT_IN_EXECLE:
6037 id = get_identifier ("__gcov_execle");
6038 break;
6039
6040 case BUILT_IN_EXECVP:
6041 id = get_identifier ("__gcov_execvp");
6042 break;
6043
6044 case BUILT_IN_EXECVE:
6045 id = get_identifier ("__gcov_execve");
6046 break;
6047
6048 default:
64db345d 6049 gcc_unreachable ();
73673831 6050 }
6051
e60a6f7b 6052 decl = build_decl (DECL_SOURCE_LOCATION (fn),
6053 FUNCTION_DECL, id, TREE_TYPE (fn));
73673831 6054 DECL_EXTERNAL (decl) = 1;
6055 TREE_PUBLIC (decl) = 1;
6056 DECL_ARTIFICIAL (decl) = 1;
6057 TREE_NOTHROW (decl) = 1;
e82d310b 6058 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
6059 DECL_VISIBILITY_SPECIFIED (decl) = 1;
389dd41b 6060 call = rewrite_call_expr (EXPR_LOCATION (exp), exp, 0, decl, 0);
73673831 6061 return expand_call (call, target, ignore);
c2f47e15 6062 }
6063
b6a5fc45 6064
6065\f
3e272de8 6066/* Reconstitute a mode for a __sync intrinsic operation. Since the type of
6067 the pointer in these functions is void*, the tree optimizers may remove
6068 casts. The mode computed in expand_builtin isn't reliable either, due
6069 to __sync_bool_compare_and_swap.
6070
6071 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
6072 group of builtins. This gives us log2 of the mode size. */
6073
6074static inline enum machine_mode
6075get_builtin_sync_mode (int fcode_diff)
6076{
ad3a13b5 6077 /* The size is not negotiable, so ask not to get BLKmode in return
6078 if the target indicates that a smaller size would be better. */
6079 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
3e272de8 6080}
6081
041e0215 6082/* Expand the memory expression LOC and return the appropriate memory operand
6083 for the builtin_sync operations. */
6084
6085static rtx
6086get_builtin_sync_mem (tree loc, enum machine_mode mode)
6087{
6088 rtx addr, mem;
6089
1db6d067 6090 addr = expand_expr (loc, NULL_RTX, Pmode, EXPAND_SUM);
041e0215 6091
6092 /* Note that we explicitly do not want any alias information for this
6093 memory, so that we kill all other live memories. Otherwise we don't
6094 satisfy the full barrier semantics of the intrinsic. */
6095 mem = validize_mem (gen_rtx_MEM (mode, addr));
6096
6097 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
c94cfd1c 6098 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
041e0215 6099 MEM_VOLATILE_P (mem) = 1;
6100
6101 return mem;
6102}
6103
b6a5fc45 6104/* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
c2f47e15 6105 EXP is the CALL_EXPR. CODE is the rtx code
b6a5fc45 6106 that corresponds to the arithmetic or logical operation from the name;
6107 an exception here is that NOT actually means NAND. TARGET is an optional
6108 place for us to store the results; AFTER is true if this is the
6109 fetch_and_xxx form. IGNORE is true if we don't actually care about
6110 the result of the operation at all. */
6111
6112static rtx
c2f47e15 6113expand_builtin_sync_operation (enum machine_mode mode, tree exp,
3e272de8 6114 enum rtx_code code, bool after,
b6a5fc45 6115 rtx target, bool ignore)
6116{
041e0215 6117 rtx val, mem;
a8bb7059 6118 enum machine_mode old_mode;
e60a6f7b 6119 location_t loc = EXPR_LOCATION (exp);
b6a5fc45 6120
cf73e559 6121 if (code == NOT && warn_sync_nand)
6122 {
6123 tree fndecl = get_callee_fndecl (exp);
6124 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6125
6126 static bool warned_f_a_n, warned_n_a_f;
6127
6128 switch (fcode)
6129 {
6130 case BUILT_IN_FETCH_AND_NAND_1:
6131 case BUILT_IN_FETCH_AND_NAND_2:
6132 case BUILT_IN_FETCH_AND_NAND_4:
6133 case BUILT_IN_FETCH_AND_NAND_8:
6134 case BUILT_IN_FETCH_AND_NAND_16:
6135
6136 if (warned_f_a_n)
6137 break;
6138
6139 fndecl = implicit_built_in_decls[BUILT_IN_FETCH_AND_NAND_N];
e60a6f7b 6140 inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
cf73e559 6141 warned_f_a_n = true;
6142 break;
6143
6144 case BUILT_IN_NAND_AND_FETCH_1:
6145 case BUILT_IN_NAND_AND_FETCH_2:
6146 case BUILT_IN_NAND_AND_FETCH_4:
6147 case BUILT_IN_NAND_AND_FETCH_8:
6148 case BUILT_IN_NAND_AND_FETCH_16:
6149
6150 if (warned_n_a_f)
6151 break;
6152
6153 fndecl = implicit_built_in_decls[BUILT_IN_NAND_AND_FETCH_N];
e60a6f7b 6154 inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
cf73e559 6155 warned_n_a_f = true;
6156 break;
6157
6158 default:
6159 gcc_unreachable ();
6160 }
6161 }
6162
b6a5fc45 6163 /* Expand the operands. */
c2f47e15 6164 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
b6a5fc45 6165
1db6d067 6166 val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
a8bb7059 6167 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
6168 of CONST_INTs, where we know the old_mode only from the call argument. */
6169 old_mode = GET_MODE (val);
6170 if (old_mode == VOIDmode)
6171 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
6172 val = convert_modes (mode, old_mode, val, 1);
b6a5fc45 6173
b6a5fc45 6174 if (ignore)
6175 return expand_sync_operation (mem, val, code);
6176 else
6177 return expand_sync_fetch_operation (mem, val, code, after, target);
6178}
6179
6180/* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
c2f47e15 6181 intrinsics. EXP is the CALL_EXPR. IS_BOOL is
b6a5fc45 6182 true if this is the boolean form. TARGET is a place for us to store the
6183 results; this is NOT optional if IS_BOOL is true. */
6184
6185static rtx
c2f47e15 6186expand_builtin_compare_and_swap (enum machine_mode mode, tree exp,
3e272de8 6187 bool is_bool, rtx target)
b6a5fc45 6188{
041e0215 6189 rtx old_val, new_val, mem;
a8bb7059 6190 enum machine_mode old_mode;
b6a5fc45 6191
6192 /* Expand the operands. */
c2f47e15 6193 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
b6a5fc45 6194
c2f47e15 6195
1db6d067 6196 old_val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX,
6197 mode, EXPAND_NORMAL);
a8bb7059 6198 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
6199 of CONST_INTs, where we know the old_mode only from the call argument. */
6200 old_mode = GET_MODE (old_val);
6201 if (old_mode == VOIDmode)
6202 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
6203 old_val = convert_modes (mode, old_mode, old_val, 1);
b6a5fc45 6204
1db6d067 6205 new_val = expand_expr (CALL_EXPR_ARG (exp, 2), NULL_RTX,
6206 mode, EXPAND_NORMAL);
a8bb7059 6207 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
6208 of CONST_INTs, where we know the old_mode only from the call argument. */
6209 old_mode = GET_MODE (new_val);
6210 if (old_mode == VOIDmode)
6211 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2)));
6212 new_val = convert_modes (mode, old_mode, new_val, 1);
b6a5fc45 6213
b6a5fc45 6214 if (is_bool)
6215 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
6216 else
6217 return expand_val_compare_and_swap (mem, old_val, new_val, target);
6218}
6219
6220/* Expand the __sync_lock_test_and_set intrinsic. Note that the most
6221 general form is actually an atomic exchange, and some targets only
6222 support a reduced form with the second argument being a constant 1.
c2f47e15 6223 EXP is the CALL_EXPR; TARGET is an optional place for us to store
6224 the results. */
b6a5fc45 6225
6226static rtx
c2f47e15 6227expand_builtin_lock_test_and_set (enum machine_mode mode, tree exp,
3e272de8 6228 rtx target)
b6a5fc45 6229{
041e0215 6230 rtx val, mem;
a8bb7059 6231 enum machine_mode old_mode;
b6a5fc45 6232
6233 /* Expand the operands. */
c2f47e15 6234 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
1db6d067 6235 val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
a8bb7059 6236 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
6237 of CONST_INTs, where we know the old_mode only from the call argument. */
6238 old_mode = GET_MODE (val);
6239 if (old_mode == VOIDmode)
6240 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
6241 val = convert_modes (mode, old_mode, val, 1);
b6a5fc45 6242
b6a5fc45 6243 return expand_sync_lock_test_and_set (mem, val, target);
6244}
6245
6246/* Expand the __sync_synchronize intrinsic. */
6247
6248static void
6249expand_builtin_synchronize (void)
6250{
16c9337c 6251 gimple x;
78f55ca8 6252 VEC (tree, gc) *v_clobbers;
b6a5fc45 6253
6254#ifdef HAVE_memory_barrier
6255 if (HAVE_memory_barrier)
6256 {
6257 emit_insn (gen_memory_barrier ());
6258 return;
6259 }
6260#endif
6261
047a7e40 6262 if (synchronize_libfunc != NULL_RTX)
6263 {
6264 emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
6265 return;
6266 }
6267
82e58396 6268 /* If no explicit memory barrier instruction is available, create an
6269 empty asm stmt with a memory clobber. */
78f55ca8 6270 v_clobbers = VEC_alloc (tree, gc, 1);
6271 VEC_quick_push (tree, v_clobbers,
6272 tree_cons (NULL, build_string (6, "memory"), NULL));
6273 x = gimple_build_asm_vec ("", NULL, NULL, v_clobbers, NULL);
16c9337c 6274 gimple_asm_set_volatile (x, true);
6275 expand_asm_stmt (x);
b6a5fc45 6276}
6277
c2f47e15 6278/* Expand the __sync_lock_release intrinsic. EXP is the CALL_EXPR. */
b6a5fc45 6279
6280static void
c2f47e15 6281expand_builtin_lock_release (enum machine_mode mode, tree exp)
b6a5fc45 6282{
b6a5fc45 6283 enum insn_code icode;
041e0215 6284 rtx mem, insn;
3e272de8 6285 rtx val = const0_rtx;
b6a5fc45 6286
6287 /* Expand the operands. */
c2f47e15 6288 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
b6a5fc45 6289
6290 /* If there is an explicit operation in the md file, use it. */
6291 icode = sync_lock_release[mode];
6292 if (icode != CODE_FOR_nothing)
6293 {
6294 if (!insn_data[icode].operand[1].predicate (val, mode))
6295 val = force_reg (mode, val);
6296
6297 insn = GEN_FCN (icode) (mem, val);
6298 if (insn)
6299 {
6300 emit_insn (insn);
6301 return;
6302 }
6303 }
6304
6305 /* Otherwise we can implement this operation by emitting a barrier
6306 followed by a store of zero. */
6307 expand_builtin_synchronize ();
6308 emit_move_insn (mem, val);
6309}
53800dbe 6310\f
6311/* Expand an expression EXP that calls a built-in function,
6312 with result going to TARGET if that's convenient
6313 (and in mode MODE if that's convenient).
6314 SUBTARGET may be used as the target for computing one of EXP's operands.
6315 IGNORE is nonzero if the value is to be ignored. */
6316
6317rtx
aecda0d6 6318expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
6319 int ignore)
53800dbe 6320{
c6e6ecb1 6321 tree fndecl = get_callee_fndecl (exp);
53800dbe 6322 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
efb070c8 6323 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
53800dbe 6324
8305149e 6325 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
883b2e73 6326 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
bf8e3599 6327
53800dbe 6328 /* When not optimizing, generate calls to library functions for a certain
6329 set of builtins. */
cd9ff771 6330 if (!optimize
b6a5fc45 6331 && !called_as_built_in (fndecl)
cd9ff771 6332 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
2c281b15 6333 && fcode != BUILT_IN_ALLOCA
6334 && fcode != BUILT_IN_FREE)
cd9ff771 6335 return expand_call (exp, target, ignore);
53800dbe 6336
8d6d7930 6337 /* The built-in function expanders test for target == const0_rtx
6338 to determine whether the function's result will be ignored. */
6339 if (ignore)
6340 target = const0_rtx;
6341
6342 /* If the result of a pure or const built-in function is ignored, and
6343 none of its arguments are volatile, we can avoid expanding the
6344 built-in call and just evaluate the arguments for side-effects. */
6345 if (target == const0_rtx
9c2a0c05 6346 && (DECL_PURE_P (fndecl) || TREE_READONLY (fndecl)))
8d6d7930 6347 {
6348 bool volatilep = false;
6349 tree arg;
c2f47e15 6350 call_expr_arg_iterator iter;
8d6d7930 6351
c2f47e15 6352 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
6353 if (TREE_THIS_VOLATILE (arg))
8d6d7930 6354 {
6355 volatilep = true;
6356 break;
6357 }
6358
6359 if (! volatilep)
6360 {
c2f47e15 6361 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
6362 expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL);
8d6d7930 6363 return const0_rtx;
6364 }
6365 }
6366
53800dbe 6367 switch (fcode)
6368 {
4f35b1fc 6369 CASE_FLT_FN (BUILT_IN_FABS):
c2f47e15 6370 target = expand_builtin_fabs (exp, target, subtarget);
78a74442 6371 if (target)
a0c938f0 6372 return target;
78a74442 6373 break;
6374
4f35b1fc 6375 CASE_FLT_FN (BUILT_IN_COPYSIGN):
c2f47e15 6376 target = expand_builtin_copysign (exp, target, subtarget);
270436f3 6377 if (target)
6378 return target;
6379 break;
6380
7d3f6cc7 6381 /* Just do a normal library call if we were unable to fold
6382 the values. */
4f35b1fc 6383 CASE_FLT_FN (BUILT_IN_CABS):
78a74442 6384 break;
53800dbe 6385
4f35b1fc 6386 CASE_FLT_FN (BUILT_IN_EXP):
6387 CASE_FLT_FN (BUILT_IN_EXP10):
6388 CASE_FLT_FN (BUILT_IN_POW10):
6389 CASE_FLT_FN (BUILT_IN_EXP2):
6390 CASE_FLT_FN (BUILT_IN_EXPM1):
6391 CASE_FLT_FN (BUILT_IN_LOGB):
4f35b1fc 6392 CASE_FLT_FN (BUILT_IN_LOG):
6393 CASE_FLT_FN (BUILT_IN_LOG10):
6394 CASE_FLT_FN (BUILT_IN_LOG2):
6395 CASE_FLT_FN (BUILT_IN_LOG1P):
6396 CASE_FLT_FN (BUILT_IN_TAN):
6397 CASE_FLT_FN (BUILT_IN_ASIN):
6398 CASE_FLT_FN (BUILT_IN_ACOS):
6399 CASE_FLT_FN (BUILT_IN_ATAN):
b3154a1f 6400 CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
7f3be425 6401 /* Treat these like sqrt only if unsafe math optimizations are allowed,
6402 because of possible accuracy problems. */
6403 if (! flag_unsafe_math_optimizations)
53800dbe 6404 break;
4f35b1fc 6405 CASE_FLT_FN (BUILT_IN_SQRT):
6406 CASE_FLT_FN (BUILT_IN_FLOOR):
6407 CASE_FLT_FN (BUILT_IN_CEIL):
6408 CASE_FLT_FN (BUILT_IN_TRUNC):
6409 CASE_FLT_FN (BUILT_IN_ROUND):
6410 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6411 CASE_FLT_FN (BUILT_IN_RINT):
53800dbe 6412 target = expand_builtin_mathfn (exp, target, subtarget);
6413 if (target)
6414 return target;
6415 break;
6416
a67a90e5 6417 CASE_FLT_FN (BUILT_IN_ILOGB):
6418 if (! flag_unsafe_math_optimizations)
6419 break;
69b779ea 6420 CASE_FLT_FN (BUILT_IN_ISINF):
cde061c1 6421 CASE_FLT_FN (BUILT_IN_FINITE):
6422 case BUILT_IN_ISFINITE:
8a1a9cb7 6423 case BUILT_IN_ISNORMAL:
a67a90e5 6424 target = expand_builtin_interclass_mathfn (exp, target, subtarget);
6425 if (target)
6426 return target;
6427 break;
6428
4f35b1fc 6429 CASE_FLT_FN (BUILT_IN_LCEIL):
6430 CASE_FLT_FN (BUILT_IN_LLCEIL):
6431 CASE_FLT_FN (BUILT_IN_LFLOOR):
6432 CASE_FLT_FN (BUILT_IN_LLFLOOR):
ff1b14e4 6433 target = expand_builtin_int_roundingfn (exp, target);
ad52b9b7 6434 if (target)
6435 return target;
6436 break;
6437
7d3afc77 6438 CASE_FLT_FN (BUILT_IN_LRINT):
6439 CASE_FLT_FN (BUILT_IN_LLRINT):
ef2f1a10 6440 CASE_FLT_FN (BUILT_IN_LROUND):
6441 CASE_FLT_FN (BUILT_IN_LLROUND):
ff1b14e4 6442 target = expand_builtin_int_roundingfn_2 (exp, target);
7d3afc77 6443 if (target)
6444 return target;
6445 break;
6446
4f35b1fc 6447 CASE_FLT_FN (BUILT_IN_POW):
f1b844c6 6448 target = expand_builtin_pow (exp, target, subtarget);
6449 if (target)
6450 return target;
6451 break;
6452
4f35b1fc 6453 CASE_FLT_FN (BUILT_IN_POWI):
757c219d 6454 target = expand_builtin_powi (exp, target, subtarget);
6455 if (target)
6456 return target;
6457 break;
6458
4f35b1fc 6459 CASE_FLT_FN (BUILT_IN_ATAN2):
6460 CASE_FLT_FN (BUILT_IN_LDEXP):
73a954a1 6461 CASE_FLT_FN (BUILT_IN_SCALB):
6462 CASE_FLT_FN (BUILT_IN_SCALBN):
6463 CASE_FLT_FN (BUILT_IN_SCALBLN):
0fd605a5 6464 if (! flag_unsafe_math_optimizations)
6465 break;
ef722005 6466
6467 CASE_FLT_FN (BUILT_IN_FMOD):
6468 CASE_FLT_FN (BUILT_IN_REMAINDER):
6469 CASE_FLT_FN (BUILT_IN_DREM):
0fd605a5 6470 target = expand_builtin_mathfn_2 (exp, target, subtarget);
6471 if (target)
6472 return target;
6473 break;
6474
d735c391 6475 CASE_FLT_FN (BUILT_IN_CEXPI):
6476 target = expand_builtin_cexpi (exp, target, subtarget);
6477 gcc_assert (target);
6478 return target;
6479
4f35b1fc 6480 CASE_FLT_FN (BUILT_IN_SIN):
6481 CASE_FLT_FN (BUILT_IN_COS):
6b43bae4 6482 if (! flag_unsafe_math_optimizations)
6483 break;
6484 target = expand_builtin_mathfn_3 (exp, target, subtarget);
6485 if (target)
6486 return target;
6487 break;
6488
c3147c1a 6489 CASE_FLT_FN (BUILT_IN_SINCOS):
6490 if (! flag_unsafe_math_optimizations)
6491 break;
6492 target = expand_builtin_sincos (exp);
6493 if (target)
6494 return target;
6495 break;
6496
53800dbe 6497 case BUILT_IN_APPLY_ARGS:
6498 return expand_builtin_apply_args ();
6499
6500 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
6501 FUNCTION with a copy of the parameters described by
6502 ARGUMENTS, and ARGSIZE. It returns a block of memory
6503 allocated on the stack into which is stored all the registers
6504 that might possibly be used for returning the result of a
6505 function. ARGUMENTS is the value returned by
6506 __builtin_apply_args. ARGSIZE is the number of bytes of
6507 arguments that must be copied. ??? How should this value be
6508 computed? We'll also need a safe worst case value for varargs
6509 functions. */
6510 case BUILT_IN_APPLY:
c2f47e15 6511 if (!validate_arglist (exp, POINTER_TYPE,
0eb671f7 6512 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
c2f47e15 6513 && !validate_arglist (exp, REFERENCE_TYPE,
0eb671f7 6514 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
53800dbe 6515 return const0_rtx;
6516 else
6517 {
53800dbe 6518 rtx ops[3];
6519
c2f47e15 6520 ops[0] = expand_normal (CALL_EXPR_ARG (exp, 0));
6521 ops[1] = expand_normal (CALL_EXPR_ARG (exp, 1));
6522 ops[2] = expand_normal (CALL_EXPR_ARG (exp, 2));
53800dbe 6523
6524 return expand_builtin_apply (ops[0], ops[1], ops[2]);
6525 }
6526
6527 /* __builtin_return (RESULT) causes the function to return the
6528 value described by RESULT. RESULT is address of the block of
6529 memory returned by __builtin_apply. */
6530 case BUILT_IN_RETURN:
c2f47e15 6531 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6532 expand_builtin_return (expand_normal (CALL_EXPR_ARG (exp, 0)));
53800dbe 6533 return const0_rtx;
6534
6535 case BUILT_IN_SAVEREGS:
a66c9326 6536 return expand_builtin_saveregs ();
53800dbe 6537
6538 case BUILT_IN_ARGS_INFO:
c2f47e15 6539 return expand_builtin_args_info (exp);
53800dbe 6540
48dc2227 6541 case BUILT_IN_VA_ARG_PACK:
6542 /* All valid uses of __builtin_va_arg_pack () are removed during
6543 inlining. */
b8c23db3 6544 error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp);
48dc2227 6545 return const0_rtx;
6546
4e1d7ea4 6547 case BUILT_IN_VA_ARG_PACK_LEN:
6548 /* All valid uses of __builtin_va_arg_pack_len () are removed during
6549 inlining. */
b8c23db3 6550 error ("%Kinvalid use of %<__builtin_va_arg_pack_len ()%>", exp);
4e1d7ea4 6551 return const0_rtx;
6552
53800dbe 6553 /* Return the address of the first anonymous stack arg. */
6554 case BUILT_IN_NEXT_ARG:
c2f47e15 6555 if (fold_builtin_next_arg (exp, false))
a0c938f0 6556 return const0_rtx;
79012a9d 6557 return expand_builtin_next_arg ();
53800dbe 6558
ac8fb6db 6559 case BUILT_IN_CLEAR_CACHE:
6560 target = expand_builtin___clear_cache (exp);
6561 if (target)
6562 return target;
6563 break;
6564
53800dbe 6565 case BUILT_IN_CLASSIFY_TYPE:
c2f47e15 6566 return expand_builtin_classify_type (exp);
53800dbe 6567
6568 case BUILT_IN_CONSTANT_P:
4ee9c684 6569 return const0_rtx;
53800dbe 6570
6571 case BUILT_IN_FRAME_ADDRESS:
6572 case BUILT_IN_RETURN_ADDRESS:
c2f47e15 6573 return expand_builtin_frame_address (fndecl, exp);
53800dbe 6574
6575 /* Returns the address of the area where the structure is returned.
6576 0 otherwise. */
6577 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
c2f47e15 6578 if (call_expr_nargs (exp) != 0
9342ee68 6579 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
e16ceb8e 6580 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
9342ee68 6581 return const0_rtx;
53800dbe 6582 else
9342ee68 6583 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
53800dbe 6584
6585 case BUILT_IN_ALLOCA:
c2f47e15 6586 target = expand_builtin_alloca (exp, target);
53800dbe 6587 if (target)
6588 return target;
6589 break;
6590
4ee9c684 6591 case BUILT_IN_STACK_SAVE:
6592 return expand_stack_save ();
6593
6594 case BUILT_IN_STACK_RESTORE:
c2f47e15 6595 expand_stack_restore (CALL_EXPR_ARG (exp, 0));
4ee9c684 6596 return const0_rtx;
6597
42791117 6598 case BUILT_IN_BSWAP32:
6599 case BUILT_IN_BSWAP64:
c2f47e15 6600 target = expand_builtin_bswap (exp, target, subtarget);
42791117 6601
6602 if (target)
6603 return target;
6604 break;
6605
4f35b1fc 6606 CASE_INT_FN (BUILT_IN_FFS):
5053259b 6607 case BUILT_IN_FFSIMAX:
c2f47e15 6608 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6609 subtarget, ffs_optab);
6a08d0ab 6610 if (target)
6611 return target;
6612 break;
6613
4f35b1fc 6614 CASE_INT_FN (BUILT_IN_CLZ):
5053259b 6615 case BUILT_IN_CLZIMAX:
c2f47e15 6616 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6617 subtarget, clz_optab);
6a08d0ab 6618 if (target)
6619 return target;
6620 break;
6621
4f35b1fc 6622 CASE_INT_FN (BUILT_IN_CTZ):
5053259b 6623 case BUILT_IN_CTZIMAX:
c2f47e15 6624 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6625 subtarget, ctz_optab);
6a08d0ab 6626 if (target)
6627 return target;
6628 break;
6629
4f35b1fc 6630 CASE_INT_FN (BUILT_IN_POPCOUNT):
5053259b 6631 case BUILT_IN_POPCOUNTIMAX:
c2f47e15 6632 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6633 subtarget, popcount_optab);
6a08d0ab 6634 if (target)
6635 return target;
6636 break;
6637
4f35b1fc 6638 CASE_INT_FN (BUILT_IN_PARITY):
5053259b 6639 case BUILT_IN_PARITYIMAX:
c2f47e15 6640 target = expand_builtin_unop (target_mode, exp, target,
efb070c8 6641 subtarget, parity_optab);
53800dbe 6642 if (target)
6643 return target;
6644 break;
6645
6646 case BUILT_IN_STRLEN:
c2f47e15 6647 target = expand_builtin_strlen (exp, target, target_mode);
53800dbe 6648 if (target)
6649 return target;
6650 break;
6651
6652 case BUILT_IN_STRCPY:
c2f47e15 6653 target = expand_builtin_strcpy (fndecl, exp, target, mode);
53800dbe 6654 if (target)
6655 return target;
6656 break;
bf8e3599 6657
ed09096d 6658 case BUILT_IN_STRNCPY:
8ff6a5cd 6659 target = expand_builtin_strncpy (exp, target, mode);
ed09096d 6660 if (target)
6661 return target;
6662 break;
bf8e3599 6663
3b824fa6 6664 case BUILT_IN_STPCPY:
dc369150 6665 target = expand_builtin_stpcpy (exp, target, mode);
3b824fa6 6666 if (target)
6667 return target;
6668 break;
6669
49f0327b 6670 case BUILT_IN_STRCAT:
c2f47e15 6671 target = expand_builtin_strcat (fndecl, exp, target, mode);
49f0327b 6672 if (target)
6673 return target;
6674 break;
bf8e3599 6675
49f0327b 6676 case BUILT_IN_STRNCAT:
c2f47e15 6677 target = expand_builtin_strncat (exp, target, mode);
49f0327b 6678 if (target)
6679 return target;
6680 break;
bf8e3599 6681
49f0327b 6682 case BUILT_IN_STRSPN:
c2f47e15 6683 target = expand_builtin_strspn (exp, target, mode);
49f0327b 6684 if (target)
6685 return target;
6686 break;
bf8e3599 6687
49f0327b 6688 case BUILT_IN_STRCSPN:
c2f47e15 6689 target = expand_builtin_strcspn (exp, target, mode);
49f0327b 6690 if (target)
6691 return target;
6692 break;
bf8e3599 6693
17f5ea87 6694 case BUILT_IN_STRSTR:
c2f47e15 6695 target = expand_builtin_strstr (exp, target, mode);
17f5ea87 6696 if (target)
6697 return target;
6698 break;
bf8e3599 6699
46f3a74a 6700 case BUILT_IN_STRPBRK:
c2f47e15 6701 target = expand_builtin_strpbrk (exp, target, mode);
46f3a74a 6702 if (target)
6703 return target;
6704 break;
bf8e3599 6705
398aae36 6706 case BUILT_IN_INDEX:
83d79705 6707 case BUILT_IN_STRCHR:
c2f47e15 6708 target = expand_builtin_strchr (exp, target, mode);
83d79705 6709 if (target)
6710 return target;
6711 break;
6712
398aae36 6713 case BUILT_IN_RINDEX:
83d79705 6714 case BUILT_IN_STRRCHR:
c2f47e15 6715 target = expand_builtin_strrchr (exp, target, mode);
83d79705 6716 if (target)
6717 return target;
6718 break;
6719
53800dbe 6720 case BUILT_IN_MEMCPY:
5a0de151 6721 target = expand_builtin_memcpy (exp, target, mode);
3b824fa6 6722 if (target)
6723 return target;
6724 break;
6725
6726 case BUILT_IN_MEMPCPY:
c2f47e15 6727 target = expand_builtin_mempcpy (exp, target, mode);
53800dbe 6728 if (target)
6729 return target;
6730 break;
6731
c4950093 6732 case BUILT_IN_MEMMOVE:
c2f47e15 6733 target = expand_builtin_memmove (exp, target, mode, ignore);
c4950093 6734 if (target)
6735 return target;
6736 break;
6737
6738 case BUILT_IN_BCOPY:
c2f47e15 6739 target = expand_builtin_bcopy (exp, ignore);
c4950093 6740 if (target)
6741 return target;
6742 break;
6743
53800dbe 6744 case BUILT_IN_MEMSET:
c2f47e15 6745 target = expand_builtin_memset (exp, target, mode);
53800dbe 6746 if (target)
6747 return target;
6748 break;
6749
ffc83088 6750 case BUILT_IN_BZERO:
0b25db21 6751 target = expand_builtin_bzero (exp);
ffc83088 6752 if (target)
6753 return target;
6754 break;
6755
53800dbe 6756 case BUILT_IN_STRCMP:
83d79705 6757 target = expand_builtin_strcmp (exp, target, mode);
53800dbe 6758 if (target)
6759 return target;
6760 break;
6761
ed09096d 6762 case BUILT_IN_STRNCMP:
6763 target = expand_builtin_strncmp (exp, target, mode);
6764 if (target)
6765 return target;
6766 break;
6767
7959b13b 6768 case BUILT_IN_MEMCHR:
6769 target = expand_builtin_memchr (exp, target, mode);
6770 if (target)
6771 return target;
6772 break;
6773
071f1696 6774 case BUILT_IN_BCMP:
53800dbe 6775 case BUILT_IN_MEMCMP:
c2f47e15 6776 target = expand_builtin_memcmp (exp, target, mode);
53800dbe 6777 if (target)
6778 return target;
6779 break;
53800dbe 6780
6781 case BUILT_IN_SETJMP:
2c8a1497 6782 /* This should have been lowered to the builtins below. */
6783 gcc_unreachable ();
6784
6785 case BUILT_IN_SETJMP_SETUP:
6786 /* __builtin_setjmp_setup is passed a pointer to an array of five words
6787 and the receiver label. */
c2f47e15 6788 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2c8a1497 6789 {
c2f47e15 6790 rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
2c8a1497 6791 VOIDmode, EXPAND_NORMAL);
c2f47e15 6792 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 1), 0);
2c8a1497 6793 rtx label_r = label_rtx (label);
6794
6795 /* This is copied from the handling of non-local gotos. */
6796 expand_builtin_setjmp_setup (buf_addr, label_r);
6797 nonlocal_goto_handler_labels
6798 = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6799 nonlocal_goto_handler_labels);
6800 /* ??? Do not let expand_label treat us as such since we would
6801 not want to be both on the list of non-local labels and on
6802 the list of forced labels. */
6803 FORCED_LABEL (label) = 0;
6804 return const0_rtx;
6805 }
6806 break;
6807
6808 case BUILT_IN_SETJMP_DISPATCHER:
6809 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */
c2f47e15 6810 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
2c8a1497 6811 {
c2f47e15 6812 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
2c8a1497 6813 rtx label_r = label_rtx (label);
6814
6815 /* Remove the dispatcher label from the list of non-local labels
6816 since the receiver labels have been added to it above. */
6817 remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6818 return const0_rtx;
6819 }
6820 break;
6821
6822 case BUILT_IN_SETJMP_RECEIVER:
6823 /* __builtin_setjmp_receiver is passed the receiver label. */
c2f47e15 6824 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
2c8a1497 6825 {
c2f47e15 6826 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
2c8a1497 6827 rtx label_r = label_rtx (label);
6828
6829 expand_builtin_setjmp_receiver (label_r);
6830 return const0_rtx;
6831 }
6b7f6858 6832 break;
53800dbe 6833
6834 /* __builtin_longjmp is passed a pointer to an array of five words.
6835 It's similar to the C library longjmp function but works with
6836 __builtin_setjmp above. */
6837 case BUILT_IN_LONGJMP:
c2f47e15 6838 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
53800dbe 6839 {
c2f47e15 6840 rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
8ec3c5c2 6841 VOIDmode, EXPAND_NORMAL);
c2f47e15 6842 rtx value = expand_normal (CALL_EXPR_ARG (exp, 1));
53800dbe 6843
6844 if (value != const1_rtx)
6845 {
1e5fcbe2 6846 error ("%<__builtin_longjmp%> second argument must be 1");
53800dbe 6847 return const0_rtx;
6848 }
6849
6850 expand_builtin_longjmp (buf_addr, value);
6851 return const0_rtx;
6852 }
2c8a1497 6853 break;
53800dbe 6854
4ee9c684 6855 case BUILT_IN_NONLOCAL_GOTO:
c2f47e15 6856 target = expand_builtin_nonlocal_goto (exp);
4ee9c684 6857 if (target)
6858 return target;
6859 break;
6860
843d08a9 6861 /* This updates the setjmp buffer that is its argument with the value
6862 of the current stack pointer. */
6863 case BUILT_IN_UPDATE_SETJMP_BUF:
c2f47e15 6864 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
843d08a9 6865 {
6866 rtx buf_addr
c2f47e15 6867 = expand_normal (CALL_EXPR_ARG (exp, 0));
843d08a9 6868
6869 expand_builtin_update_setjmp_buf (buf_addr);
6870 return const0_rtx;
6871 }
6872 break;
6873
53800dbe 6874 case BUILT_IN_TRAP:
a0ef1725 6875 expand_builtin_trap ();
53800dbe 6876 return const0_rtx;
6877
d2b48f0c 6878 case BUILT_IN_UNREACHABLE:
6879 expand_builtin_unreachable ();
6880 return const0_rtx;
6881
19bf118a 6882 case BUILT_IN_PRINTF:
0b25db21 6883 target = expand_builtin_printf (exp, target, mode, false);
19bf118a 6884 if (target)
6885 return target;
6886 break;
6887
6888 case BUILT_IN_PRINTF_UNLOCKED:
0b25db21 6889 target = expand_builtin_printf (exp, target, mode, true);
19bf118a 6890 if (target)
6891 return target;
6892 break;
6893
df94cd3b 6894 case BUILT_IN_FPUTS:
c2f47e15 6895 target = expand_builtin_fputs (exp, target, false);
c013a46e 6896 if (target)
6897 return target;
6898 break;
6899 case BUILT_IN_FPUTS_UNLOCKED:
c2f47e15 6900 target = expand_builtin_fputs (exp, target, true);
19bf118a 6901 if (target)
6902 return target;
6903 break;
6904
6905 case BUILT_IN_FPRINTF:
0b25db21 6906 target = expand_builtin_fprintf (exp, target, mode, false);
19bf118a 6907 if (target)
6908 return target;
6909 break;
6910
6911 case BUILT_IN_FPRINTF_UNLOCKED:
0b25db21 6912 target = expand_builtin_fprintf (exp, target, mode, true);
df94cd3b 6913 if (target)
6914 return target;
6915 break;
bf8e3599 6916
6411575e 6917 case BUILT_IN_SPRINTF:
c2f47e15 6918 target = expand_builtin_sprintf (exp, target, mode);
6411575e 6919 if (target)
6920 return target;
6921 break;
6922
4f35b1fc 6923 CASE_FLT_FN (BUILT_IN_SIGNBIT):
004e23c4 6924 case BUILT_IN_SIGNBITD32:
6925 case BUILT_IN_SIGNBITD64:
6926 case BUILT_IN_SIGNBITD128:
27f261ef 6927 target = expand_builtin_signbit (exp, target);
6928 if (target)
6929 return target;
6930 break;
6931
53800dbe 6932 /* Various hooks for the DWARF 2 __throw routine. */
6933 case BUILT_IN_UNWIND_INIT:
6934 expand_builtin_unwind_init ();
6935 return const0_rtx;
6936 case BUILT_IN_DWARF_CFA:
6937 return virtual_cfa_rtx;
6938#ifdef DWARF2_UNWIND_INFO
f8f023a5 6939 case BUILT_IN_DWARF_SP_COLUMN:
6940 return expand_builtin_dwarf_sp_column ();
695e919b 6941 case BUILT_IN_INIT_DWARF_REG_SIZES:
c2f47e15 6942 expand_builtin_init_dwarf_reg_sizes (CALL_EXPR_ARG (exp, 0));
695e919b 6943 return const0_rtx;
53800dbe 6944#endif
6945 case BUILT_IN_FROB_RETURN_ADDR:
c2f47e15 6946 return expand_builtin_frob_return_addr (CALL_EXPR_ARG (exp, 0));
53800dbe 6947 case BUILT_IN_EXTRACT_RETURN_ADDR:
c2f47e15 6948 return expand_builtin_extract_return_addr (CALL_EXPR_ARG (exp, 0));
53800dbe 6949 case BUILT_IN_EH_RETURN:
c2f47e15 6950 expand_builtin_eh_return (CALL_EXPR_ARG (exp, 0),
6951 CALL_EXPR_ARG (exp, 1));
53800dbe 6952 return const0_rtx;
df4b504c 6953#ifdef EH_RETURN_DATA_REGNO
6954 case BUILT_IN_EH_RETURN_DATA_REGNO:
c2f47e15 6955 return expand_builtin_eh_return_data_regno (exp);
df4b504c 6956#endif
26093bf4 6957 case BUILT_IN_EXTEND_POINTER:
c2f47e15 6958 return expand_builtin_extend_pointer (CALL_EXPR_ARG (exp, 0));
e38def9c 6959 case BUILT_IN_EH_POINTER:
6960 return expand_builtin_eh_pointer (exp);
6961 case BUILT_IN_EH_FILTER:
6962 return expand_builtin_eh_filter (exp);
6963 case BUILT_IN_EH_COPY_VALUES:
6964 return expand_builtin_eh_copy_values (exp);
26093bf4 6965
7ccc713a 6966 case BUILT_IN_VA_START:
c2f47e15 6967 return expand_builtin_va_start (exp);
a66c9326 6968 case BUILT_IN_VA_END:
c2f47e15 6969 return expand_builtin_va_end (exp);
a66c9326 6970 case BUILT_IN_VA_COPY:
c2f47e15 6971 return expand_builtin_va_copy (exp);
89cfe6e5 6972 case BUILT_IN_EXPECT:
c2f47e15 6973 return expand_builtin_expect (exp, target);
5e3608d8 6974 case BUILT_IN_PREFETCH:
c2f47e15 6975 expand_builtin_prefetch (exp);
5e3608d8 6976 return const0_rtx;
6977
4ee9c684 6978 case BUILT_IN_PROFILE_FUNC_ENTER:
6979 return expand_builtin_profile_func (false);
6980 case BUILT_IN_PROFILE_FUNC_EXIT:
6981 return expand_builtin_profile_func (true);
6982
6983 case BUILT_IN_INIT_TRAMPOLINE:
c2f47e15 6984 return expand_builtin_init_trampoline (exp);
4ee9c684 6985 case BUILT_IN_ADJUST_TRAMPOLINE:
c2f47e15 6986 return expand_builtin_adjust_trampoline (exp);
4ee9c684 6987
73673831 6988 case BUILT_IN_FORK:
6989 case BUILT_IN_EXECL:
6990 case BUILT_IN_EXECV:
6991 case BUILT_IN_EXECLP:
6992 case BUILT_IN_EXECLE:
6993 case BUILT_IN_EXECVP:
6994 case BUILT_IN_EXECVE:
c2f47e15 6995 target = expand_builtin_fork_or_exec (fndecl, exp, target, ignore);
73673831 6996 if (target)
6997 return target;
6998 break;
53800dbe 6999
b6a5fc45 7000 case BUILT_IN_FETCH_AND_ADD_1:
7001 case BUILT_IN_FETCH_AND_ADD_2:
7002 case BUILT_IN_FETCH_AND_ADD_4:
7003 case BUILT_IN_FETCH_AND_ADD_8:
27213ba3 7004 case BUILT_IN_FETCH_AND_ADD_16:
3e272de8 7005 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
c2f47e15 7006 target = expand_builtin_sync_operation (mode, exp, PLUS,
b6a5fc45 7007 false, target, ignore);
7008 if (target)
7009 return target;
7010 break;
7011
7012 case BUILT_IN_FETCH_AND_SUB_1:
7013 case BUILT_IN_FETCH_AND_SUB_2:
7014 case BUILT_IN_FETCH_AND_SUB_4:
7015 case BUILT_IN_FETCH_AND_SUB_8:
27213ba3 7016 case BUILT_IN_FETCH_AND_SUB_16:
3e272de8 7017 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
c2f47e15 7018 target = expand_builtin_sync_operation (mode, exp, MINUS,
b6a5fc45 7019 false, target, ignore);
7020 if (target)
7021 return target;
7022 break;
7023
7024 case BUILT_IN_FETCH_AND_OR_1:
7025 case BUILT_IN_FETCH_AND_OR_2:
7026 case BUILT_IN_FETCH_AND_OR_4:
7027 case BUILT_IN_FETCH_AND_OR_8:
27213ba3 7028 case BUILT_IN_FETCH_AND_OR_16:
3e272de8 7029 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
c2f47e15 7030 target = expand_builtin_sync_operation (mode, exp, IOR,
b6a5fc45 7031 false, target, ignore);
7032 if (target)
7033 return target;
7034 break;
7035
7036 case BUILT_IN_FETCH_AND_AND_1:
7037 case BUILT_IN_FETCH_AND_AND_2:
7038 case BUILT_IN_FETCH_AND_AND_4:
7039 case BUILT_IN_FETCH_AND_AND_8:
27213ba3 7040 case BUILT_IN_FETCH_AND_AND_16:
3e272de8 7041 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
c2f47e15 7042 target = expand_builtin_sync_operation (mode, exp, AND,
b6a5fc45 7043 false, target, ignore);
7044 if (target)
7045 return target;
7046 break;
7047
7048 case BUILT_IN_FETCH_AND_XOR_1:
7049 case BUILT_IN_FETCH_AND_XOR_2:
7050 case BUILT_IN_FETCH_AND_XOR_4:
7051 case BUILT_IN_FETCH_AND_XOR_8:
27213ba3 7052 case BUILT_IN_FETCH_AND_XOR_16:
3e272de8 7053 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
c2f47e15 7054 target = expand_builtin_sync_operation (mode, exp, XOR,
b6a5fc45 7055 false, target, ignore);
7056 if (target)
7057 return target;
7058 break;
7059
7060 case BUILT_IN_FETCH_AND_NAND_1:
7061 case BUILT_IN_FETCH_AND_NAND_2:
7062 case BUILT_IN_FETCH_AND_NAND_4:
7063 case BUILT_IN_FETCH_AND_NAND_8:
27213ba3 7064 case BUILT_IN_FETCH_AND_NAND_16:
3e272de8 7065 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
c2f47e15 7066 target = expand_builtin_sync_operation (mode, exp, NOT,
b6a5fc45 7067 false, target, ignore);
7068 if (target)
7069 return target;
7070 break;
7071
7072 case BUILT_IN_ADD_AND_FETCH_1:
7073 case BUILT_IN_ADD_AND_FETCH_2:
7074 case BUILT_IN_ADD_AND_FETCH_4:
7075 case BUILT_IN_ADD_AND_FETCH_8:
27213ba3 7076 case BUILT_IN_ADD_AND_FETCH_16:
3e272de8 7077 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
c2f47e15 7078 target = expand_builtin_sync_operation (mode, exp, PLUS,
b6a5fc45 7079 true, target, ignore);
7080 if (target)
7081 return target;
7082 break;
7083
7084 case BUILT_IN_SUB_AND_FETCH_1:
7085 case BUILT_IN_SUB_AND_FETCH_2:
7086 case BUILT_IN_SUB_AND_FETCH_4:
7087 case BUILT_IN_SUB_AND_FETCH_8:
27213ba3 7088 case BUILT_IN_SUB_AND_FETCH_16:
3e272de8 7089 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
c2f47e15 7090 target = expand_builtin_sync_operation (mode, exp, MINUS,
b6a5fc45 7091 true, target, ignore);
7092 if (target)
7093 return target;
7094 break;
7095
7096 case BUILT_IN_OR_AND_FETCH_1:
7097 case BUILT_IN_OR_AND_FETCH_2:
7098 case BUILT_IN_OR_AND_FETCH_4:
7099 case BUILT_IN_OR_AND_FETCH_8:
27213ba3 7100 case BUILT_IN_OR_AND_FETCH_16:
3e272de8 7101 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
c2f47e15 7102 target = expand_builtin_sync_operation (mode, exp, IOR,
b6a5fc45 7103 true, target, ignore);
7104 if (target)
7105 return target;
7106 break;
7107
7108 case BUILT_IN_AND_AND_FETCH_1:
7109 case BUILT_IN_AND_AND_FETCH_2:
7110 case BUILT_IN_AND_AND_FETCH_4:
7111 case BUILT_IN_AND_AND_FETCH_8:
27213ba3 7112 case BUILT_IN_AND_AND_FETCH_16:
3e272de8 7113 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
c2f47e15 7114 target = expand_builtin_sync_operation (mode, exp, AND,
b6a5fc45 7115 true, target, ignore);
7116 if (target)
7117 return target;
7118 break;
7119
7120 case BUILT_IN_XOR_AND_FETCH_1:
7121 case BUILT_IN_XOR_AND_FETCH_2:
7122 case BUILT_IN_XOR_AND_FETCH_4:
7123 case BUILT_IN_XOR_AND_FETCH_8:
27213ba3 7124 case BUILT_IN_XOR_AND_FETCH_16:
3e272de8 7125 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
c2f47e15 7126 target = expand_builtin_sync_operation (mode, exp, XOR,
b6a5fc45 7127 true, target, ignore);
7128 if (target)
7129 return target;
7130 break;
7131
7132 case BUILT_IN_NAND_AND_FETCH_1:
7133 case BUILT_IN_NAND_AND_FETCH_2:
7134 case BUILT_IN_NAND_AND_FETCH_4:
7135 case BUILT_IN_NAND_AND_FETCH_8:
27213ba3 7136 case BUILT_IN_NAND_AND_FETCH_16:
3e272de8 7137 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
c2f47e15 7138 target = expand_builtin_sync_operation (mode, exp, NOT,
b6a5fc45 7139 true, target, ignore);
7140 if (target)
7141 return target;
7142 break;
7143
7144 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
7145 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
7146 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
7147 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
27213ba3 7148 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
a601d32a 7149 if (mode == VOIDmode)
7150 mode = TYPE_MODE (boolean_type_node);
b6a5fc45 7151 if (!target || !register_operand (target, mode))
7152 target = gen_reg_rtx (mode);
3e272de8 7153
7154 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
c2f47e15 7155 target = expand_builtin_compare_and_swap (mode, exp, true, target);
b6a5fc45 7156 if (target)
7157 return target;
7158 break;
7159
7160 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
7161 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
7162 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
7163 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
27213ba3 7164 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
3e272de8 7165 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
c2f47e15 7166 target = expand_builtin_compare_and_swap (mode, exp, false, target);
b6a5fc45 7167 if (target)
7168 return target;
7169 break;
7170
7171 case BUILT_IN_LOCK_TEST_AND_SET_1:
7172 case BUILT_IN_LOCK_TEST_AND_SET_2:
7173 case BUILT_IN_LOCK_TEST_AND_SET_4:
7174 case BUILT_IN_LOCK_TEST_AND_SET_8:
27213ba3 7175 case BUILT_IN_LOCK_TEST_AND_SET_16:
3e272de8 7176 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
c2f47e15 7177 target = expand_builtin_lock_test_and_set (mode, exp, target);
b6a5fc45 7178 if (target)
7179 return target;
7180 break;
7181
7182 case BUILT_IN_LOCK_RELEASE_1:
7183 case BUILT_IN_LOCK_RELEASE_2:
7184 case BUILT_IN_LOCK_RELEASE_4:
7185 case BUILT_IN_LOCK_RELEASE_8:
27213ba3 7186 case BUILT_IN_LOCK_RELEASE_16:
3e272de8 7187 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
c2f47e15 7188 expand_builtin_lock_release (mode, exp);
b6a5fc45 7189 return const0_rtx;
7190
7191 case BUILT_IN_SYNCHRONIZE:
7192 expand_builtin_synchronize ();
7193 return const0_rtx;
7194
0a39fd54 7195 case BUILT_IN_OBJECT_SIZE:
7196 return expand_builtin_object_size (exp);
7197
7198 case BUILT_IN_MEMCPY_CHK:
7199 case BUILT_IN_MEMPCPY_CHK:
7200 case BUILT_IN_MEMMOVE_CHK:
7201 case BUILT_IN_MEMSET_CHK:
7202 target = expand_builtin_memory_chk (exp, target, mode, fcode);
7203 if (target)
7204 return target;
7205 break;
7206
7207 case BUILT_IN_STRCPY_CHK:
7208 case BUILT_IN_STPCPY_CHK:
7209 case BUILT_IN_STRNCPY_CHK:
7210 case BUILT_IN_STRCAT_CHK:
b356dfef 7211 case BUILT_IN_STRNCAT_CHK:
0a39fd54 7212 case BUILT_IN_SNPRINTF_CHK:
7213 case BUILT_IN_VSNPRINTF_CHK:
7214 maybe_emit_chk_warning (exp, fcode);
7215 break;
7216
7217 case BUILT_IN_SPRINTF_CHK:
7218 case BUILT_IN_VSPRINTF_CHK:
7219 maybe_emit_sprintf_chk_warning (exp, fcode);
7220 break;
7221
2c281b15 7222 case BUILT_IN_FREE:
7223 maybe_emit_free_warning (exp);
7224 break;
7225
92482ee0 7226 default: /* just do library call, if unknown builtin */
146c1b4f 7227 break;
53800dbe 7228 }
7229
7230 /* The switch statement above can drop through to cause the function
7231 to be called normally. */
7232 return expand_call (exp, target, ignore);
7233}
650e4c94 7234
805e22b2 7235/* Determine whether a tree node represents a call to a built-in
52203a9d 7236 function. If the tree T is a call to a built-in function with
7237 the right number of arguments of the appropriate types, return
7238 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
7239 Otherwise the return value is END_BUILTINS. */
aecda0d6 7240
805e22b2 7241enum built_in_function
b7bf20db 7242builtin_mathfn_code (const_tree t)
805e22b2 7243{
b7bf20db 7244 const_tree fndecl, arg, parmlist;
7245 const_tree argtype, parmtype;
7246 const_call_expr_arg_iterator iter;
805e22b2 7247
7248 if (TREE_CODE (t) != CALL_EXPR
c2f47e15 7249 || TREE_CODE (CALL_EXPR_FN (t)) != ADDR_EXPR)
805e22b2 7250 return END_BUILTINS;
7251
c6e6ecb1 7252 fndecl = get_callee_fndecl (t);
7253 if (fndecl == NULL_TREE
52203a9d 7254 || TREE_CODE (fndecl) != FUNCTION_DECL
805e22b2 7255 || ! DECL_BUILT_IN (fndecl)
7256 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7257 return END_BUILTINS;
7258
52203a9d 7259 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
b7bf20db 7260 init_const_call_expr_arg_iterator (t, &iter);
52203a9d 7261 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
e9f80ff5 7262 {
52203a9d 7263 /* If a function doesn't take a variable number of arguments,
7264 the last element in the list will have type `void'. */
7265 parmtype = TREE_VALUE (parmlist);
7266 if (VOID_TYPE_P (parmtype))
7267 {
b7bf20db 7268 if (more_const_call_expr_args_p (&iter))
52203a9d 7269 return END_BUILTINS;
7270 return DECL_FUNCTION_CODE (fndecl);
7271 }
7272
b7bf20db 7273 if (! more_const_call_expr_args_p (&iter))
e9f80ff5 7274 return END_BUILTINS;
c2f47e15 7275
b7bf20db 7276 arg = next_const_call_expr_arg (&iter);
c2f47e15 7277 argtype = TREE_TYPE (arg);
52203a9d 7278
7279 if (SCALAR_FLOAT_TYPE_P (parmtype))
7280 {
7281 if (! SCALAR_FLOAT_TYPE_P (argtype))
7282 return END_BUILTINS;
7283 }
7284 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
7285 {
7286 if (! COMPLEX_FLOAT_TYPE_P (argtype))
7287 return END_BUILTINS;
7288 }
7289 else if (POINTER_TYPE_P (parmtype))
7290 {
7291 if (! POINTER_TYPE_P (argtype))
7292 return END_BUILTINS;
7293 }
7294 else if (INTEGRAL_TYPE_P (parmtype))
7295 {
7296 if (! INTEGRAL_TYPE_P (argtype))
7297 return END_BUILTINS;
7298 }
7299 else
e9f80ff5 7300 return END_BUILTINS;
e9f80ff5 7301 }
7302
52203a9d 7303 /* Variable-length argument list. */
805e22b2 7304 return DECL_FUNCTION_CODE (fndecl);
7305}
7306
c2f47e15 7307/* Fold a call to __builtin_constant_p, if we know its argument ARG will
7308 evaluate to a constant. */
650e4c94 7309
7310static tree
c2f47e15 7311fold_builtin_constant_p (tree arg)
650e4c94 7312{
650e4c94 7313 /* We return 1 for a numeric type that's known to be a constant
7314 value at compile-time or for an aggregate type that's a
7315 literal constant. */
c2f47e15 7316 STRIP_NOPS (arg);
650e4c94 7317
7318 /* If we know this is a constant, emit the constant of one. */
c2f47e15 7319 if (CONSTANT_CLASS_P (arg)
7320 || (TREE_CODE (arg) == CONSTRUCTOR
7321 && TREE_CONSTANT (arg)))
650e4c94 7322 return integer_one_node;
c2f47e15 7323 if (TREE_CODE (arg) == ADDR_EXPR)
adcfa3a3 7324 {
c2f47e15 7325 tree op = TREE_OPERAND (arg, 0);
adcfa3a3 7326 if (TREE_CODE (op) == STRING_CST
7327 || (TREE_CODE (op) == ARRAY_REF
7328 && integer_zerop (TREE_OPERAND (op, 1))
7329 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
7330 return integer_one_node;
7331 }
650e4c94 7332
1fb4300c 7333 /* If this expression has side effects, show we don't know it to be a
7334 constant. Likewise if it's a pointer or aggregate type since in
7335 those case we only want literals, since those are only optimized
f97c71a1 7336 when generating RTL, not later.
7337 And finally, if we are compiling an initializer, not code, we
7338 need to return a definite result now; there's not going to be any
7339 more optimization done. */
c2f47e15 7340 if (TREE_SIDE_EFFECTS (arg)
7341 || AGGREGATE_TYPE_P (TREE_TYPE (arg))
7342 || POINTER_TYPE_P (TREE_TYPE (arg))
47be647d 7343 || cfun == 0
7344 || folding_initializer)
650e4c94 7345 return integer_zero_node;
7346
c2f47e15 7347 return NULL_TREE;
650e4c94 7348}
7349
76f5a783 7350/* Create builtin_expect with PRED and EXPECTED as its arguments and
7351 return it as a truthvalue. */
4ee9c684 7352
7353static tree
389dd41b 7354build_builtin_expect_predicate (location_t loc, tree pred, tree expected)
4ee9c684 7355{
76f5a783 7356 tree fn, arg_types, pred_type, expected_type, call_expr, ret_type;
4ee9c684 7357
76f5a783 7358 fn = built_in_decls[BUILT_IN_EXPECT];
7359 arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
7360 ret_type = TREE_TYPE (TREE_TYPE (fn));
7361 pred_type = TREE_VALUE (arg_types);
7362 expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
7363
389dd41b 7364 pred = fold_convert_loc (loc, pred_type, pred);
7365 expected = fold_convert_loc (loc, expected_type, expected);
7366 call_expr = build_call_expr_loc (loc, fn, 2, pred, expected);
76f5a783 7367
7368 return build2 (NE_EXPR, TREE_TYPE (pred), call_expr,
7369 build_int_cst (ret_type, 0));
7370}
7371
7372/* Fold a call to builtin_expect with arguments ARG0 and ARG1. Return
7373 NULL_TREE if no simplification is possible. */
7374
7375static tree
389dd41b 7376fold_builtin_expect (location_t loc, tree arg0, tree arg1)
76f5a783 7377{
7378 tree inner, fndecl;
7379 enum tree_code code;
7380
7381 /* If this is a builtin_expect within a builtin_expect keep the
7382 inner one. See through a comparison against a constant. It
7383 might have been added to create a thruthvalue. */
7384 inner = arg0;
7385 if (COMPARISON_CLASS_P (inner)
7386 && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST)
7387 inner = TREE_OPERAND (inner, 0);
7388
7389 if (TREE_CODE (inner) == CALL_EXPR
7390 && (fndecl = get_callee_fndecl (inner))
7391 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
7392 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT)
7393 return arg0;
7394
7395 /* Distribute the expected value over short-circuiting operators.
7396 See through the cast from truthvalue_type_node to long. */
7397 inner = arg0;
7398 while (TREE_CODE (inner) == NOP_EXPR
7399 && INTEGRAL_TYPE_P (TREE_TYPE (inner))
7400 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (inner, 0))))
7401 inner = TREE_OPERAND (inner, 0);
7402
7403 code = TREE_CODE (inner);
7404 if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
7405 {
7406 tree op0 = TREE_OPERAND (inner, 0);
7407 tree op1 = TREE_OPERAND (inner, 1);
7408
389dd41b 7409 op0 = build_builtin_expect_predicate (loc, op0, arg1);
7410 op1 = build_builtin_expect_predicate (loc, op1, arg1);
76f5a783 7411 inner = build2 (code, TREE_TYPE (inner), op0, op1);
7412
389dd41b 7413 return fold_convert_loc (loc, TREE_TYPE (arg0), inner);
76f5a783 7414 }
7415
7416 /* If the argument isn't invariant then there's nothing else we can do. */
c7d4e749 7417 if (!TREE_CONSTANT (arg0))
c2f47e15 7418 return NULL_TREE;
4ee9c684 7419
76f5a783 7420 /* If we expect that a comparison against the argument will fold to
7421 a constant return the constant. In practice, this means a true
7422 constant or the address of a non-weak symbol. */
7423 inner = arg0;
4ee9c684 7424 STRIP_NOPS (inner);
7425 if (TREE_CODE (inner) == ADDR_EXPR)
7426 {
7427 do
7428 {
7429 inner = TREE_OPERAND (inner, 0);
7430 }
7431 while (TREE_CODE (inner) == COMPONENT_REF
7432 || TREE_CODE (inner) == ARRAY_REF);
062b4460 7433 if ((TREE_CODE (inner) == VAR_DECL
7434 || TREE_CODE (inner) == FUNCTION_DECL)
7435 && DECL_WEAK (inner))
c2f47e15 7436 return NULL_TREE;
4ee9c684 7437 }
7438
76f5a783 7439 /* Otherwise, ARG0 already has the proper type for the return value. */
7440 return arg0;
4ee9c684 7441}
7442
c2f47e15 7443/* Fold a call to __builtin_classify_type with argument ARG. */
27d0c333 7444
539a3a92 7445static tree
c2f47e15 7446fold_builtin_classify_type (tree arg)
539a3a92 7447{
c2f47e15 7448 if (arg == 0)
7016c612 7449 return build_int_cst (NULL_TREE, no_type_class);
539a3a92 7450
c2f47e15 7451 return build_int_cst (NULL_TREE, type_to_class (TREE_TYPE (arg)));
539a3a92 7452}
7453
c2f47e15 7454/* Fold a call to __builtin_strlen with argument ARG. */
e6e27594 7455
7456static tree
389dd41b 7457fold_builtin_strlen (location_t loc, tree arg)
e6e27594 7458{
c2f47e15 7459 if (!validate_arg (arg, POINTER_TYPE))
e6e27594 7460 return NULL_TREE;
7461 else
7462 {
c2f47e15 7463 tree len = c_strlen (arg, 0);
e6e27594 7464
7465 if (len)
7466 {
7467 /* Convert from the internal "sizetype" type to "size_t". */
7468 if (size_type_node)
389dd41b 7469 len = fold_convert_loc (loc, size_type_node, len);
e6e27594 7470 return len;
7471 }
7472
7473 return NULL_TREE;
7474 }
7475}
7476
92c43e3c 7477/* Fold a call to __builtin_inf or __builtin_huge_val. */
7478
7479static tree
389dd41b 7480fold_builtin_inf (location_t loc, tree type, int warn)
92c43e3c 7481{
aa870c1b 7482 REAL_VALUE_TYPE real;
7483
40f4dbd5 7484 /* __builtin_inff is intended to be usable to define INFINITY on all
7485 targets. If an infinity is not available, INFINITY expands "to a
7486 positive constant of type float that overflows at translation
7487 time", footnote "In this case, using INFINITY will violate the
7488 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
7489 Thus we pedwarn to ensure this constraint violation is
7490 diagnosed. */
92c43e3c 7491 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
389dd41b 7492 pedwarn (loc, 0, "target format does not support infinity");
92c43e3c 7493
aa870c1b 7494 real_inf (&real);
7495 return build_real (type, real);
92c43e3c 7496}
7497
c2f47e15 7498/* Fold a call to __builtin_nan or __builtin_nans with argument ARG. */
b0db7939 7499
7500static tree
c2f47e15 7501fold_builtin_nan (tree arg, tree type, int quiet)
b0db7939 7502{
7503 REAL_VALUE_TYPE real;
7504 const char *str;
7505
c2f47e15 7506 if (!validate_arg (arg, POINTER_TYPE))
7507 return NULL_TREE;
7508 str = c_getstr (arg);
b0db7939 7509 if (!str)
c2f47e15 7510 return NULL_TREE;
b0db7939 7511
7512 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
c2f47e15 7513 return NULL_TREE;
b0db7939 7514
7515 return build_real (type, real);
7516}
7517
277f8dd2 7518/* Return true if the floating point expression T has an integer value.
7519 We also allow +Inf, -Inf and NaN to be considered integer values. */
7520
7521static bool
7522integer_valued_real_p (tree t)
7523{
7524 switch (TREE_CODE (t))
7525 {
7526 case FLOAT_EXPR:
7527 return true;
7528
7529 case ABS_EXPR:
7530 case SAVE_EXPR:
277f8dd2 7531 return integer_valued_real_p (TREE_OPERAND (t, 0));
7532
7533 case COMPOUND_EXPR:
41076ef6 7534 case MODIFY_EXPR:
277f8dd2 7535 case BIND_EXPR:
75a70cf9 7536 return integer_valued_real_p (TREE_OPERAND (t, 1));
277f8dd2 7537
7538 case PLUS_EXPR:
7539 case MINUS_EXPR:
7540 case MULT_EXPR:
7541 case MIN_EXPR:
7542 case MAX_EXPR:
7543 return integer_valued_real_p (TREE_OPERAND (t, 0))
7544 && integer_valued_real_p (TREE_OPERAND (t, 1));
7545
7546 case COND_EXPR:
7547 return integer_valued_real_p (TREE_OPERAND (t, 1))
7548 && integer_valued_real_p (TREE_OPERAND (t, 2));
7549
7550 case REAL_CST:
0570334c 7551 return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t)));
277f8dd2 7552
7553 case NOP_EXPR:
7554 {
7555 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
7556 if (TREE_CODE (type) == INTEGER_TYPE)
7557 return true;
7558 if (TREE_CODE (type) == REAL_TYPE)
7559 return integer_valued_real_p (TREE_OPERAND (t, 0));
7560 break;
7561 }
7562
7563 case CALL_EXPR:
7564 switch (builtin_mathfn_code (t))
7565 {
4f35b1fc 7566 CASE_FLT_FN (BUILT_IN_CEIL):
7567 CASE_FLT_FN (BUILT_IN_FLOOR):
7568 CASE_FLT_FN (BUILT_IN_NEARBYINT):
7569 CASE_FLT_FN (BUILT_IN_RINT):
7570 CASE_FLT_FN (BUILT_IN_ROUND):
7571 CASE_FLT_FN (BUILT_IN_TRUNC):
277f8dd2 7572 return true;
7573
d4a43a03 7574 CASE_FLT_FN (BUILT_IN_FMIN):
7575 CASE_FLT_FN (BUILT_IN_FMAX):
c2f47e15 7576 return integer_valued_real_p (CALL_EXPR_ARG (t, 0))
7577 && integer_valued_real_p (CALL_EXPR_ARG (t, 1));
d4a43a03 7578
277f8dd2 7579 default:
7580 break;
7581 }
7582 break;
7583
7584 default:
7585 break;
7586 }
7587 return false;
7588}
7589
c2f47e15 7590/* FNDECL is assumed to be a builtin where truncation can be propagated
6528f4f4 7591 across (for instance floor((double)f) == (double)floorf (f).
c2f47e15 7592 Do the transformation for a call with argument ARG. */
277f8dd2 7593
6528f4f4 7594static tree
389dd41b 7595fold_trunc_transparent_mathfn (location_t loc, tree fndecl, tree arg)
6528f4f4 7596{
6528f4f4 7597 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
277f8dd2 7598
c2f47e15 7599 if (!validate_arg (arg, REAL_TYPE))
7600 return NULL_TREE;
6528f4f4 7601
277f8dd2 7602 /* Integer rounding functions are idempotent. */
7603 if (fcode == builtin_mathfn_code (arg))
7604 return arg;
7605
7606 /* If argument is already integer valued, and we don't need to worry
7607 about setting errno, there's no need to perform rounding. */
7608 if (! flag_errno_math && integer_valued_real_p (arg))
7609 return arg;
7610
7611 if (optimize)
6528f4f4 7612 {
277f8dd2 7613 tree arg0 = strip_float_extensions (arg);
2426241c 7614 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6528f4f4 7615 tree newtype = TREE_TYPE (arg0);
7616 tree decl;
7617
7618 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7619 && (decl = mathfn_built_in (newtype, fcode)))
389dd41b 7620 return fold_convert_loc (loc, ftype,
7621 build_call_expr_loc (loc, decl, 1,
7622 fold_convert_loc (loc,
7623 newtype,
7624 arg0)));
6528f4f4 7625 }
c2f47e15 7626 return NULL_TREE;
6528f4f4 7627}
7628
c2f47e15 7629/* FNDECL is assumed to be builtin which can narrow the FP type of
7630 the argument, for instance lround((double)f) -> lroundf (f).
7631 Do the transformation for a call with argument ARG. */
9ed65c7f 7632
7633static tree
389dd41b 7634fold_fixed_mathfn (location_t loc, tree fndecl, tree arg)
9ed65c7f 7635{
9ed65c7f 7636 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
9ed65c7f 7637
c2f47e15 7638 if (!validate_arg (arg, REAL_TYPE))
7639 return NULL_TREE;
9ed65c7f 7640
7641 /* If argument is already integer valued, and we don't need to worry
7642 about setting errno, there's no need to perform rounding. */
7643 if (! flag_errno_math && integer_valued_real_p (arg))
389dd41b 7644 return fold_build1_loc (loc, FIX_TRUNC_EXPR,
7645 TREE_TYPE (TREE_TYPE (fndecl)), arg);
9ed65c7f 7646
7647 if (optimize)
7648 {
7649 tree ftype = TREE_TYPE (arg);
7650 tree arg0 = strip_float_extensions (arg);
7651 tree newtype = TREE_TYPE (arg0);
7652 tree decl;
7653
7654 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7655 && (decl = mathfn_built_in (newtype, fcode)))
389dd41b 7656 return build_call_expr_loc (loc, decl, 1,
7657 fold_convert_loc (loc, newtype, arg0));
9ed65c7f 7658 }
73a0da56 7659
7660 /* Canonicalize llround (x) to lround (x) on LP64 targets where
7661 sizeof (long long) == sizeof (long). */
7662 if (TYPE_PRECISION (long_long_integer_type_node)
7663 == TYPE_PRECISION (long_integer_type_node))
7664 {
7665 tree newfn = NULL_TREE;
7666 switch (fcode)
7667 {
7668 CASE_FLT_FN (BUILT_IN_LLCEIL):
7669 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7670 break;
7671
7672 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7673 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7674 break;
7675
7676 CASE_FLT_FN (BUILT_IN_LLROUND):
7677 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7678 break;
7679
7680 CASE_FLT_FN (BUILT_IN_LLRINT):
7681 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7682 break;
7683
7684 default:
7685 break;
7686 }
7687
7688 if (newfn)
7689 {
389dd41b 7690 tree newcall = build_call_expr_loc (loc, newfn, 1, arg);
7691 return fold_convert_loc (loc,
7692 TREE_TYPE (TREE_TYPE (fndecl)), newcall);
73a0da56 7693 }
7694 }
7695
c2f47e15 7696 return NULL_TREE;
9ed65c7f 7697}
7698
c2f47e15 7699/* Fold call to builtin cabs, cabsf or cabsl with argument ARG. TYPE is the
7700 return type. Return NULL_TREE if no simplification can be made. */
c63f4ad3 7701
7702static tree
389dd41b 7703fold_builtin_cabs (location_t loc, tree arg, tree type, tree fndecl)
c63f4ad3 7704{
c2f47e15 7705 tree res;
c63f4ad3 7706
c63f4ad3 7707 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
7708 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7709 return NULL_TREE;
7710
b4725390 7711 /* Calculate the result when the argument is a constant. */
7712 if (TREE_CODE (arg) == COMPLEX_CST
7713 && (res = do_mpfr_arg2 (TREE_REALPART (arg), TREE_IMAGPART (arg),
7714 type, mpfr_hypot)))
7715 return res;
7716
1af0d139 7717 if (TREE_CODE (arg) == COMPLEX_EXPR)
7718 {
7719 tree real = TREE_OPERAND (arg, 0);
7720 tree imag = TREE_OPERAND (arg, 1);
7721
7722 /* If either part is zero, cabs is fabs of the other. */
7723 if (real_zerop (real))
389dd41b 7724 return fold_build1_loc (loc, ABS_EXPR, type, imag);
1af0d139 7725 if (real_zerop (imag))
389dd41b 7726 return fold_build1_loc (loc, ABS_EXPR, type, real);
1af0d139 7727
7728 /* cabs(x+xi) -> fabs(x)*sqrt(2). */
7729 if (flag_unsafe_math_optimizations
7730 && operand_equal_p (real, imag, OEP_PURE_SAME))
7731 {
2e7ca27b 7732 const REAL_VALUE_TYPE sqrt2_trunc
7910b2fb 7733 = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
1af0d139 7734 STRIP_NOPS (real);
389dd41b 7735 return fold_build2_loc (loc, MULT_EXPR, type,
7736 fold_build1_loc (loc, ABS_EXPR, type, real),
2e7ca27b 7737 build_real (type, sqrt2_trunc));
1af0d139 7738 }
7739 }
c63f4ad3 7740
749891b2 7741 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
7742 if (TREE_CODE (arg) == NEGATE_EXPR
7743 || TREE_CODE (arg) == CONJ_EXPR)
389dd41b 7744 return build_call_expr_loc (loc, fndecl, 1, TREE_OPERAND (arg, 0));
749891b2 7745
7d3f6cc7 7746 /* Don't do this when optimizing for size. */
7747 if (flag_unsafe_math_optimizations
0bfd8d5c 7748 && optimize && optimize_function_for_speed_p (cfun))
c63f4ad3 7749 {
0da0dbfa 7750 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
c63f4ad3 7751
7752 if (sqrtfn != NULL_TREE)
7753 {
c2f47e15 7754 tree rpart, ipart, result;
c63f4ad3 7755
4ee9c684 7756 arg = builtin_save_expr (arg);
29a6518e 7757
389dd41b 7758 rpart = fold_build1_loc (loc, REALPART_EXPR, type, arg);
7759 ipart = fold_build1_loc (loc, IMAGPART_EXPR, type, arg);
c63f4ad3 7760
4ee9c684 7761 rpart = builtin_save_expr (rpart);
7762 ipart = builtin_save_expr (ipart);
c63f4ad3 7763
389dd41b 7764 result = fold_build2_loc (loc, PLUS_EXPR, type,
7765 fold_build2_loc (loc, MULT_EXPR, type,
49d00087 7766 rpart, rpart),
389dd41b 7767 fold_build2_loc (loc, MULT_EXPR, type,
49d00087 7768 ipart, ipart));
c63f4ad3 7769
389dd41b 7770 return build_call_expr_loc (loc, sqrtfn, 1, result);
c63f4ad3 7771 }
7772 }
7773
7774 return NULL_TREE;
7775}
7776
c2f47e15 7777/* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG.
7778 Return NULL_TREE if no simplification can be made. */
e6e27594 7779
7780static tree
389dd41b 7781fold_builtin_sqrt (location_t loc, tree arg, tree type)
e6e27594 7782{
7783
7784 enum built_in_function fcode;
b4e8ab0c 7785 tree res;
c2f47e15 7786
7787 if (!validate_arg (arg, REAL_TYPE))
e6e27594 7788 return NULL_TREE;
7789
b4e8ab0c 7790 /* Calculate the result when the argument is a constant. */
7791 if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst0, NULL, true)))
7792 return res;
7793
e6e27594 7794 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7795 fcode = builtin_mathfn_code (arg);
7796 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7797 {
c2f47e15 7798 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
389dd41b 7799 arg = fold_build2_loc (loc, MULT_EXPR, type,
c2f47e15 7800 CALL_EXPR_ARG (arg, 0),
49d00087 7801 build_real (type, dconsthalf));
389dd41b 7802 return build_call_expr_loc (loc, expfn, 1, arg);
e6e27594 7803 }
7804
7805 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7806 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7807 {
7808 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7809
7810 if (powfn)
7811 {
c2f47e15 7812 tree arg0 = CALL_EXPR_ARG (arg, 0);
e6e27594 7813 tree tree_root;
7814 /* The inner root was either sqrt or cbrt. */
57510da6 7815 /* This was a conditional expression but it triggered a bug
18381619 7816 in Sun C 5.5. */
ce6cd837 7817 REAL_VALUE_TYPE dconstroot;
7818 if (BUILTIN_SQRT_P (fcode))
7819 dconstroot = dconsthalf;
7820 else
7821 dconstroot = dconst_third ();
e6e27594 7822
7823 /* Adjust for the outer root. */
7824 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7825 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7826 tree_root = build_real (type, dconstroot);
389dd41b 7827 return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
e6e27594 7828 }
7829 }
7830
bc33117f 7831 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
e6e27594 7832 if (flag_unsafe_math_optimizations
7833 && (fcode == BUILT_IN_POW
7834 || fcode == BUILT_IN_POWF
7835 || fcode == BUILT_IN_POWL))
7836 {
c2f47e15 7837 tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7838 tree arg0 = CALL_EXPR_ARG (arg, 0);
7839 tree arg1 = CALL_EXPR_ARG (arg, 1);
bc33117f 7840 tree narg1;
7841 if (!tree_expr_nonnegative_p (arg0))
7842 arg0 = build1 (ABS_EXPR, type, arg0);
389dd41b 7843 narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
49d00087 7844 build_real (type, dconsthalf));
389dd41b 7845 return build_call_expr_loc (loc, powfn, 2, arg0, narg1);
e6e27594 7846 }
7847
7848 return NULL_TREE;
7849}
7850
c2f47e15 7851/* Fold a builtin function call to cbrt, cbrtf, or cbrtl with argument ARG.
7852 Return NULL_TREE if no simplification can be made. */
7853
e6e27594 7854static tree
389dd41b 7855fold_builtin_cbrt (location_t loc, tree arg, tree type)
e6e27594 7856{
e6e27594 7857 const enum built_in_function fcode = builtin_mathfn_code (arg);
29f4cd78 7858 tree res;
e6e27594 7859
c2f47e15 7860 if (!validate_arg (arg, REAL_TYPE))
e6e27594 7861 return NULL_TREE;
7862
29f4cd78 7863 /* Calculate the result when the argument is a constant. */
7864 if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7865 return res;
e6e27594 7866
cdfeb715 7867 if (flag_unsafe_math_optimizations)
e6e27594 7868 {
cdfeb715 7869 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7870 if (BUILTIN_EXPONENT_P (fcode))
a0c938f0 7871 {
c2f47e15 7872 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
cdfeb715 7873 const REAL_VALUE_TYPE third_trunc =
7910b2fb 7874 real_value_truncate (TYPE_MODE (type), dconst_third ());
389dd41b 7875 arg = fold_build2_loc (loc, MULT_EXPR, type,
c2f47e15 7876 CALL_EXPR_ARG (arg, 0),
49d00087 7877 build_real (type, third_trunc));
389dd41b 7878 return build_call_expr_loc (loc, expfn, 1, arg);
cdfeb715 7879 }
e6e27594 7880
cdfeb715 7881 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7882 if (BUILTIN_SQRT_P (fcode))
a0c938f0 7883 {
cdfeb715 7884 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
e6e27594 7885
cdfeb715 7886 if (powfn)
7887 {
c2f47e15 7888 tree arg0 = CALL_EXPR_ARG (arg, 0);
cdfeb715 7889 tree tree_root;
7910b2fb 7890 REAL_VALUE_TYPE dconstroot = dconst_third ();
cdfeb715 7891
7892 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7893 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7894 tree_root = build_real (type, dconstroot);
389dd41b 7895 return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
cdfeb715 7896 }
e6e27594 7897 }
7898
cdfeb715 7899 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7900 if (BUILTIN_CBRT_P (fcode))
a0c938f0 7901 {
c2f47e15 7902 tree arg0 = CALL_EXPR_ARG (arg, 0);
cdfeb715 7903 if (tree_expr_nonnegative_p (arg0))
7904 {
7905 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7906
7907 if (powfn)
a0c938f0 7908 {
cdfeb715 7909 tree tree_root;
7910 REAL_VALUE_TYPE dconstroot;
a0c938f0 7911
3fa759a9 7912 real_arithmetic (&dconstroot, MULT_EXPR,
7910b2fb 7913 dconst_third_ptr (), dconst_third_ptr ());
cdfeb715 7914 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7915 tree_root = build_real (type, dconstroot);
389dd41b 7916 return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
cdfeb715 7917 }
7918 }
7919 }
a0c938f0 7920
cdfeb715 7921 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
c2f47e15 7922 if (fcode == BUILT_IN_POW
7923 || fcode == BUILT_IN_POWF
cdfeb715 7924 || fcode == BUILT_IN_POWL)
a0c938f0 7925 {
c2f47e15 7926 tree arg00 = CALL_EXPR_ARG (arg, 0);
7927 tree arg01 = CALL_EXPR_ARG (arg, 1);
cdfeb715 7928 if (tree_expr_nonnegative_p (arg00))
7929 {
c2f47e15 7930 tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
cdfeb715 7931 const REAL_VALUE_TYPE dconstroot
7910b2fb 7932 = real_value_truncate (TYPE_MODE (type), dconst_third ());
389dd41b 7933 tree narg01 = fold_build2_loc (loc, MULT_EXPR, type, arg01,
49d00087 7934 build_real (type, dconstroot));
389dd41b 7935 return build_call_expr_loc (loc, powfn, 2, arg00, narg01);
cdfeb715 7936 }
7937 }
e6e27594 7938 }
7939 return NULL_TREE;
7940}
7941
c2f47e15 7942/* Fold function call to builtin cos, cosf, or cosl with argument ARG.
7943 TYPE is the type of the return value. Return NULL_TREE if no
7944 simplification can be made. */
7945
e6e27594 7946static tree
389dd41b 7947fold_builtin_cos (location_t loc,
7948 tree arg, tree type, tree fndecl)
e6e27594 7949{
e6ab33d8 7950 tree res, narg;
e6e27594 7951
c2f47e15 7952 if (!validate_arg (arg, REAL_TYPE))
e6e27594 7953 return NULL_TREE;
7954
bffb7645 7955 /* Calculate the result when the argument is a constant. */
728bac60 7956 if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
bffb7645 7957 return res;
7958
e6e27594 7959 /* Optimize cos(-x) into cos (x). */
e6ab33d8 7960 if ((narg = fold_strip_sign_ops (arg)))
389dd41b 7961 return build_call_expr_loc (loc, fndecl, 1, narg);
e6e27594 7962
7963 return NULL_TREE;
7964}
7965
c2f47e15 7966/* Fold function call to builtin cosh, coshf, or coshl with argument ARG.
7967 Return NULL_TREE if no simplification can be made. */
7968
cacdc1af 7969static tree
389dd41b 7970fold_builtin_cosh (location_t loc, tree arg, tree type, tree fndecl)
cacdc1af 7971{
c2f47e15 7972 if (validate_arg (arg, REAL_TYPE))
cacdc1af 7973 {
cacdc1af 7974 tree res, narg;
7975
7976 /* Calculate the result when the argument is a constant. */
7977 if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0)))
7978 return res;
7979
7980 /* Optimize cosh(-x) into cosh (x). */
7981 if ((narg = fold_strip_sign_ops (arg)))
389dd41b 7982 return build_call_expr_loc (loc, fndecl, 1, narg);
cacdc1af 7983 }
7984
7985 return NULL_TREE;
7986}
7987
239d491a 7988/* Fold function call to builtin ccos (or ccosh if HYPER is TRUE) with
7989 argument ARG. TYPE is the type of the return value. Return
7990 NULL_TREE if no simplification can be made. */
7991
7992static tree
389dd41b 7993fold_builtin_ccos (location_t loc,
7994 tree arg, tree type ATTRIBUTE_UNUSED, tree fndecl,
239d491a 7995 bool hyper ATTRIBUTE_UNUSED)
7996{
7997 if (validate_arg (arg, COMPLEX_TYPE)
7998 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
7999 {
8000 tree tmp;
8001
8002#ifdef HAVE_mpc
8003 /* Calculate the result when the argument is a constant. */
8004 if ((tmp = do_mpc_arg1 (arg, type, (hyper ? mpc_cosh : mpc_cos))))
8005 return tmp;
8006#endif
8007
8008 /* Optimize fn(-x) into fn(x). */
8009 if ((tmp = fold_strip_sign_ops (arg)))
389dd41b 8010 return build_call_expr_loc (loc, fndecl, 1, tmp);
239d491a 8011 }
8012
8013 return NULL_TREE;
8014}
8015
c2f47e15 8016/* Fold function call to builtin tan, tanf, or tanl with argument ARG.
8017 Return NULL_TREE if no simplification can be made. */
8018
e6e27594 8019static tree
c2f47e15 8020fold_builtin_tan (tree arg, tree type)
e6e27594 8021{
8022 enum built_in_function fcode;
29f4cd78 8023 tree res;
e6e27594 8024
c2f47e15 8025 if (!validate_arg (arg, REAL_TYPE))
e6e27594 8026 return NULL_TREE;
8027
bffb7645 8028 /* Calculate the result when the argument is a constant. */
728bac60 8029 if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0)))
bffb7645 8030 return res;
8031
e6e27594 8032 /* Optimize tan(atan(x)) = x. */
8033 fcode = builtin_mathfn_code (arg);
8034 if (flag_unsafe_math_optimizations
8035 && (fcode == BUILT_IN_ATAN
8036 || fcode == BUILT_IN_ATANF
8037 || fcode == BUILT_IN_ATANL))
c2f47e15 8038 return CALL_EXPR_ARG (arg, 0);
e6e27594 8039
8040 return NULL_TREE;
8041}
8042
d735c391 8043/* Fold function call to builtin sincos, sincosf, or sincosl. Return
8044 NULL_TREE if no simplification can be made. */
8045
8046static tree
389dd41b 8047fold_builtin_sincos (location_t loc,
8048 tree arg0, tree arg1, tree arg2)
d735c391 8049{
c2f47e15 8050 tree type;
d735c391 8051 tree res, fn, call;
8052
c2f47e15 8053 if (!validate_arg (arg0, REAL_TYPE)
8054 || !validate_arg (arg1, POINTER_TYPE)
8055 || !validate_arg (arg2, POINTER_TYPE))
d735c391 8056 return NULL_TREE;
8057
d735c391 8058 type = TREE_TYPE (arg0);
d735c391 8059
8060 /* Calculate the result when the argument is a constant. */
8061 if ((res = do_mpfr_sincos (arg0, arg1, arg2)))
8062 return res;
8063
8064 /* Canonicalize sincos to cexpi. */
2a6b4c77 8065 if (!TARGET_C99_FUNCTIONS)
8066 return NULL_TREE;
d735c391 8067 fn = mathfn_built_in (type, BUILT_IN_CEXPI);
8068 if (!fn)
8069 return NULL_TREE;
8070
389dd41b 8071 call = build_call_expr_loc (loc, fn, 1, arg0);
d735c391 8072 call = builtin_save_expr (call);
8073
a75b1c71 8074 return build2 (COMPOUND_EXPR, void_type_node,
d735c391 8075 build2 (MODIFY_EXPR, void_type_node,
389dd41b 8076 build_fold_indirect_ref_loc (loc, arg1),
d735c391 8077 build1 (IMAGPART_EXPR, type, call)),
8078 build2 (MODIFY_EXPR, void_type_node,
389dd41b 8079 build_fold_indirect_ref_loc (loc, arg2),
d735c391 8080 build1 (REALPART_EXPR, type, call)));
8081}
8082
c5bb2c4b 8083/* Fold function call to builtin cexp, cexpf, or cexpl. Return
8084 NULL_TREE if no simplification can be made. */
8085
8086static tree
389dd41b 8087fold_builtin_cexp (location_t loc, tree arg0, tree type)
c5bb2c4b 8088{
c2f47e15 8089 tree rtype;
c5bb2c4b 8090 tree realp, imagp, ifn;
239d491a 8091#ifdef HAVE_mpc
8092 tree res;
8093#endif
c5bb2c4b 8094
239d491a 8095 if (!validate_arg (arg0, COMPLEX_TYPE)
8096 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
c5bb2c4b 8097 return NULL_TREE;
8098
239d491a 8099#ifdef HAVE_mpc
8100 /* Calculate the result when the argument is a constant. */
8101 if ((res = do_mpc_arg1 (arg0, type, mpc_exp)))
8102 return res;
8103#endif
8104
c5bb2c4b 8105 rtype = TREE_TYPE (TREE_TYPE (arg0));
8106
8107 /* In case we can figure out the real part of arg0 and it is constant zero
8108 fold to cexpi. */
2a6b4c77 8109 if (!TARGET_C99_FUNCTIONS)
8110 return NULL_TREE;
c5bb2c4b 8111 ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
8112 if (!ifn)
8113 return NULL_TREE;
8114
389dd41b 8115 if ((realp = fold_unary_loc (loc, REALPART_EXPR, rtype, arg0))
c5bb2c4b 8116 && real_zerop (realp))
8117 {
389dd41b 8118 tree narg = fold_build1_loc (loc, IMAGPART_EXPR, rtype, arg0);
8119 return build_call_expr_loc (loc, ifn, 1, narg);
c5bb2c4b 8120 }
8121
8122 /* In case we can easily decompose real and imaginary parts split cexp
8123 to exp (r) * cexpi (i). */
8124 if (flag_unsafe_math_optimizations
8125 && realp)
8126 {
8127 tree rfn, rcall, icall;
8128
8129 rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
8130 if (!rfn)
8131 return NULL_TREE;
8132
389dd41b 8133 imagp = fold_unary_loc (loc, IMAGPART_EXPR, rtype, arg0);
c5bb2c4b 8134 if (!imagp)
8135 return NULL_TREE;
8136
389dd41b 8137 icall = build_call_expr_loc (loc, ifn, 1, imagp);
c5bb2c4b 8138 icall = builtin_save_expr (icall);
389dd41b 8139 rcall = build_call_expr_loc (loc, rfn, 1, realp);
c5bb2c4b 8140 rcall = builtin_save_expr (rcall);
389dd41b 8141 return fold_build2_loc (loc, COMPLEX_EXPR, type,
8142 fold_build2_loc (loc, MULT_EXPR, rtype,
71bf42bb 8143 rcall,
389dd41b 8144 fold_build1_loc (loc, REALPART_EXPR,
8145 rtype, icall)),
8146 fold_build2_loc (loc, MULT_EXPR, rtype,
71bf42bb 8147 rcall,
389dd41b 8148 fold_build1_loc (loc, IMAGPART_EXPR,
8149 rtype, icall)));
c5bb2c4b 8150 }
8151
8152 return NULL_TREE;
8153}
8154
c2f47e15 8155/* Fold function call to builtin trunc, truncf or truncl with argument ARG.
8156 Return NULL_TREE if no simplification can be made. */
277f8dd2 8157
8158static tree
389dd41b 8159fold_builtin_trunc (location_t loc, tree fndecl, tree arg)
277f8dd2 8160{
c2f47e15 8161 if (!validate_arg (arg, REAL_TYPE))
8162 return NULL_TREE;
277f8dd2 8163
8164 /* Optimize trunc of constant value. */
f96bd2bf 8165 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
277f8dd2 8166 {
8167 REAL_VALUE_TYPE r, x;
2426241c 8168 tree type = TREE_TYPE (TREE_TYPE (fndecl));
277f8dd2 8169
8170 x = TREE_REAL_CST (arg);
8171 real_trunc (&r, TYPE_MODE (type), &x);
8172 return build_real (type, r);
8173 }
8174
389dd41b 8175 return fold_trunc_transparent_mathfn (loc, fndecl, arg);
277f8dd2 8176}
8177
c2f47e15 8178/* Fold function call to builtin floor, floorf or floorl with argument ARG.
8179 Return NULL_TREE if no simplification can be made. */
277f8dd2 8180
8181static tree
389dd41b 8182fold_builtin_floor (location_t loc, tree fndecl, tree arg)
277f8dd2 8183{
c2f47e15 8184 if (!validate_arg (arg, REAL_TYPE))
8185 return NULL_TREE;
277f8dd2 8186
8187 /* Optimize floor of constant value. */
f96bd2bf 8188 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
277f8dd2 8189 {
8190 REAL_VALUE_TYPE x;
8191
8192 x = TREE_REAL_CST (arg);
8193 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
8194 {
2426241c 8195 tree type = TREE_TYPE (TREE_TYPE (fndecl));
277f8dd2 8196 REAL_VALUE_TYPE r;
8197
8198 real_floor (&r, TYPE_MODE (type), &x);
8199 return build_real (type, r);
8200 }
8201 }
8202
acc2b92e 8203 /* Fold floor (x) where x is nonnegative to trunc (x). */
8204 if (tree_expr_nonnegative_p (arg))
30fe8286 8205 {
8206 tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
8207 if (truncfn)
389dd41b 8208 return build_call_expr_loc (loc, truncfn, 1, arg);
30fe8286 8209 }
acc2b92e 8210
389dd41b 8211 return fold_trunc_transparent_mathfn (loc, fndecl, arg);
277f8dd2 8212}
8213
c2f47e15 8214/* Fold function call to builtin ceil, ceilf or ceill with argument ARG.
8215 Return NULL_TREE if no simplification can be made. */
277f8dd2 8216
8217static tree
389dd41b 8218fold_builtin_ceil (location_t loc, tree fndecl, tree arg)
277f8dd2 8219{
c2f47e15 8220 if (!validate_arg (arg, REAL_TYPE))
8221 return NULL_TREE;
277f8dd2 8222
8223 /* Optimize ceil of constant value. */
f96bd2bf 8224 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
277f8dd2 8225 {
8226 REAL_VALUE_TYPE x;
8227
8228 x = TREE_REAL_CST (arg);
8229 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
8230 {
2426241c 8231 tree type = TREE_TYPE (TREE_TYPE (fndecl));
277f8dd2 8232 REAL_VALUE_TYPE r;
8233
8234 real_ceil (&r, TYPE_MODE (type), &x);
8235 return build_real (type, r);
8236 }
8237 }
8238
389dd41b 8239 return fold_trunc_transparent_mathfn (loc, fndecl, arg);
277f8dd2 8240}
8241
c2f47e15 8242/* Fold function call to builtin round, roundf or roundl with argument ARG.
8243 Return NULL_TREE if no simplification can be made. */
89ab3887 8244
8245static tree
389dd41b 8246fold_builtin_round (location_t loc, tree fndecl, tree arg)
89ab3887 8247{
c2f47e15 8248 if (!validate_arg (arg, REAL_TYPE))
8249 return NULL_TREE;
89ab3887 8250
34f17811 8251 /* Optimize round of constant value. */
f96bd2bf 8252 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
89ab3887 8253 {
8254 REAL_VALUE_TYPE x;
8255
8256 x = TREE_REAL_CST (arg);
8257 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
8258 {
2426241c 8259 tree type = TREE_TYPE (TREE_TYPE (fndecl));
89ab3887 8260 REAL_VALUE_TYPE r;
8261
8262 real_round (&r, TYPE_MODE (type), &x);
8263 return build_real (type, r);
8264 }
8265 }
8266
389dd41b 8267 return fold_trunc_transparent_mathfn (loc, fndecl, arg);
89ab3887 8268}
8269
34f17811 8270/* Fold function call to builtin lround, lroundf or lroundl (or the
c2f47e15 8271 corresponding long long versions) and other rounding functions. ARG
8272 is the argument to the call. Return NULL_TREE if no simplification
8273 can be made. */
34f17811 8274
8275static tree
389dd41b 8276fold_builtin_int_roundingfn (location_t loc, tree fndecl, tree arg)
34f17811 8277{
c2f47e15 8278 if (!validate_arg (arg, REAL_TYPE))
8279 return NULL_TREE;
34f17811 8280
8281 /* Optimize lround of constant value. */
f96bd2bf 8282 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
34f17811 8283 {
8284 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
8285
776a7bab 8286 if (real_isfinite (&x))
34f17811 8287 {
2426241c 8288 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
ca9b061d 8289 tree ftype = TREE_TYPE (arg);
8290 unsigned HOST_WIDE_INT lo2;
34f17811 8291 HOST_WIDE_INT hi, lo;
8292 REAL_VALUE_TYPE r;
8293
ad52b9b7 8294 switch (DECL_FUNCTION_CODE (fndecl))
8295 {
4f35b1fc 8296 CASE_FLT_FN (BUILT_IN_LFLOOR):
8297 CASE_FLT_FN (BUILT_IN_LLFLOOR):
ad52b9b7 8298 real_floor (&r, TYPE_MODE (ftype), &x);
8299 break;
8300
4f35b1fc 8301 CASE_FLT_FN (BUILT_IN_LCEIL):
8302 CASE_FLT_FN (BUILT_IN_LLCEIL):
ac148751 8303 real_ceil (&r, TYPE_MODE (ftype), &x);
8304 break;
8305
4f35b1fc 8306 CASE_FLT_FN (BUILT_IN_LROUND):
8307 CASE_FLT_FN (BUILT_IN_LLROUND):
ad52b9b7 8308 real_round (&r, TYPE_MODE (ftype), &x);
8309 break;
8310
8311 default:
8312 gcc_unreachable ();
8313 }
8314
34f17811 8315 REAL_VALUE_TO_INT (&lo, &hi, r);
ca9b061d 8316 if (!fit_double_type (lo, hi, &lo2, &hi, itype))
8317 return build_int_cst_wide (itype, lo2, hi);
34f17811 8318 }
8319 }
8320
acc2b92e 8321 switch (DECL_FUNCTION_CODE (fndecl))
8322 {
8323 CASE_FLT_FN (BUILT_IN_LFLOOR):
8324 CASE_FLT_FN (BUILT_IN_LLFLOOR):
8325 /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x). */
8326 if (tree_expr_nonnegative_p (arg))
389dd41b 8327 return fold_build1_loc (loc, FIX_TRUNC_EXPR,
8328 TREE_TYPE (TREE_TYPE (fndecl)), arg);
acc2b92e 8329 break;
8330 default:;
8331 }
8332
389dd41b 8333 return fold_fixed_mathfn (loc, fndecl, arg);
34f17811 8334}
8335
70fb4c07 8336/* Fold function call to builtin ffs, clz, ctz, popcount and parity
c2f47e15 8337 and their long and long long variants (i.e. ffsl and ffsll). ARG is
8338 the argument to the call. Return NULL_TREE if no simplification can
8339 be made. */
70fb4c07 8340
8341static tree
c2f47e15 8342fold_builtin_bitop (tree fndecl, tree arg)
70fb4c07 8343{
c2f47e15 8344 if (!validate_arg (arg, INTEGER_TYPE))
70fb4c07 8345 return NULL_TREE;
8346
8347 /* Optimize for constant argument. */
f96bd2bf 8348 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
70fb4c07 8349 {
8350 HOST_WIDE_INT hi, width, result;
8351 unsigned HOST_WIDE_INT lo;
7c446c95 8352 tree type;
70fb4c07 8353
8354 type = TREE_TYPE (arg);
8355 width = TYPE_PRECISION (type);
8356 lo = TREE_INT_CST_LOW (arg);
8357
8358 /* Clear all the bits that are beyond the type's precision. */
8359 if (width > HOST_BITS_PER_WIDE_INT)
8360 {
8361 hi = TREE_INT_CST_HIGH (arg);
8362 if (width < 2 * HOST_BITS_PER_WIDE_INT)
8363 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
8364 }
8365 else
8366 {
8367 hi = 0;
8368 if (width < HOST_BITS_PER_WIDE_INT)
8369 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
8370 }
8371
8372 switch (DECL_FUNCTION_CODE (fndecl))
8373 {
4f35b1fc 8374 CASE_INT_FN (BUILT_IN_FFS):
70fb4c07 8375 if (lo != 0)
8376 result = exact_log2 (lo & -lo) + 1;
8377 else if (hi != 0)
8378 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
8379 else
8380 result = 0;
8381 break;
8382
4f35b1fc 8383 CASE_INT_FN (BUILT_IN_CLZ):
70fb4c07 8384 if (hi != 0)
8385 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
8386 else if (lo != 0)
8387 result = width - floor_log2 (lo) - 1;
8388 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8389 result = width;
8390 break;
8391
4f35b1fc 8392 CASE_INT_FN (BUILT_IN_CTZ):
70fb4c07 8393 if (lo != 0)
8394 result = exact_log2 (lo & -lo);
8395 else if (hi != 0)
8396 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
8397 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8398 result = width;
8399 break;
8400
4f35b1fc 8401 CASE_INT_FN (BUILT_IN_POPCOUNT):
70fb4c07 8402 result = 0;
8403 while (lo)
8404 result++, lo &= lo - 1;
8405 while (hi)
8406 result++, hi &= hi - 1;
8407 break;
8408
4f35b1fc 8409 CASE_INT_FN (BUILT_IN_PARITY):
70fb4c07 8410 result = 0;
8411 while (lo)
8412 result++, lo &= lo - 1;
8413 while (hi)
8414 result++, hi &= hi - 1;
8415 result &= 1;
8416 break;
8417
8418 default:
64db345d 8419 gcc_unreachable ();
70fb4c07 8420 }
8421
2426241c 8422 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
70fb4c07 8423 }
8424
8425 return NULL_TREE;
8426}
8427
42791117 8428/* Fold function call to builtin_bswap and the long and long long
8429 variants. Return NULL_TREE if no simplification can be made. */
8430static tree
c2f47e15 8431fold_builtin_bswap (tree fndecl, tree arg)
42791117 8432{
c2f47e15 8433 if (! validate_arg (arg, INTEGER_TYPE))
8434 return NULL_TREE;
42791117 8435
8436 /* Optimize constant value. */
f96bd2bf 8437 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
42791117 8438 {
8439 HOST_WIDE_INT hi, width, r_hi = 0;
8440 unsigned HOST_WIDE_INT lo, r_lo = 0;
8441 tree type;
8442
8443 type = TREE_TYPE (arg);
8444 width = TYPE_PRECISION (type);
8445 lo = TREE_INT_CST_LOW (arg);
8446 hi = TREE_INT_CST_HIGH (arg);
8447
8448 switch (DECL_FUNCTION_CODE (fndecl))
8449 {
8450 case BUILT_IN_BSWAP32:
8451 case BUILT_IN_BSWAP64:
8452 {
8453 int s;
8454
8455 for (s = 0; s < width; s += 8)
8456 {
8457 int d = width - s - 8;
8458 unsigned HOST_WIDE_INT byte;
8459
8460 if (s < HOST_BITS_PER_WIDE_INT)
8461 byte = (lo >> s) & 0xff;
8462 else
8463 byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
8464
8465 if (d < HOST_BITS_PER_WIDE_INT)
8466 r_lo |= byte << d;
8467 else
8468 r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
8469 }
8470 }
8471
8472 break;
8473
8474 default:
8475 gcc_unreachable ();
8476 }
8477
8478 if (width < HOST_BITS_PER_WIDE_INT)
8479 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo);
8480 else
8481 return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi);
8482 }
8483
8484 return NULL_TREE;
8485}
c2f47e15 8486
8918c507 8487/* A subroutine of fold_builtin to fold the various logarithmic
29f4cd78 8488 functions. Return NULL_TREE if no simplification can me made.
8489 FUNC is the corresponding MPFR logarithm function. */
8918c507 8490
8491static tree
389dd41b 8492fold_builtin_logarithm (location_t loc, tree fndecl, tree arg,
29f4cd78 8493 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8918c507 8494{
c2f47e15 8495 if (validate_arg (arg, REAL_TYPE))
8918c507 8496 {
8918c507 8497 tree type = TREE_TYPE (TREE_TYPE (fndecl));
29f4cd78 8498 tree res;
8918c507 8499 const enum built_in_function fcode = builtin_mathfn_code (arg);
0862b7e9 8500
29f4cd78 8501 /* Calculate the result when the argument is a constant. */
8502 if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
8503 return res;
8504
8918c507 8505 /* Special case, optimize logN(expN(x)) = x. */
8506 if (flag_unsafe_math_optimizations
29f4cd78 8507 && ((func == mpfr_log
8918c507 8508 && (fcode == BUILT_IN_EXP
8509 || fcode == BUILT_IN_EXPF
8510 || fcode == BUILT_IN_EXPL))
29f4cd78 8511 || (func == mpfr_log2
8918c507 8512 && (fcode == BUILT_IN_EXP2
8513 || fcode == BUILT_IN_EXP2F
8514 || fcode == BUILT_IN_EXP2L))
29f4cd78 8515 || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
389dd41b 8516 return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0));
8918c507 8517
ca273d4a 8518 /* Optimize logN(func()) for various exponential functions. We
a0c938f0 8519 want to determine the value "x" and the power "exponent" in
8520 order to transform logN(x**exponent) into exponent*logN(x). */
8918c507 8521 if (flag_unsafe_math_optimizations)
a0c938f0 8522 {
8918c507 8523 tree exponent = 0, x = 0;
0862b7e9 8524
8918c507 8525 switch (fcode)
8526 {
4f35b1fc 8527 CASE_FLT_FN (BUILT_IN_EXP):
8918c507 8528 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7910b2fb 8529 x = build_real (type, real_value_truncate (TYPE_MODE (type),
8530 dconst_e ()));
c2f47e15 8531 exponent = CALL_EXPR_ARG (arg, 0);
8918c507 8532 break;
4f35b1fc 8533 CASE_FLT_FN (BUILT_IN_EXP2):
8918c507 8534 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
8535 x = build_real (type, dconst2);
c2f47e15 8536 exponent = CALL_EXPR_ARG (arg, 0);
8918c507 8537 break;
4f35b1fc 8538 CASE_FLT_FN (BUILT_IN_EXP10):
8539 CASE_FLT_FN (BUILT_IN_POW10):
8918c507 8540 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
3fa759a9 8541 {
8542 REAL_VALUE_TYPE dconst10;
8543 real_from_integer (&dconst10, VOIDmode, 10, 0, 0);
8544 x = build_real (type, dconst10);
8545 }
c2f47e15 8546 exponent = CALL_EXPR_ARG (arg, 0);
8918c507 8547 break;
4f35b1fc 8548 CASE_FLT_FN (BUILT_IN_SQRT):
8918c507 8549 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
c2f47e15 8550 x = CALL_EXPR_ARG (arg, 0);
8918c507 8551 exponent = build_real (type, dconsthalf);
8552 break;
4f35b1fc 8553 CASE_FLT_FN (BUILT_IN_CBRT):
8918c507 8554 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
c2f47e15 8555 x = CALL_EXPR_ARG (arg, 0);
8918c507 8556 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7910b2fb 8557 dconst_third ()));
8918c507 8558 break;
4f35b1fc 8559 CASE_FLT_FN (BUILT_IN_POW):
8918c507 8560 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
c2f47e15 8561 x = CALL_EXPR_ARG (arg, 0);
8562 exponent = CALL_EXPR_ARG (arg, 1);
8918c507 8563 break;
8564 default:
8565 break;
8566 }
8567
8568 /* Now perform the optimization. */
8569 if (x && exponent)
8570 {
389dd41b 8571 tree logfn = build_call_expr_loc (loc, fndecl, 1, x);
8572 return fold_build2_loc (loc, MULT_EXPR, type, exponent, logfn);
8918c507 8573 }
8574 }
8575 }
8576
c2f47e15 8577 return NULL_TREE;
8918c507 8578}
0862b7e9 8579
f0c477f2 8580/* Fold a builtin function call to hypot, hypotf, or hypotl. Return
8581 NULL_TREE if no simplification can be made. */
8582
8583static tree
389dd41b 8584fold_builtin_hypot (location_t loc, tree fndecl,
8585 tree arg0, tree arg1, tree type)
f0c477f2 8586{
e6ab33d8 8587 tree res, narg0, narg1;
f0c477f2 8588
c2f47e15 8589 if (!validate_arg (arg0, REAL_TYPE)
8590 || !validate_arg (arg1, REAL_TYPE))
f0c477f2 8591 return NULL_TREE;
8592
8593 /* Calculate the result when the argument is a constant. */
8594 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
8595 return res;
8596
6c95f21c 8597 /* If either argument to hypot has a negate or abs, strip that off.
8598 E.g. hypot(-x,fabs(y)) -> hypot(x,y). */
e6ab33d8 8599 narg0 = fold_strip_sign_ops (arg0);
8600 narg1 = fold_strip_sign_ops (arg1);
8601 if (narg0 || narg1)
8602 {
389dd41b 8603 return build_call_expr_loc (loc, fndecl, 2, narg0 ? narg0 : arg0,
c2f47e15 8604 narg1 ? narg1 : arg1);
6c95f21c 8605 }
8606
f0c477f2 8607 /* If either argument is zero, hypot is fabs of the other. */
8608 if (real_zerop (arg0))
389dd41b 8609 return fold_build1_loc (loc, ABS_EXPR, type, arg1);
f0c477f2 8610 else if (real_zerop (arg1))
389dd41b 8611 return fold_build1_loc (loc, ABS_EXPR, type, arg0);
f0c477f2 8612
6c95f21c 8613 /* hypot(x,x) -> fabs(x)*sqrt(2). */
8614 if (flag_unsafe_math_optimizations
8615 && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
f0c477f2 8616 {
2e7ca27b 8617 const REAL_VALUE_TYPE sqrt2_trunc
7910b2fb 8618 = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
389dd41b 8619 return fold_build2_loc (loc, MULT_EXPR, type,
8620 fold_build1_loc (loc, ABS_EXPR, type, arg0),
2e7ca27b 8621 build_real (type, sqrt2_trunc));
f0c477f2 8622 }
8623
f0c477f2 8624 return NULL_TREE;
8625}
8626
8627
e6e27594 8628/* Fold a builtin function call to pow, powf, or powl. Return
8629 NULL_TREE if no simplification can be made. */
8630static tree
389dd41b 8631fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
e6e27594 8632{
f0c477f2 8633 tree res;
e6e27594 8634
c2f47e15 8635 if (!validate_arg (arg0, REAL_TYPE)
8636 || !validate_arg (arg1, REAL_TYPE))
e6e27594 8637 return NULL_TREE;
8638
f0c477f2 8639 /* Calculate the result when the argument is a constant. */
8640 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
8641 return res;
8642
e6e27594 8643 /* Optimize pow(1.0,y) = 1.0. */
8644 if (real_onep (arg0))
389dd41b 8645 return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
e6e27594 8646
8647 if (TREE_CODE (arg1) == REAL_CST
f96bd2bf 8648 && !TREE_OVERFLOW (arg1))
e6e27594 8649 {
198d9bbe 8650 REAL_VALUE_TYPE cint;
e6e27594 8651 REAL_VALUE_TYPE c;
198d9bbe 8652 HOST_WIDE_INT n;
8653
e6e27594 8654 c = TREE_REAL_CST (arg1);
8655
8656 /* Optimize pow(x,0.0) = 1.0. */
8657 if (REAL_VALUES_EQUAL (c, dconst0))
389dd41b 8658 return omit_one_operand_loc (loc, type, build_real (type, dconst1),
e6e27594 8659 arg0);
8660
8661 /* Optimize pow(x,1.0) = x. */
8662 if (REAL_VALUES_EQUAL (c, dconst1))
8663 return arg0;
8664
8665 /* Optimize pow(x,-1.0) = 1.0/x. */
8666 if (REAL_VALUES_EQUAL (c, dconstm1))
389dd41b 8667 return fold_build2_loc (loc, RDIV_EXPR, type,
49d00087 8668 build_real (type, dconst1), arg0);
e6e27594 8669
8670 /* Optimize pow(x,0.5) = sqrt(x). */
8671 if (flag_unsafe_math_optimizations
8672 && REAL_VALUES_EQUAL (c, dconsthalf))
8673 {
8674 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8675
8676 if (sqrtfn != NULL_TREE)
389dd41b 8677 return build_call_expr_loc (loc, sqrtfn, 1, arg0);
e6e27594 8678 }
8679
feb5b3eb 8680 /* Optimize pow(x,1.0/3.0) = cbrt(x). */
8681 if (flag_unsafe_math_optimizations)
8682 {
8683 const REAL_VALUE_TYPE dconstroot
7910b2fb 8684 = real_value_truncate (TYPE_MODE (type), dconst_third ());
feb5b3eb 8685
8686 if (REAL_VALUES_EQUAL (c, dconstroot))
8687 {
8688 tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
8689 if (cbrtfn != NULL_TREE)
389dd41b 8690 return build_call_expr_loc (loc, cbrtfn, 1, arg0);
feb5b3eb 8691 }
8692 }
8693
198d9bbe 8694 /* Check for an integer exponent. */
8695 n = real_to_integer (&c);
8696 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
8697 if (real_identical (&c, &cint))
e6e27594 8698 {
a2b30b48 8699 /* Attempt to evaluate pow at compile-time, unless this should
8700 raise an exception. */
198d9bbe 8701 if (TREE_CODE (arg0) == REAL_CST
a2b30b48 8702 && !TREE_OVERFLOW (arg0)
8703 && (n > 0
8704 || (!flag_trapping_math && !flag_errno_math)
8705 || !REAL_VALUES_EQUAL (TREE_REAL_CST (arg0), dconst0)))
e6e27594 8706 {
8707 REAL_VALUE_TYPE x;
8708 bool inexact;
8709
8710 x = TREE_REAL_CST (arg0);
8711 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8712 if (flag_unsafe_math_optimizations || !inexact)
8713 return build_real (type, x);
8714 }
198d9bbe 8715
8716 /* Strip sign ops from even integer powers. */
8717 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
8718 {
8719 tree narg0 = fold_strip_sign_ops (arg0);
8720 if (narg0)
389dd41b 8721 return build_call_expr_loc (loc, fndecl, 2, narg0, arg1);
198d9bbe 8722 }
e6e27594 8723 }
8724 }
8725
cdfeb715 8726 if (flag_unsafe_math_optimizations)
e6e27594 8727 {
cdfeb715 8728 const enum built_in_function fcode = builtin_mathfn_code (arg0);
e6e27594 8729
cdfeb715 8730 /* Optimize pow(expN(x),y) = expN(x*y). */
8731 if (BUILTIN_EXPONENT_P (fcode))
a0c938f0 8732 {
c2f47e15 8733 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0);
8734 tree arg = CALL_EXPR_ARG (arg0, 0);
389dd41b 8735 arg = fold_build2_loc (loc, MULT_EXPR, type, arg, arg1);
8736 return build_call_expr_loc (loc, expfn, 1, arg);
cdfeb715 8737 }
e6e27594 8738
cdfeb715 8739 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
8740 if (BUILTIN_SQRT_P (fcode))
a0c938f0 8741 {
c2f47e15 8742 tree narg0 = CALL_EXPR_ARG (arg0, 0);
389dd41b 8743 tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
49d00087 8744 build_real (type, dconsthalf));
389dd41b 8745 return build_call_expr_loc (loc, fndecl, 2, narg0, narg1);
cdfeb715 8746 }
8747
8748 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
8749 if (BUILTIN_CBRT_P (fcode))
a0c938f0 8750 {
c2f47e15 8751 tree arg = CALL_EXPR_ARG (arg0, 0);
cdfeb715 8752 if (tree_expr_nonnegative_p (arg))
8753 {
8754 const REAL_VALUE_TYPE dconstroot
7910b2fb 8755 = real_value_truncate (TYPE_MODE (type), dconst_third ());
389dd41b 8756 tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
49d00087 8757 build_real (type, dconstroot));
389dd41b 8758 return build_call_expr_loc (loc, fndecl, 2, arg, narg1);
cdfeb715 8759 }
8760 }
a0c938f0 8761
49e436b5 8762 /* Optimize pow(pow(x,y),z) = pow(x,y*z) iff x is nonnegative. */
c2f47e15 8763 if (fcode == BUILT_IN_POW
8764 || fcode == BUILT_IN_POWF
8765 || fcode == BUILT_IN_POWL)
a0c938f0 8766 {
c2f47e15 8767 tree arg00 = CALL_EXPR_ARG (arg0, 0);
49e436b5 8768 if (tree_expr_nonnegative_p (arg00))
8769 {
8770 tree arg01 = CALL_EXPR_ARG (arg0, 1);
8771 tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg01, arg1);
8772 return build_call_expr_loc (loc, fndecl, 2, arg00, narg1);
8773 }
cdfeb715 8774 }
e6e27594 8775 }
cdfeb715 8776
e6e27594 8777 return NULL_TREE;
8778}
8779
c2f47e15 8780/* Fold a builtin function call to powi, powif, or powil with argument ARG.
8781 Return NULL_TREE if no simplification can be made. */
b4d0c20c 8782static tree
389dd41b 8783fold_builtin_powi (location_t loc, tree fndecl ATTRIBUTE_UNUSED,
c2f47e15 8784 tree arg0, tree arg1, tree type)
b4d0c20c 8785{
c2f47e15 8786 if (!validate_arg (arg0, REAL_TYPE)
8787 || !validate_arg (arg1, INTEGER_TYPE))
b4d0c20c 8788 return NULL_TREE;
8789
8790 /* Optimize pow(1.0,y) = 1.0. */
8791 if (real_onep (arg0))
389dd41b 8792 return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
b4d0c20c 8793
8794 if (host_integerp (arg1, 0))
8795 {
8796 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
8797
8798 /* Evaluate powi at compile-time. */
8799 if (TREE_CODE (arg0) == REAL_CST
f96bd2bf 8800 && !TREE_OVERFLOW (arg0))
b4d0c20c 8801 {
8802 REAL_VALUE_TYPE x;
8803 x = TREE_REAL_CST (arg0);
8804 real_powi (&x, TYPE_MODE (type), &x, c);
8805 return build_real (type, x);
8806 }
8807
8808 /* Optimize pow(x,0) = 1.0. */
8809 if (c == 0)
389dd41b 8810 return omit_one_operand_loc (loc, type, build_real (type, dconst1),
b4d0c20c 8811 arg0);
8812
8813 /* Optimize pow(x,1) = x. */
8814 if (c == 1)
8815 return arg0;
8816
8817 /* Optimize pow(x,-1) = 1.0/x. */
8818 if (c == -1)
389dd41b 8819 return fold_build2_loc (loc, RDIV_EXPR, type,
49d00087 8820 build_real (type, dconst1), arg0);
b4d0c20c 8821 }
8822
8823 return NULL_TREE;
8824}
8825
8918c507 8826/* A subroutine of fold_builtin to fold the various exponent
c2f47e15 8827 functions. Return NULL_TREE if no simplification can be made.
debf9994 8828 FUNC is the corresponding MPFR exponent function. */
8918c507 8829
8830static tree
389dd41b 8831fold_builtin_exponent (location_t loc, tree fndecl, tree arg,
debf9994 8832 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8918c507 8833{
c2f47e15 8834 if (validate_arg (arg, REAL_TYPE))
8918c507 8835 {
8918c507 8836 tree type = TREE_TYPE (TREE_TYPE (fndecl));
29f4cd78 8837 tree res;
debf9994 8838
8839 /* Calculate the result when the argument is a constant. */
728bac60 8840 if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
debf9994 8841 return res;
8918c507 8842
8843 /* Optimize expN(logN(x)) = x. */
8844 if (flag_unsafe_math_optimizations)
a0c938f0 8845 {
8918c507 8846 const enum built_in_function fcode = builtin_mathfn_code (arg);
8847
debf9994 8848 if ((func == mpfr_exp
8918c507 8849 && (fcode == BUILT_IN_LOG
8850 || fcode == BUILT_IN_LOGF
8851 || fcode == BUILT_IN_LOGL))
debf9994 8852 || (func == mpfr_exp2
8918c507 8853 && (fcode == BUILT_IN_LOG2
8854 || fcode == BUILT_IN_LOG2F
8855 || fcode == BUILT_IN_LOG2L))
debf9994 8856 || (func == mpfr_exp10
8918c507 8857 && (fcode == BUILT_IN_LOG10
8858 || fcode == BUILT_IN_LOG10F
8859 || fcode == BUILT_IN_LOG10L)))
389dd41b 8860 return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0));
8918c507 8861 }
8862 }
8863
c2f47e15 8864 return NULL_TREE;
8918c507 8865}
8866
e973ffcc 8867/* Return true if VAR is a VAR_DECL or a component thereof. */
8868
8869static bool
8870var_decl_component_p (tree var)
8871{
8872 tree inner = var;
8873 while (handled_component_p (inner))
8874 inner = TREE_OPERAND (inner, 0);
8875 return SSA_VAR_P (inner);
8876}
8877
4f46f2b9 8878/* Fold function call to builtin memset. Return
9c8a1629 8879 NULL_TREE if no simplification can be made. */
8880
8881static tree
389dd41b 8882fold_builtin_memset (location_t loc, tree dest, tree c, tree len,
8883 tree type, bool ignore)
9c8a1629 8884{
45bb3afb 8885 tree var, ret, etype;
4f46f2b9 8886 unsigned HOST_WIDE_INT length, cval;
9c8a1629 8887
c2f47e15 8888 if (! validate_arg (dest, POINTER_TYPE)
8889 || ! validate_arg (c, INTEGER_TYPE)
8890 || ! validate_arg (len, INTEGER_TYPE))
8891 return NULL_TREE;
9c8a1629 8892
4f46f2b9 8893 if (! host_integerp (len, 1))
c2f47e15 8894 return NULL_TREE;
4f46f2b9 8895
9c8a1629 8896 /* If the LEN parameter is zero, return DEST. */
8897 if (integer_zerop (len))
389dd41b 8898 return omit_one_operand_loc (loc, type, dest, c);
9c8a1629 8899
4f46f2b9 8900 if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
c2f47e15 8901 return NULL_TREE;
9c8a1629 8902
4f46f2b9 8903 var = dest;
8904 STRIP_NOPS (var);
8905 if (TREE_CODE (var) != ADDR_EXPR)
c2f47e15 8906 return NULL_TREE;
4f46f2b9 8907
8908 var = TREE_OPERAND (var, 0);
8909 if (TREE_THIS_VOLATILE (var))
c2f47e15 8910 return NULL_TREE;
4f46f2b9 8911
45bb3afb 8912 etype = TREE_TYPE (var);
8913 if (TREE_CODE (etype) == ARRAY_TYPE)
8914 etype = TREE_TYPE (etype);
8915
8916 if (!INTEGRAL_TYPE_P (etype)
8917 && !POINTER_TYPE_P (etype))
c2f47e15 8918 return NULL_TREE;
4f46f2b9 8919
e973ffcc 8920 if (! var_decl_component_p (var))
c2f47e15 8921 return NULL_TREE;
e973ffcc 8922
4f46f2b9 8923 length = tree_low_cst (len, 1);
45bb3afb 8924 if (GET_MODE_SIZE (TYPE_MODE (etype)) != length
4f46f2b9 8925 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8926 < (int) length)
c2f47e15 8927 return NULL_TREE;
4f46f2b9 8928
8929 if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
c2f47e15 8930 return NULL_TREE;
4f46f2b9 8931
8932 if (integer_zerop (c))
8933 cval = 0;
8934 else
8935 {
8936 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
c2f47e15 8937 return NULL_TREE;
4f46f2b9 8938
8939 cval = tree_low_cst (c, 1);
8940 cval &= 0xff;
8941 cval |= cval << 8;
8942 cval |= cval << 16;
8943 cval |= (cval << 31) << 1;
8944 }
8945
45bb3afb 8946 ret = build_int_cst_type (etype, cval);
389dd41b 8947 var = build_fold_indirect_ref_loc (loc,
8948 fold_convert_loc (loc,
8949 build_pointer_type (etype),
8950 dest));
45bb3afb 8951 ret = build2 (MODIFY_EXPR, etype, var, ret);
4f46f2b9 8952 if (ignore)
8953 return ret;
8954
389dd41b 8955 return omit_one_operand_loc (loc, type, dest, ret);
9c8a1629 8956}
8957
4f46f2b9 8958/* Fold function call to builtin memset. Return
9c8a1629 8959 NULL_TREE if no simplification can be made. */
8960
8961static tree
389dd41b 8962fold_builtin_bzero (location_t loc, tree dest, tree size, bool ignore)
9c8a1629 8963{
c2f47e15 8964 if (! validate_arg (dest, POINTER_TYPE)
8965 || ! validate_arg (size, INTEGER_TYPE))
8966 return NULL_TREE;
9c8a1629 8967
4f46f2b9 8968 if (!ignore)
c2f47e15 8969 return NULL_TREE;
a0c938f0 8970
4f46f2b9 8971 /* New argument list transforming bzero(ptr x, int y) to
8972 memset(ptr x, int 0, size_t y). This is done this way
8973 so that if it isn't expanded inline, we fallback to
8974 calling bzero instead of memset. */
8975
389dd41b 8976 return fold_builtin_memset (loc, dest, integer_zero_node,
8977 fold_convert_loc (loc, sizetype, size),
c2f47e15 8978 void_type_node, ignore);
9c8a1629 8979}
8980
4f46f2b9 8981/* Fold function call to builtin mem{{,p}cpy,move}. Return
8982 NULL_TREE if no simplification can be made.
8983 If ENDP is 0, return DEST (like memcpy).
8984 If ENDP is 1, return DEST+LEN (like mempcpy).
8985 If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8986 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8987 (memmove). */
9c8a1629 8988
8989static tree
389dd41b 8990fold_builtin_memory_op (location_t loc, tree dest, tree src,
8991 tree len, tree type, bool ignore, int endp)
9c8a1629 8992{
c2f47e15 8993 tree destvar, srcvar, expr;
9c8a1629 8994
c2f47e15 8995 if (! validate_arg (dest, POINTER_TYPE)
8996 || ! validate_arg (src, POINTER_TYPE)
8997 || ! validate_arg (len, INTEGER_TYPE))
8998 return NULL_TREE;
9c8a1629 8999
9000 /* If the LEN parameter is zero, return DEST. */
9001 if (integer_zerop (len))
389dd41b 9002 return omit_one_operand_loc (loc, type, dest, src);
9c8a1629 9003
4f46f2b9 9004 /* If SRC and DEST are the same (and not volatile), return
9005 DEST{,+LEN,+LEN-1}. */
9c8a1629 9006 if (operand_equal_p (src, dest, 0))
4f46f2b9 9007 expr = len;
9008 else
9009 {
5a84fdd6 9010 tree srctype, desttype;
5383fb56 9011 int src_align, dest_align;
9012
3b1757a2 9013 if (endp == 3)
9014 {
5383fb56 9015 src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
9016 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
5a84fdd6 9017
3b1757a2 9018 /* Both DEST and SRC must be pointer types.
9019 ??? This is what old code did. Is the testing for pointer types
9020 really mandatory?
9021
9022 If either SRC is readonly or length is 1, we can use memcpy. */
3f95c690 9023 if (!dest_align || !src_align)
9024 return NULL_TREE;
9025 if (readonly_data_expr (src)
9026 || (host_integerp (len, 1)
9027 && (MIN (src_align, dest_align) / BITS_PER_UNIT
9028 >= tree_low_cst (len, 1))))
3b1757a2 9029 {
9030 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
9031 if (!fn)
c2f47e15 9032 return NULL_TREE;
389dd41b 9033 return build_call_expr_loc (loc, fn, 3, dest, src, len);
3b1757a2 9034 }
3f95c690 9035
9036 /* If *src and *dest can't overlap, optimize into memcpy as well. */
f85fb819 9037 srcvar = build_fold_indirect_ref_loc (loc, src);
9038 destvar = build_fold_indirect_ref_loc (loc, dest);
9039 if (srcvar
9040 && !TREE_THIS_VOLATILE (srcvar)
9041 && destvar
9042 && !TREE_THIS_VOLATILE (destvar))
3f95c690 9043 {
f85fb819 9044 tree src_base, dest_base, fn;
9045 HOST_WIDE_INT src_offset = 0, dest_offset = 0;
9046 HOST_WIDE_INT size = -1;
9047 HOST_WIDE_INT maxsize = -1;
9048
9049 src_base = srcvar;
9050 if (handled_component_p (src_base))
9051 src_base = get_ref_base_and_extent (src_base, &src_offset,
9052 &size, &maxsize);
9053 dest_base = destvar;
9054 if (handled_component_p (dest_base))
9055 dest_base = get_ref_base_and_extent (dest_base, &dest_offset,
9056 &size, &maxsize);
9057 if (host_integerp (len, 1))
9058 {
9059 maxsize = tree_low_cst (len, 1);
9060 if (maxsize
9061 > INTTYPE_MAXIMUM (HOST_WIDE_INT) / BITS_PER_UNIT)
9062 maxsize = -1;
9063 else
9064 maxsize *= BITS_PER_UNIT;
9065 }
9066 else
9067 maxsize = -1;
9068 if (SSA_VAR_P (src_base)
9069 && SSA_VAR_P (dest_base))
9070 {
9071 if (operand_equal_p (src_base, dest_base, 0)
9072 && ranges_overlap_p (src_offset, maxsize,
9073 dest_offset, maxsize))
9074 return NULL_TREE;
9075 }
9076 else if (TREE_CODE (src_base) == INDIRECT_REF
9077 && TREE_CODE (dest_base) == INDIRECT_REF)
9078 {
9079 if (! operand_equal_p (TREE_OPERAND (src_base, 0),
9080 TREE_OPERAND (dest_base, 0), 0)
9081 || ranges_overlap_p (src_offset, maxsize,
9082 dest_offset, maxsize))
9083 return NULL_TREE;
9084 }
9085 else
9086 return NULL_TREE;
9087
9088 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3f95c690 9089 if (!fn)
9090 return NULL_TREE;
389dd41b 9091 return build_call_expr_loc (loc, fn, 3, dest, src, len);
3f95c690 9092 }
c2f47e15 9093 return NULL_TREE;
3b1757a2 9094 }
4f46f2b9 9095
5a84fdd6 9096 if (!host_integerp (len, 0))
c2f47e15 9097 return NULL_TREE;
5a84fdd6 9098 /* FIXME:
9099 This logic lose for arguments like (type *)malloc (sizeof (type)),
9100 since we strip the casts of up to VOID return value from malloc.
9101 Perhaps we ought to inherit type from non-VOID argument here? */
9102 STRIP_NOPS (src);
9103 STRIP_NOPS (dest);
45bb3afb 9104 /* As we fold (void *)(p + CST) to (void *)p + CST undo this here. */
9105 if (TREE_CODE (src) == POINTER_PLUS_EXPR)
9106 {
9107 tree tem = TREE_OPERAND (src, 0);
9108 STRIP_NOPS (tem);
9109 if (tem != TREE_OPERAND (src, 0))
9110 src = build1 (NOP_EXPR, TREE_TYPE (tem), src);
9111 }
9112 if (TREE_CODE (dest) == POINTER_PLUS_EXPR)
9113 {
9114 tree tem = TREE_OPERAND (dest, 0);
9115 STRIP_NOPS (tem);
9116 if (tem != TREE_OPERAND (dest, 0))
9117 dest = build1 (NOP_EXPR, TREE_TYPE (tem), dest);
9118 }
5a84fdd6 9119 srctype = TREE_TYPE (TREE_TYPE (src));
45bb3afb 9120 if (srctype
97d4c6a6 9121 && TREE_CODE (srctype) == ARRAY_TYPE
9122 && !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
45bb3afb 9123 {
9124 srctype = TREE_TYPE (srctype);
9125 STRIP_NOPS (src);
9126 src = build1 (NOP_EXPR, build_pointer_type (srctype), src);
9127 }
5a84fdd6 9128 desttype = TREE_TYPE (TREE_TYPE (dest));
45bb3afb 9129 if (desttype
97d4c6a6 9130 && TREE_CODE (desttype) == ARRAY_TYPE
9131 && !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
45bb3afb 9132 {
9133 desttype = TREE_TYPE (desttype);
9134 STRIP_NOPS (dest);
9135 dest = build1 (NOP_EXPR, build_pointer_type (desttype), dest);
9136 }
5a84fdd6 9137 if (!srctype || !desttype
9138 || !TYPE_SIZE_UNIT (srctype)
9139 || !TYPE_SIZE_UNIT (desttype)
9140 || TREE_CODE (TYPE_SIZE_UNIT (srctype)) != INTEGER_CST
6f52ebeb 9141 || TREE_CODE (TYPE_SIZE_UNIT (desttype)) != INTEGER_CST
9142 || TYPE_VOLATILE (srctype)
9143 || TYPE_VOLATILE (desttype))
c2f47e15 9144 return NULL_TREE;
4f46f2b9 9145
5383fb56 9146 src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
9147 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
9148 if (dest_align < (int) TYPE_ALIGN (desttype)
9149 || src_align < (int) TYPE_ALIGN (srctype))
c2f47e15 9150 return NULL_TREE;
e973ffcc 9151
5a84fdd6 9152 if (!ignore)
9153 dest = builtin_save_expr (dest);
4f46f2b9 9154
5383fb56 9155 srcvar = NULL_TREE;
9156 if (tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
9157 {
389dd41b 9158 srcvar = build_fold_indirect_ref_loc (loc, src);
5383fb56 9159 if (TREE_THIS_VOLATILE (srcvar))
6f52ebeb 9160 return NULL_TREE;
92ddcd97 9161 else if (!tree_int_cst_equal (tree_expr_size (srcvar), len))
5383fb56 9162 srcvar = NULL_TREE;
9163 /* With memcpy, it is possible to bypass aliasing rules, so without
9164 this check i.e. execute/20060930-2.c would be misoptimized,
9165 because it use conflicting alias set to hold argument for the
9166 memcpy call. This check is probably unnecessary with
9167 -fno-strict-aliasing. Similarly for destvar. See also
9168 PR29286. */
9169 else if (!var_decl_component_p (srcvar))
9170 srcvar = NULL_TREE;
9171 }
4f46f2b9 9172
5383fb56 9173 destvar = NULL_TREE;
9174 if (tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
9175 {
389dd41b 9176 destvar = build_fold_indirect_ref_loc (loc, dest);
5383fb56 9177 if (TREE_THIS_VOLATILE (destvar))
6f52ebeb 9178 return NULL_TREE;
92ddcd97 9179 else if (!tree_int_cst_equal (tree_expr_size (destvar), len))
5383fb56 9180 destvar = NULL_TREE;
9181 else if (!var_decl_component_p (destvar))
9182 destvar = NULL_TREE;
9183 }
9184
9185 if (srcvar == NULL_TREE && destvar == NULL_TREE)
c2f47e15 9186 return NULL_TREE;
4f46f2b9 9187
5383fb56 9188 if (srcvar == NULL_TREE)
9189 {
9190 tree srcptype;
9191 if (TREE_ADDRESSABLE (TREE_TYPE (destvar)))
9192 return NULL_TREE;
9193
6f52ebeb 9194 srctype = build_qualified_type (desttype, 0);
5383fb56 9195 if (src_align < (int) TYPE_ALIGN (srctype))
9196 {
9197 if (AGGREGATE_TYPE_P (srctype)
9198 || SLOW_UNALIGNED_ACCESS (TYPE_MODE (srctype), src_align))
9199 return NULL_TREE;
9200
9201 srctype = build_variant_type_copy (srctype);
9202 TYPE_ALIGN (srctype) = src_align;
9203 TYPE_USER_ALIGN (srctype) = 1;
9204 TYPE_PACKED (srctype) = 1;
9205 }
9206 srcptype = build_pointer_type_for_mode (srctype, ptr_mode, true);
389dd41b 9207 src = fold_convert_loc (loc, srcptype, src);
9208 srcvar = build_fold_indirect_ref_loc (loc, src);
5383fb56 9209 }
9210 else if (destvar == NULL_TREE)
9211 {
9212 tree destptype;
9213 if (TREE_ADDRESSABLE (TREE_TYPE (srcvar)))
9214 return NULL_TREE;
9215
6f52ebeb 9216 desttype = build_qualified_type (srctype, 0);
5383fb56 9217 if (dest_align < (int) TYPE_ALIGN (desttype))
9218 {
9219 if (AGGREGATE_TYPE_P (desttype)
9220 || SLOW_UNALIGNED_ACCESS (TYPE_MODE (desttype), dest_align))
9221 return NULL_TREE;
9222
9223 desttype = build_variant_type_copy (desttype);
9224 TYPE_ALIGN (desttype) = dest_align;
9225 TYPE_USER_ALIGN (desttype) = 1;
9226 TYPE_PACKED (desttype) = 1;
9227 }
9228 destptype = build_pointer_type_for_mode (desttype, ptr_mode, true);
389dd41b 9229 dest = fold_convert_loc (loc, destptype, dest);
9230 destvar = build_fold_indirect_ref_loc (loc, dest);
5383fb56 9231 }
9232
5a84fdd6 9233 if (srctype == desttype
2d04fd8d 9234 || (gimple_in_ssa_p (cfun)
548044d8 9235 && useless_type_conversion_p (desttype, srctype)))
5a84fdd6 9236 expr = srcvar;
9237 else if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
4f46f2b9 9238 || POINTER_TYPE_P (TREE_TYPE (srcvar)))
9239 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
9240 || POINTER_TYPE_P (TREE_TYPE (destvar))))
389dd41b 9241 expr = fold_convert_loc (loc, TREE_TYPE (destvar), srcvar);
4f46f2b9 9242 else
389dd41b 9243 expr = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
9244 TREE_TYPE (destvar), srcvar);
41076ef6 9245 expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, expr);
4f46f2b9 9246 }
9247
9248 if (ignore)
9249 return expr;
9250
9251 if (endp == 0 || endp == 3)
389dd41b 9252 return omit_one_operand_loc (loc, type, dest, expr);
4f46f2b9 9253
9254 if (expr == len)
c2f47e15 9255 expr = NULL_TREE;
4f46f2b9 9256
9257 if (endp == 2)
389dd41b 9258 len = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (len), len,
4f46f2b9 9259 ssize_int (1));
9260
389dd41b 9261 len = fold_convert_loc (loc, sizetype, len);
9262 dest = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
9263 dest = fold_convert_loc (loc, type, dest);
4f46f2b9 9264 if (expr)
389dd41b 9265 dest = omit_one_operand_loc (loc, type, dest, expr);
4f46f2b9 9266 return dest;
9267}
9268
c2f47e15 9269/* Fold function call to builtin strcpy with arguments DEST and SRC.
9270 If LEN is not NULL, it represents the length of the string to be
9271 copied. Return NULL_TREE if no simplification can be made. */
9c8a1629 9272
f0613857 9273tree
389dd41b 9274fold_builtin_strcpy (location_t loc, tree fndecl, tree dest, tree src, tree len)
9c8a1629 9275{
c2f47e15 9276 tree fn;
9c8a1629 9277
c2f47e15 9278 if (!validate_arg (dest, POINTER_TYPE)
9279 || !validate_arg (src, POINTER_TYPE))
9280 return NULL_TREE;
9c8a1629 9281
9282 /* If SRC and DEST are the same (and not volatile), return DEST. */
9283 if (operand_equal_p (src, dest, 0))
389dd41b 9284 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest);
9c8a1629 9285
0bfd8d5c 9286 if (optimize_function_for_size_p (cfun))
c2f47e15 9287 return NULL_TREE;
f0613857 9288
9289 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
9290 if (!fn)
c2f47e15 9291 return NULL_TREE;
f0613857 9292
9293 if (!len)
9294 {
9295 len = c_strlen (src, 1);
9296 if (! len || TREE_SIDE_EFFECTS (len))
c2f47e15 9297 return NULL_TREE;
f0613857 9298 }
9299
389dd41b 9300 len = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
9301 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
9302 build_call_expr_loc (loc, fn, 3, dest, src, len));
9c8a1629 9303}
9304
c2f47e15 9305/* Fold function call to builtin strncpy with arguments DEST, SRC, and LEN.
9306 If SLEN is not NULL, it represents the length of the source string.
9307 Return NULL_TREE if no simplification can be made. */
9c8a1629 9308
f0613857 9309tree
389dd41b 9310fold_builtin_strncpy (location_t loc, tree fndecl, tree dest,
9311 tree src, tree len, tree slen)
9c8a1629 9312{
c2f47e15 9313 tree fn;
9c8a1629 9314
c2f47e15 9315 if (!validate_arg (dest, POINTER_TYPE)
9316 || !validate_arg (src, POINTER_TYPE)
9317 || !validate_arg (len, INTEGER_TYPE))
9318 return NULL_TREE;
9c8a1629 9319
9320 /* If the LEN parameter is zero, return DEST. */
9321 if (integer_zerop (len))
389dd41b 9322 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
9c8a1629 9323
19226313 9324 /* We can't compare slen with len as constants below if len is not a
9325 constant. */
9326 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
c2f47e15 9327 return NULL_TREE;
19226313 9328
f0613857 9329 if (!slen)
9330 slen = c_strlen (src, 1);
9331
9332 /* Now, we must be passed a constant src ptr parameter. */
9333 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
c2f47e15 9334 return NULL_TREE;
f0613857 9335
389dd41b 9336 slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
f0613857 9337
9338 /* We do not support simplification of this case, though we do
9339 support it when expanding trees into RTL. */
9340 /* FIXME: generate a call to __builtin_memset. */
9341 if (tree_int_cst_lt (slen, len))
c2f47e15 9342 return NULL_TREE;
f0613857 9343
9344 /* OK transform into builtin memcpy. */
9345 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
9346 if (!fn)
c2f47e15 9347 return NULL_TREE;
389dd41b 9348 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
9349 build_call_expr_loc (loc, fn, 3, dest, src, len));
9c8a1629 9350}
9351
7959b13b 9352/* Fold function call to builtin memchr. ARG1, ARG2 and LEN are the
9353 arguments to the call, and TYPE is its return type.
9354 Return NULL_TREE if no simplification can be made. */
9355
9356static tree
389dd41b 9357fold_builtin_memchr (location_t loc, tree arg1, tree arg2, tree len, tree type)
7959b13b 9358{
9359 if (!validate_arg (arg1, POINTER_TYPE)
9360 || !validate_arg (arg2, INTEGER_TYPE)
9361 || !validate_arg (len, INTEGER_TYPE))
9362 return NULL_TREE;
9363 else
9364 {
9365 const char *p1;
9366
9367 if (TREE_CODE (arg2) != INTEGER_CST
9368 || !host_integerp (len, 1))
9369 return NULL_TREE;
9370
9371 p1 = c_getstr (arg1);
9372 if (p1 && compare_tree_int (len, strlen (p1) + 1) <= 0)
9373 {
9374 char c;
9375 const char *r;
9376 tree tem;
9377
9378 if (target_char_cast (arg2, &c))
9379 return NULL_TREE;
9380
364c0c59 9381 r = (char *) memchr (p1, c, tree_low_cst (len, 1));
7959b13b 9382
9383 if (r == NULL)
9384 return build_int_cst (TREE_TYPE (arg1), 0);
9385
389dd41b 9386 tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (arg1), arg1,
0de36bdb 9387 size_int (r - p1));
389dd41b 9388 return fold_convert_loc (loc, type, tem);
7959b13b 9389 }
9390 return NULL_TREE;
9391 }
9392}
9393
c2f47e15 9394/* Fold function call to builtin memcmp with arguments ARG1 and ARG2.
9395 Return NULL_TREE if no simplification can be made. */
9c8a1629 9396
9397static tree
389dd41b 9398fold_builtin_memcmp (location_t loc, tree arg1, tree arg2, tree len)
9c8a1629 9399{
c4fef134 9400 const char *p1, *p2;
9c8a1629 9401
c2f47e15 9402 if (!validate_arg (arg1, POINTER_TYPE)
9403 || !validate_arg (arg2, POINTER_TYPE)
9404 || !validate_arg (len, INTEGER_TYPE))
9405 return NULL_TREE;
9c8a1629 9406
9407 /* If the LEN parameter is zero, return zero. */
9408 if (integer_zerop (len))
389dd41b 9409 return omit_two_operands_loc (loc, integer_type_node, integer_zero_node,
c4fef134 9410 arg1, arg2);
9c8a1629 9411
9412 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
9413 if (operand_equal_p (arg1, arg2, 0))
389dd41b 9414 return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len);
c4fef134 9415
9416 p1 = c_getstr (arg1);
9417 p2 = c_getstr (arg2);
9418
9419 /* If all arguments are constant, and the value of len is not greater
9420 than the lengths of arg1 and arg2, evaluate at compile-time. */
9421 if (host_integerp (len, 1) && p1 && p2
9422 && compare_tree_int (len, strlen (p1) + 1) <= 0
9423 && compare_tree_int (len, strlen (p2) + 1) <= 0)
9424 {
9425 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
9426
9427 if (r > 0)
9428 return integer_one_node;
9429 else if (r < 0)
9430 return integer_minus_one_node;
9431 else
9432 return integer_zero_node;
9433 }
9434
9435 /* If len parameter is one, return an expression corresponding to
9436 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
9437 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9438 {
9439 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9440 tree cst_uchar_ptr_node
9441 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9442
389dd41b 9443 tree ind1
9444 = fold_convert_loc (loc, integer_type_node,
9445 build1 (INDIRECT_REF, cst_uchar_node,
9446 fold_convert_loc (loc,
9447 cst_uchar_ptr_node,
c4fef134 9448 arg1)));
389dd41b 9449 tree ind2
9450 = fold_convert_loc (loc, integer_type_node,
9451 build1 (INDIRECT_REF, cst_uchar_node,
9452 fold_convert_loc (loc,
9453 cst_uchar_ptr_node,
c4fef134 9454 arg2)));
389dd41b 9455 return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2);
c4fef134 9456 }
9c8a1629 9457
c2f47e15 9458 return NULL_TREE;
9c8a1629 9459}
9460
c2f47e15 9461/* Fold function call to builtin strcmp with arguments ARG1 and ARG2.
9462 Return NULL_TREE if no simplification can be made. */
9c8a1629 9463
9464static tree
389dd41b 9465fold_builtin_strcmp (location_t loc, tree arg1, tree arg2)
9c8a1629 9466{
9c8a1629 9467 const char *p1, *p2;
9468
c2f47e15 9469 if (!validate_arg (arg1, POINTER_TYPE)
9470 || !validate_arg (arg2, POINTER_TYPE))
9471 return NULL_TREE;
9c8a1629 9472
9473 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
9474 if (operand_equal_p (arg1, arg2, 0))
c4fef134 9475 return integer_zero_node;
9c8a1629 9476
9477 p1 = c_getstr (arg1);
9478 p2 = c_getstr (arg2);
9479
9480 if (p1 && p2)
9481 {
9c8a1629 9482 const int i = strcmp (p1, p2);
9483 if (i < 0)
c4fef134 9484 return integer_minus_one_node;
9c8a1629 9485 else if (i > 0)
c4fef134 9486 return integer_one_node;
9c8a1629 9487 else
c4fef134 9488 return integer_zero_node;
9489 }
9490
9491 /* If the second arg is "", return *(const unsigned char*)arg1. */
9492 if (p2 && *p2 == '\0')
9493 {
9494 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9495 tree cst_uchar_ptr_node
9496 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9497
389dd41b 9498 return fold_convert_loc (loc, integer_type_node,
9499 build1 (INDIRECT_REF, cst_uchar_node,
9500 fold_convert_loc (loc,
9501 cst_uchar_ptr_node,
9502 arg1)));
c4fef134 9503 }
9504
9505 /* If the first arg is "", return -*(const unsigned char*)arg2. */
9506 if (p1 && *p1 == '\0')
9507 {
9508 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9509 tree cst_uchar_ptr_node
9510 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9511
389dd41b 9512 tree temp
9513 = fold_convert_loc (loc, integer_type_node,
9514 build1 (INDIRECT_REF, cst_uchar_node,
9515 fold_convert_loc (loc,
9516 cst_uchar_ptr_node,
c4fef134 9517 arg2)));
389dd41b 9518 return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp);
9c8a1629 9519 }
9520
c2f47e15 9521 return NULL_TREE;
9c8a1629 9522}
9523
c2f47e15 9524/* Fold function call to builtin strncmp with arguments ARG1, ARG2, and LEN.
9525 Return NULL_TREE if no simplification can be made. */
9c8a1629 9526
9527static tree
389dd41b 9528fold_builtin_strncmp (location_t loc, tree arg1, tree arg2, tree len)
9c8a1629 9529{
9c8a1629 9530 const char *p1, *p2;
9531
c2f47e15 9532 if (!validate_arg (arg1, POINTER_TYPE)
9533 || !validate_arg (arg2, POINTER_TYPE)
9534 || !validate_arg (len, INTEGER_TYPE))
9535 return NULL_TREE;
9c8a1629 9536
9537 /* If the LEN parameter is zero, return zero. */
9538 if (integer_zerop (len))
389dd41b 9539 return omit_two_operands_loc (loc, integer_type_node, integer_zero_node,
c4fef134 9540 arg1, arg2);
9c8a1629 9541
9542 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
9543 if (operand_equal_p (arg1, arg2, 0))
389dd41b 9544 return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len);
9c8a1629 9545
9546 p1 = c_getstr (arg1);
9547 p2 = c_getstr (arg2);
9548
9549 if (host_integerp (len, 1) && p1 && p2)
9550 {
9c8a1629 9551 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
c4fef134 9552 if (i > 0)
9553 return integer_one_node;
9554 else if (i < 0)
9555 return integer_minus_one_node;
9c8a1629 9556 else
c4fef134 9557 return integer_zero_node;
9558 }
9559
9560 /* If the second arg is "", and the length is greater than zero,
9561 return *(const unsigned char*)arg1. */
9562 if (p2 && *p2 == '\0'
9563 && TREE_CODE (len) == INTEGER_CST
9564 && tree_int_cst_sgn (len) == 1)
9565 {
9566 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9567 tree cst_uchar_ptr_node
9568 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9569
389dd41b 9570 return fold_convert_loc (loc, integer_type_node,
9571 build1 (INDIRECT_REF, cst_uchar_node,
9572 fold_convert_loc (loc,
9573 cst_uchar_ptr_node,
9574 arg1)));
c4fef134 9575 }
9576
9577 /* If the first arg is "", and the length is greater than zero,
9578 return -*(const unsigned char*)arg2. */
9579 if (p1 && *p1 == '\0'
9580 && TREE_CODE (len) == INTEGER_CST
9581 && tree_int_cst_sgn (len) == 1)
9582 {
9583 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9584 tree cst_uchar_ptr_node
9585 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9586
389dd41b 9587 tree temp = fold_convert_loc (loc, integer_type_node,
9588 build1 (INDIRECT_REF, cst_uchar_node,
9589 fold_convert_loc (loc,
9590 cst_uchar_ptr_node,
9591 arg2)));
9592 return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp);
c4fef134 9593 }
9594
9595 /* If len parameter is one, return an expression corresponding to
9596 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
9597 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9598 {
9599 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
4f1b71c0 9600 tree cst_uchar_ptr_node
9601 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9602
389dd41b 9603 tree ind1 = fold_convert_loc (loc, integer_type_node,
9604 build1 (INDIRECT_REF, cst_uchar_node,
9605 fold_convert_loc (loc,
9606 cst_uchar_ptr_node,
9607 arg1)));
9608 tree ind2 = fold_convert_loc (loc, integer_type_node,
9609 build1 (INDIRECT_REF, cst_uchar_node,
9610 fold_convert_loc (loc,
9611 cst_uchar_ptr_node,
9612 arg2)));
9613 return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2);
9c8a1629 9614 }
9615
c2f47e15 9616 return NULL_TREE;
9c8a1629 9617}
9618
c2f47e15 9619/* Fold function call to builtin signbit, signbitf or signbitl with argument
9620 ARG. Return NULL_TREE if no simplification can be made. */
27f261ef 9621
9622static tree
389dd41b 9623fold_builtin_signbit (location_t loc, tree arg, tree type)
27f261ef 9624{
c2f47e15 9625 tree temp;
27f261ef 9626
c2f47e15 9627 if (!validate_arg (arg, REAL_TYPE))
27f261ef 9628 return NULL_TREE;
9629
27f261ef 9630 /* If ARG is a compile-time constant, determine the result. */
9631 if (TREE_CODE (arg) == REAL_CST
f96bd2bf 9632 && !TREE_OVERFLOW (arg))
27f261ef 9633 {
9634 REAL_VALUE_TYPE c;
9635
9636 c = TREE_REAL_CST (arg);
9637 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
389dd41b 9638 return fold_convert_loc (loc, type, temp);
27f261ef 9639 }
9640
9641 /* If ARG is non-negative, the result is always zero. */
9642 if (tree_expr_nonnegative_p (arg))
389dd41b 9643 return omit_one_operand_loc (loc, type, integer_zero_node, arg);
27f261ef 9644
9645 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
9646 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
389dd41b 9647 return fold_build2_loc (loc, LT_EXPR, type, arg,
49d00087 9648 build_real (TREE_TYPE (arg), dconst0));
27f261ef 9649
9650 return NULL_TREE;
9651}
9652
c2f47e15 9653/* Fold function call to builtin copysign, copysignf or copysignl with
9654 arguments ARG1 and ARG2. Return NULL_TREE if no simplification can
9655 be made. */
467214fd 9656
9657static tree
389dd41b 9658fold_builtin_copysign (location_t loc, tree fndecl,
9659 tree arg1, tree arg2, tree type)
467214fd 9660{
c2f47e15 9661 tree tem;
467214fd 9662
c2f47e15 9663 if (!validate_arg (arg1, REAL_TYPE)
9664 || !validate_arg (arg2, REAL_TYPE))
467214fd 9665 return NULL_TREE;
9666
467214fd 9667 /* copysign(X,X) is X. */
9668 if (operand_equal_p (arg1, arg2, 0))
389dd41b 9669 return fold_convert_loc (loc, type, arg1);
467214fd 9670
9671 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
9672 if (TREE_CODE (arg1) == REAL_CST
9673 && TREE_CODE (arg2) == REAL_CST
f96bd2bf 9674 && !TREE_OVERFLOW (arg1)
9675 && !TREE_OVERFLOW (arg2))
467214fd 9676 {
9677 REAL_VALUE_TYPE c1, c2;
9678
9679 c1 = TREE_REAL_CST (arg1);
9680 c2 = TREE_REAL_CST (arg2);
749680e2 9681 /* c1.sign := c2.sign. */
467214fd 9682 real_copysign (&c1, &c2);
9683 return build_real (type, c1);
467214fd 9684 }
9685
9686 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
9687 Remember to evaluate Y for side-effects. */
9688 if (tree_expr_nonnegative_p (arg2))
389dd41b 9689 return omit_one_operand_loc (loc, type,
9690 fold_build1_loc (loc, ABS_EXPR, type, arg1),
467214fd 9691 arg2);
9692
198d9bbe 9693 /* Strip sign changing operations for the first argument. */
9694 tem = fold_strip_sign_ops (arg1);
9695 if (tem)
389dd41b 9696 return build_call_expr_loc (loc, fndecl, 2, tem, arg2);
198d9bbe 9697
467214fd 9698 return NULL_TREE;
9699}
9700
c2f47e15 9701/* Fold a call to builtin isascii with argument ARG. */
d49367d4 9702
9703static tree
389dd41b 9704fold_builtin_isascii (location_t loc, tree arg)
d49367d4 9705{
c2f47e15 9706 if (!validate_arg (arg, INTEGER_TYPE))
9707 return NULL_TREE;
d49367d4 9708 else
9709 {
9710 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
7c446c95 9711 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
9712 build_int_cst (NULL_TREE,
7016c612 9713 ~ (unsigned HOST_WIDE_INT) 0x7f));
389dd41b 9714 return fold_build2_loc (loc, EQ_EXPR, integer_type_node,
f2532264 9715 arg, integer_zero_node);
d49367d4 9716 }
9717}
9718
c2f47e15 9719/* Fold a call to builtin toascii with argument ARG. */
d49367d4 9720
9721static tree
389dd41b 9722fold_builtin_toascii (location_t loc, tree arg)
d49367d4 9723{
c2f47e15 9724 if (!validate_arg (arg, INTEGER_TYPE))
9725 return NULL_TREE;
9726
9727 /* Transform toascii(c) -> (c & 0x7f). */
389dd41b 9728 return fold_build2_loc (loc, BIT_AND_EXPR, integer_type_node, arg,
c2f47e15 9729 build_int_cst (NULL_TREE, 0x7f));
d49367d4 9730}
9731
c2f47e15 9732/* Fold a call to builtin isdigit with argument ARG. */
df1cf42e 9733
9734static tree
389dd41b 9735fold_builtin_isdigit (location_t loc, tree arg)
df1cf42e 9736{
c2f47e15 9737 if (!validate_arg (arg, INTEGER_TYPE))
9738 return NULL_TREE;
df1cf42e 9739 else
9740 {
9741 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
624d37a6 9742 /* According to the C standard, isdigit is unaffected by locale.
9743 However, it definitely is affected by the target character set. */
624d37a6 9744 unsigned HOST_WIDE_INT target_digit0
9745 = lang_hooks.to_target_charset ('0');
9746
9747 if (target_digit0 == 0)
9748 return NULL_TREE;
9749
389dd41b 9750 arg = fold_convert_loc (loc, unsigned_type_node, arg);
05abc81b 9751 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
624d37a6 9752 build_int_cst (unsigned_type_node, target_digit0));
389dd41b 9753 return fold_build2_loc (loc, LE_EXPR, integer_type_node, arg,
f2532264 9754 build_int_cst (unsigned_type_node, 9));
df1cf42e 9755 }
9756}
27f261ef 9757
c2f47e15 9758/* Fold a call to fabs, fabsf or fabsl with argument ARG. */
d1aade50 9759
9760static tree
389dd41b 9761fold_builtin_fabs (location_t loc, tree arg, tree type)
d1aade50 9762{
c2f47e15 9763 if (!validate_arg (arg, REAL_TYPE))
9764 return NULL_TREE;
d1aade50 9765
389dd41b 9766 arg = fold_convert_loc (loc, type, arg);
d1aade50 9767 if (TREE_CODE (arg) == REAL_CST)
9768 return fold_abs_const (arg, type);
389dd41b 9769 return fold_build1_loc (loc, ABS_EXPR, type, arg);
d1aade50 9770}
9771
c2f47e15 9772/* Fold a call to abs, labs, llabs or imaxabs with argument ARG. */
d1aade50 9773
9774static tree
389dd41b 9775fold_builtin_abs (location_t loc, tree arg, tree type)
d1aade50 9776{
c2f47e15 9777 if (!validate_arg (arg, INTEGER_TYPE))
9778 return NULL_TREE;
d1aade50 9779
389dd41b 9780 arg = fold_convert_loc (loc, type, arg);
d1aade50 9781 if (TREE_CODE (arg) == INTEGER_CST)
9782 return fold_abs_const (arg, type);
389dd41b 9783 return fold_build1_loc (loc, ABS_EXPR, type, arg);
d1aade50 9784}
9785
d4a43a03 9786/* Fold a call to builtin fmin or fmax. */
9787
9788static tree
389dd41b 9789fold_builtin_fmin_fmax (location_t loc, tree arg0, tree arg1,
9790 tree type, bool max)
d4a43a03 9791{
c2f47e15 9792 if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, REAL_TYPE))
d4a43a03 9793 {
d4a43a03 9794 /* Calculate the result when the argument is a constant. */
9795 tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
9796
9797 if (res)
9798 return res;
9799
61fe3555 9800 /* If either argument is NaN, return the other one. Avoid the
9801 transformation if we get (and honor) a signalling NaN. Using
9802 omit_one_operand() ensures we create a non-lvalue. */
9803 if (TREE_CODE (arg0) == REAL_CST
9804 && real_isnan (&TREE_REAL_CST (arg0))
9805 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
9806 || ! TREE_REAL_CST (arg0).signalling))
389dd41b 9807 return omit_one_operand_loc (loc, type, arg1, arg0);
61fe3555 9808 if (TREE_CODE (arg1) == REAL_CST
9809 && real_isnan (&TREE_REAL_CST (arg1))
9810 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
9811 || ! TREE_REAL_CST (arg1).signalling))
389dd41b 9812 return omit_one_operand_loc (loc, type, arg0, arg1);
61fe3555 9813
d4a43a03 9814 /* Transform fmin/fmax(x,x) -> x. */
9815 if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
389dd41b 9816 return omit_one_operand_loc (loc, type, arg0, arg1);
d4a43a03 9817
9818 /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR. C99 requires these
9819 functions to return the numeric arg if the other one is NaN.
9820 These tree codes don't honor that, so only transform if
9821 -ffinite-math-only is set. C99 doesn't require -0.0 to be
9822 handled, so we don't have to worry about it either. */
9823 if (flag_finite_math_only)
389dd41b 9824 return fold_build2_loc (loc, (max ? MAX_EXPR : MIN_EXPR), type,
9825 fold_convert_loc (loc, type, arg0),
9826 fold_convert_loc (loc, type, arg1));
d4a43a03 9827 }
9828 return NULL_TREE;
9829}
9830
abe4dcf6 9831/* Fold a call to builtin carg(a+bi) -> atan2(b,a). */
9832
9833static tree
389dd41b 9834fold_builtin_carg (location_t loc, tree arg, tree type)
abe4dcf6 9835{
239d491a 9836 if (validate_arg (arg, COMPLEX_TYPE)
9837 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
abe4dcf6 9838 {
9839 tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2);
9840
9841 if (atan2_fn)
9842 {
c2f47e15 9843 tree new_arg = builtin_save_expr (arg);
389dd41b 9844 tree r_arg = fold_build1_loc (loc, REALPART_EXPR, type, new_arg);
9845 tree i_arg = fold_build1_loc (loc, IMAGPART_EXPR, type, new_arg);
9846 return build_call_expr_loc (loc, atan2_fn, 2, i_arg, r_arg);
abe4dcf6 9847 }
9848 }
9849
9850 return NULL_TREE;
9851}
9852
cb2b9385 9853/* Fold a call to builtin logb/ilogb. */
9854
9855static tree
389dd41b 9856fold_builtin_logb (location_t loc, tree arg, tree rettype)
cb2b9385 9857{
9858 if (! validate_arg (arg, REAL_TYPE))
9859 return NULL_TREE;
9860
9861 STRIP_NOPS (arg);
9862
9863 if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9864 {
9865 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9866
9867 switch (value->cl)
9868 {
9869 case rvc_nan:
9870 case rvc_inf:
9871 /* If arg is Inf or NaN and we're logb, return it. */
9872 if (TREE_CODE (rettype) == REAL_TYPE)
389dd41b 9873 return fold_convert_loc (loc, rettype, arg);
cb2b9385 9874 /* Fall through... */
9875 case rvc_zero:
9876 /* Zero may set errno and/or raise an exception for logb, also
9877 for ilogb we don't know FP_ILOGB0. */
9878 return NULL_TREE;
9879 case rvc_normal:
9880 /* For normal numbers, proceed iff radix == 2. In GCC,
9881 normalized significands are in the range [0.5, 1.0). We
9882 want the exponent as if they were [1.0, 2.0) so get the
9883 exponent and subtract 1. */
9884 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
389dd41b 9885 return fold_convert_loc (loc, rettype,
9886 build_int_cst (NULL_TREE,
9887 REAL_EXP (value)-1));
cb2b9385 9888 break;
9889 }
9890 }
9891
9892 return NULL_TREE;
9893}
9894
9895/* Fold a call to builtin significand, if radix == 2. */
9896
9897static tree
389dd41b 9898fold_builtin_significand (location_t loc, tree arg, tree rettype)
cb2b9385 9899{
9900 if (! validate_arg (arg, REAL_TYPE))
9901 return NULL_TREE;
9902
9903 STRIP_NOPS (arg);
9904
9905 if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9906 {
9907 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9908
9909 switch (value->cl)
9910 {
9911 case rvc_zero:
9912 case rvc_nan:
9913 case rvc_inf:
9914 /* If arg is +-0, +-Inf or +-NaN, then return it. */
389dd41b 9915 return fold_convert_loc (loc, rettype, arg);
cb2b9385 9916 case rvc_normal:
9917 /* For normal numbers, proceed iff radix == 2. */
9918 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9919 {
9920 REAL_VALUE_TYPE result = *value;
9921 /* In GCC, normalized significands are in the range [0.5,
9922 1.0). We want them to be [1.0, 2.0) so set the
9923 exponent to 1. */
9924 SET_REAL_EXP (&result, 1);
9925 return build_real (rettype, result);
9926 }
9927 break;
9928 }
9929 }
9930
9931 return NULL_TREE;
9932}
9933
3838b9ae 9934/* Fold a call to builtin frexp, we can assume the base is 2. */
9935
9936static tree
389dd41b 9937fold_builtin_frexp (location_t loc, tree arg0, tree arg1, tree rettype)
3838b9ae 9938{
9939 if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9940 return NULL_TREE;
9941
9942 STRIP_NOPS (arg0);
9943
9944 if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9945 return NULL_TREE;
9946
389dd41b 9947 arg1 = build_fold_indirect_ref_loc (loc, arg1);
3838b9ae 9948
9949 /* Proceed if a valid pointer type was passed in. */
9950 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == integer_type_node)
9951 {
9952 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9953 tree frac, exp;
9954
9955 switch (value->cl)
9956 {
9957 case rvc_zero:
9958 /* For +-0, return (*exp = 0, +-0). */
9959 exp = integer_zero_node;
9960 frac = arg0;
9961 break;
9962 case rvc_nan:
9963 case rvc_inf:
9964 /* For +-NaN or +-Inf, *exp is unspecified, return arg0. */
389dd41b 9965 return omit_one_operand_loc (loc, rettype, arg0, arg1);
3838b9ae 9966 case rvc_normal:
9967 {
9968 /* Since the frexp function always expects base 2, and in
9969 GCC normalized significands are already in the range
9970 [0.5, 1.0), we have exactly what frexp wants. */
9971 REAL_VALUE_TYPE frac_rvt = *value;
9972 SET_REAL_EXP (&frac_rvt, 0);
9973 frac = build_real (rettype, frac_rvt);
9974 exp = build_int_cst (NULL_TREE, REAL_EXP (value));
9975 }
9976 break;
9977 default:
9978 gcc_unreachable ();
9979 }
9980
9981 /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
389dd41b 9982 arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1, exp);
3838b9ae 9983 TREE_SIDE_EFFECTS (arg1) = 1;
389dd41b 9984 return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1, frac);
3838b9ae 9985 }
9986
9987 return NULL_TREE;
9988}
9989
7587301b 9990/* Fold a call to builtin ldexp or scalbn/scalbln. If LDEXP is true
9991 then we can assume the base is two. If it's false, then we have to
9992 check the mode of the TYPE parameter in certain cases. */
9993
9994static tree
389dd41b 9995fold_builtin_load_exponent (location_t loc, tree arg0, tree arg1,
9996 tree type, bool ldexp)
7587301b 9997{
9998 if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, INTEGER_TYPE))
9999 {
10000 STRIP_NOPS (arg0);
10001 STRIP_NOPS (arg1);
10002
10003 /* If arg0 is 0, Inf or NaN, or if arg1 is 0, then return arg0. */
10004 if (real_zerop (arg0) || integer_zerop (arg1)
10005 || (TREE_CODE (arg0) == REAL_CST
776a7bab 10006 && !real_isfinite (&TREE_REAL_CST (arg0))))
389dd41b 10007 return omit_one_operand_loc (loc, type, arg0, arg1);
7587301b 10008
10009 /* If both arguments are constant, then try to evaluate it. */
10010 if ((ldexp || REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2)
10011 && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
10012 && host_integerp (arg1, 0))
10013 {
10014 /* Bound the maximum adjustment to twice the range of the
10015 mode's valid exponents. Use abs to ensure the range is
10016 positive as a sanity check. */
10017 const long max_exp_adj = 2 *
10018 labs (REAL_MODE_FORMAT (TYPE_MODE (type))->emax
10019 - REAL_MODE_FORMAT (TYPE_MODE (type))->emin);
10020
10021 /* Get the user-requested adjustment. */
10022 const HOST_WIDE_INT req_exp_adj = tree_low_cst (arg1, 0);
10023
10024 /* The requested adjustment must be inside this range. This
10025 is a preliminary cap to avoid things like overflow, we
10026 may still fail to compute the result for other reasons. */
10027 if (-max_exp_adj < req_exp_adj && req_exp_adj < max_exp_adj)
10028 {
10029 REAL_VALUE_TYPE initial_result;
10030
10031 real_ldexp (&initial_result, &TREE_REAL_CST (arg0), req_exp_adj);
10032
10033 /* Ensure we didn't overflow. */
10034 if (! real_isinf (&initial_result))
10035 {
10036 const REAL_VALUE_TYPE trunc_result
10037 = real_value_truncate (TYPE_MODE (type), initial_result);
10038
10039 /* Only proceed if the target mode can hold the
10040 resulting value. */
10041 if (REAL_VALUES_EQUAL (initial_result, trunc_result))
10042 return build_real (type, trunc_result);
10043 }
10044 }
10045 }
10046 }
10047
10048 return NULL_TREE;
10049}
10050
ebf8b4f5 10051/* Fold a call to builtin modf. */
10052
10053static tree
389dd41b 10054fold_builtin_modf (location_t loc, tree arg0, tree arg1, tree rettype)
ebf8b4f5 10055{
10056 if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
10057 return NULL_TREE;
10058
10059 STRIP_NOPS (arg0);
10060
10061 if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
10062 return NULL_TREE;
10063
389dd41b 10064 arg1 = build_fold_indirect_ref_loc (loc, arg1);
ebf8b4f5 10065
10066 /* Proceed if a valid pointer type was passed in. */
10067 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == TYPE_MAIN_VARIANT (rettype))
10068 {
10069 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
10070 REAL_VALUE_TYPE trunc, frac;
10071
10072 switch (value->cl)
10073 {
10074 case rvc_nan:
10075 case rvc_zero:
10076 /* For +-NaN or +-0, return (*arg1 = arg0, arg0). */
10077 trunc = frac = *value;
10078 break;
10079 case rvc_inf:
10080 /* For +-Inf, return (*arg1 = arg0, +-0). */
10081 frac = dconst0;
10082 frac.sign = value->sign;
10083 trunc = *value;
10084 break;
10085 case rvc_normal:
10086 /* Return (*arg1 = trunc(arg0), arg0-trunc(arg0)). */
10087 real_trunc (&trunc, VOIDmode, value);
10088 real_arithmetic (&frac, MINUS_EXPR, value, &trunc);
10089 /* If the original number was negative and already
10090 integral, then the fractional part is -0.0. */
10091 if (value->sign && frac.cl == rvc_zero)
10092 frac.sign = value->sign;
10093 break;
10094 }
10095
10096 /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
389dd41b 10097 arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1,
ebf8b4f5 10098 build_real (rettype, trunc));
10099 TREE_SIDE_EFFECTS (arg1) = 1;
389dd41b 10100 return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1,
ebf8b4f5 10101 build_real (rettype, frac));
10102 }
10103
10104 return NULL_TREE;
10105}
10106
726069ba 10107/* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
c2f47e15 10108 ARG is the argument for the call. */
726069ba 10109
10110static tree
389dd41b 10111fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index)
726069ba 10112{
726069ba 10113 tree type = TREE_TYPE (TREE_TYPE (fndecl));
726069ba 10114 REAL_VALUE_TYPE r;
10115
c2f47e15 10116 if (!validate_arg (arg, REAL_TYPE))
d43cee80 10117 return NULL_TREE;
726069ba 10118
726069ba 10119 switch (builtin_index)
10120 {
10121 case BUILT_IN_ISINF:
b70bfd00 10122 if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
389dd41b 10123 return omit_one_operand_loc (loc, type, integer_zero_node, arg);
726069ba 10124
10125 if (TREE_CODE (arg) == REAL_CST)
10126 {
10127 r = TREE_REAL_CST (arg);
10128 if (real_isinf (&r))
10129 return real_compare (GT_EXPR, &r, &dconst0)
10130 ? integer_one_node : integer_minus_one_node;
10131 else
10132 return integer_zero_node;
10133 }
10134
10135 return NULL_TREE;
10136
c319d56a 10137 case BUILT_IN_ISINF_SIGN:
10138 {
10139 /* isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 */
10140 /* In a boolean context, GCC will fold the inner COND_EXPR to
10141 1. So e.g. "if (isinf_sign(x))" would be folded to just
10142 "if (isinf(x) ? 1 : 0)" which becomes "if (isinf(x))". */
10143 tree signbit_fn = mathfn_built_in_1 (TREE_TYPE (arg), BUILT_IN_SIGNBIT, 0);
10144 tree isinf_fn = built_in_decls[BUILT_IN_ISINF];
10145 tree tmp = NULL_TREE;
10146
10147 arg = builtin_save_expr (arg);
10148
10149 if (signbit_fn && isinf_fn)
10150 {
389dd41b 10151 tree signbit_call = build_call_expr_loc (loc, signbit_fn, 1, arg);
10152 tree isinf_call = build_call_expr_loc (loc, isinf_fn, 1, arg);
c319d56a 10153
389dd41b 10154 signbit_call = fold_build2_loc (loc, NE_EXPR, integer_type_node,
c319d56a 10155 signbit_call, integer_zero_node);
389dd41b 10156 isinf_call = fold_build2_loc (loc, NE_EXPR, integer_type_node,
c319d56a 10157 isinf_call, integer_zero_node);
10158
389dd41b 10159 tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node, signbit_call,
c319d56a 10160 integer_minus_one_node, integer_one_node);
389dd41b 10161 tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node,
10162 isinf_call, tmp,
c319d56a 10163 integer_zero_node);
10164 }
10165
10166 return tmp;
10167 }
10168
cde061c1 10169 case BUILT_IN_ISFINITE:
b70bfd00 10170 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
10171 && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
389dd41b 10172 return omit_one_operand_loc (loc, type, integer_one_node, arg);
726069ba 10173
10174 if (TREE_CODE (arg) == REAL_CST)
10175 {
10176 r = TREE_REAL_CST (arg);
776a7bab 10177 return real_isfinite (&r) ? integer_one_node : integer_zero_node;
726069ba 10178 }
10179
10180 return NULL_TREE;
10181
10182 case BUILT_IN_ISNAN:
b70bfd00 10183 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
389dd41b 10184 return omit_one_operand_loc (loc, type, integer_zero_node, arg);
726069ba 10185
10186 if (TREE_CODE (arg) == REAL_CST)
10187 {
10188 r = TREE_REAL_CST (arg);
10189 return real_isnan (&r) ? integer_one_node : integer_zero_node;
10190 }
10191
10192 arg = builtin_save_expr (arg);
389dd41b 10193 return fold_build2_loc (loc, UNORDERED_EXPR, type, arg, arg);
726069ba 10194
10195 default:
64db345d 10196 gcc_unreachable ();
726069ba 10197 }
10198}
10199
19fbe3a4 10200/* Fold a call to __builtin_fpclassify(int, int, int, int, int, ...).
10201 This builtin will generate code to return the appropriate floating
10202 point classification depending on the value of the floating point
10203 number passed in. The possible return values must be supplied as
921b27c0 10204 int arguments to the call in the following order: FP_NAN, FP_INFINITE,
19fbe3a4 10205 FP_NORMAL, FP_SUBNORMAL and FP_ZERO. The ellipses is for exactly
10206 one floating point argument which is "type generic". */
10207
10208static tree
389dd41b 10209fold_builtin_fpclassify (location_t loc, tree exp)
19fbe3a4 10210{
921b27c0 10211 tree fp_nan, fp_infinite, fp_normal, fp_subnormal, fp_zero,
10212 arg, type, res, tmp;
19fbe3a4 10213 enum machine_mode mode;
10214 REAL_VALUE_TYPE r;
10215 char buf[128];
10216
10217 /* Verify the required arguments in the original call. */
10218 if (!validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE,
10219 INTEGER_TYPE, INTEGER_TYPE,
10220 INTEGER_TYPE, REAL_TYPE, VOID_TYPE))
10221 return NULL_TREE;
10222
10223 fp_nan = CALL_EXPR_ARG (exp, 0);
921b27c0 10224 fp_infinite = CALL_EXPR_ARG (exp, 1);
19fbe3a4 10225 fp_normal = CALL_EXPR_ARG (exp, 2);
10226 fp_subnormal = CALL_EXPR_ARG (exp, 3);
10227 fp_zero = CALL_EXPR_ARG (exp, 4);
10228 arg = CALL_EXPR_ARG (exp, 5);
10229 type = TREE_TYPE (arg);
10230 mode = TYPE_MODE (type);
389dd41b 10231 arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg));
19fbe3a4 10232
10233 /* fpclassify(x) ->
10234 isnan(x) ? FP_NAN :
921b27c0 10235 (fabs(x) == Inf ? FP_INFINITE :
19fbe3a4 10236 (fabs(x) >= DBL_MIN ? FP_NORMAL :
10237 (x == 0 ? FP_ZERO : FP_SUBNORMAL))). */
10238
389dd41b 10239 tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
19fbe3a4 10240 build_real (type, dconst0));
389dd41b 10241 res = fold_build3_loc (loc, COND_EXPR, integer_type_node,
10242 tmp, fp_zero, fp_subnormal);
19fbe3a4 10243
10244 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
10245 real_from_string (&r, buf);
389dd41b 10246 tmp = fold_build2_loc (loc, GE_EXPR, integer_type_node,
10247 arg, build_real (type, r));
10248 res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, fp_normal, res);
19fbe3a4 10249
10250 if (HONOR_INFINITIES (mode))
10251 {
10252 real_inf (&r);
389dd41b 10253 tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
19fbe3a4 10254 build_real (type, r));
389dd41b 10255 res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp,
10256 fp_infinite, res);
19fbe3a4 10257 }
10258
10259 if (HONOR_NANS (mode))
10260 {
389dd41b 10261 tmp = fold_build2_loc (loc, ORDERED_EXPR, integer_type_node, arg, arg);
10262 res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, res, fp_nan);
19fbe3a4 10263 }
10264
10265 return res;
10266}
10267
9bc9f15f 10268/* Fold a call to an unordered comparison function such as
d5019fe8 10269 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
c2f47e15 10270 being called and ARG0 and ARG1 are the arguments for the call.
726069ba 10271 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
10272 the opposite of the desired result. UNORDERED_CODE is used
10273 for modes that can hold NaNs and ORDERED_CODE is used for
10274 the rest. */
9bc9f15f 10275
10276static tree
389dd41b 10277fold_builtin_unordered_cmp (location_t loc, tree fndecl, tree arg0, tree arg1,
9bc9f15f 10278 enum tree_code unordered_code,
10279 enum tree_code ordered_code)
10280{
859f903a 10281 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9bc9f15f 10282 enum tree_code code;
6978db0d 10283 tree type0, type1;
10284 enum tree_code code0, code1;
10285 tree cmp_type = NULL_TREE;
9bc9f15f 10286
6978db0d 10287 type0 = TREE_TYPE (arg0);
10288 type1 = TREE_TYPE (arg1);
a0c938f0 10289
6978db0d 10290 code0 = TREE_CODE (type0);
10291 code1 = TREE_CODE (type1);
a0c938f0 10292
6978db0d 10293 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
10294 /* Choose the wider of two real types. */
10295 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
10296 ? type0 : type1;
10297 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
10298 cmp_type = type0;
10299 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
10300 cmp_type = type1;
a0c938f0 10301
389dd41b 10302 arg0 = fold_convert_loc (loc, cmp_type, arg0);
10303 arg1 = fold_convert_loc (loc, cmp_type, arg1);
859f903a 10304
10305 if (unordered_code == UNORDERED_EXPR)
10306 {
b70bfd00 10307 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
389dd41b 10308 return omit_two_operands_loc (loc, type, integer_zero_node, arg0, arg1);
10309 return fold_build2_loc (loc, UNORDERED_EXPR, type, arg0, arg1);
859f903a 10310 }
9bc9f15f 10311
b70bfd00 10312 code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
10313 : ordered_code;
389dd41b 10314 return fold_build1_loc (loc, TRUTH_NOT_EXPR, type,
10315 fold_build2_loc (loc, code, type, arg0, arg1));
9bc9f15f 10316}
10317
c2f47e15 10318/* Fold a call to built-in function FNDECL with 0 arguments.
10319 IGNORE is true if the result of the function call is ignored. This
10320 function returns NULL_TREE if no simplification was possible. */
650e4c94 10321
4ee9c684 10322static tree
389dd41b 10323fold_builtin_0 (location_t loc, tree fndecl, bool ignore ATTRIBUTE_UNUSED)
650e4c94 10324{
e9f80ff5 10325 tree type = TREE_TYPE (TREE_TYPE (fndecl));
c2f47e15 10326 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
189b3398 10327 switch (fcode)
650e4c94 10328 {
c2f47e15 10329 CASE_FLT_FN (BUILT_IN_INF):
10330 case BUILT_IN_INFD32:
10331 case BUILT_IN_INFD64:
10332 case BUILT_IN_INFD128:
389dd41b 10333 return fold_builtin_inf (loc, type, true);
7c2f0500 10334
c2f47e15 10335 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
389dd41b 10336 return fold_builtin_inf (loc, type, false);
7c2f0500 10337
c2f47e15 10338 case BUILT_IN_CLASSIFY_TYPE:
10339 return fold_builtin_classify_type (NULL_TREE);
7c2f0500 10340
c2f47e15 10341 default:
10342 break;
10343 }
10344 return NULL_TREE;
10345}
7c2f0500 10346
c2f47e15 10347/* Fold a call to built-in function FNDECL with 1 argument, ARG0.
10348 IGNORE is true if the result of the function call is ignored. This
10349 function returns NULL_TREE if no simplification was possible. */
7c2f0500 10350
c2f47e15 10351static tree
389dd41b 10352fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool ignore)
c2f47e15 10353{
10354 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10355 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10356 switch (fcode)
10357 {
7c2f0500 10358
650e4c94 10359 case BUILT_IN_CONSTANT_P:
7c2f0500 10360 {
c2f47e15 10361 tree val = fold_builtin_constant_p (arg0);
7c2f0500 10362
7c2f0500 10363 /* Gimplification will pull the CALL_EXPR for the builtin out of
10364 an if condition. When not optimizing, we'll not CSE it back.
10365 To avoid link error types of regressions, return false now. */
10366 if (!val && !optimize)
10367 val = integer_zero_node;
10368
10369 return val;
10370 }
650e4c94 10371
539a3a92 10372 case BUILT_IN_CLASSIFY_TYPE:
c2f47e15 10373 return fold_builtin_classify_type (arg0);
539a3a92 10374
650e4c94 10375 case BUILT_IN_STRLEN:
389dd41b 10376 return fold_builtin_strlen (loc, arg0);
650e4c94 10377
4f35b1fc 10378 CASE_FLT_FN (BUILT_IN_FABS):
389dd41b 10379 return fold_builtin_fabs (loc, arg0, type);
d1aade50 10380
10381 case BUILT_IN_ABS:
10382 case BUILT_IN_LABS:
10383 case BUILT_IN_LLABS:
10384 case BUILT_IN_IMAXABS:
389dd41b 10385 return fold_builtin_abs (loc, arg0, type);
c63f4ad3 10386
4f35b1fc 10387 CASE_FLT_FN (BUILT_IN_CONJ):
239d491a 10388 if (validate_arg (arg0, COMPLEX_TYPE)
10389 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
389dd41b 10390 return fold_build1_loc (loc, CONJ_EXPR, type, arg0);
c2f47e15 10391 break;
36d3581d 10392
4f35b1fc 10393 CASE_FLT_FN (BUILT_IN_CREAL):
239d491a 10394 if (validate_arg (arg0, COMPLEX_TYPE)
10395 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
389dd41b 10396 return non_lvalue_loc (loc, fold_build1_loc (loc, REALPART_EXPR, type, arg0));;
c2f47e15 10397 break;
36d3581d 10398
4f35b1fc 10399 CASE_FLT_FN (BUILT_IN_CIMAG):
c2f47e15 10400 if (validate_arg (arg0, COMPLEX_TYPE))
389dd41b 10401 return non_lvalue_loc (loc, fold_build1_loc (loc, IMAGPART_EXPR, type, arg0));
c2f47e15 10402 break;
36d3581d 10403
503733d5 10404 CASE_FLT_FN (BUILT_IN_CCOS):
389dd41b 10405 return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ false);
239d491a 10406
503733d5 10407 CASE_FLT_FN (BUILT_IN_CCOSH):
389dd41b 10408 return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ true);
239d491a 10409
10410#ifdef HAVE_mpc
10411 CASE_FLT_FN (BUILT_IN_CSIN):
10412 if (validate_arg (arg0, COMPLEX_TYPE)
10413 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10414 return do_mpc_arg1 (arg0, type, mpc_sin);
c2f47e15 10415 break;
239d491a 10416
10417 CASE_FLT_FN (BUILT_IN_CSINH):
10418 if (validate_arg (arg0, COMPLEX_TYPE)
10419 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10420 return do_mpc_arg1 (arg0, type, mpc_sinh);
10421 break;
10422
10423 CASE_FLT_FN (BUILT_IN_CTAN):
10424 if (validate_arg (arg0, COMPLEX_TYPE)
10425 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10426 return do_mpc_arg1 (arg0, type, mpc_tan);
10427 break;
10428
10429 CASE_FLT_FN (BUILT_IN_CTANH):
10430 if (validate_arg (arg0, COMPLEX_TYPE)
10431 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10432 return do_mpc_arg1 (arg0, type, mpc_tanh);
10433 break;
10434
10435 CASE_FLT_FN (BUILT_IN_CLOG):
10436 if (validate_arg (arg0, COMPLEX_TYPE)
10437 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10438 return do_mpc_arg1 (arg0, type, mpc_log);
10439 break;
10440
10441 CASE_FLT_FN (BUILT_IN_CSQRT):
10442 if (validate_arg (arg0, COMPLEX_TYPE)
10443 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10444 return do_mpc_arg1 (arg0, type, mpc_sqrt);
10445 break;
10446#endif
10447
4f35b1fc 10448 CASE_FLT_FN (BUILT_IN_CABS):
389dd41b 10449 return fold_builtin_cabs (loc, arg0, type, fndecl);
c63f4ad3 10450
abe4dcf6 10451 CASE_FLT_FN (BUILT_IN_CARG):
389dd41b 10452 return fold_builtin_carg (loc, arg0, type);
abe4dcf6 10453
4f35b1fc 10454 CASE_FLT_FN (BUILT_IN_SQRT):
389dd41b 10455 return fold_builtin_sqrt (loc, arg0, type);
805e22b2 10456
4f35b1fc 10457 CASE_FLT_FN (BUILT_IN_CBRT):
389dd41b 10458 return fold_builtin_cbrt (loc, arg0, type);
3bc5c41b 10459
728bac60 10460 CASE_FLT_FN (BUILT_IN_ASIN):
c2f47e15 10461 if (validate_arg (arg0, REAL_TYPE))
10462 return do_mpfr_arg1 (arg0, type, mpfr_asin,
728bac60 10463 &dconstm1, &dconst1, true);
10464 break;
10465
10466 CASE_FLT_FN (BUILT_IN_ACOS):
c2f47e15 10467 if (validate_arg (arg0, REAL_TYPE))
10468 return do_mpfr_arg1 (arg0, type, mpfr_acos,
728bac60 10469 &dconstm1, &dconst1, true);
10470 break;
10471
10472 CASE_FLT_FN (BUILT_IN_ATAN):
c2f47e15 10473 if (validate_arg (arg0, REAL_TYPE))
10474 return do_mpfr_arg1 (arg0, type, mpfr_atan, NULL, NULL, 0);
728bac60 10475 break;
10476
10477 CASE_FLT_FN (BUILT_IN_ASINH):
c2f47e15 10478 if (validate_arg (arg0, REAL_TYPE))
10479 return do_mpfr_arg1 (arg0, type, mpfr_asinh, NULL, NULL, 0);
728bac60 10480 break;
10481
10482 CASE_FLT_FN (BUILT_IN_ACOSH):
c2f47e15 10483 if (validate_arg (arg0, REAL_TYPE))
10484 return do_mpfr_arg1 (arg0, type, mpfr_acosh,
728bac60 10485 &dconst1, NULL, true);
10486 break;
10487
10488 CASE_FLT_FN (BUILT_IN_ATANH):
c2f47e15 10489 if (validate_arg (arg0, REAL_TYPE))
10490 return do_mpfr_arg1 (arg0, type, mpfr_atanh,
728bac60 10491 &dconstm1, &dconst1, false);
10492 break;
10493
4f35b1fc 10494 CASE_FLT_FN (BUILT_IN_SIN):
c2f47e15 10495 if (validate_arg (arg0, REAL_TYPE))
10496 return do_mpfr_arg1 (arg0, type, mpfr_sin, NULL, NULL, 0);
728bac60 10497 break;
77e89269 10498
4f35b1fc 10499 CASE_FLT_FN (BUILT_IN_COS):
389dd41b 10500 return fold_builtin_cos (loc, arg0, type, fndecl);
77e89269 10501
728bac60 10502 CASE_FLT_FN (BUILT_IN_TAN):
c2f47e15 10503 return fold_builtin_tan (arg0, type);
d735c391 10504
c5bb2c4b 10505 CASE_FLT_FN (BUILT_IN_CEXP):
389dd41b 10506 return fold_builtin_cexp (loc, arg0, type);
c5bb2c4b 10507
d735c391 10508 CASE_FLT_FN (BUILT_IN_CEXPI):
c2f47e15 10509 if (validate_arg (arg0, REAL_TYPE))
10510 return do_mpfr_sincos (arg0, NULL_TREE, NULL_TREE);
10511 break;
d92f994c 10512
728bac60 10513 CASE_FLT_FN (BUILT_IN_SINH):
c2f47e15 10514 if (validate_arg (arg0, REAL_TYPE))
10515 return do_mpfr_arg1 (arg0, type, mpfr_sinh, NULL, NULL, 0);
728bac60 10516 break;
10517
10518 CASE_FLT_FN (BUILT_IN_COSH):
389dd41b 10519 return fold_builtin_cosh (loc, arg0, type, fndecl);
728bac60 10520
10521 CASE_FLT_FN (BUILT_IN_TANH):
c2f47e15 10522 if (validate_arg (arg0, REAL_TYPE))
10523 return do_mpfr_arg1 (arg0, type, mpfr_tanh, NULL, NULL, 0);
728bac60 10524 break;
10525
29f4cd78 10526 CASE_FLT_FN (BUILT_IN_ERF):
c2f47e15 10527 if (validate_arg (arg0, REAL_TYPE))
10528 return do_mpfr_arg1 (arg0, type, mpfr_erf, NULL, NULL, 0);
29f4cd78 10529 break;
10530
10531 CASE_FLT_FN (BUILT_IN_ERFC):
c2f47e15 10532 if (validate_arg (arg0, REAL_TYPE))
10533 return do_mpfr_arg1 (arg0, type, mpfr_erfc, NULL, NULL, 0);
29f4cd78 10534 break;
10535
32dba52b 10536 CASE_FLT_FN (BUILT_IN_TGAMMA):
c2f47e15 10537 if (validate_arg (arg0, REAL_TYPE))
10538 return do_mpfr_arg1 (arg0, type, mpfr_gamma, NULL, NULL, 0);
32dba52b 10539 break;
10540
4f35b1fc 10541 CASE_FLT_FN (BUILT_IN_EXP):
389dd41b 10542 return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp);
467214fd 10543
4f35b1fc 10544 CASE_FLT_FN (BUILT_IN_EXP2):
389dd41b 10545 return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp2);
467214fd 10546
4f35b1fc 10547 CASE_FLT_FN (BUILT_IN_EXP10):
10548 CASE_FLT_FN (BUILT_IN_POW10):
389dd41b 10549 return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp10);
467214fd 10550
29f4cd78 10551 CASE_FLT_FN (BUILT_IN_EXPM1):
c2f47e15 10552 if (validate_arg (arg0, REAL_TYPE))
10553 return do_mpfr_arg1 (arg0, type, mpfr_expm1, NULL, NULL, 0);
29f4cd78 10554 break;
10555
4f35b1fc 10556 CASE_FLT_FN (BUILT_IN_LOG):
389dd41b 10557 return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log);
467214fd 10558
4f35b1fc 10559 CASE_FLT_FN (BUILT_IN_LOG2):
389dd41b 10560 return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log2);
467214fd 10561
4f35b1fc 10562 CASE_FLT_FN (BUILT_IN_LOG10):
389dd41b 10563 return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log10);
29f4cd78 10564
10565 CASE_FLT_FN (BUILT_IN_LOG1P):
c2f47e15 10566 if (validate_arg (arg0, REAL_TYPE))
10567 return do_mpfr_arg1 (arg0, type, mpfr_log1p,
29f4cd78 10568 &dconstm1, NULL, false);
10569 break;
805e22b2 10570
65dd1378 10571 CASE_FLT_FN (BUILT_IN_J0):
10572 if (validate_arg (arg0, REAL_TYPE))
10573 return do_mpfr_arg1 (arg0, type, mpfr_j0,
10574 NULL, NULL, 0);
10575 break;
10576
10577 CASE_FLT_FN (BUILT_IN_J1):
10578 if (validate_arg (arg0, REAL_TYPE))
10579 return do_mpfr_arg1 (arg0, type, mpfr_j1,
10580 NULL, NULL, 0);
10581 break;
6ff9eeff 10582
10583 CASE_FLT_FN (BUILT_IN_Y0):
10584 if (validate_arg (arg0, REAL_TYPE))
10585 return do_mpfr_arg1 (arg0, type, mpfr_y0,
10586 &dconst0, NULL, false);
10587 break;
10588
10589 CASE_FLT_FN (BUILT_IN_Y1):
10590 if (validate_arg (arg0, REAL_TYPE))
10591 return do_mpfr_arg1 (arg0, type, mpfr_y1,
10592 &dconst0, NULL, false);
10593 break;
65dd1378 10594
4f35b1fc 10595 CASE_FLT_FN (BUILT_IN_NAN):
c4503c0a 10596 case BUILT_IN_NAND32:
10597 case BUILT_IN_NAND64:
10598 case BUILT_IN_NAND128:
c2f47e15 10599 return fold_builtin_nan (arg0, type, true);
b0db7939 10600
4f35b1fc 10601 CASE_FLT_FN (BUILT_IN_NANS):
c2f47e15 10602 return fold_builtin_nan (arg0, type, false);
b0db7939 10603
4f35b1fc 10604 CASE_FLT_FN (BUILT_IN_FLOOR):
389dd41b 10605 return fold_builtin_floor (loc, fndecl, arg0);
277f8dd2 10606
4f35b1fc 10607 CASE_FLT_FN (BUILT_IN_CEIL):
389dd41b 10608 return fold_builtin_ceil (loc, fndecl, arg0);
277f8dd2 10609
4f35b1fc 10610 CASE_FLT_FN (BUILT_IN_TRUNC):
389dd41b 10611 return fold_builtin_trunc (loc, fndecl, arg0);
277f8dd2 10612
4f35b1fc 10613 CASE_FLT_FN (BUILT_IN_ROUND):
389dd41b 10614 return fold_builtin_round (loc, fndecl, arg0);
89ab3887 10615
4f35b1fc 10616 CASE_FLT_FN (BUILT_IN_NEARBYINT):
10617 CASE_FLT_FN (BUILT_IN_RINT):
389dd41b 10618 return fold_trunc_transparent_mathfn (loc, fndecl, arg0);
6528f4f4 10619
4f35b1fc 10620 CASE_FLT_FN (BUILT_IN_LCEIL):
10621 CASE_FLT_FN (BUILT_IN_LLCEIL):
10622 CASE_FLT_FN (BUILT_IN_LFLOOR):
10623 CASE_FLT_FN (BUILT_IN_LLFLOOR):
a0c938f0 10624 CASE_FLT_FN (BUILT_IN_LROUND):
4f35b1fc 10625 CASE_FLT_FN (BUILT_IN_LLROUND):
389dd41b 10626 return fold_builtin_int_roundingfn (loc, fndecl, arg0);
34f17811 10627
4f35b1fc 10628 CASE_FLT_FN (BUILT_IN_LRINT):
10629 CASE_FLT_FN (BUILT_IN_LLRINT):
389dd41b 10630 return fold_fixed_mathfn (loc, fndecl, arg0);
9ed65c7f 10631
42791117 10632 case BUILT_IN_BSWAP32:
10633 case BUILT_IN_BSWAP64:
c2f47e15 10634 return fold_builtin_bswap (fndecl, arg0);
42791117 10635
4f35b1fc 10636 CASE_INT_FN (BUILT_IN_FFS):
10637 CASE_INT_FN (BUILT_IN_CLZ):
10638 CASE_INT_FN (BUILT_IN_CTZ):
10639 CASE_INT_FN (BUILT_IN_POPCOUNT):
10640 CASE_INT_FN (BUILT_IN_PARITY):
c2f47e15 10641 return fold_builtin_bitop (fndecl, arg0);
9c8a1629 10642
4f35b1fc 10643 CASE_FLT_FN (BUILT_IN_SIGNBIT):
389dd41b 10644 return fold_builtin_signbit (loc, arg0, type);
27f261ef 10645
cb2b9385 10646 CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
389dd41b 10647 return fold_builtin_significand (loc, arg0, type);
cb2b9385 10648
10649 CASE_FLT_FN (BUILT_IN_ILOGB):
10650 CASE_FLT_FN (BUILT_IN_LOGB):
389dd41b 10651 return fold_builtin_logb (loc, arg0, type);
cb2b9385 10652
d49367d4 10653 case BUILT_IN_ISASCII:
389dd41b 10654 return fold_builtin_isascii (loc, arg0);
d49367d4 10655
10656 case BUILT_IN_TOASCII:
389dd41b 10657 return fold_builtin_toascii (loc, arg0);
d49367d4 10658
df1cf42e 10659 case BUILT_IN_ISDIGIT:
389dd41b 10660 return fold_builtin_isdigit (loc, arg0);
467214fd 10661
4f35b1fc 10662 CASE_FLT_FN (BUILT_IN_FINITE):
c4503c0a 10663 case BUILT_IN_FINITED32:
10664 case BUILT_IN_FINITED64:
10665 case BUILT_IN_FINITED128:
cde061c1 10666 case BUILT_IN_ISFINITE:
389dd41b 10667 return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISFINITE);
726069ba 10668
4f35b1fc 10669 CASE_FLT_FN (BUILT_IN_ISINF):
c4503c0a 10670 case BUILT_IN_ISINFD32:
10671 case BUILT_IN_ISINFD64:
10672 case BUILT_IN_ISINFD128:
389dd41b 10673 return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF);
726069ba 10674
c319d56a 10675 case BUILT_IN_ISINF_SIGN:
389dd41b 10676 return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF_SIGN);
c319d56a 10677
4f35b1fc 10678 CASE_FLT_FN (BUILT_IN_ISNAN):
c4503c0a 10679 case BUILT_IN_ISNAND32:
10680 case BUILT_IN_ISNAND64:
10681 case BUILT_IN_ISNAND128:
389dd41b 10682 return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISNAN);
c2f47e15 10683
10684 case BUILT_IN_PRINTF:
10685 case BUILT_IN_PRINTF_UNLOCKED:
10686 case BUILT_IN_VPRINTF:
389dd41b 10687 return fold_builtin_printf (loc, fndecl, arg0, NULL_TREE, ignore, fcode);
c2f47e15 10688
10689 default:
10690 break;
10691 }
10692
10693 return NULL_TREE;
10694
10695}
10696
10697/* Fold a call to built-in function FNDECL with 2 arguments, ARG0 and ARG1.
10698 IGNORE is true if the result of the function call is ignored. This
10699 function returns NULL_TREE if no simplification was possible. */
10700
10701static tree
389dd41b 10702fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1, bool ignore)
c2f47e15 10703{
10704 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10705 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10706
10707 switch (fcode)
10708 {
65dd1378 10709 CASE_FLT_FN (BUILT_IN_JN):
10710 if (validate_arg (arg0, INTEGER_TYPE)
10711 && validate_arg (arg1, REAL_TYPE))
10712 return do_mpfr_bessel_n (arg0, arg1, type, mpfr_jn, NULL, 0);
10713 break;
6ff9eeff 10714
10715 CASE_FLT_FN (BUILT_IN_YN):
10716 if (validate_arg (arg0, INTEGER_TYPE)
10717 && validate_arg (arg1, REAL_TYPE))
10718 return do_mpfr_bessel_n (arg0, arg1, type, mpfr_yn,
10719 &dconst0, false);
10720 break;
e5407ca6 10721
10722 CASE_FLT_FN (BUILT_IN_DREM):
10723 CASE_FLT_FN (BUILT_IN_REMAINDER):
10724 if (validate_arg (arg0, REAL_TYPE)
10725 && validate_arg(arg1, REAL_TYPE))
10726 return do_mpfr_arg2 (arg0, arg1, type, mpfr_remainder);
10727 break;
e84da7c1 10728
10729 CASE_FLT_FN_REENT (BUILT_IN_GAMMA): /* GAMMA_R */
10730 CASE_FLT_FN_REENT (BUILT_IN_LGAMMA): /* LGAMMA_R */
10731 if (validate_arg (arg0, REAL_TYPE)
10732 && validate_arg(arg1, POINTER_TYPE))
10733 return do_mpfr_lgamma_r (arg0, arg1, type);
10734 break;
c2f47e15 10735
10736 CASE_FLT_FN (BUILT_IN_ATAN2):
10737 if (validate_arg (arg0, REAL_TYPE)
10738 && validate_arg(arg1, REAL_TYPE))
10739 return do_mpfr_arg2 (arg0, arg1, type, mpfr_atan2);
10740 break;
10741
10742 CASE_FLT_FN (BUILT_IN_FDIM):
10743 if (validate_arg (arg0, REAL_TYPE)
10744 && validate_arg(arg1, REAL_TYPE))
10745 return do_mpfr_arg2 (arg0, arg1, type, mpfr_dim);
10746 break;
10747
10748 CASE_FLT_FN (BUILT_IN_HYPOT):
389dd41b 10749 return fold_builtin_hypot (loc, fndecl, arg0, arg1, type);
c2f47e15 10750
c699fab8 10751#ifdef HAVE_mpc_pow
10752 CASE_FLT_FN (BUILT_IN_CPOW):
10753 if (validate_arg (arg0, COMPLEX_TYPE)
10754 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
10755 && validate_arg (arg1, COMPLEX_TYPE)
10756 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE)
652d9409 10757 return do_mpc_arg2 (arg0, arg1, type, /*do_nonfinite=*/ 0, mpc_pow);
c699fab8 10758 break;
10759#endif
10760
7587301b 10761 CASE_FLT_FN (BUILT_IN_LDEXP):
389dd41b 10762 return fold_builtin_load_exponent (loc, arg0, arg1, type, /*ldexp=*/true);
7587301b 10763 CASE_FLT_FN (BUILT_IN_SCALBN):
10764 CASE_FLT_FN (BUILT_IN_SCALBLN):
389dd41b 10765 return fold_builtin_load_exponent (loc, arg0, arg1,
10766 type, /*ldexp=*/false);
7587301b 10767
3838b9ae 10768 CASE_FLT_FN (BUILT_IN_FREXP):
389dd41b 10769 return fold_builtin_frexp (loc, arg0, arg1, type);
3838b9ae 10770
ebf8b4f5 10771 CASE_FLT_FN (BUILT_IN_MODF):
389dd41b 10772 return fold_builtin_modf (loc, arg0, arg1, type);
ebf8b4f5 10773
c2f47e15 10774 case BUILT_IN_BZERO:
389dd41b 10775 return fold_builtin_bzero (loc, arg0, arg1, ignore);
c2f47e15 10776
10777 case BUILT_IN_FPUTS:
389dd41b 10778 return fold_builtin_fputs (loc, arg0, arg1, ignore, false, NULL_TREE);
c2f47e15 10779
10780 case BUILT_IN_FPUTS_UNLOCKED:
389dd41b 10781 return fold_builtin_fputs (loc, arg0, arg1, ignore, true, NULL_TREE);
c2f47e15 10782
10783 case BUILT_IN_STRSTR:
389dd41b 10784 return fold_builtin_strstr (loc, arg0, arg1, type);
c2f47e15 10785
10786 case BUILT_IN_STRCAT:
389dd41b 10787 return fold_builtin_strcat (loc, arg0, arg1);
c2f47e15 10788
10789 case BUILT_IN_STRSPN:
389dd41b 10790 return fold_builtin_strspn (loc, arg0, arg1);
c2f47e15 10791
10792 case BUILT_IN_STRCSPN:
389dd41b 10793 return fold_builtin_strcspn (loc, arg0, arg1);
c2f47e15 10794
10795 case BUILT_IN_STRCHR:
10796 case BUILT_IN_INDEX:
389dd41b 10797 return fold_builtin_strchr (loc, arg0, arg1, type);
c2f47e15 10798
10799 case BUILT_IN_STRRCHR:
10800 case BUILT_IN_RINDEX:
389dd41b 10801 return fold_builtin_strrchr (loc, arg0, arg1, type);
c2f47e15 10802
10803 case BUILT_IN_STRCPY:
389dd41b 10804 return fold_builtin_strcpy (loc, fndecl, arg0, arg1, NULL_TREE);
c2f47e15 10805
c8b17b2e 10806 case BUILT_IN_STPCPY:
10807 if (ignore)
10808 {
10809 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10810 if (!fn)
10811 break;
10812
389dd41b 10813 return build_call_expr_loc (loc, fn, 2, arg0, arg1);
c8b17b2e 10814 }
10815 break;
10816
c2f47e15 10817 case BUILT_IN_STRCMP:
389dd41b 10818 return fold_builtin_strcmp (loc, arg0, arg1);
c2f47e15 10819
10820 case BUILT_IN_STRPBRK:
389dd41b 10821 return fold_builtin_strpbrk (loc, arg0, arg1, type);
c2f47e15 10822
10823 case BUILT_IN_EXPECT:
389dd41b 10824 return fold_builtin_expect (loc, arg0, arg1);
c2f47e15 10825
10826 CASE_FLT_FN (BUILT_IN_POW):
389dd41b 10827 return fold_builtin_pow (loc, fndecl, arg0, arg1, type);
c2f47e15 10828
10829 CASE_FLT_FN (BUILT_IN_POWI):
389dd41b 10830 return fold_builtin_powi (loc, fndecl, arg0, arg1, type);
c2f47e15 10831
10832 CASE_FLT_FN (BUILT_IN_COPYSIGN):
389dd41b 10833 return fold_builtin_copysign (loc, fndecl, arg0, arg1, type);
c2f47e15 10834
10835 CASE_FLT_FN (BUILT_IN_FMIN):
389dd41b 10836 return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/false);
c2f47e15 10837
10838 CASE_FLT_FN (BUILT_IN_FMAX):
389dd41b 10839 return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/true);
726069ba 10840
9bc9f15f 10841 case BUILT_IN_ISGREATER:
389dd41b 10842 return fold_builtin_unordered_cmp (loc, fndecl,
10843 arg0, arg1, UNLE_EXPR, LE_EXPR);
9bc9f15f 10844 case BUILT_IN_ISGREATEREQUAL:
389dd41b 10845 return fold_builtin_unordered_cmp (loc, fndecl,
10846 arg0, arg1, UNLT_EXPR, LT_EXPR);
9bc9f15f 10847 case BUILT_IN_ISLESS:
389dd41b 10848 return fold_builtin_unordered_cmp (loc, fndecl,
10849 arg0, arg1, UNGE_EXPR, GE_EXPR);
9bc9f15f 10850 case BUILT_IN_ISLESSEQUAL:
389dd41b 10851 return fold_builtin_unordered_cmp (loc, fndecl,
10852 arg0, arg1, UNGT_EXPR, GT_EXPR);
9bc9f15f 10853 case BUILT_IN_ISLESSGREATER:
389dd41b 10854 return fold_builtin_unordered_cmp (loc, fndecl,
10855 arg0, arg1, UNEQ_EXPR, EQ_EXPR);
9bc9f15f 10856 case BUILT_IN_ISUNORDERED:
389dd41b 10857 return fold_builtin_unordered_cmp (loc, fndecl,
10858 arg0, arg1, UNORDERED_EXPR,
d5019fe8 10859 NOP_EXPR);
9bc9f15f 10860
7c2f0500 10861 /* We do the folding for va_start in the expander. */
10862 case BUILT_IN_VA_START:
10863 break;
f0613857 10864
c2f47e15 10865 case BUILT_IN_SPRINTF:
389dd41b 10866 return fold_builtin_sprintf (loc, arg0, arg1, NULL_TREE, ignore);
c2f47e15 10867
0a39fd54 10868 case BUILT_IN_OBJECT_SIZE:
c2f47e15 10869 return fold_builtin_object_size (arg0, arg1);
0a39fd54 10870
10871 case BUILT_IN_PRINTF:
10872 case BUILT_IN_PRINTF_UNLOCKED:
10873 case BUILT_IN_VPRINTF:
389dd41b 10874 return fold_builtin_printf (loc, fndecl, arg0, arg1, ignore, fcode);
c2f47e15 10875
0a39fd54 10876 case BUILT_IN_PRINTF_CHK:
10877 case BUILT_IN_VPRINTF_CHK:
c2f47e15 10878 if (!validate_arg (arg0, INTEGER_TYPE)
10879 || TREE_SIDE_EFFECTS (arg0))
10880 return NULL_TREE;
10881 else
389dd41b 10882 return fold_builtin_printf (loc, fndecl,
10883 arg1, NULL_TREE, ignore, fcode);
c2f47e15 10884 break;
0a39fd54 10885
10886 case BUILT_IN_FPRINTF:
10887 case BUILT_IN_FPRINTF_UNLOCKED:
10888 case BUILT_IN_VFPRINTF:
389dd41b 10889 return fold_builtin_fprintf (loc, fndecl, arg0, arg1, NULL_TREE,
c2f47e15 10890 ignore, fcode);
10891
10892 default:
10893 break;
10894 }
10895 return NULL_TREE;
10896}
10897
10898/* Fold a call to built-in function FNDECL with 3 arguments, ARG0, ARG1,
10899 and ARG2. IGNORE is true if the result of the function call is ignored.
10900 This function returns NULL_TREE if no simplification was possible. */
10901
10902static tree
389dd41b 10903fold_builtin_3 (location_t loc, tree fndecl,
10904 tree arg0, tree arg1, tree arg2, bool ignore)
c2f47e15 10905{
10906 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10907 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10908 switch (fcode)
10909 {
10910
10911 CASE_FLT_FN (BUILT_IN_SINCOS):
389dd41b 10912 return fold_builtin_sincos (loc, arg0, arg1, arg2);
c2f47e15 10913
10914 CASE_FLT_FN (BUILT_IN_FMA):
10915 if (validate_arg (arg0, REAL_TYPE)
10916 && validate_arg(arg1, REAL_TYPE)
10917 && validate_arg(arg2, REAL_TYPE))
10918 return do_mpfr_arg3 (arg0, arg1, arg2, type, mpfr_fma);
10919 break;
10920
e5407ca6 10921 CASE_FLT_FN (BUILT_IN_REMQUO):
10922 if (validate_arg (arg0, REAL_TYPE)
10923 && validate_arg(arg1, REAL_TYPE)
10924 && validate_arg(arg2, POINTER_TYPE))
10925 return do_mpfr_remquo (arg0, arg1, arg2);
10926 break;
e5407ca6 10927
c2f47e15 10928 case BUILT_IN_MEMSET:
389dd41b 10929 return fold_builtin_memset (loc, arg0, arg1, arg2, type, ignore);
c2f47e15 10930
10931 case BUILT_IN_BCOPY:
389dd41b 10932 return fold_builtin_memory_op (loc, arg1, arg0, arg2,
10933 void_type_node, true, /*endp=*/3);
c2f47e15 10934
10935 case BUILT_IN_MEMCPY:
389dd41b 10936 return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10937 type, ignore, /*endp=*/0);
c2f47e15 10938
10939 case BUILT_IN_MEMPCPY:
389dd41b 10940 return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10941 type, ignore, /*endp=*/1);
c2f47e15 10942
10943 case BUILT_IN_MEMMOVE:
389dd41b 10944 return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10945 type, ignore, /*endp=*/3);
c2f47e15 10946
10947 case BUILT_IN_STRNCAT:
389dd41b 10948 return fold_builtin_strncat (loc, arg0, arg1, arg2);
c2f47e15 10949
10950 case BUILT_IN_STRNCPY:
389dd41b 10951 return fold_builtin_strncpy (loc, fndecl, arg0, arg1, arg2, NULL_TREE);
c2f47e15 10952
10953 case BUILT_IN_STRNCMP:
389dd41b 10954 return fold_builtin_strncmp (loc, arg0, arg1, arg2);
c2f47e15 10955
7959b13b 10956 case BUILT_IN_MEMCHR:
389dd41b 10957 return fold_builtin_memchr (loc, arg0, arg1, arg2, type);
7959b13b 10958
c2f47e15 10959 case BUILT_IN_BCMP:
10960 case BUILT_IN_MEMCMP:
389dd41b 10961 return fold_builtin_memcmp (loc, arg0, arg1, arg2);;
c2f47e15 10962
10963 case BUILT_IN_SPRINTF:
389dd41b 10964 return fold_builtin_sprintf (loc, arg0, arg1, arg2, ignore);
c2f47e15 10965
10966 case BUILT_IN_STRCPY_CHK:
10967 case BUILT_IN_STPCPY_CHK:
389dd41b 10968 return fold_builtin_stxcpy_chk (loc, fndecl, arg0, arg1, arg2, NULL_TREE,
c2f47e15 10969 ignore, fcode);
10970
10971 case BUILT_IN_STRCAT_CHK:
389dd41b 10972 return fold_builtin_strcat_chk (loc, fndecl, arg0, arg1, arg2);
c2f47e15 10973
10974 case BUILT_IN_PRINTF_CHK:
10975 case BUILT_IN_VPRINTF_CHK:
10976 if (!validate_arg (arg0, INTEGER_TYPE)
10977 || TREE_SIDE_EFFECTS (arg0))
10978 return NULL_TREE;
10979 else
389dd41b 10980 return fold_builtin_printf (loc, fndecl, arg1, arg2, ignore, fcode);
c2f47e15 10981 break;
10982
10983 case BUILT_IN_FPRINTF:
10984 case BUILT_IN_FPRINTF_UNLOCKED:
10985 case BUILT_IN_VFPRINTF:
389dd41b 10986 return fold_builtin_fprintf (loc, fndecl, arg0, arg1, arg2,
10987 ignore, fcode);
c2f47e15 10988
0a39fd54 10989 case BUILT_IN_FPRINTF_CHK:
10990 case BUILT_IN_VFPRINTF_CHK:
c2f47e15 10991 if (!validate_arg (arg1, INTEGER_TYPE)
10992 || TREE_SIDE_EFFECTS (arg1))
10993 return NULL_TREE;
10994 else
389dd41b 10995 return fold_builtin_fprintf (loc, fndecl, arg0, arg2, NULL_TREE,
c2f47e15 10996 ignore, fcode);
0a39fd54 10997
650e4c94 10998 default:
10999 break;
11000 }
c2f47e15 11001 return NULL_TREE;
11002}
650e4c94 11003
c2f47e15 11004/* Fold a call to built-in function FNDECL with 4 arguments, ARG0, ARG1,
11005 ARG2, and ARG3. IGNORE is true if the result of the function call is
11006 ignored. This function returns NULL_TREE if no simplification was
11007 possible. */
11008
11009static tree
389dd41b 11010fold_builtin_4 (location_t loc, tree fndecl,
11011 tree arg0, tree arg1, tree arg2, tree arg3, bool ignore)
c2f47e15 11012{
11013 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
11014
11015 switch (fcode)
11016 {
11017 case BUILT_IN_MEMCPY_CHK:
11018 case BUILT_IN_MEMPCPY_CHK:
11019 case BUILT_IN_MEMMOVE_CHK:
11020 case BUILT_IN_MEMSET_CHK:
389dd41b 11021 return fold_builtin_memory_chk (loc, fndecl, arg0, arg1, arg2, arg3,
c2f47e15 11022 NULL_TREE, ignore,
11023 DECL_FUNCTION_CODE (fndecl));
11024
11025 case BUILT_IN_STRNCPY_CHK:
389dd41b 11026 return fold_builtin_strncpy_chk (loc, arg0, arg1, arg2, arg3, NULL_TREE);
c2f47e15 11027
11028 case BUILT_IN_STRNCAT_CHK:
389dd41b 11029 return fold_builtin_strncat_chk (loc, fndecl, arg0, arg1, arg2, arg3);
c2f47e15 11030
11031 case BUILT_IN_FPRINTF_CHK:
11032 case BUILT_IN_VFPRINTF_CHK:
11033 if (!validate_arg (arg1, INTEGER_TYPE)
11034 || TREE_SIDE_EFFECTS (arg1))
11035 return NULL_TREE;
11036 else
389dd41b 11037 return fold_builtin_fprintf (loc, fndecl, arg0, arg2, arg3,
c2f47e15 11038 ignore, fcode);
11039 break;
11040
11041 default:
11042 break;
11043 }
11044 return NULL_TREE;
11045}
11046
11047/* Fold a call to built-in function FNDECL. ARGS is an array of NARGS
11048 arguments, where NARGS <= 4. IGNORE is true if the result of the
11049 function call is ignored. This function returns NULL_TREE if no
11050 simplification was possible. Note that this only folds builtins with
11051 fixed argument patterns. Foldings that do varargs-to-varargs
11052 transformations, or that match calls with more than 4 arguments,
11053 need to be handled with fold_builtin_varargs instead. */
11054
11055#define MAX_ARGS_TO_FOLD_BUILTIN 4
11056
11057static tree
389dd41b 11058fold_builtin_n (location_t loc, tree fndecl, tree *args, int nargs, bool ignore)
c2f47e15 11059{
11060 tree ret = NULL_TREE;
a7f5bb2d 11061
c2f47e15 11062 switch (nargs)
11063 {
11064 case 0:
389dd41b 11065 ret = fold_builtin_0 (loc, fndecl, ignore);
c2f47e15 11066 break;
11067 case 1:
389dd41b 11068 ret = fold_builtin_1 (loc, fndecl, args[0], ignore);
c2f47e15 11069 break;
11070 case 2:
389dd41b 11071 ret = fold_builtin_2 (loc, fndecl, args[0], args[1], ignore);
c2f47e15 11072 break;
11073 case 3:
389dd41b 11074 ret = fold_builtin_3 (loc, fndecl, args[0], args[1], args[2], ignore);
c2f47e15 11075 break;
11076 case 4:
389dd41b 11077 ret = fold_builtin_4 (loc, fndecl, args[0], args[1], args[2], args[3],
c2f47e15 11078 ignore);
11079 break;
11080 default:
11081 break;
11082 }
11083 if (ret)
11084 {
75a70cf9 11085 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
389dd41b 11086 SET_EXPR_LOCATION (ret, loc);
c2f47e15 11087 TREE_NO_WARNING (ret) = 1;
11088 return ret;
11089 }
11090 return NULL_TREE;
11091}
11092
11093/* Builtins with folding operations that operate on "..." arguments
11094 need special handling; we need to store the arguments in a convenient
11095 data structure before attempting any folding. Fortunately there are
11096 only a few builtins that fall into this category. FNDECL is the
11097 function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
11098 result of the function call is ignored. */
11099
11100static tree
389dd41b 11101fold_builtin_varargs (location_t loc, tree fndecl, tree exp,
11102 bool ignore ATTRIBUTE_UNUSED)
c2f47e15 11103{
11104 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
11105 tree ret = NULL_TREE;
11106
11107 switch (fcode)
11108 {
11109 case BUILT_IN_SPRINTF_CHK:
11110 case BUILT_IN_VSPRINTF_CHK:
389dd41b 11111 ret = fold_builtin_sprintf_chk (loc, exp, fcode);
c2f47e15 11112 break;
11113
11114 case BUILT_IN_SNPRINTF_CHK:
11115 case BUILT_IN_VSNPRINTF_CHK:
389dd41b 11116 ret = fold_builtin_snprintf_chk (loc, exp, NULL_TREE, fcode);
19fbe3a4 11117 break;
11118
11119 case BUILT_IN_FPCLASSIFY:
389dd41b 11120 ret = fold_builtin_fpclassify (loc, exp);
19fbe3a4 11121 break;
c2f47e15 11122
11123 default:
11124 break;
11125 }
11126 if (ret)
11127 {
11128 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
389dd41b 11129 SET_EXPR_LOCATION (ret, loc);
c2f47e15 11130 TREE_NO_WARNING (ret) = 1;
11131 return ret;
11132 }
11133 return NULL_TREE;
650e4c94 11134}
7e15618b 11135
198622c0 11136/* Return true if FNDECL shouldn't be folded right now.
11137 If a built-in function has an inline attribute always_inline
11138 wrapper, defer folding it after always_inline functions have
11139 been inlined, otherwise e.g. -D_FORTIFY_SOURCE checking
11140 might not be performed. */
11141
11142static bool
11143avoid_folding_inline_builtin (tree fndecl)
11144{
11145 return (DECL_DECLARED_INLINE_P (fndecl)
11146 && DECL_DISREGARD_INLINE_LIMITS (fndecl)
11147 && cfun
11148 && !cfun->always_inline_functions_inlined
11149 && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fndecl)));
11150}
11151
4ee9c684 11152/* A wrapper function for builtin folding that prevents warnings for
491e04ef 11153 "statement without effect" and the like, caused by removing the
4ee9c684 11154 call node earlier than the warning is generated. */
11155
11156tree
389dd41b 11157fold_call_expr (location_t loc, tree exp, bool ignore)
4ee9c684 11158{
c2f47e15 11159 tree ret = NULL_TREE;
11160 tree fndecl = get_callee_fndecl (exp);
11161 if (fndecl
11162 && TREE_CODE (fndecl) == FUNCTION_DECL
48dc2227 11163 && DECL_BUILT_IN (fndecl)
11164 /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized
11165 yet. Defer folding until we see all the arguments
11166 (after inlining). */
11167 && !CALL_EXPR_VA_ARG_PACK (exp))
11168 {
11169 int nargs = call_expr_nargs (exp);
11170
11171 /* Before gimplification CALL_EXPR_VA_ARG_PACK is not set, but
11172 instead last argument is __builtin_va_arg_pack (). Defer folding
11173 even in that case, until arguments are finalized. */
11174 if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR)
11175 {
11176 tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1));
11177 if (fndecl2
11178 && TREE_CODE (fndecl2) == FUNCTION_DECL
11179 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
11180 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
11181 return NULL_TREE;
11182 }
11183
198622c0 11184 if (avoid_folding_inline_builtin (fndecl))
11185 return NULL_TREE;
11186
c2f47e15 11187 /* FIXME: Don't use a list in this interface. */
11188 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
11189 return targetm.fold_builtin (fndecl, CALL_EXPR_ARGS (exp), ignore);
11190 else
11191 {
c2f47e15 11192 if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
11193 {
11194 tree *args = CALL_EXPR_ARGP (exp);
389dd41b 11195 ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
c2f47e15 11196 }
11197 if (!ret)
389dd41b 11198 ret = fold_builtin_varargs (loc, fndecl, exp, ignore);
c2f47e15 11199 if (ret)
389dd41b 11200 return ret;
c2f47e15 11201 }
4ee9c684 11202 }
c2f47e15 11203 return NULL_TREE;
11204}
11205
11206/* Conveniently construct a function call expression. FNDECL names the
11207 function to be called and ARGLIST is a TREE_LIST of arguments. */
11208
11209tree
389dd41b 11210build_function_call_expr (location_t loc, tree fndecl, tree arglist)
c2f47e15 11211{
11212 tree fntype = TREE_TYPE (fndecl);
11213 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
d01f58f9 11214 int n = list_length (arglist);
11215 tree *argarray = (tree *) alloca (n * sizeof (tree));
11216 int i;
389dd41b 11217
d01f58f9 11218 for (i = 0; i < n; i++, arglist = TREE_CHAIN (arglist))
11219 argarray[i] = TREE_VALUE (arglist);
389dd41b 11220 return fold_builtin_call_array (loc, TREE_TYPE (fntype), fn, n, argarray);
c2f47e15 11221}
11222
11223/* Conveniently construct a function call expression. FNDECL names the
11224 function to be called, N is the number of arguments, and the "..."
11225 parameters are the argument expressions. */
11226
11227tree
389dd41b 11228build_call_expr_loc (location_t loc, tree fndecl, int n, ...)
c2f47e15 11229{
11230 va_list ap;
c2f47e15 11231 tree fntype = TREE_TYPE (fndecl);
11232 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
d01f58f9 11233 tree *argarray = (tree *) alloca (n * sizeof (tree));
11234 int i;
c2f47e15 11235
11236 va_start (ap, n);
d01f58f9 11237 for (i = 0; i < n; i++)
11238 argarray[i] = va_arg (ap, tree);
c2f47e15 11239 va_end (ap);
389dd41b 11240 return fold_builtin_call_array (loc, TREE_TYPE (fntype), fn, n, argarray);
4ee9c684 11241}
11242
c2f47e15 11243/* Construct a CALL_EXPR with type TYPE with FN as the function expression.
d01f58f9 11244 N arguments are passed in the array ARGARRAY. */
805e22b2 11245
11246tree
389dd41b 11247fold_builtin_call_array (location_t loc, tree type,
d01f58f9 11248 tree fn,
11249 int n,
11250 tree *argarray)
7e15618b 11251{
c2f47e15 11252 tree ret = NULL_TREE;
11253 int i;
11254 tree exp;
11255
11256 if (TREE_CODE (fn) == ADDR_EXPR)
11257 {
11258 tree fndecl = TREE_OPERAND (fn, 0);
11259 if (TREE_CODE (fndecl) == FUNCTION_DECL
11260 && DECL_BUILT_IN (fndecl))
11261 {
48dc2227 11262 /* If last argument is __builtin_va_arg_pack (), arguments to this
11263 function are not finalized yet. Defer folding until they are. */
11264 if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
11265 {
11266 tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
11267 if (fndecl2
11268 && TREE_CODE (fndecl2) == FUNCTION_DECL
11269 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
11270 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
389dd41b 11271 return build_call_array_loc (loc, type, fn, n, argarray);
48dc2227 11272 }
198622c0 11273 if (avoid_folding_inline_builtin (fndecl))
389dd41b 11274 return build_call_array_loc (loc, type, fn, n, argarray);
c2f47e15 11275 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
11276 {
11277 tree arglist = NULL_TREE;
d01f58f9 11278 for (i = n - 1; i >= 0; i--)
11279 arglist = tree_cons (NULL_TREE, argarray[i], arglist);
c2f47e15 11280 ret = targetm.fold_builtin (fndecl, arglist, false);
11281 if (ret)
11282 return ret;
389dd41b 11283 return build_call_array_loc (loc, type, fn, n, argarray);
c2f47e15 11284 }
11285 else if (n <= MAX_ARGS_TO_FOLD_BUILTIN)
11286 {
11287 /* First try the transformations that don't require consing up
11288 an exp. */
389dd41b 11289 ret = fold_builtin_n (loc, fndecl, argarray, n, false);
c2f47e15 11290 if (ret)
11291 return ret;
11292 }
11293
11294 /* If we got this far, we need to build an exp. */
389dd41b 11295 exp = build_call_array_loc (loc, type, fn, n, argarray);
11296 ret = fold_builtin_varargs (loc, fndecl, exp, false);
c2f47e15 11297 return ret ? ret : exp;
11298 }
11299 }
11300
389dd41b 11301 return build_call_array_loc (loc, type, fn, n, argarray);
c2f47e15 11302}
11303
11304/* Construct a new CALL_EXPR using the tail of the argument list of EXP
11305 along with N new arguments specified as the "..." parameters. SKIP
11306 is the number of arguments in EXP to be omitted. This function is used
11307 to do varargs-to-varargs transformations. */
11308
11309static tree
389dd41b 11310rewrite_call_expr (location_t loc, tree exp, int skip, tree fndecl, int n, ...)
c2f47e15 11311{
11312 int oldnargs = call_expr_nargs (exp);
11313 int nargs = oldnargs - skip + n;
11314 tree fntype = TREE_TYPE (fndecl);
11315 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
11316 tree *buffer;
11317
11318 if (n > 0)
11319 {
11320 int i, j;
11321 va_list ap;
7e15618b 11322
364c0c59 11323 buffer = XALLOCAVEC (tree, nargs);
c2f47e15 11324 va_start (ap, n);
11325 for (i = 0; i < n; i++)
11326 buffer[i] = va_arg (ap, tree);
11327 va_end (ap);
11328 for (j = skip; j < oldnargs; j++, i++)
11329 buffer[i] = CALL_EXPR_ARG (exp, j);
11330 }
11331 else
11332 buffer = CALL_EXPR_ARGP (exp) + skip;
11333
389dd41b 11334 return fold (build_call_array_loc (loc, TREE_TYPE (exp), fn, nargs, buffer));
c2f47e15 11335}
11336
11337/* Validate a single argument ARG against a tree code CODE representing
11338 a type. */
11339
11340static bool
b7bf20db 11341validate_arg (const_tree arg, enum tree_code code)
c2f47e15 11342{
11343 if (!arg)
11344 return false;
11345 else if (code == POINTER_TYPE)
11346 return POINTER_TYPE_P (TREE_TYPE (arg));
c7f617c2 11347 else if (code == INTEGER_TYPE)
11348 return INTEGRAL_TYPE_P (TREE_TYPE (arg));
c2f47e15 11349 return code == TREE_CODE (TREE_TYPE (arg));
7e15618b 11350}
0eb671f7 11351
75a70cf9 11352/* This function validates the types of a function call argument list
11353 against a specified list of tree_codes. If the last specifier is a 0,
11354 that represents an ellipses, otherwise the last specifier must be a
11355 VOID_TYPE.
11356
11357 This is the GIMPLE version of validate_arglist. Eventually we want to
11358 completely convert builtins.c to work from GIMPLEs and the tree based
11359 validate_arglist will then be removed. */
11360
11361bool
11362validate_gimple_arglist (const_gimple call, ...)
11363{
11364 enum tree_code code;
11365 bool res = 0;
11366 va_list ap;
11367 const_tree arg;
11368 size_t i;
11369
11370 va_start (ap, call);
11371 i = 0;
11372
11373 do
11374 {
d62e827b 11375 code = (enum tree_code) va_arg (ap, int);
75a70cf9 11376 switch (code)
11377 {
11378 case 0:
11379 /* This signifies an ellipses, any further arguments are all ok. */
11380 res = true;
11381 goto end;
11382 case VOID_TYPE:
11383 /* This signifies an endlink, if no arguments remain, return
11384 true, otherwise return false. */
11385 res = (i == gimple_call_num_args (call));
11386 goto end;
11387 default:
11388 /* If no parameters remain or the parameter's code does not
11389 match the specified code, return false. Otherwise continue
11390 checking any remaining arguments. */
11391 arg = gimple_call_arg (call, i++);
11392 if (!validate_arg (arg, code))
11393 goto end;
11394 break;
11395 }
11396 }
11397 while (1);
11398
11399 /* We need gotos here since we can only have one VA_CLOSE in a
11400 function. */
11401 end: ;
11402 va_end (ap);
11403
11404 return res;
11405}
11406
0eb671f7 11407/* This function validates the types of a function call argument list
c2f47e15 11408 against a specified list of tree_codes. If the last specifier is a 0,
11409 that represents an ellipses, otherwise the last specifier must be a
11410 VOID_TYPE. */
27d0c333 11411
c2f47e15 11412bool
b7bf20db 11413validate_arglist (const_tree callexpr, ...)
0eb671f7 11414{
0eb671f7 11415 enum tree_code code;
c2f47e15 11416 bool res = 0;
ee582a61 11417 va_list ap;
b7bf20db 11418 const_call_expr_arg_iterator iter;
11419 const_tree arg;
aecda0d6 11420
c2f47e15 11421 va_start (ap, callexpr);
b7bf20db 11422 init_const_call_expr_arg_iterator (callexpr, &iter);
0eb671f7 11423
f0ce3b1f 11424 do
0eb671f7 11425 {
d62e827b 11426 code = (enum tree_code) va_arg (ap, int);
f0ce3b1f 11427 switch (code)
11428 {
11429 case 0:
11430 /* This signifies an ellipses, any further arguments are all ok. */
c2f47e15 11431 res = true;
f0ce3b1f 11432 goto end;
11433 case VOID_TYPE:
11434 /* This signifies an endlink, if no arguments remain, return
11435 true, otherwise return false. */
b7bf20db 11436 res = !more_const_call_expr_args_p (&iter);
f0ce3b1f 11437 goto end;
11438 default:
11439 /* If no parameters remain or the parameter's code does not
11440 match the specified code, return false. Otherwise continue
11441 checking any remaining arguments. */
b7bf20db 11442 arg = next_const_call_expr_arg (&iter);
c2f47e15 11443 if (!validate_arg (arg, code))
f0ce3b1f 11444 goto end;
11445 break;
11446 }
0eb671f7 11447 }
f0ce3b1f 11448 while (1);
0903457a 11449
11450 /* We need gotos here since we can only have one VA_CLOSE in a
11451 function. */
11452 end: ;
ee582a61 11453 va_end (ap);
0903457a 11454
11455 return res;
0eb671f7 11456}
fc2a2dcb 11457
fc2a2dcb 11458/* Default target-specific builtin expander that does nothing. */
11459
11460rtx
aecda0d6 11461default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
11462 rtx target ATTRIBUTE_UNUSED,
11463 rtx subtarget ATTRIBUTE_UNUSED,
11464 enum machine_mode mode ATTRIBUTE_UNUSED,
11465 int ignore ATTRIBUTE_UNUSED)
fc2a2dcb 11466{
11467 return NULL_RTX;
11468}
c7926a82 11469
01537105 11470/* Returns true is EXP represents data that would potentially reside
11471 in a readonly section. */
11472
11473static bool
11474readonly_data_expr (tree exp)
11475{
11476 STRIP_NOPS (exp);
11477
9ff0637e 11478 if (TREE_CODE (exp) != ADDR_EXPR)
11479 return false;
11480
11481 exp = get_base_address (TREE_OPERAND (exp, 0));
11482 if (!exp)
11483 return false;
11484
11485 /* Make sure we call decl_readonly_section only for trees it
11486 can handle (since it returns true for everything it doesn't
11487 understand). */
491e04ef 11488 if (TREE_CODE (exp) == STRING_CST
9ff0637e 11489 || TREE_CODE (exp) == CONSTRUCTOR
11490 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
11491 return decl_readonly_section (exp, 0);
01537105 11492 else
11493 return false;
11494}
4ee9c684 11495
c2f47e15 11496/* Simplify a call to the strstr builtin. S1 and S2 are the arguments
11497 to the call, and TYPE is its return type.
4ee9c684 11498
c2f47e15 11499 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11500 simplified form of the call as a tree.
11501
11502 The simplified form may be a constant or other expression which
11503 computes the same value, but in a more efficient manner (including
11504 calls to other builtin functions).
11505
11506 The call may contain arguments which need to be evaluated, but
11507 which are not useful to determine the result of the call. In
11508 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11509 COMPOUND_EXPR will be an argument which must be evaluated.
11510 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11511 COMPOUND_EXPR in the chain will contain the tree for the simplified
11512 form of the builtin function call. */
11513
11514static tree
389dd41b 11515fold_builtin_strstr (location_t loc, tree s1, tree s2, tree type)
4ee9c684 11516{
c2f47e15 11517 if (!validate_arg (s1, POINTER_TYPE)
11518 || !validate_arg (s2, POINTER_TYPE))
11519 return NULL_TREE;
4ee9c684 11520 else
11521 {
4ee9c684 11522 tree fn;
11523 const char *p1, *p2;
11524
11525 p2 = c_getstr (s2);
11526 if (p2 == NULL)
c2f47e15 11527 return NULL_TREE;
4ee9c684 11528
11529 p1 = c_getstr (s1);
11530 if (p1 != NULL)
11531 {
11532 const char *r = strstr (p1, p2);
daa1d5f5 11533 tree tem;
4ee9c684 11534
4ee9c684 11535 if (r == NULL)
779b4c41 11536 return build_int_cst (TREE_TYPE (s1), 0);
c0c67e38 11537
11538 /* Return an offset into the constant string argument. */
389dd41b 11539 tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (s1),
0de36bdb 11540 s1, size_int (r - p1));
389dd41b 11541 return fold_convert_loc (loc, type, tem);
4ee9c684 11542 }
11543
7efa231c 11544 /* The argument is const char *, and the result is char *, so we need
11545 a type conversion here to avoid a warning. */
4ee9c684 11546 if (p2[0] == '\0')
389dd41b 11547 return fold_convert_loc (loc, type, s1);
4ee9c684 11548
11549 if (p2[1] != '\0')
c2f47e15 11550 return NULL_TREE;
4ee9c684 11551
11552 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11553 if (!fn)
c2f47e15 11554 return NULL_TREE;
4ee9c684 11555
11556 /* New argument list transforming strstr(s1, s2) to
11557 strchr(s1, s2[0]). */
389dd41b 11558 return build_call_expr_loc (loc, fn, 2, s1, build_int_cst (NULL_TREE, p2[0]));
4ee9c684 11559 }
11560}
11561
c2f47e15 11562/* Simplify a call to the strchr builtin. S1 and S2 are the arguments to
11563 the call, and TYPE is its return type.
4ee9c684 11564
c2f47e15 11565 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11566 simplified form of the call as a tree.
11567
11568 The simplified form may be a constant or other expression which
11569 computes the same value, but in a more efficient manner (including
11570 calls to other builtin functions).
11571
11572 The call may contain arguments which need to be evaluated, but
11573 which are not useful to determine the result of the call. In
11574 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11575 COMPOUND_EXPR will be an argument which must be evaluated.
11576 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11577 COMPOUND_EXPR in the chain will contain the tree for the simplified
11578 form of the builtin function call. */
11579
11580static tree
389dd41b 11581fold_builtin_strchr (location_t loc, tree s1, tree s2, tree type)
4ee9c684 11582{
c2f47e15 11583 if (!validate_arg (s1, POINTER_TYPE)
11584 || !validate_arg (s2, INTEGER_TYPE))
11585 return NULL_TREE;
4ee9c684 11586 else
11587 {
4ee9c684 11588 const char *p1;
11589
11590 if (TREE_CODE (s2) != INTEGER_CST)
c2f47e15 11591 return NULL_TREE;
4ee9c684 11592
11593 p1 = c_getstr (s1);
11594 if (p1 != NULL)
11595 {
11596 char c;
11597 const char *r;
daa1d5f5 11598 tree tem;
4ee9c684 11599
11600 if (target_char_cast (s2, &c))
c2f47e15 11601 return NULL_TREE;
4ee9c684 11602
11603 r = strchr (p1, c);
11604
11605 if (r == NULL)
779b4c41 11606 return build_int_cst (TREE_TYPE (s1), 0);
4ee9c684 11607
11608 /* Return an offset into the constant string argument. */
389dd41b 11609 tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (s1),
0de36bdb 11610 s1, size_int (r - p1));
389dd41b 11611 return fold_convert_loc (loc, type, tem);
4ee9c684 11612 }
c2f47e15 11613 return NULL_TREE;
4ee9c684 11614 }
11615}
11616
c2f47e15 11617/* Simplify a call to the strrchr builtin. S1 and S2 are the arguments to
11618 the call, and TYPE is its return type.
4ee9c684 11619
c2f47e15 11620 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11621 simplified form of the call as a tree.
11622
11623 The simplified form may be a constant or other expression which
11624 computes the same value, but in a more efficient manner (including
11625 calls to other builtin functions).
11626
11627 The call may contain arguments which need to be evaluated, but
11628 which are not useful to determine the result of the call. In
11629 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11630 COMPOUND_EXPR will be an argument which must be evaluated.
11631 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11632 COMPOUND_EXPR in the chain will contain the tree for the simplified
11633 form of the builtin function call. */
11634
11635static tree
389dd41b 11636fold_builtin_strrchr (location_t loc, tree s1, tree s2, tree type)
4ee9c684 11637{
c2f47e15 11638 if (!validate_arg (s1, POINTER_TYPE)
11639 || !validate_arg (s2, INTEGER_TYPE))
11640 return NULL_TREE;
4ee9c684 11641 else
11642 {
4ee9c684 11643 tree fn;
11644 const char *p1;
11645
11646 if (TREE_CODE (s2) != INTEGER_CST)
c2f47e15 11647 return NULL_TREE;
4ee9c684 11648
11649 p1 = c_getstr (s1);
11650 if (p1 != NULL)
11651 {
11652 char c;
11653 const char *r;
daa1d5f5 11654 tree tem;
4ee9c684 11655
11656 if (target_char_cast (s2, &c))
c2f47e15 11657 return NULL_TREE;
4ee9c684 11658
11659 r = strrchr (p1, c);
11660
11661 if (r == NULL)
779b4c41 11662 return build_int_cst (TREE_TYPE (s1), 0);
4ee9c684 11663
11664 /* Return an offset into the constant string argument. */
389dd41b 11665 tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (s1),
0de36bdb 11666 s1, size_int (r - p1));
389dd41b 11667 return fold_convert_loc (loc, type, tem);
4ee9c684 11668 }
11669
11670 if (! integer_zerop (s2))
c2f47e15 11671 return NULL_TREE;
4ee9c684 11672
11673 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11674 if (!fn)
c2f47e15 11675 return NULL_TREE;
4ee9c684 11676
11677 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
389dd41b 11678 return build_call_expr_loc (loc, fn, 2, s1, s2);
4ee9c684 11679 }
11680}
11681
c2f47e15 11682/* Simplify a call to the strpbrk builtin. S1 and S2 are the arguments
11683 to the call, and TYPE is its return type.
4ee9c684 11684
c2f47e15 11685 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11686 simplified form of the call as a tree.
11687
11688 The simplified form may be a constant or other expression which
11689 computes the same value, but in a more efficient manner (including
11690 calls to other builtin functions).
11691
11692 The call may contain arguments which need to be evaluated, but
11693 which are not useful to determine the result of the call. In
11694 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11695 COMPOUND_EXPR will be an argument which must be evaluated.
11696 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11697 COMPOUND_EXPR in the chain will contain the tree for the simplified
11698 form of the builtin function call. */
11699
11700static tree
389dd41b 11701fold_builtin_strpbrk (location_t loc, tree s1, tree s2, tree type)
4ee9c684 11702{
c2f47e15 11703 if (!validate_arg (s1, POINTER_TYPE)
11704 || !validate_arg (s2, POINTER_TYPE))
11705 return NULL_TREE;
4ee9c684 11706 else
11707 {
4ee9c684 11708 tree fn;
11709 const char *p1, *p2;
11710
11711 p2 = c_getstr (s2);
11712 if (p2 == NULL)
c2f47e15 11713 return NULL_TREE;
4ee9c684 11714
11715 p1 = c_getstr (s1);
11716 if (p1 != NULL)
11717 {
11718 const char *r = strpbrk (p1, p2);
daa1d5f5 11719 tree tem;
4ee9c684 11720
11721 if (r == NULL)
779b4c41 11722 return build_int_cst (TREE_TYPE (s1), 0);
4ee9c684 11723
11724 /* Return an offset into the constant string argument. */
389dd41b 11725 tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (s1),
0de36bdb 11726 s1, size_int (r - p1));
389dd41b 11727 return fold_convert_loc (loc, type, tem);
4ee9c684 11728 }
11729
11730 if (p2[0] == '\0')
05abc81b 11731 /* strpbrk(x, "") == NULL.
11732 Evaluate and ignore s1 in case it had side-effects. */
389dd41b 11733 return omit_one_operand_loc (loc, TREE_TYPE (s1), integer_zero_node, s1);
4ee9c684 11734
11735 if (p2[1] != '\0')
c2f47e15 11736 return NULL_TREE; /* Really call strpbrk. */
4ee9c684 11737
11738 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11739 if (!fn)
c2f47e15 11740 return NULL_TREE;
4ee9c684 11741
11742 /* New argument list transforming strpbrk(s1, s2) to
11743 strchr(s1, s2[0]). */
389dd41b 11744 return build_call_expr_loc (loc, fn, 2, s1, build_int_cst (NULL_TREE, p2[0]));
4ee9c684 11745 }
11746}
11747
c2f47e15 11748/* Simplify a call to the strcat builtin. DST and SRC are the arguments
11749 to the call.
4ee9c684 11750
c2f47e15 11751 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11752 simplified form of the call as a tree.
11753
11754 The simplified form may be a constant or other expression which
11755 computes the same value, but in a more efficient manner (including
11756 calls to other builtin functions).
11757
11758 The call may contain arguments which need to be evaluated, but
11759 which are not useful to determine the result of the call. In
11760 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11761 COMPOUND_EXPR will be an argument which must be evaluated.
11762 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11763 COMPOUND_EXPR in the chain will contain the tree for the simplified
11764 form of the builtin function call. */
11765
11766static tree
389dd41b 11767fold_builtin_strcat (location_t loc ATTRIBUTE_UNUSED, tree dst, tree src)
4ee9c684 11768{
c2f47e15 11769 if (!validate_arg (dst, POINTER_TYPE)
11770 || !validate_arg (src, POINTER_TYPE))
11771 return NULL_TREE;
4ee9c684 11772 else
11773 {
4ee9c684 11774 const char *p = c_getstr (src);
11775
11776 /* If the string length is zero, return the dst parameter. */
11777 if (p && *p == '\0')
11778 return dst;
11779
c2f47e15 11780 return NULL_TREE;
4ee9c684 11781 }
11782}
11783
c2f47e15 11784/* Simplify a call to the strncat builtin. DST, SRC, and LEN are the
11785 arguments to the call.
4ee9c684 11786
c2f47e15 11787 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11788 simplified form of the call as a tree.
11789
11790 The simplified form may be a constant or other expression which
11791 computes the same value, but in a more efficient manner (including
11792 calls to other builtin functions).
11793
11794 The call may contain arguments which need to be evaluated, but
11795 which are not useful to determine the result of the call. In
11796 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11797 COMPOUND_EXPR will be an argument which must be evaluated.
11798 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11799 COMPOUND_EXPR in the chain will contain the tree for the simplified
11800 form of the builtin function call. */
11801
11802static tree
389dd41b 11803fold_builtin_strncat (location_t loc, tree dst, tree src, tree len)
4ee9c684 11804{
c2f47e15 11805 if (!validate_arg (dst, POINTER_TYPE)
11806 || !validate_arg (src, POINTER_TYPE)
11807 || !validate_arg (len, INTEGER_TYPE))
11808 return NULL_TREE;
4ee9c684 11809 else
11810 {
4ee9c684 11811 const char *p = c_getstr (src);
11812
11813 /* If the requested length is zero, or the src parameter string
0a39fd54 11814 length is zero, return the dst parameter. */
4ee9c684 11815 if (integer_zerop (len) || (p && *p == '\0'))
389dd41b 11816 return omit_two_operands_loc (loc, TREE_TYPE (dst), dst, src, len);
4ee9c684 11817
11818 /* If the requested len is greater than or equal to the string
a0c938f0 11819 length, call strcat. */
4ee9c684 11820 if (TREE_CODE (len) == INTEGER_CST && p
11821 && compare_tree_int (len, strlen (p)) >= 0)
11822 {
4ee9c684 11823 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
11824
11825 /* If the replacement _DECL isn't initialized, don't do the
11826 transformation. */
11827 if (!fn)
c2f47e15 11828 return NULL_TREE;
4ee9c684 11829
389dd41b 11830 return build_call_expr_loc (loc, fn, 2, dst, src);
4ee9c684 11831 }
c2f47e15 11832 return NULL_TREE;
4ee9c684 11833 }
11834}
11835
c2f47e15 11836/* Simplify a call to the strspn builtin. S1 and S2 are the arguments
11837 to the call.
4ee9c684 11838
c2f47e15 11839 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11840 simplified form of the call as a tree.
11841
11842 The simplified form may be a constant or other expression which
11843 computes the same value, but in a more efficient manner (including
11844 calls to other builtin functions).
11845
11846 The call may contain arguments which need to be evaluated, but
11847 which are not useful to determine the result of the call. In
11848 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11849 COMPOUND_EXPR will be an argument which must be evaluated.
11850 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11851 COMPOUND_EXPR in the chain will contain the tree for the simplified
11852 form of the builtin function call. */
11853
11854static tree
389dd41b 11855fold_builtin_strspn (location_t loc, tree s1, tree s2)
4ee9c684 11856{
c2f47e15 11857 if (!validate_arg (s1, POINTER_TYPE)
11858 || !validate_arg (s2, POINTER_TYPE))
11859 return NULL_TREE;
4ee9c684 11860 else
11861 {
4ee9c684 11862 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11863
11864 /* If both arguments are constants, evaluate at compile-time. */
11865 if (p1 && p2)
11866 {
11867 const size_t r = strspn (p1, p2);
11868 return size_int (r);
11869 }
11870
c2f47e15 11871 /* If either argument is "", return NULL_TREE. */
4ee9c684 11872 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9bc9f15f 11873 /* Evaluate and ignore both arguments in case either one has
11874 side-effects. */
389dd41b 11875 return omit_two_operands_loc (loc, size_type_node, size_zero_node,
9bc9f15f 11876 s1, s2);
c2f47e15 11877 return NULL_TREE;
4ee9c684 11878 }
11879}
11880
c2f47e15 11881/* Simplify a call to the strcspn builtin. S1 and S2 are the arguments
11882 to the call.
4ee9c684 11883
c2f47e15 11884 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 11885 simplified form of the call as a tree.
11886
11887 The simplified form may be a constant or other expression which
11888 computes the same value, but in a more efficient manner (including
11889 calls to other builtin functions).
11890
11891 The call may contain arguments which need to be evaluated, but
11892 which are not useful to determine the result of the call. In
11893 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11894 COMPOUND_EXPR will be an argument which must be evaluated.
11895 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11896 COMPOUND_EXPR in the chain will contain the tree for the simplified
11897 form of the builtin function call. */
11898
11899static tree
389dd41b 11900fold_builtin_strcspn (location_t loc, tree s1, tree s2)
4ee9c684 11901{
c2f47e15 11902 if (!validate_arg (s1, POINTER_TYPE)
11903 || !validate_arg (s2, POINTER_TYPE))
11904 return NULL_TREE;
4ee9c684 11905 else
11906 {
4ee9c684 11907 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11908
11909 /* If both arguments are constants, evaluate at compile-time. */
11910 if (p1 && p2)
11911 {
11912 const size_t r = strcspn (p1, p2);
11913 return size_int (r);
11914 }
11915
c2f47e15 11916 /* If the first argument is "", return NULL_TREE. */
4ee9c684 11917 if (p1 && *p1 == '\0')
11918 {
11919 /* Evaluate and ignore argument s2 in case it has
11920 side-effects. */
389dd41b 11921 return omit_one_operand_loc (loc, size_type_node,
39761420 11922 size_zero_node, s2);
4ee9c684 11923 }
11924
11925 /* If the second argument is "", return __builtin_strlen(s1). */
11926 if (p2 && *p2 == '\0')
11927 {
c2f47e15 11928 tree fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4ee9c684 11929
11930 /* If the replacement _DECL isn't initialized, don't do the
11931 transformation. */
11932 if (!fn)
c2f47e15 11933 return NULL_TREE;
4ee9c684 11934
389dd41b 11935 return build_call_expr_loc (loc, fn, 1, s1);
4ee9c684 11936 }
c2f47e15 11937 return NULL_TREE;
4ee9c684 11938 }
11939}
11940
c2f47e15 11941/* Fold a call to the fputs builtin. ARG0 and ARG1 are the arguments
11942 to the call. IGNORE is true if the value returned
f0613857 11943 by the builtin will be ignored. UNLOCKED is true is true if this
11944 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
11945 the known length of the string. Return NULL_TREE if no simplification
11946 was possible. */
4ee9c684 11947
11948tree
389dd41b 11949fold_builtin_fputs (location_t loc, tree arg0, tree arg1,
11950 bool ignore, bool unlocked, tree len)
4ee9c684 11951{
6d77ed92 11952 /* If we're using an unlocked function, assume the other unlocked
11953 functions exist explicitly. */
11954 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4ee9c684 11955 : implicit_built_in_decls[BUILT_IN_FPUTC];
6d77ed92 11956 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4ee9c684 11957 : implicit_built_in_decls[BUILT_IN_FWRITE];
11958
c403edd4 11959 /* If the return value is used, don't do the transformation. */
11960 if (!ignore)
c2f47e15 11961 return NULL_TREE;
4ee9c684 11962
11963 /* Verify the arguments in the original call. */
c2f47e15 11964 if (!validate_arg (arg0, POINTER_TYPE)
11965 || !validate_arg (arg1, POINTER_TYPE))
11966 return NULL_TREE;
4ee9c684 11967
f0613857 11968 if (! len)
c2f47e15 11969 len = c_strlen (arg0, 0);
4ee9c684 11970
11971 /* Get the length of the string passed to fputs. If the length
11972 can't be determined, punt. */
11973 if (!len
11974 || TREE_CODE (len) != INTEGER_CST)
c2f47e15 11975 return NULL_TREE;
4ee9c684 11976
11977 switch (compare_tree_int (len, 1))
11978 {
11979 case -1: /* length is 0, delete the call entirely . */
389dd41b 11980 return omit_one_operand_loc (loc, integer_type_node,
11981 integer_zero_node, arg1);;
05abc81b 11982
4ee9c684 11983 case 0: /* length is 1, call fputc. */
11984 {
c2f47e15 11985 const char *p = c_getstr (arg0);
4ee9c684 11986
11987 if (p != NULL)
11988 {
c2f47e15 11989 if (fn_fputc)
389dd41b 11990 return build_call_expr_loc (loc, fn_fputc, 2,
c2f47e15 11991 build_int_cst (NULL_TREE, p[0]), arg1);
11992 else
11993 return NULL_TREE;
4ee9c684 11994 }
11995 }
11996 /* FALLTHROUGH */
11997 case 1: /* length is greater than 1, call fwrite. */
11998 {
0bed3869 11999 /* If optimizing for size keep fputs. */
0bfd8d5c 12000 if (optimize_function_for_size_p (cfun))
c2f47e15 12001 return NULL_TREE;
4ee9c684 12002 /* New argument list transforming fputs(string, stream) to
12003 fwrite(string, 1, len, stream). */
c2f47e15 12004 if (fn_fwrite)
389dd41b 12005 return build_call_expr_loc (loc, fn_fwrite, 4, arg0,
12006 size_one_node, len, arg1);
c2f47e15 12007 else
12008 return NULL_TREE;
4ee9c684 12009 }
12010 default:
64db345d 12011 gcc_unreachable ();
4ee9c684 12012 }
c2f47e15 12013 return NULL_TREE;
4ee9c684 12014}
12015
c2f47e15 12016/* Fold the next_arg or va_start call EXP. Returns true if there was an error
743b0c6a 12017 produced. False otherwise. This is done so that we don't output the error
12018 or warning twice or three times. */
75a70cf9 12019
743b0c6a 12020bool
c2f47e15 12021fold_builtin_next_arg (tree exp, bool va_start_p)
4ee9c684 12022{
12023 tree fntype = TREE_TYPE (current_function_decl);
c2f47e15 12024 int nargs = call_expr_nargs (exp);
12025 tree arg;
4ee9c684 12026
12027 if (TYPE_ARG_TYPES (fntype) == 0
12028 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
12029 == void_type_node))
743b0c6a 12030 {
12031 error ("%<va_start%> used in function with fixed args");
12032 return true;
12033 }
c2f47e15 12034
12035 if (va_start_p)
79012a9d 12036 {
c2f47e15 12037 if (va_start_p && (nargs != 2))
12038 {
12039 error ("wrong number of arguments to function %<va_start%>");
12040 return true;
12041 }
12042 arg = CALL_EXPR_ARG (exp, 1);
79012a9d 12043 }
12044 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
12045 when we checked the arguments and if needed issued a warning. */
c2f47e15 12046 else
4ee9c684 12047 {
c2f47e15 12048 if (nargs == 0)
12049 {
12050 /* Evidently an out of date version of <stdarg.h>; can't validate
12051 va_start's second argument, but can still work as intended. */
12052 warning (0, "%<__builtin_next_arg%> called without an argument");
12053 return true;
12054 }
12055 else if (nargs > 1)
a0c938f0 12056 {
c2f47e15 12057 error ("wrong number of arguments to function %<__builtin_next_arg%>");
a0c938f0 12058 return true;
12059 }
c2f47e15 12060 arg = CALL_EXPR_ARG (exp, 0);
12061 }
12062
a8dd994c 12063 if (TREE_CODE (arg) == SSA_NAME)
12064 arg = SSA_NAME_VAR (arg);
12065
c2f47e15 12066 /* We destructively modify the call to be __builtin_va_start (ap, 0)
12067 or __builtin_next_arg (0) the first time we see it, after checking
12068 the arguments and if needed issuing a warning. */
12069 if (!integer_zerop (arg))
12070 {
12071 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
79012a9d 12072
4ee9c684 12073 /* Strip off all nops for the sake of the comparison. This
12074 is not quite the same as STRIP_NOPS. It does more.
12075 We must also strip off INDIRECT_EXPR for C++ reference
12076 parameters. */
72dd6141 12077 while (CONVERT_EXPR_P (arg)
4ee9c684 12078 || TREE_CODE (arg) == INDIRECT_REF)
12079 arg = TREE_OPERAND (arg, 0);
12080 if (arg != last_parm)
a0c938f0 12081 {
b08cf617 12082 /* FIXME: Sometimes with the tree optimizers we can get the
12083 not the last argument even though the user used the last
12084 argument. We just warn and set the arg to be the last
12085 argument so that we will get wrong-code because of
12086 it. */
c3ceba8e 12087 warning (0, "second parameter of %<va_start%> not last named argument");
743b0c6a 12088 }
24158ad7 12089
12090 /* Undefined by C99 7.15.1.4p4 (va_start):
12091 "If the parameter parmN is declared with the register storage
12092 class, with a function or array type, or with a type that is
12093 not compatible with the type that results after application of
12094 the default argument promotions, the behavior is undefined."
12095 */
12096 else if (DECL_REGISTER (arg))
12097 warning (0, "undefined behaviour when second parameter of "
12098 "%<va_start%> is declared with %<register%> storage");
12099
79012a9d 12100 /* We want to verify the second parameter just once before the tree
a0c938f0 12101 optimizers are run and then avoid keeping it in the tree,
12102 as otherwise we could warn even for correct code like:
12103 void foo (int i, ...)
12104 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
c2f47e15 12105 if (va_start_p)
12106 CALL_EXPR_ARG (exp, 1) = integer_zero_node;
12107 else
12108 CALL_EXPR_ARG (exp, 0) = integer_zero_node;
743b0c6a 12109 }
12110 return false;
4ee9c684 12111}
12112
12113
c2f47e15 12114/* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG.
12115 ORIG may be null if this is a 2-argument call. We don't attempt to
12116 simplify calls with more than 3 arguments.
4ee9c684 12117
c2f47e15 12118 Return NULL_TREE if no simplification was possible, otherwise return the
4ee9c684 12119 simplified form of the call as a tree. If IGNORED is true, it means that
12120 the caller does not use the returned value of the function. */
12121
12122static tree
389dd41b 12123fold_builtin_sprintf (location_t loc, tree dest, tree fmt,
12124 tree orig, int ignored)
4ee9c684 12125{
c2f47e15 12126 tree call, retval;
4ee9c684 12127 const char *fmt_str = NULL;
12128
12129 /* Verify the required arguments in the original call. We deal with two
12130 types of sprintf() calls: 'sprintf (str, fmt)' and
12131 'sprintf (dest, "%s", orig)'. */
c2f47e15 12132 if (!validate_arg (dest, POINTER_TYPE)
12133 || !validate_arg (fmt, POINTER_TYPE))
12134 return NULL_TREE;
12135 if (orig && !validate_arg (orig, POINTER_TYPE))
4ee9c684 12136 return NULL_TREE;
4ee9c684 12137
12138 /* Check whether the format is a literal string constant. */
12139 fmt_str = c_getstr (fmt);
12140 if (fmt_str == NULL)
12141 return NULL_TREE;
12142
12143 call = NULL_TREE;
12144 retval = NULL_TREE;
12145
d4473c84 12146 if (!init_target_chars ())
c2f47e15 12147 return NULL_TREE;
99eabcc1 12148
4ee9c684 12149 /* If the format doesn't contain % args or %%, use strcpy. */
99eabcc1 12150 if (strchr (fmt_str, target_percent) == NULL)
4ee9c684 12151 {
12152 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
12153
12154 if (!fn)
12155 return NULL_TREE;
12156
72dfb3f2 12157 /* Don't optimize sprintf (buf, "abc", ptr++). */
c2f47e15 12158 if (orig)
72dfb3f2 12159 return NULL_TREE;
12160
4ee9c684 12161 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
12162 'format' is known to contain no % formats. */
389dd41b 12163 call = build_call_expr_loc (loc, fn, 2, dest, fmt);
4ee9c684 12164 if (!ignored)
7016c612 12165 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
4ee9c684 12166 }
12167
12168 /* If the format is "%s", use strcpy if the result isn't used. */
99eabcc1 12169 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
4ee9c684 12170 {
c2f47e15 12171 tree fn;
4ee9c684 12172 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
12173
12174 if (!fn)
12175 return NULL_TREE;
12176
72dfb3f2 12177 /* Don't crash on sprintf (str1, "%s"). */
c2f47e15 12178 if (!orig)
72dfb3f2 12179 return NULL_TREE;
12180
4ee9c684 12181 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
4ee9c684 12182 if (!ignored)
12183 {
12184 retval = c_strlen (orig, 1);
12185 if (!retval || TREE_CODE (retval) != INTEGER_CST)
12186 return NULL_TREE;
12187 }
389dd41b 12188 call = build_call_expr_loc (loc, fn, 2, dest, orig);
4ee9c684 12189 }
12190
12191 if (call && retval)
12192 {
389dd41b 12193 retval = fold_convert_loc
12194 (loc, TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
4ee9c684 12195 retval);
05abc81b 12196 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
4ee9c684 12197 }
12198 else
12199 return call;
12200}
0a39fd54 12201
c2f47e15 12202/* Expand a call EXP to __builtin_object_size. */
0a39fd54 12203
12204rtx
12205expand_builtin_object_size (tree exp)
12206{
12207 tree ost;
12208 int object_size_type;
12209 tree fndecl = get_callee_fndecl (exp);
0a39fd54 12210
c2f47e15 12211 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
0a39fd54 12212 {
b8c23db3 12213 error ("%Kfirst argument of %D must be a pointer, second integer constant",
12214 exp, fndecl);
0a39fd54 12215 expand_builtin_trap ();
12216 return const0_rtx;
12217 }
12218
c2f47e15 12219 ost = CALL_EXPR_ARG (exp, 1);
0a39fd54 12220 STRIP_NOPS (ost);
12221
12222 if (TREE_CODE (ost) != INTEGER_CST
12223 || tree_int_cst_sgn (ost) < 0
12224 || compare_tree_int (ost, 3) > 0)
12225 {
b8c23db3 12226 error ("%Klast argument of %D is not integer constant between 0 and 3",
12227 exp, fndecl);
0a39fd54 12228 expand_builtin_trap ();
12229 return const0_rtx;
12230 }
12231
12232 object_size_type = tree_low_cst (ost, 0);
12233
12234 return object_size_type < 2 ? constm1_rtx : const0_rtx;
12235}
12236
12237/* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
12238 FCODE is the BUILT_IN_* to use.
c2f47e15 12239 Return NULL_RTX if we failed; the caller should emit a normal call,
0a39fd54 12240 otherwise try to get the result in TARGET, if convenient (and in
12241 mode MODE if that's convenient). */
12242
12243static rtx
12244expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
12245 enum built_in_function fcode)
12246{
0a39fd54 12247 tree dest, src, len, size;
12248
c2f47e15 12249 if (!validate_arglist (exp,
0a39fd54 12250 POINTER_TYPE,
12251 fcode == BUILT_IN_MEMSET_CHK
12252 ? INTEGER_TYPE : POINTER_TYPE,
12253 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
c2f47e15 12254 return NULL_RTX;
0a39fd54 12255
c2f47e15 12256 dest = CALL_EXPR_ARG (exp, 0);
12257 src = CALL_EXPR_ARG (exp, 1);
12258 len = CALL_EXPR_ARG (exp, 2);
12259 size = CALL_EXPR_ARG (exp, 3);
0a39fd54 12260
12261 if (! host_integerp (size, 1))
c2f47e15 12262 return NULL_RTX;
0a39fd54 12263
12264 if (host_integerp (len, 1) || integer_all_onesp (size))
12265 {
12266 tree fn;
12267
12268 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
12269 {
b430e8d9 12270 warning_at (tree_nonartificial_location (exp),
12271 0, "%Kcall to %D will always overflow destination buffer",
12272 exp, get_callee_fndecl (exp));
c2f47e15 12273 return NULL_RTX;
0a39fd54 12274 }
12275
0a39fd54 12276 fn = NULL_TREE;
12277 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12278 mem{cpy,pcpy,move,set} is available. */
12279 switch (fcode)
12280 {
12281 case BUILT_IN_MEMCPY_CHK:
12282 fn = built_in_decls[BUILT_IN_MEMCPY];
12283 break;
12284 case BUILT_IN_MEMPCPY_CHK:
12285 fn = built_in_decls[BUILT_IN_MEMPCPY];
12286 break;
12287 case BUILT_IN_MEMMOVE_CHK:
12288 fn = built_in_decls[BUILT_IN_MEMMOVE];
12289 break;
12290 case BUILT_IN_MEMSET_CHK:
12291 fn = built_in_decls[BUILT_IN_MEMSET];
12292 break;
12293 default:
12294 break;
12295 }
12296
12297 if (! fn)
c2f47e15 12298 return NULL_RTX;
0a39fd54 12299
c2f47e15 12300 fn = build_call_expr (fn, 3, dest, src, len);
6d54e886 12301 STRIP_TYPE_NOPS (fn);
12302 while (TREE_CODE (fn) == COMPOUND_EXPR)
12303 {
12304 expand_expr (TREE_OPERAND (fn, 0), const0_rtx, VOIDmode,
12305 EXPAND_NORMAL);
12306 fn = TREE_OPERAND (fn, 1);
12307 }
0a39fd54 12308 if (TREE_CODE (fn) == CALL_EXPR)
12309 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
12310 return expand_expr (fn, target, mode, EXPAND_NORMAL);
12311 }
12312 else if (fcode == BUILT_IN_MEMSET_CHK)
c2f47e15 12313 return NULL_RTX;
0a39fd54 12314 else
12315 {
12316 unsigned int dest_align
12317 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
12318
12319 /* If DEST is not a pointer type, call the normal function. */
12320 if (dest_align == 0)
c2f47e15 12321 return NULL_RTX;
0a39fd54 12322
12323 /* If SRC and DEST are the same (and not volatile), do nothing. */
12324 if (operand_equal_p (src, dest, 0))
12325 {
12326 tree expr;
12327
12328 if (fcode != BUILT_IN_MEMPCPY_CHK)
12329 {
12330 /* Evaluate and ignore LEN in case it has side-effects. */
12331 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
12332 return expand_expr (dest, target, mode, EXPAND_NORMAL);
12333 }
12334
0de36bdb 12335 expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
0a39fd54 12336 return expand_expr (expr, target, mode, EXPAND_NORMAL);
12337 }
12338
12339 /* __memmove_chk special case. */
12340 if (fcode == BUILT_IN_MEMMOVE_CHK)
12341 {
12342 unsigned int src_align
12343 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
12344
12345 if (src_align == 0)
c2f47e15 12346 return NULL_RTX;
0a39fd54 12347
12348 /* If src is categorized for a readonly section we can use
12349 normal __memcpy_chk. */
12350 if (readonly_data_expr (src))
12351 {
12352 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12353 if (!fn)
c2f47e15 12354 return NULL_RTX;
12355 fn = build_call_expr (fn, 4, dest, src, len, size);
6d54e886 12356 STRIP_TYPE_NOPS (fn);
12357 while (TREE_CODE (fn) == COMPOUND_EXPR)
12358 {
12359 expand_expr (TREE_OPERAND (fn, 0), const0_rtx, VOIDmode,
12360 EXPAND_NORMAL);
12361 fn = TREE_OPERAND (fn, 1);
12362 }
0a39fd54 12363 if (TREE_CODE (fn) == CALL_EXPR)
12364 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
12365 return expand_expr (fn, target, mode, EXPAND_NORMAL);
12366 }
12367 }
c2f47e15 12368 return NULL_RTX;
0a39fd54 12369 }
12370}
12371
12372/* Emit warning if a buffer overflow is detected at compile time. */
12373
12374static void
12375maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
12376{
c2f47e15 12377 int is_strlen = 0;
0a39fd54 12378 tree len, size;
b430e8d9 12379 location_t loc = tree_nonartificial_location (exp);
0a39fd54 12380
12381 switch (fcode)
12382 {
12383 case BUILT_IN_STRCPY_CHK:
12384 case BUILT_IN_STPCPY_CHK:
12385 /* For __strcat_chk the warning will be emitted only if overflowing
12386 by at least strlen (dest) + 1 bytes. */
12387 case BUILT_IN_STRCAT_CHK:
c2f47e15 12388 len = CALL_EXPR_ARG (exp, 1);
12389 size = CALL_EXPR_ARG (exp, 2);
0a39fd54 12390 is_strlen = 1;
12391 break;
b356dfef 12392 case BUILT_IN_STRNCAT_CHK:
0a39fd54 12393 case BUILT_IN_STRNCPY_CHK:
c2f47e15 12394 len = CALL_EXPR_ARG (exp, 2);
12395 size = CALL_EXPR_ARG (exp, 3);
0a39fd54 12396 break;
12397 case BUILT_IN_SNPRINTF_CHK:
12398 case BUILT_IN_VSNPRINTF_CHK:
c2f47e15 12399 len = CALL_EXPR_ARG (exp, 1);
12400 size = CALL_EXPR_ARG (exp, 3);
0a39fd54 12401 break;
12402 default:
12403 gcc_unreachable ();
12404 }
12405
0a39fd54 12406 if (!len || !size)
12407 return;
12408
0a39fd54 12409 if (! host_integerp (size, 1) || integer_all_onesp (size))
12410 return;
12411
12412 if (is_strlen)
12413 {
12414 len = c_strlen (len, 1);
12415 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12416 return;
12417 }
b356dfef 12418 else if (fcode == BUILT_IN_STRNCAT_CHK)
12419 {
c2f47e15 12420 tree src = CALL_EXPR_ARG (exp, 1);
b356dfef 12421 if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12422 return;
12423 src = c_strlen (src, 1);
12424 if (! src || ! host_integerp (src, 1))
12425 {
b430e8d9 12426 warning_at (loc, 0, "%Kcall to %D might overflow destination buffer",
12427 exp, get_callee_fndecl (exp));
b356dfef 12428 return;
12429 }
12430 else if (tree_int_cst_lt (src, size))
12431 return;
12432 }
0a39fd54 12433 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
12434 return;
12435
b430e8d9 12436 warning_at (loc, 0, "%Kcall to %D will always overflow destination buffer",
12437 exp, get_callee_fndecl (exp));
0a39fd54 12438}
12439
12440/* Emit warning if a buffer overflow is detected at compile time
12441 in __sprintf_chk/__vsprintf_chk calls. */
12442
12443static void
12444maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
12445{
0a39fd54 12446 tree dest, size, len, fmt, flag;
12447 const char *fmt_str;
c2f47e15 12448 int nargs = call_expr_nargs (exp);
0a39fd54 12449
12450 /* Verify the required arguments in the original call. */
c2f47e15 12451
12452 if (nargs < 4)
0a39fd54 12453 return;
c2f47e15 12454 dest = CALL_EXPR_ARG (exp, 0);
12455 flag = CALL_EXPR_ARG (exp, 1);
12456 size = CALL_EXPR_ARG (exp, 2);
12457 fmt = CALL_EXPR_ARG (exp, 3);
0a39fd54 12458
12459 if (! host_integerp (size, 1) || integer_all_onesp (size))
12460 return;
12461
12462 /* Check whether the format is a literal string constant. */
12463 fmt_str = c_getstr (fmt);
12464 if (fmt_str == NULL)
12465 return;
12466
d4473c84 12467 if (!init_target_chars ())
99eabcc1 12468 return;
12469
0a39fd54 12470 /* If the format doesn't contain % args or %%, we know its size. */
99eabcc1 12471 if (strchr (fmt_str, target_percent) == 0)
0a39fd54 12472 len = build_int_cstu (size_type_node, strlen (fmt_str));
12473 /* If the format is "%s" and first ... argument is a string literal,
12474 we know it too. */
c2f47e15 12475 else if (fcode == BUILT_IN_SPRINTF_CHK
12476 && strcmp (fmt_str, target_percent_s) == 0)
0a39fd54 12477 {
12478 tree arg;
12479
c2f47e15 12480 if (nargs < 5)
0a39fd54 12481 return;
c2f47e15 12482 arg = CALL_EXPR_ARG (exp, 4);
0a39fd54 12483 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
12484 return;
12485
12486 len = c_strlen (arg, 1);
12487 if (!len || ! host_integerp (len, 1))
12488 return;
12489 }
12490 else
12491 return;
12492
12493 if (! tree_int_cst_lt (len, size))
b430e8d9 12494 warning_at (tree_nonartificial_location (exp),
12495 0, "%Kcall to %D will always overflow destination buffer",
12496 exp, get_callee_fndecl (exp));
0a39fd54 12497}
12498
2c281b15 12499/* Emit warning if a free is called with address of a variable. */
12500
12501static void
12502maybe_emit_free_warning (tree exp)
12503{
12504 tree arg = CALL_EXPR_ARG (exp, 0);
12505
12506 STRIP_NOPS (arg);
12507 if (TREE_CODE (arg) != ADDR_EXPR)
12508 return;
12509
12510 arg = get_base_address (TREE_OPERAND (arg, 0));
12511 if (arg == NULL || INDIRECT_REF_P (arg))
12512 return;
12513
12514 if (SSA_VAR_P (arg))
b430e8d9 12515 warning_at (tree_nonartificial_location (exp),
12516 0, "%Kattempt to free a non-heap object %qD", exp, arg);
2c281b15 12517 else
b430e8d9 12518 warning_at (tree_nonartificial_location (exp),
12519 0, "%Kattempt to free a non-heap object", exp);
2c281b15 12520}
12521
c2f47e15 12522/* Fold a call to __builtin_object_size with arguments PTR and OST,
12523 if possible. */
0a39fd54 12524
12525tree
c2f47e15 12526fold_builtin_object_size (tree ptr, tree ost)
0a39fd54 12527{
c2f47e15 12528 tree ret = NULL_TREE;
0a39fd54 12529 int object_size_type;
12530
c2f47e15 12531 if (!validate_arg (ptr, POINTER_TYPE)
12532 || !validate_arg (ost, INTEGER_TYPE))
12533 return NULL_TREE;
0a39fd54 12534
0a39fd54 12535 STRIP_NOPS (ost);
12536
12537 if (TREE_CODE (ost) != INTEGER_CST
12538 || tree_int_cst_sgn (ost) < 0
12539 || compare_tree_int (ost, 3) > 0)
c2f47e15 12540 return NULL_TREE;
0a39fd54 12541
12542 object_size_type = tree_low_cst (ost, 0);
12543
12544 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
12545 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
12546 and (size_t) 0 for types 2 and 3. */
12547 if (TREE_SIDE_EFFECTS (ptr))
697bbc3f 12548 return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0);
0a39fd54 12549
12550 if (TREE_CODE (ptr) == ADDR_EXPR)
12551 ret = build_int_cstu (size_type_node,
697bbc3f 12552 compute_builtin_object_size (ptr, object_size_type));
0a39fd54 12553
12554 else if (TREE_CODE (ptr) == SSA_NAME)
12555 {
12556 unsigned HOST_WIDE_INT bytes;
12557
12558 /* If object size is not known yet, delay folding until
12559 later. Maybe subsequent passes will help determining
12560 it. */
12561 bytes = compute_builtin_object_size (ptr, object_size_type);
12562 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
12563 ? -1 : 0))
12564 ret = build_int_cstu (size_type_node, bytes);
12565 }
12566
12567 if (ret)
12568 {
697bbc3f 12569 unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (ret);
12570 HOST_WIDE_INT high = TREE_INT_CST_HIGH (ret);
12571 if (fit_double_type (low, high, &low, &high, TREE_TYPE (ret)))
12572 ret = NULL_TREE;
0a39fd54 12573 }
12574
12575 return ret;
12576}
12577
12578/* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
c2f47e15 12579 DEST, SRC, LEN, and SIZE are the arguments to the call.
0a39fd54 12580 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
12581 code of the builtin. If MAXLEN is not NULL, it is maximum length
12582 passed as third argument. */
12583
12584tree
389dd41b 12585fold_builtin_memory_chk (location_t loc, tree fndecl,
c2f47e15 12586 tree dest, tree src, tree len, tree size,
12587 tree maxlen, bool ignore,
0a39fd54 12588 enum built_in_function fcode)
12589{
c2f47e15 12590 tree fn;
0a39fd54 12591
c2f47e15 12592 if (!validate_arg (dest, POINTER_TYPE)
12593 || !validate_arg (src,
12594 (fcode == BUILT_IN_MEMSET_CHK
12595 ? INTEGER_TYPE : POINTER_TYPE))
12596 || !validate_arg (len, INTEGER_TYPE)
12597 || !validate_arg (size, INTEGER_TYPE))
12598 return NULL_TREE;
0a39fd54 12599
12600 /* If SRC and DEST are the same (and not volatile), return DEST
12601 (resp. DEST+LEN for __mempcpy_chk). */
12602 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
12603 {
12604 if (fcode != BUILT_IN_MEMPCPY_CHK)
389dd41b 12605 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
12606 dest, len);
0a39fd54 12607 else
12608 {
389dd41b 12609 tree temp = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (dest),
12610 dest, len);
12611 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), temp);
0a39fd54 12612 }
12613 }
12614
12615 if (! host_integerp (size, 1))
c2f47e15 12616 return NULL_TREE;
0a39fd54 12617
12618 if (! integer_all_onesp (size))
12619 {
12620 if (! host_integerp (len, 1))
12621 {
12622 /* If LEN is not constant, try MAXLEN too.
12623 For MAXLEN only allow optimizing into non-_ocs function
12624 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12625 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12626 {
12627 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
12628 {
12629 /* (void) __mempcpy_chk () can be optimized into
12630 (void) __memcpy_chk (). */
12631 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12632 if (!fn)
c2f47e15 12633 return NULL_TREE;
0a39fd54 12634
389dd41b 12635 return build_call_expr_loc (loc, fn, 4, dest, src, len, size);
0a39fd54 12636 }
c2f47e15 12637 return NULL_TREE;
0a39fd54 12638 }
0a39fd54 12639 }
ad89623c 12640 else
12641 maxlen = len;
0a39fd54 12642
ad89623c 12643 if (tree_int_cst_lt (size, maxlen))
c2f47e15 12644 return NULL_TREE;
0a39fd54 12645 }
12646
0a39fd54 12647 fn = NULL_TREE;
12648 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12649 mem{cpy,pcpy,move,set} is available. */
12650 switch (fcode)
12651 {
12652 case BUILT_IN_MEMCPY_CHK:
12653 fn = built_in_decls[BUILT_IN_MEMCPY];
12654 break;
12655 case BUILT_IN_MEMPCPY_CHK:
12656 fn = built_in_decls[BUILT_IN_MEMPCPY];
12657 break;
12658 case BUILT_IN_MEMMOVE_CHK:
12659 fn = built_in_decls[BUILT_IN_MEMMOVE];
12660 break;
12661 case BUILT_IN_MEMSET_CHK:
12662 fn = built_in_decls[BUILT_IN_MEMSET];
12663 break;
12664 default:
12665 break;
12666 }
12667
12668 if (!fn)
c2f47e15 12669 return NULL_TREE;
0a39fd54 12670
389dd41b 12671 return build_call_expr_loc (loc, fn, 3, dest, src, len);
0a39fd54 12672}
12673
12674/* Fold a call to the __st[rp]cpy_chk builtin.
c2f47e15 12675 DEST, SRC, and SIZE are the arguments to the call.
12676 IGNORE is true if return value can be ignored. FCODE is the BUILT_IN_*
0a39fd54 12677 code of the builtin. If MAXLEN is not NULL, it is maximum length of
12678 strings passed as second argument. */
12679
12680tree
389dd41b 12681fold_builtin_stxcpy_chk (location_t loc, tree fndecl, tree dest,
12682 tree src, tree size,
c2f47e15 12683 tree maxlen, bool ignore,
0a39fd54 12684 enum built_in_function fcode)
12685{
c2f47e15 12686 tree len, fn;
0a39fd54 12687
c2f47e15 12688 if (!validate_arg (dest, POINTER_TYPE)
12689 || !validate_arg (src, POINTER_TYPE)
12690 || !validate_arg (size, INTEGER_TYPE))
12691 return NULL_TREE;
0a39fd54 12692
12693 /* If SRC and DEST are the same (and not volatile), return DEST. */
12694 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
389dd41b 12695 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest);
a0c938f0 12696
0a39fd54 12697 if (! host_integerp (size, 1))
c2f47e15 12698 return NULL_TREE;
0a39fd54 12699
12700 if (! integer_all_onesp (size))
12701 {
12702 len = c_strlen (src, 1);
12703 if (! len || ! host_integerp (len, 1))
12704 {
12705 /* If LEN is not constant, try MAXLEN too.
12706 For MAXLEN only allow optimizing into non-_ocs function
12707 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12708 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12709 {
12710 if (fcode == BUILT_IN_STPCPY_CHK)
12711 {
12712 if (! ignore)
c2f47e15 12713 return NULL_TREE;
0a39fd54 12714
12715 /* If return value of __stpcpy_chk is ignored,
12716 optimize into __strcpy_chk. */
12717 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
12718 if (!fn)
c2f47e15 12719 return NULL_TREE;
0a39fd54 12720
389dd41b 12721 return build_call_expr_loc (loc, fn, 3, dest, src, size);
0a39fd54 12722 }
12723
12724 if (! len || TREE_SIDE_EFFECTS (len))
c2f47e15 12725 return NULL_TREE;
0a39fd54 12726
12727 /* If c_strlen returned something, but not a constant,
12728 transform __strcpy_chk into __memcpy_chk. */
12729 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12730 if (!fn)
c2f47e15 12731 return NULL_TREE;
0a39fd54 12732
389dd41b 12733 len = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
12734 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
12735 build_call_expr_loc (loc, fn, 4,
12736 dest, src, len, size));
0a39fd54 12737 }
0a39fd54 12738 }
ad89623c 12739 else
12740 maxlen = len;
12741
12742 if (! tree_int_cst_lt (maxlen, size))
c2f47e15 12743 return NULL_TREE;
0a39fd54 12744 }
12745
0a39fd54 12746 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
12747 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
12748 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
12749 if (!fn)
c2f47e15 12750 return NULL_TREE;
0a39fd54 12751
389dd41b 12752 return build_call_expr_loc (loc, fn, 2, dest, src);
0a39fd54 12753}
12754
c2f47e15 12755/* Fold a call to the __strncpy_chk builtin. DEST, SRC, LEN, and SIZE
12756 are the arguments to the call. If MAXLEN is not NULL, it is maximum
12757 length passed as third argument. */
0a39fd54 12758
12759tree
389dd41b 12760fold_builtin_strncpy_chk (location_t loc, tree dest, tree src,
12761 tree len, tree size, tree maxlen)
0a39fd54 12762{
c2f47e15 12763 tree fn;
0a39fd54 12764
c2f47e15 12765 if (!validate_arg (dest, POINTER_TYPE)
12766 || !validate_arg (src, POINTER_TYPE)
12767 || !validate_arg (len, INTEGER_TYPE)
12768 || !validate_arg (size, INTEGER_TYPE))
12769 return NULL_TREE;
0a39fd54 12770
12771 if (! host_integerp (size, 1))
c2f47e15 12772 return NULL_TREE;
0a39fd54 12773
12774 if (! integer_all_onesp (size))
12775 {
12776 if (! host_integerp (len, 1))
12777 {
12778 /* If LEN is not constant, try MAXLEN too.
12779 For MAXLEN only allow optimizing into non-_ocs function
12780 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12781 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
c2f47e15 12782 return NULL_TREE;
0a39fd54 12783 }
ad89623c 12784 else
12785 maxlen = len;
0a39fd54 12786
ad89623c 12787 if (tree_int_cst_lt (size, maxlen))
c2f47e15 12788 return NULL_TREE;
0a39fd54 12789 }
12790
0a39fd54 12791 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
12792 fn = built_in_decls[BUILT_IN_STRNCPY];
12793 if (!fn)
c2f47e15 12794 return NULL_TREE;
0a39fd54 12795
389dd41b 12796 return build_call_expr_loc (loc, fn, 3, dest, src, len);
0a39fd54 12797}
12798
c2f47e15 12799/* Fold a call to the __strcat_chk builtin FNDECL. DEST, SRC, and SIZE
12800 are the arguments to the call. */
0a39fd54 12801
12802static tree
389dd41b 12803fold_builtin_strcat_chk (location_t loc, tree fndecl, tree dest,
12804 tree src, tree size)
0a39fd54 12805{
c2f47e15 12806 tree fn;
0a39fd54 12807 const char *p;
12808
c2f47e15 12809 if (!validate_arg (dest, POINTER_TYPE)
12810 || !validate_arg (src, POINTER_TYPE)
12811 || !validate_arg (size, INTEGER_TYPE))
12812 return NULL_TREE;
0a39fd54 12813
12814 p = c_getstr (src);
12815 /* If the SRC parameter is "", return DEST. */
12816 if (p && *p == '\0')
389dd41b 12817 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
0a39fd54 12818
12819 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
c2f47e15 12820 return NULL_TREE;
0a39fd54 12821
12822 /* If __builtin_strcat_chk is used, assume strcat is available. */
12823 fn = built_in_decls[BUILT_IN_STRCAT];
12824 if (!fn)
c2f47e15 12825 return NULL_TREE;
0a39fd54 12826
389dd41b 12827 return build_call_expr_loc (loc, fn, 2, dest, src);
0a39fd54 12828}
12829
c2f47e15 12830/* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
12831 LEN, and SIZE. */
0a39fd54 12832
12833static tree
389dd41b 12834fold_builtin_strncat_chk (location_t loc, tree fndecl,
c2f47e15 12835 tree dest, tree src, tree len, tree size)
0a39fd54 12836{
c2f47e15 12837 tree fn;
0a39fd54 12838 const char *p;
12839
c2f47e15 12840 if (!validate_arg (dest, POINTER_TYPE)
12841 || !validate_arg (src, POINTER_TYPE)
12842 || !validate_arg (size, INTEGER_TYPE)
12843 || !validate_arg (size, INTEGER_TYPE))
12844 return NULL_TREE;
0a39fd54 12845
12846 p = c_getstr (src);
12847 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
12848 if (p && *p == '\0')
389dd41b 12849 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
0a39fd54 12850 else if (integer_zerop (len))
389dd41b 12851 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
0a39fd54 12852
12853 if (! host_integerp (size, 1))
c2f47e15 12854 return NULL_TREE;
0a39fd54 12855
12856 if (! integer_all_onesp (size))
12857 {
12858 tree src_len = c_strlen (src, 1);
12859 if (src_len
12860 && host_integerp (src_len, 1)
12861 && host_integerp (len, 1)
12862 && ! tree_int_cst_lt (len, src_len))
12863 {
12864 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
12865 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
12866 if (!fn)
c2f47e15 12867 return NULL_TREE;
0a39fd54 12868
389dd41b 12869 return build_call_expr_loc (loc, fn, 3, dest, src, size);
0a39fd54 12870 }
c2f47e15 12871 return NULL_TREE;
0a39fd54 12872 }
12873
0a39fd54 12874 /* If __builtin_strncat_chk is used, assume strncat is available. */
12875 fn = built_in_decls[BUILT_IN_STRNCAT];
12876 if (!fn)
c2f47e15 12877 return NULL_TREE;
0a39fd54 12878
389dd41b 12879 return build_call_expr_loc (loc, fn, 3, dest, src, len);
0a39fd54 12880}
12881
c2f47e15 12882/* Fold a call EXP to __{,v}sprintf_chk. Return NULL_TREE if
0a39fd54 12883 a normal call should be emitted rather than expanding the function
12884 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
12885
12886static tree
389dd41b 12887fold_builtin_sprintf_chk (location_t loc, tree exp,
12888 enum built_in_function fcode)
0a39fd54 12889{
12890 tree dest, size, len, fn, fmt, flag;
12891 const char *fmt_str;
c2f47e15 12892 int nargs = call_expr_nargs (exp);
0a39fd54 12893
12894 /* Verify the required arguments in the original call. */
c2f47e15 12895 if (nargs < 4)
12896 return NULL_TREE;
12897 dest = CALL_EXPR_ARG (exp, 0);
12898 if (!validate_arg (dest, POINTER_TYPE))
12899 return NULL_TREE;
12900 flag = CALL_EXPR_ARG (exp, 1);
12901 if (!validate_arg (flag, INTEGER_TYPE))
12902 return NULL_TREE;
12903 size = CALL_EXPR_ARG (exp, 2);
12904 if (!validate_arg (size, INTEGER_TYPE))
12905 return NULL_TREE;
12906 fmt = CALL_EXPR_ARG (exp, 3);
12907 if (!validate_arg (fmt, POINTER_TYPE))
12908 return NULL_TREE;
0a39fd54 12909
12910 if (! host_integerp (size, 1))
c2f47e15 12911 return NULL_TREE;
0a39fd54 12912
12913 len = NULL_TREE;
12914
d4473c84 12915 if (!init_target_chars ())
c2f47e15 12916 return NULL_TREE;
99eabcc1 12917
0a39fd54 12918 /* Check whether the format is a literal string constant. */
12919 fmt_str = c_getstr (fmt);
12920 if (fmt_str != NULL)
12921 {
12922 /* If the format doesn't contain % args or %%, we know the size. */
99eabcc1 12923 if (strchr (fmt_str, target_percent) == 0)
0a39fd54 12924 {
c2f47e15 12925 if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
0a39fd54 12926 len = build_int_cstu (size_type_node, strlen (fmt_str));
12927 }
12928 /* If the format is "%s" and first ... argument is a string literal,
12929 we know the size too. */
c2f47e15 12930 else if (fcode == BUILT_IN_SPRINTF_CHK
12931 && strcmp (fmt_str, target_percent_s) == 0)
0a39fd54 12932 {
12933 tree arg;
12934
c2f47e15 12935 if (nargs == 5)
0a39fd54 12936 {
c2f47e15 12937 arg = CALL_EXPR_ARG (exp, 4);
12938 if (validate_arg (arg, POINTER_TYPE))
0a39fd54 12939 {
12940 len = c_strlen (arg, 1);
12941 if (! len || ! host_integerp (len, 1))
12942 len = NULL_TREE;
12943 }
12944 }
12945 }
12946 }
12947
12948 if (! integer_all_onesp (size))
12949 {
12950 if (! len || ! tree_int_cst_lt (len, size))
c2f47e15 12951 return NULL_TREE;
0a39fd54 12952 }
12953
12954 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
12955 or if format doesn't contain % chars or is "%s". */
12956 if (! integer_zerop (flag))
12957 {
12958 if (fmt_str == NULL)
c2f47e15 12959 return NULL_TREE;
12960 if (strchr (fmt_str, target_percent) != NULL
12961 && strcmp (fmt_str, target_percent_s))
12962 return NULL_TREE;
0a39fd54 12963 }
12964
0a39fd54 12965 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
12966 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
12967 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
12968 if (!fn)
c2f47e15 12969 return NULL_TREE;
0a39fd54 12970
389dd41b 12971 return rewrite_call_expr (loc, exp, 4, fn, 2, dest, fmt);
0a39fd54 12972}
12973
c2f47e15 12974/* Fold a call EXP to {,v}snprintf. Return NULL_TREE if
0a39fd54 12975 a normal call should be emitted rather than expanding the function
12976 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
12977 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
12978 passed as second argument. */
12979
12980tree
389dd41b 12981fold_builtin_snprintf_chk (location_t loc, tree exp, tree maxlen,
0a39fd54 12982 enum built_in_function fcode)
12983{
12984 tree dest, size, len, fn, fmt, flag;
12985 const char *fmt_str;
12986
12987 /* Verify the required arguments in the original call. */
c2f47e15 12988 if (call_expr_nargs (exp) < 5)
12989 return NULL_TREE;
12990 dest = CALL_EXPR_ARG (exp, 0);
12991 if (!validate_arg (dest, POINTER_TYPE))
12992 return NULL_TREE;
12993 len = CALL_EXPR_ARG (exp, 1);
12994 if (!validate_arg (len, INTEGER_TYPE))
12995 return NULL_TREE;
12996 flag = CALL_EXPR_ARG (exp, 2);
12997 if (!validate_arg (flag, INTEGER_TYPE))
12998 return NULL_TREE;
12999 size = CALL_EXPR_ARG (exp, 3);
13000 if (!validate_arg (size, INTEGER_TYPE))
13001 return NULL_TREE;
13002 fmt = CALL_EXPR_ARG (exp, 4);
13003 if (!validate_arg (fmt, POINTER_TYPE))
13004 return NULL_TREE;
0a39fd54 13005
13006 if (! host_integerp (size, 1))
c2f47e15 13007 return NULL_TREE;
0a39fd54 13008
13009 if (! integer_all_onesp (size))
13010 {
13011 if (! host_integerp (len, 1))
13012 {
13013 /* If LEN is not constant, try MAXLEN too.
13014 For MAXLEN only allow optimizing into non-_ocs function
13015 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
13016 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
c2f47e15 13017 return NULL_TREE;
0a39fd54 13018 }
ad89623c 13019 else
13020 maxlen = len;
0a39fd54 13021
ad89623c 13022 if (tree_int_cst_lt (size, maxlen))
c2f47e15 13023 return NULL_TREE;
0a39fd54 13024 }
13025
d4473c84 13026 if (!init_target_chars ())
c2f47e15 13027 return NULL_TREE;
99eabcc1 13028
0a39fd54 13029 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
13030 or if format doesn't contain % chars or is "%s". */
13031 if (! integer_zerop (flag))
13032 {
13033 fmt_str = c_getstr (fmt);
13034 if (fmt_str == NULL)
c2f47e15 13035 return NULL_TREE;
13036 if (strchr (fmt_str, target_percent) != NULL
13037 && strcmp (fmt_str, target_percent_s))
13038 return NULL_TREE;
0a39fd54 13039 }
13040
0a39fd54 13041 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
13042 available. */
13043 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
13044 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
13045 if (!fn)
c2f47e15 13046 return NULL_TREE;
0a39fd54 13047
389dd41b 13048 return rewrite_call_expr (loc, exp, 5, fn, 3, dest, len, fmt);
0a39fd54 13049}
13050
13051/* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
c2f47e15 13052 FMT and ARG are the arguments to the call; we don't fold cases with
13053 more than 2 arguments, and ARG may be null if this is a 1-argument case.
0a39fd54 13054
c2f47e15 13055 Return NULL_TREE if no simplification was possible, otherwise return the
0a39fd54 13056 simplified form of the call as a tree. FCODE is the BUILT_IN_*
13057 code of the function to be simplified. */
13058
13059static tree
389dd41b 13060fold_builtin_printf (location_t loc, tree fndecl, tree fmt,
13061 tree arg, bool ignore,
0a39fd54 13062 enum built_in_function fcode)
13063{
c2f47e15 13064 tree fn_putchar, fn_puts, newarg, call = NULL_TREE;
0a39fd54 13065 const char *fmt_str = NULL;
13066
13067 /* If the return value is used, don't do the transformation. */
13068 if (! ignore)
c2f47e15 13069 return NULL_TREE;
0a39fd54 13070
13071 /* Verify the required arguments in the original call. */
c2f47e15 13072 if (!validate_arg (fmt, POINTER_TYPE))
13073 return NULL_TREE;
0a39fd54 13074
13075 /* Check whether the format is a literal string constant. */
13076 fmt_str = c_getstr (fmt);
13077 if (fmt_str == NULL)
13078 return NULL_TREE;
13079
13080 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
13081 {
6d77ed92 13082 /* If we're using an unlocked function, assume the other
13083 unlocked functions exist explicitly. */
13084 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
13085 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
0a39fd54 13086 }
13087 else
13088 {
13089 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
13090 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
13091 }
13092
d4473c84 13093 if (!init_target_chars ())
c2f47e15 13094 return NULL_TREE;
a0c938f0 13095
c2f47e15 13096 if (strcmp (fmt_str, target_percent_s) == 0
13097 || strchr (fmt_str, target_percent) == NULL)
0a39fd54 13098 {
13099 const char *str;
13100
99eabcc1 13101 if (strcmp (fmt_str, target_percent_s) == 0)
0a39fd54 13102 {
13103 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
c2f47e15 13104 return NULL_TREE;
0a39fd54 13105
c2f47e15 13106 if (!arg || !validate_arg (arg, POINTER_TYPE))
13107 return NULL_TREE;
0a39fd54 13108
c2f47e15 13109 str = c_getstr (arg);
0a39fd54 13110 if (str == NULL)
c2f47e15 13111 return NULL_TREE;
0a39fd54 13112 }
13113 else
13114 {
13115 /* The format specifier doesn't contain any '%' characters. */
13116 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
c2f47e15 13117 && arg)
13118 return NULL_TREE;
0a39fd54 13119 str = fmt_str;
13120 }
13121
13122 /* If the string was "", printf does nothing. */
13123 if (str[0] == '\0')
13124 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
13125
13126 /* If the string has length of 1, call putchar. */
13127 if (str[1] == '\0')
13128 {
13129 /* Given printf("c"), (where c is any one character,)
13130 convert "c"[0] to an int and pass that to the replacement
13131 function. */
c2f47e15 13132 newarg = build_int_cst (NULL_TREE, str[0]);
13133 if (fn_putchar)
389dd41b 13134 call = build_call_expr_loc (loc, fn_putchar, 1, newarg);
0a39fd54 13135 }
13136 else
13137 {
13138 /* If the string was "string\n", call puts("string"). */
13139 size_t len = strlen (str);
99eabcc1 13140 if ((unsigned char)str[len - 1] == target_newline)
0a39fd54 13141 {
13142 /* Create a NUL-terminated string that's one char shorter
13143 than the original, stripping off the trailing '\n'. */
364c0c59 13144 char *newstr = XALLOCAVEC (char, len);
0a39fd54 13145 memcpy (newstr, str, len - 1);
13146 newstr[len - 1] = 0;
13147
c2f47e15 13148 newarg = build_string_literal (len, newstr);
13149 if (fn_puts)
389dd41b 13150 call = build_call_expr_loc (loc, fn_puts, 1, newarg);
0a39fd54 13151 }
13152 else
13153 /* We'd like to arrange to call fputs(string,stdout) here,
13154 but we need stdout and don't have a way to get it yet. */
c2f47e15 13155 return NULL_TREE;
0a39fd54 13156 }
13157 }
13158
13159 /* The other optimizations can be done only on the non-va_list variants. */
13160 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
c2f47e15 13161 return NULL_TREE;
0a39fd54 13162
13163 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
99eabcc1 13164 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
0a39fd54 13165 {
c2f47e15 13166 if (!arg || !validate_arg (arg, POINTER_TYPE))
13167 return NULL_TREE;
13168 if (fn_puts)
389dd41b 13169 call = build_call_expr_loc (loc, fn_puts, 1, arg);
0a39fd54 13170 }
13171
13172 /* If the format specifier was "%c", call __builtin_putchar(arg). */
99eabcc1 13173 else if (strcmp (fmt_str, target_percent_c) == 0)
0a39fd54 13174 {
c2f47e15 13175 if (!arg || !validate_arg (arg, INTEGER_TYPE))
13176 return NULL_TREE;
13177 if (fn_putchar)
389dd41b 13178 call = build_call_expr_loc (loc, fn_putchar, 1, arg);
0a39fd54 13179 }
13180
c2f47e15 13181 if (!call)
13182 return NULL_TREE;
0a39fd54 13183
389dd41b 13184 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), call);
0a39fd54 13185}
13186
13187/* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
c2f47e15 13188 FP, FMT, and ARG are the arguments to the call. We don't fold calls with
13189 more than 3 arguments, and ARG may be null in the 2-argument case.
0a39fd54 13190
c2f47e15 13191 Return NULL_TREE if no simplification was possible, otherwise return the
0a39fd54 13192 simplified form of the call as a tree. FCODE is the BUILT_IN_*
13193 code of the function to be simplified. */
13194
13195static tree
389dd41b 13196fold_builtin_fprintf (location_t loc, tree fndecl, tree fp,
13197 tree fmt, tree arg, bool ignore,
0a39fd54 13198 enum built_in_function fcode)
13199{
c2f47e15 13200 tree fn_fputc, fn_fputs, call = NULL_TREE;
0a39fd54 13201 const char *fmt_str = NULL;
13202
13203 /* If the return value is used, don't do the transformation. */
13204 if (! ignore)
c2f47e15 13205 return NULL_TREE;
0a39fd54 13206
13207 /* Verify the required arguments in the original call. */
c2f47e15 13208 if (!validate_arg (fp, POINTER_TYPE))
13209 return NULL_TREE;
13210 if (!validate_arg (fmt, POINTER_TYPE))
13211 return NULL_TREE;
0a39fd54 13212
13213 /* Check whether the format is a literal string constant. */
13214 fmt_str = c_getstr (fmt);
13215 if (fmt_str == NULL)
13216 return NULL_TREE;
13217
13218 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
13219 {
6d77ed92 13220 /* If we're using an unlocked function, assume the other
13221 unlocked functions exist explicitly. */
13222 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
13223 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
0a39fd54 13224 }
13225 else
13226 {
13227 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
13228 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
13229 }
13230
d4473c84 13231 if (!init_target_chars ())
c2f47e15 13232 return NULL_TREE;
a0c938f0 13233
0a39fd54 13234 /* If the format doesn't contain % args or %%, use strcpy. */
99eabcc1 13235 if (strchr (fmt_str, target_percent) == NULL)
0a39fd54 13236 {
13237 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
c2f47e15 13238 && arg)
13239 return NULL_TREE;
0a39fd54 13240
13241 /* If the format specifier was "", fprintf does nothing. */
13242 if (fmt_str[0] == '\0')
13243 {
13244 /* If FP has side-effects, just wait until gimplification is
13245 done. */
13246 if (TREE_SIDE_EFFECTS (fp))
c2f47e15 13247 return NULL_TREE;
0a39fd54 13248
13249 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
13250 }
13251
13252 /* When "string" doesn't contain %, replace all cases of
13253 fprintf (fp, string) with fputs (string, fp). The fputs
13254 builtin will take care of special cases like length == 1. */
c2f47e15 13255 if (fn_fputs)
389dd41b 13256 call = build_call_expr_loc (loc, fn_fputs, 2, fmt, fp);
0a39fd54 13257 }
13258
13259 /* The other optimizations can be done only on the non-va_list variants. */
13260 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
c2f47e15 13261 return NULL_TREE;
0a39fd54 13262
13263 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
99eabcc1 13264 else if (strcmp (fmt_str, target_percent_s) == 0)
0a39fd54 13265 {
c2f47e15 13266 if (!arg || !validate_arg (arg, POINTER_TYPE))
13267 return NULL_TREE;
13268 if (fn_fputs)
389dd41b 13269 call = build_call_expr_loc (loc, fn_fputs, 2, arg, fp);
0a39fd54 13270 }
13271
13272 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
99eabcc1 13273 else if (strcmp (fmt_str, target_percent_c) == 0)
0a39fd54 13274 {
c2f47e15 13275 if (!arg || !validate_arg (arg, INTEGER_TYPE))
13276 return NULL_TREE;
13277 if (fn_fputc)
389dd41b 13278 call = build_call_expr_loc (loc, fn_fputc, 2, arg, fp);
0a39fd54 13279 }
13280
c2f47e15 13281 if (!call)
13282 return NULL_TREE;
389dd41b 13283 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), call);
0a39fd54 13284}
99eabcc1 13285
13286/* Initialize format string characters in the target charset. */
13287
13288static bool
13289init_target_chars (void)
13290{
13291 static bool init;
13292 if (!init)
13293 {
13294 target_newline = lang_hooks.to_target_charset ('\n');
13295 target_percent = lang_hooks.to_target_charset ('%');
13296 target_c = lang_hooks.to_target_charset ('c');
13297 target_s = lang_hooks.to_target_charset ('s');
13298 if (target_newline == 0 || target_percent == 0 || target_c == 0
13299 || target_s == 0)
13300 return false;
13301
13302 target_percent_c[0] = target_percent;
13303 target_percent_c[1] = target_c;
13304 target_percent_c[2] = '\0';
13305
13306 target_percent_s[0] = target_percent;
13307 target_percent_s[1] = target_s;
13308 target_percent_s[2] = '\0';
13309
13310 target_percent_s_newline[0] = target_percent;
13311 target_percent_s_newline[1] = target_s;
13312 target_percent_s_newline[2] = target_newline;
13313 target_percent_s_newline[3] = '\0';
a0c938f0 13314
99eabcc1 13315 init = true;
13316 }
13317 return true;
13318}
bffb7645 13319
f0c477f2 13320/* Helper function for do_mpfr_arg*(). Ensure M is a normal number
13321 and no overflow/underflow occurred. INEXACT is true if M was not
fa7637bd 13322 exactly calculated. TYPE is the tree type for the result. This
f0c477f2 13323 function assumes that you cleared the MPFR flags and then
13324 calculated M to see if anything subsequently set a flag prior to
13325 entering this function. Return NULL_TREE if any checks fail. */
13326
13327static tree
d4473c84 13328do_mpfr_ckconv (mpfr_srcptr m, tree type, int inexact)
f0c477f2 13329{
13330 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13331 overflow/underflow occurred. If -frounding-math, proceed iff the
13332 result of calling FUNC was exact. */
d4473c84 13333 if (mpfr_number_p (m) && !mpfr_overflow_p () && !mpfr_underflow_p ()
f0c477f2 13334 && (!flag_rounding_math || !inexact))
13335 {
13336 REAL_VALUE_TYPE rr;
13337
66fa16e6 13338 real_from_mpfr (&rr, m, type, GMP_RNDN);
f0c477f2 13339 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
13340 check for overflow/underflow. If the REAL_VALUE_TYPE is zero
13341 but the mpft_t is not, then we underflowed in the
13342 conversion. */
776a7bab 13343 if (real_isfinite (&rr)
f0c477f2 13344 && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
13345 {
13346 REAL_VALUE_TYPE rmode;
13347
13348 real_convert (&rmode, TYPE_MODE (type), &rr);
13349 /* Proceed iff the specified mode can hold the value. */
13350 if (real_identical (&rmode, &rr))
13351 return build_real (type, rmode);
13352 }
13353 }
13354 return NULL_TREE;
13355}
13356
239d491a 13357#ifdef HAVE_mpc
13358/* Helper function for do_mpc_arg*(). Ensure M is a normal complex
13359 number and no overflow/underflow occurred. INEXACT is true if M
13360 was not exactly calculated. TYPE is the tree type for the result.
13361 This function assumes that you cleared the MPFR flags and then
13362 calculated M to see if anything subsequently set a flag prior to
652d9409 13363 entering this function. Return NULL_TREE if any checks fail, if
13364 FORCE_CONVERT is true, then bypass the checks. */
239d491a 13365
13366static tree
652d9409 13367do_mpc_ckconv (mpc_srcptr m, tree type, int inexact, int force_convert)
239d491a 13368{
13369 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13370 overflow/underflow occurred. If -frounding-math, proceed iff the
13371 result of calling FUNC was exact. */
652d9409 13372 if (force_convert
13373 || (mpfr_number_p (mpc_realref (m)) && mpfr_number_p (mpc_imagref (m))
13374 && !mpfr_overflow_p () && !mpfr_underflow_p ()
13375 && (!flag_rounding_math || !inexact)))
239d491a 13376 {
13377 REAL_VALUE_TYPE re, im;
13378
c3cfad90 13379 real_from_mpfr (&re, mpc_realref (m), type, GMP_RNDN);
13380 real_from_mpfr (&im, mpc_imagref (m), type, GMP_RNDN);
239d491a 13381 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR values,
13382 check for overflow/underflow. If the REAL_VALUE_TYPE is zero
13383 but the mpft_t is not, then we underflowed in the
13384 conversion. */
652d9409 13385 if (force_convert
13386 || (real_isfinite (&re) && real_isfinite (&im)
13387 && (re.cl == rvc_zero) == (mpfr_zero_p (mpc_realref (m)) != 0)
13388 && (im.cl == rvc_zero) == (mpfr_zero_p (mpc_imagref (m)) != 0)))
239d491a 13389 {
13390 REAL_VALUE_TYPE re_mode, im_mode;
13391
13392 real_convert (&re_mode, TYPE_MODE (TREE_TYPE (type)), &re);
13393 real_convert (&im_mode, TYPE_MODE (TREE_TYPE (type)), &im);
13394 /* Proceed iff the specified mode can hold the value. */
652d9409 13395 if (force_convert
13396 || (real_identical (&re_mode, &re)
13397 && real_identical (&im_mode, &im)))
239d491a 13398 return build_complex (type, build_real (TREE_TYPE (type), re_mode),
13399 build_real (TREE_TYPE (type), im_mode));
13400 }
13401 }
13402 return NULL_TREE;
13403}
13404#endif /* HAVE_mpc */
13405
bffb7645 13406/* If argument ARG is a REAL_CST, call the one-argument mpfr function
13407 FUNC on it and return the resulting value as a tree with type TYPE.
728bac60 13408 If MIN and/or MAX are not NULL, then the supplied ARG must be
13409 within those bounds. If INCLUSIVE is true, then MIN/MAX are
13410 acceptable values, otherwise they are not. The mpfr precision is
13411 set to the precision of TYPE. We assume that function FUNC returns
13412 zero if the result could be calculated exactly within the requested
13413 precision. */
bffb7645 13414
13415static tree
728bac60 13416do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
13417 const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
13418 bool inclusive)
bffb7645 13419{
13420 tree result = NULL_TREE;
13421
13422 STRIP_NOPS (arg);
13423
bd7d6fa4 13424 /* To proceed, MPFR must exactly represent the target floating point
13425 format, which only happens when the target base equals two. */
13426 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
f96bd2bf 13427 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
bffb7645 13428 {
f0c477f2 13429 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
bffb7645 13430
776a7bab 13431 if (real_isfinite (ra)
f0c477f2 13432 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
13433 && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
bffb7645 13434 {
e2eb2b7f 13435 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13436 const int prec = fmt->p;
13437 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
debf9994 13438 int inexact;
bffb7645 13439 mpfr_t m;
13440
13441 mpfr_init2 (m, prec);
66fa16e6 13442 mpfr_from_real (m, ra, GMP_RNDN);
d4473c84 13443 mpfr_clear_flags ();
e2eb2b7f 13444 inexact = func (m, m, rnd);
f0c477f2 13445 result = do_mpfr_ckconv (m, type, inexact);
bffb7645 13446 mpfr_clear (m);
13447 }
13448 }
13449
13450 return result;
13451}
f0c477f2 13452
13453/* If argument ARG is a REAL_CST, call the two-argument mpfr function
13454 FUNC on it and return the resulting value as a tree with type TYPE.
13455 The mpfr precision is set to the precision of TYPE. We assume that
13456 function FUNC returns zero if the result could be calculated
13457 exactly within the requested precision. */
13458
13459static tree
13460do_mpfr_arg2 (tree arg1, tree arg2, tree type,
13461 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13462{
13463 tree result = NULL_TREE;
13464
13465 STRIP_NOPS (arg1);
13466 STRIP_NOPS (arg2);
13467
bd7d6fa4 13468 /* To proceed, MPFR must exactly represent the target floating point
13469 format, which only happens when the target base equals two. */
13470 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
f96bd2bf 13471 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13472 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
f0c477f2 13473 {
13474 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13475 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13476
776a7bab 13477 if (real_isfinite (ra1) && real_isfinite (ra2))
f0c477f2 13478 {
e2eb2b7f 13479 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13480 const int prec = fmt->p;
13481 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
f0c477f2 13482 int inexact;
13483 mpfr_t m1, m2;
13484
13485 mpfr_inits2 (prec, m1, m2, NULL);
66fa16e6 13486 mpfr_from_real (m1, ra1, GMP_RNDN);
13487 mpfr_from_real (m2, ra2, GMP_RNDN);
d4473c84 13488 mpfr_clear_flags ();
e2eb2b7f 13489 inexact = func (m1, m1, m2, rnd);
f0c477f2 13490 result = do_mpfr_ckconv (m1, type, inexact);
13491 mpfr_clears (m1, m2, NULL);
13492 }
13493 }
13494
13495 return result;
13496}
d92f994c 13497
9917422b 13498/* If argument ARG is a REAL_CST, call the three-argument mpfr function
13499 FUNC on it and return the resulting value as a tree with type TYPE.
13500 The mpfr precision is set to the precision of TYPE. We assume that
13501 function FUNC returns zero if the result could be calculated
13502 exactly within the requested precision. */
13503
13504static tree
13505do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
13506 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13507{
13508 tree result = NULL_TREE;
13509
13510 STRIP_NOPS (arg1);
13511 STRIP_NOPS (arg2);
13512 STRIP_NOPS (arg3);
13513
bd7d6fa4 13514 /* To proceed, MPFR must exactly represent the target floating point
13515 format, which only happens when the target base equals two. */
13516 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
f96bd2bf 13517 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13518 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)
13519 && TREE_CODE (arg3) == REAL_CST && !TREE_OVERFLOW (arg3))
9917422b 13520 {
13521 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13522 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13523 const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
13524
776a7bab 13525 if (real_isfinite (ra1) && real_isfinite (ra2) && real_isfinite (ra3))
9917422b 13526 {
e2eb2b7f 13527 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13528 const int prec = fmt->p;
13529 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
9917422b 13530 int inexact;
13531 mpfr_t m1, m2, m3;
13532
13533 mpfr_inits2 (prec, m1, m2, m3, NULL);
66fa16e6 13534 mpfr_from_real (m1, ra1, GMP_RNDN);
13535 mpfr_from_real (m2, ra2, GMP_RNDN);
13536 mpfr_from_real (m3, ra3, GMP_RNDN);
d4473c84 13537 mpfr_clear_flags ();
e2eb2b7f 13538 inexact = func (m1, m1, m2, m3, rnd);
9917422b 13539 result = do_mpfr_ckconv (m1, type, inexact);
13540 mpfr_clears (m1, m2, m3, NULL);
13541 }
13542 }
13543
13544 return result;
13545}
13546
d92f994c 13547/* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
13548 the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
d735c391 13549 If ARG_SINP and ARG_COSP are NULL then the result is returned
13550 as a complex value.
d92f994c 13551 The type is taken from the type of ARG and is used for setting the
13552 precision of the calculation and results. */
13553
13554static tree
13555do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
13556{
bd7d6fa4 13557 tree const type = TREE_TYPE (arg);
d92f994c 13558 tree result = NULL_TREE;
13559
13560 STRIP_NOPS (arg);
13561
bd7d6fa4 13562 /* To proceed, MPFR must exactly represent the target floating point
13563 format, which only happens when the target base equals two. */
13564 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
f96bd2bf 13565 && TREE_CODE (arg) == REAL_CST
13566 && !TREE_OVERFLOW (arg))
d92f994c 13567 {
13568 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
13569
776a7bab 13570 if (real_isfinite (ra))
d92f994c 13571 {
e2eb2b7f 13572 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13573 const int prec = fmt->p;
13574 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
d92f994c 13575 tree result_s, result_c;
13576 int inexact;
13577 mpfr_t m, ms, mc;
13578
13579 mpfr_inits2 (prec, m, ms, mc, NULL);
66fa16e6 13580 mpfr_from_real (m, ra, GMP_RNDN);
d4473c84 13581 mpfr_clear_flags ();
e2eb2b7f 13582 inexact = mpfr_sin_cos (ms, mc, m, rnd);
d92f994c 13583 result_s = do_mpfr_ckconv (ms, type, inexact);
13584 result_c = do_mpfr_ckconv (mc, type, inexact);
13585 mpfr_clears (m, ms, mc, NULL);
13586 if (result_s && result_c)
13587 {
d735c391 13588 /* If we are to return in a complex value do so. */
13589 if (!arg_sinp && !arg_cosp)
13590 return build_complex (build_complex_type (type),
13591 result_c, result_s);
13592
d92f994c 13593 /* Dereference the sin/cos pointer arguments. */
13594 arg_sinp = build_fold_indirect_ref (arg_sinp);
13595 arg_cosp = build_fold_indirect_ref (arg_cosp);
13596 /* Proceed if valid pointer type were passed in. */
13597 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
13598 && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
13599 {
13600 /* Set the values. */
41076ef6 13601 result_s = fold_build2 (MODIFY_EXPR, type, arg_sinp,
35cc02b5 13602 result_s);
d92f994c 13603 TREE_SIDE_EFFECTS (result_s) = 1;
41076ef6 13604 result_c = fold_build2 (MODIFY_EXPR, type, arg_cosp,
35cc02b5 13605 result_c);
d92f994c 13606 TREE_SIDE_EFFECTS (result_c) = 1;
13607 /* Combine the assignments into a compound expr. */
13608 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13609 result_s, result_c));
13610 }
13611 }
13612 }
13613 }
13614 return result;
13615}
65dd1378 13616
65dd1378 13617/* If argument ARG1 is an INTEGER_CST and ARG2 is a REAL_CST, call the
13618 two-argument mpfr order N Bessel function FUNC on them and return
13619 the resulting value as a tree with type TYPE. The mpfr precision
13620 is set to the precision of TYPE. We assume that function FUNC
13621 returns zero if the result could be calculated exactly within the
13622 requested precision. */
13623static tree
13624do_mpfr_bessel_n (tree arg1, tree arg2, tree type,
13625 int (*func)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
13626 const REAL_VALUE_TYPE *min, bool inclusive)
13627{
13628 tree result = NULL_TREE;
13629
13630 STRIP_NOPS (arg1);
13631 STRIP_NOPS (arg2);
13632
13633 /* To proceed, MPFR must exactly represent the target floating point
13634 format, which only happens when the target base equals two. */
13635 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13636 && host_integerp (arg1, 0)
13637 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
13638 {
13639 const HOST_WIDE_INT n = tree_low_cst(arg1, 0);
13640 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg2);
13641
13642 if (n == (long)n
776a7bab 13643 && real_isfinite (ra)
65dd1378 13644 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min)))
13645 {
e2eb2b7f 13646 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13647 const int prec = fmt->p;
13648 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
65dd1378 13649 int inexact;
13650 mpfr_t m;
13651
13652 mpfr_init2 (m, prec);
13653 mpfr_from_real (m, ra, GMP_RNDN);
13654 mpfr_clear_flags ();
e2eb2b7f 13655 inexact = func (m, n, m, rnd);
65dd1378 13656 result = do_mpfr_ckconv (m, type, inexact);
13657 mpfr_clear (m);
13658 }
13659 }
13660
13661 return result;
13662}
e5407ca6 13663
13664/* If arguments ARG0 and ARG1 are REAL_CSTs, call mpfr_remquo() to set
13665 the pointer *(ARG_QUO) and return the result. The type is taken
13666 from the type of ARG0 and is used for setting the precision of the
13667 calculation and results. */
13668
13669static tree
13670do_mpfr_remquo (tree arg0, tree arg1, tree arg_quo)
13671{
13672 tree const type = TREE_TYPE (arg0);
13673 tree result = NULL_TREE;
13674
13675 STRIP_NOPS (arg0);
13676 STRIP_NOPS (arg1);
13677
13678 /* To proceed, MPFR must exactly represent the target floating point
13679 format, which only happens when the target base equals two. */
13680 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13681 && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
13682 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1))
13683 {
13684 const REAL_VALUE_TYPE *const ra0 = TREE_REAL_CST_PTR (arg0);
13685 const REAL_VALUE_TYPE *const ra1 = TREE_REAL_CST_PTR (arg1);
13686
776a7bab 13687 if (real_isfinite (ra0) && real_isfinite (ra1))
e5407ca6 13688 {
e2eb2b7f 13689 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13690 const int prec = fmt->p;
13691 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
e5407ca6 13692 tree result_rem;
13693 long integer_quo;
13694 mpfr_t m0, m1;
13695
13696 mpfr_inits2 (prec, m0, m1, NULL);
13697 mpfr_from_real (m0, ra0, GMP_RNDN);
13698 mpfr_from_real (m1, ra1, GMP_RNDN);
13699 mpfr_clear_flags ();
e2eb2b7f 13700 mpfr_remquo (m0, &integer_quo, m0, m1, rnd);
e5407ca6 13701 /* Remquo is independent of the rounding mode, so pass
13702 inexact=0 to do_mpfr_ckconv(). */
13703 result_rem = do_mpfr_ckconv (m0, type, /*inexact=*/ 0);
13704 mpfr_clears (m0, m1, NULL);
13705 if (result_rem)
13706 {
13707 /* MPFR calculates quo in the host's long so it may
13708 return more bits in quo than the target int can hold
13709 if sizeof(host long) > sizeof(target int). This can
13710 happen even for native compilers in LP64 mode. In
13711 these cases, modulo the quo value with the largest
13712 number that the target int can hold while leaving one
13713 bit for the sign. */
13714 if (sizeof (integer_quo) * CHAR_BIT > INT_TYPE_SIZE)
13715 integer_quo %= (long)(1UL << (INT_TYPE_SIZE - 1));
13716
13717 /* Dereference the quo pointer argument. */
13718 arg_quo = build_fold_indirect_ref (arg_quo);
13719 /* Proceed iff a valid pointer type was passed in. */
13720 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_quo)) == integer_type_node)
13721 {
13722 /* Set the value. */
13723 tree result_quo = fold_build2 (MODIFY_EXPR,
13724 TREE_TYPE (arg_quo), arg_quo,
13725 build_int_cst (NULL, integer_quo));
13726 TREE_SIDE_EFFECTS (result_quo) = 1;
13727 /* Combine the quo assignment with the rem. */
13728 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13729 result_quo, result_rem));
13730 }
13731 }
13732 }
13733 }
13734 return result;
13735}
e84da7c1 13736
13737/* If ARG is a REAL_CST, call mpfr_lgamma() on it and return the
13738 resulting value as a tree with type TYPE. The mpfr precision is
13739 set to the precision of TYPE. We assume that this mpfr function
13740 returns zero if the result could be calculated exactly within the
13741 requested precision. In addition, the integer pointer represented
13742 by ARG_SG will be dereferenced and set to the appropriate signgam
13743 (-1,1) value. */
13744
13745static tree
13746do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type)
13747{
13748 tree result = NULL_TREE;
13749
13750 STRIP_NOPS (arg);
13751
13752 /* To proceed, MPFR must exactly represent the target floating point
13753 format, which only happens when the target base equals two. Also
13754 verify ARG is a constant and that ARG_SG is an int pointer. */
13755 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13756 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)
13757 && TREE_CODE (TREE_TYPE (arg_sg)) == POINTER_TYPE
13758 && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg_sg))) == integer_type_node)
13759 {
13760 const REAL_VALUE_TYPE *const ra = TREE_REAL_CST_PTR (arg);
13761
13762 /* In addition to NaN and Inf, the argument cannot be zero or a
13763 negative integer. */
776a7bab 13764 if (real_isfinite (ra)
e84da7c1 13765 && ra->cl != rvc_zero
13766 && !(real_isneg(ra) && real_isinteger(ra, TYPE_MODE (type))))
13767 {
e2eb2b7f 13768 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13769 const int prec = fmt->p;
13770 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
e84da7c1 13771 int inexact, sg;
13772 mpfr_t m;
13773 tree result_lg;
13774
13775 mpfr_init2 (m, prec);
13776 mpfr_from_real (m, ra, GMP_RNDN);
13777 mpfr_clear_flags ();
e2eb2b7f 13778 inexact = mpfr_lgamma (m, &sg, m, rnd);
e84da7c1 13779 result_lg = do_mpfr_ckconv (m, type, inexact);
13780 mpfr_clear (m);
13781 if (result_lg)
13782 {
13783 tree result_sg;
13784
13785 /* Dereference the arg_sg pointer argument. */
13786 arg_sg = build_fold_indirect_ref (arg_sg);
13787 /* Assign the signgam value into *arg_sg. */
13788 result_sg = fold_build2 (MODIFY_EXPR,
13789 TREE_TYPE (arg_sg), arg_sg,
13790 build_int_cst (NULL, sg));
13791 TREE_SIDE_EFFECTS (result_sg) = 1;
13792 /* Combine the signgam assignment with the lgamma result. */
13793 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13794 result_sg, result_lg));
13795 }
13796 }
13797 }
13798
13799 return result;
13800}
75a70cf9 13801
239d491a 13802#ifdef HAVE_mpc
13803/* If argument ARG is a COMPLEX_CST, call the one-argument mpc
13804 function FUNC on it and return the resulting value as a tree with
13805 type TYPE. The mpfr precision is set to the precision of TYPE. We
13806 assume that function FUNC returns zero if the result could be
13807 calculated exactly within the requested precision. */
13808
13809static tree
13810do_mpc_arg1 (tree arg, tree type, int (*func)(mpc_ptr, mpc_srcptr, mpc_rnd_t))
13811{
13812 tree result = NULL_TREE;
13813
13814 STRIP_NOPS (arg);
13815
13816 /* To proceed, MPFR must exactly represent the target floating point
13817 format, which only happens when the target base equals two. */
13818 if (TREE_CODE (arg) == COMPLEX_CST && !TREE_OVERFLOW (arg)
13819 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE
13820 && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg))))->b == 2)
13821 {
13822 const REAL_VALUE_TYPE *const re = TREE_REAL_CST_PTR (TREE_REALPART (arg));
13823 const REAL_VALUE_TYPE *const im = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
13824
13825 if (real_isfinite (re) && real_isfinite (im))
13826 {
13827 const struct real_format *const fmt =
13828 REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
13829 const int prec = fmt->p;
13830 const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
44d89feb 13831 const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
239d491a 13832 int inexact;
13833 mpc_t m;
13834
13835 mpc_init2 (m, prec);
c3cfad90 13836 mpfr_from_real (mpc_realref(m), re, rnd);
13837 mpfr_from_real (mpc_imagref(m), im, rnd);
239d491a 13838 mpfr_clear_flags ();
44d89feb 13839 inexact = func (m, m, crnd);
652d9409 13840 result = do_mpc_ckconv (m, type, inexact, /*force_convert=*/ 0);
239d491a 13841 mpc_clear (m);
13842 }
13843 }
13844
13845 return result;
13846}
c699fab8 13847
13848/* If arguments ARG0 and ARG1 are a COMPLEX_CST, call the two-argument
13849 mpc function FUNC on it and return the resulting value as a tree
13850 with type TYPE. The mpfr precision is set to the precision of
13851 TYPE. We assume that function FUNC returns zero if the result
652d9409 13852 could be calculated exactly within the requested precision. If
13853 DO_NONFINITE is true, then fold expressions containing Inf or NaN
13854 in the arguments and/or results. */
c699fab8 13855
63e89698 13856#ifdef HAVE_mpc
13857tree
652d9409 13858do_mpc_arg2 (tree arg0, tree arg1, tree type, int do_nonfinite,
c699fab8 13859 int (*func)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t))
13860{
13861 tree result = NULL_TREE;
13862
13863 STRIP_NOPS (arg0);
13864 STRIP_NOPS (arg1);
13865
13866 /* To proceed, MPFR must exactly represent the target floating point
13867 format, which only happens when the target base equals two. */
13868 if (TREE_CODE (arg0) == COMPLEX_CST && !TREE_OVERFLOW (arg0)
13869 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
13870 && TREE_CODE (arg1) == COMPLEX_CST && !TREE_OVERFLOW (arg1)
13871 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE
13872 && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))))->b == 2)
13873 {
13874 const REAL_VALUE_TYPE *const re0 = TREE_REAL_CST_PTR (TREE_REALPART (arg0));
13875 const REAL_VALUE_TYPE *const im0 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg0));
13876 const REAL_VALUE_TYPE *const re1 = TREE_REAL_CST_PTR (TREE_REALPART (arg1));
13877 const REAL_VALUE_TYPE *const im1 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg1));
13878
652d9409 13879 if (do_nonfinite
13880 || (real_isfinite (re0) && real_isfinite (im0)
13881 && real_isfinite (re1) && real_isfinite (im1)))
c699fab8 13882 {
13883 const struct real_format *const fmt =
13884 REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
13885 const int prec = fmt->p;
13886 const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
13887 const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
13888 int inexact;
13889 mpc_t m0, m1;
13890
13891 mpc_init2 (m0, prec);
13892 mpc_init2 (m1, prec);
13893 mpfr_from_real (mpc_realref(m0), re0, rnd);
13894 mpfr_from_real (mpc_imagref(m0), im0, rnd);
13895 mpfr_from_real (mpc_realref(m1), re1, rnd);
13896 mpfr_from_real (mpc_imagref(m1), im1, rnd);
13897 mpfr_clear_flags ();
13898 inexact = func (m0, m0, m1, crnd);
652d9409 13899 result = do_mpc_ckconv (m0, type, inexact, do_nonfinite);
c699fab8 13900 mpc_clear (m0);
13901 mpc_clear (m1);
13902 }
13903 }
13904
13905 return result;
13906}
13907# endif
239d491a 13908#endif /* HAVE_mpc */
13909
75a70cf9 13910/* FIXME tuples.
13911 The functions below provide an alternate interface for folding
13912 builtin function calls presented as GIMPLE_CALL statements rather
13913 than as CALL_EXPRs. The folded result is still expressed as a
13914 tree. There is too much code duplication in the handling of
13915 varargs functions, and a more intrusive re-factoring would permit
13916 better sharing of code between the tree and statement-based
13917 versions of these functions. */
13918
13919/* Construct a new CALL_EXPR using the tail of the argument list of STMT
13920 along with N new arguments specified as the "..." parameters. SKIP
13921 is the number of arguments in STMT to be omitted. This function is used
13922 to do varargs-to-varargs transformations. */
13923
13924static tree
13925gimple_rewrite_call_expr (gimple stmt, int skip, tree fndecl, int n, ...)
13926{
13927 int oldnargs = gimple_call_num_args (stmt);
13928 int nargs = oldnargs - skip + n;
13929 tree fntype = TREE_TYPE (fndecl);
13930 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
13931 tree *buffer;
13932 int i, j;
13933 va_list ap;
389dd41b 13934 location_t loc = gimple_location (stmt);
75a70cf9 13935
13936 buffer = XALLOCAVEC (tree, nargs);
13937 va_start (ap, n);
13938 for (i = 0; i < n; i++)
13939 buffer[i] = va_arg (ap, tree);
13940 va_end (ap);
13941 for (j = skip; j < oldnargs; j++, i++)
13942 buffer[i] = gimple_call_arg (stmt, j);
13943
389dd41b 13944 return fold (build_call_array_loc (loc, TREE_TYPE (fntype), fn, nargs, buffer));
75a70cf9 13945}
13946
13947/* Fold a call STMT to __{,v}sprintf_chk. Return NULL_TREE if
13948 a normal call should be emitted rather than expanding the function
13949 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
13950
13951static tree
13952gimple_fold_builtin_sprintf_chk (gimple stmt, enum built_in_function fcode)
13953{
13954 tree dest, size, len, fn, fmt, flag;
13955 const char *fmt_str;
13956 int nargs = gimple_call_num_args (stmt);
13957
13958 /* Verify the required arguments in the original call. */
13959 if (nargs < 4)
13960 return NULL_TREE;
13961 dest = gimple_call_arg (stmt, 0);
13962 if (!validate_arg (dest, POINTER_TYPE))
13963 return NULL_TREE;
13964 flag = gimple_call_arg (stmt, 1);
13965 if (!validate_arg (flag, INTEGER_TYPE))
13966 return NULL_TREE;
13967 size = gimple_call_arg (stmt, 2);
13968 if (!validate_arg (size, INTEGER_TYPE))
13969 return NULL_TREE;
13970 fmt = gimple_call_arg (stmt, 3);
13971 if (!validate_arg (fmt, POINTER_TYPE))
13972 return NULL_TREE;
13973
13974 if (! host_integerp (size, 1))
13975 return NULL_TREE;
13976
13977 len = NULL_TREE;
13978
13979 if (!init_target_chars ())
13980 return NULL_TREE;
13981
13982 /* Check whether the format is a literal string constant. */
13983 fmt_str = c_getstr (fmt);
13984 if (fmt_str != NULL)
13985 {
13986 /* If the format doesn't contain % args or %%, we know the size. */
13987 if (strchr (fmt_str, target_percent) == 0)
13988 {
13989 if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
13990 len = build_int_cstu (size_type_node, strlen (fmt_str));
13991 }
13992 /* If the format is "%s" and first ... argument is a string literal,
13993 we know the size too. */
13994 else if (fcode == BUILT_IN_SPRINTF_CHK
13995 && strcmp (fmt_str, target_percent_s) == 0)
13996 {
13997 tree arg;
13998
13999 if (nargs == 5)
14000 {
14001 arg = gimple_call_arg (stmt, 4);
14002 if (validate_arg (arg, POINTER_TYPE))
14003 {
14004 len = c_strlen (arg, 1);
14005 if (! len || ! host_integerp (len, 1))
14006 len = NULL_TREE;
14007 }
14008 }
14009 }
14010 }
14011
14012 if (! integer_all_onesp (size))
14013 {
14014 if (! len || ! tree_int_cst_lt (len, size))
14015 return NULL_TREE;
14016 }
14017
14018 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
14019 or if format doesn't contain % chars or is "%s". */
14020 if (! integer_zerop (flag))
14021 {
14022 if (fmt_str == NULL)
14023 return NULL_TREE;
14024 if (strchr (fmt_str, target_percent) != NULL
14025 && strcmp (fmt_str, target_percent_s))
14026 return NULL_TREE;
14027 }
14028
14029 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
14030 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
14031 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
14032 if (!fn)
14033 return NULL_TREE;
14034
14035 return gimple_rewrite_call_expr (stmt, 4, fn, 2, dest, fmt);
14036}
14037
14038/* Fold a call STMT to {,v}snprintf. Return NULL_TREE if
14039 a normal call should be emitted rather than expanding the function
14040 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
14041 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
14042 passed as second argument. */
14043
14044tree
14045gimple_fold_builtin_snprintf_chk (gimple stmt, tree maxlen,
14046 enum built_in_function fcode)
14047{
14048 tree dest, size, len, fn, fmt, flag;
14049 const char *fmt_str;
14050
14051 /* Verify the required arguments in the original call. */
14052 if (gimple_call_num_args (stmt) < 5)
14053 return NULL_TREE;
14054 dest = gimple_call_arg (stmt, 0);
14055 if (!validate_arg (dest, POINTER_TYPE))
14056 return NULL_TREE;
14057 len = gimple_call_arg (stmt, 1);
14058 if (!validate_arg (len, INTEGER_TYPE))
14059 return NULL_TREE;
14060 flag = gimple_call_arg (stmt, 2);
14061 if (!validate_arg (flag, INTEGER_TYPE))
14062 return NULL_TREE;
14063 size = gimple_call_arg (stmt, 3);
14064 if (!validate_arg (size, INTEGER_TYPE))
14065 return NULL_TREE;
14066 fmt = gimple_call_arg (stmt, 4);
14067 if (!validate_arg (fmt, POINTER_TYPE))
14068 return NULL_TREE;
14069
14070 if (! host_integerp (size, 1))
14071 return NULL_TREE;
14072
14073 if (! integer_all_onesp (size))
14074 {
14075 if (! host_integerp (len, 1))
14076 {
14077 /* If LEN is not constant, try MAXLEN too.
14078 For MAXLEN only allow optimizing into non-_ocs function
14079 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
14080 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
14081 return NULL_TREE;
14082 }
14083 else
14084 maxlen = len;
14085
14086 if (tree_int_cst_lt (size, maxlen))
14087 return NULL_TREE;
14088 }
14089
14090 if (!init_target_chars ())
14091 return NULL_TREE;
14092
14093 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
14094 or if format doesn't contain % chars or is "%s". */
14095 if (! integer_zerop (flag))
14096 {
14097 fmt_str = c_getstr (fmt);
14098 if (fmt_str == NULL)
14099 return NULL_TREE;
14100 if (strchr (fmt_str, target_percent) != NULL
14101 && strcmp (fmt_str, target_percent_s))
14102 return NULL_TREE;
14103 }
14104
14105 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
14106 available. */
14107 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
14108 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
14109 if (!fn)
14110 return NULL_TREE;
14111
14112 return gimple_rewrite_call_expr (stmt, 5, fn, 3, dest, len, fmt);
14113}
14114
14115/* Builtins with folding operations that operate on "..." arguments
14116 need special handling; we need to store the arguments in a convenient
14117 data structure before attempting any folding. Fortunately there are
14118 only a few builtins that fall into this category. FNDECL is the
14119 function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
14120 result of the function call is ignored. */
14121
14122static tree
389dd41b 14123gimple_fold_builtin_varargs (tree fndecl, gimple stmt,
14124 bool ignore ATTRIBUTE_UNUSED)
75a70cf9 14125{
14126 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
14127 tree ret = NULL_TREE;
14128
14129 switch (fcode)
14130 {
14131 case BUILT_IN_SPRINTF_CHK:
14132 case BUILT_IN_VSPRINTF_CHK:
14133 ret = gimple_fold_builtin_sprintf_chk (stmt, fcode);
14134 break;
14135
14136 case BUILT_IN_SNPRINTF_CHK:
14137 case BUILT_IN_VSNPRINTF_CHK:
14138 ret = gimple_fold_builtin_snprintf_chk (stmt, NULL_TREE, fcode);
14139
14140 default:
14141 break;
14142 }
14143 if (ret)
14144 {
14145 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
14146 TREE_NO_WARNING (ret) = 1;
14147 return ret;
14148 }
14149 return NULL_TREE;
14150}
14151
14152/* A wrapper function for builtin folding that prevents warnings for
14153 "statement without effect" and the like, caused by removing the
14154 call node earlier than the warning is generated. */
14155
14156tree
14157fold_call_stmt (gimple stmt, bool ignore)
14158{
14159 tree ret = NULL_TREE;
14160 tree fndecl = gimple_call_fndecl (stmt);
389dd41b 14161 location_t loc = gimple_location (stmt);
75a70cf9 14162 if (fndecl
14163 && TREE_CODE (fndecl) == FUNCTION_DECL
14164 && DECL_BUILT_IN (fndecl)
14165 && !gimple_call_va_arg_pack_p (stmt))
14166 {
14167 int nargs = gimple_call_num_args (stmt);
14168
198622c0 14169 if (avoid_folding_inline_builtin (fndecl))
14170 return NULL_TREE;
75a70cf9 14171 /* FIXME: Don't use a list in this interface. */
14172 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
14173 {
14174 tree arglist = NULL_TREE;
14175 int i;
14176 for (i = nargs - 1; i >= 0; i--)
14177 arglist = tree_cons (NULL_TREE, gimple_call_arg (stmt, i), arglist);
14178 return targetm.fold_builtin (fndecl, arglist, ignore);
14179 }
14180 else
14181 {
14182 if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
14183 {
14184 tree args[MAX_ARGS_TO_FOLD_BUILTIN];
14185 int i;
14186 for (i = 0; i < nargs; i++)
14187 args[i] = gimple_call_arg (stmt, i);
389dd41b 14188 ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
75a70cf9 14189 }
14190 if (!ret)
14191 ret = gimple_fold_builtin_varargs (fndecl, stmt, ignore);
14192 if (ret)
14193 {
14194 /* Propagate location information from original call to
14195 expansion of builtin. Otherwise things like
14196 maybe_emit_chk_warning, that operate on the expansion
14197 of a builtin, will use the wrong location information. */
14198 if (gimple_has_location (stmt))
14199 {
14200 tree realret = ret;
14201 if (TREE_CODE (ret) == NOP_EXPR)
14202 realret = TREE_OPERAND (ret, 0);
14203 if (CAN_HAVE_LOCATION_P (realret)
14204 && !EXPR_HAS_LOCATION (realret))
389dd41b 14205 SET_EXPR_LOCATION (realret, loc);
75a70cf9 14206 return realret;
14207 }
14208 return ret;
14209 }
14210 }
14211 }
14212 return NULL_TREE;
14213}